冰楓論壇

 找回密碼
 立即註冊
ads_sugarbook
搜索
查看: 563|回覆: 0
打印 上一主題 下一主題

[討論] STM8S003F3P6單片機製作萬用充電器

[複製鏈接]

2609

主題

0

好友

947

積分

高級會員

Rank: 4

UID
373967
帖子
7454
主題
2609
精華
0
積分
947
楓幣
11347
威望
927
存款
16000
贊助金額
0
推廣
0
GP
1205
閱讀權限
50
在線時間
408 小時
註冊時間
2023-1-12
最後登入
2024-5-7

2023端午節紀念勳章 2023中秋節紀念勳章 2023聖誕節紀念勳章

跳轉到指定樓層
1
發表於 2023-4-16 15:16:26 |只看該作者 |倒序瀏覽
這個萬用充電器支援3V、5V、9V、12V、24V的充電,並且可以通過LCD顯示器顯示目前的電壓和電流值。

所需零件:

STM8S003F3P6單片機
16x2 LCD顯示器
5V電源供應器
10k歐姆電阻器
電位器
2N3904 NPN電晶體
1N4007整流二極管
按鈕開關
電阻、電容等基本零件
連接腳位:

rust
Copy code
LCD顯示器:
VSS -> GND
VDD -> 5V電源
V0 -> 電位器中間腳位
RS -> PB4
RW -> GND
E -> PB5
D4 -> PB0
D5 -> PB1
D6 -> PB2
D7 -> PB3
A -> 5V電源
K -> GND

按鈕開關:
1端 -> 5V電源
2端 -> PA3

NPN電晶體:
C極 -> 5V電源
B極 -> PA2
E極 -> 輸出端

整流二極管:
正極 -> 輸出端
負極 -> 5V電源

其他零件:
各種電阻、電容等基本零件按需使用
程式碼:


#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "stm8s.h"
#include "stm8s_gpio.h"
#include "stm8s_tim1.h"
#include "stm8s_adc1.h"
#include "stm8s_clk.h"
#include "stm8s_lcd.h"

#define LCD_RS_PIN        GPIO_PIN_4
#define LCD_RW_PIN        GPIO_PIN_5
#define LCD_E_PIN         GPIO_PIN_6
#define LCD_D4_PIN        GPIO_PIN_0
#define LCD_D5_PIN        GPIO_PIN_1
#define LCD_D6_PIN        GPIO_PIN_2
#define LCD_D7_PIN        GPIO_PIN_3

#define BUTTON_PIN        GPIO_PIN_3
#define CHARGE_PIN        GPIO_PIN_2

#define CHARGE_3V         511   // ADC測量到的3V電壓值
#define CHARGE_5V         817   // ADC測量到的5V電壓值
#define CHARGE_9V         1517  // ADC測量到的9V電壓值
#define CHARGE_12V        2046  // ADC測量到的12V電壓值
#define CHARGE_24V        4095  // ADC測量到的24V電壓值

#define LCD_ROW_1         0
#define LCD_ROW_2         1
#define LCD_COL_1         0

// 定義全局變量
uint16_t charge_voltage = 0;   // 充電器輸出電壓
uint16_t charge_current = 0;   // 充電器輸出電流
bool button_pressed = false;   // 按鈕是否按下
bool charging = false;         // 是否正在充電
bool charged = false;          // 是否充滿電
bool over_current = false;     // 是否過流
bool over_voltage = false;     // 是否過壓
uint16_t over_current_count = 0;  // 過流計數器
uint16_t over_voltage_count = 0;  // 過壓計數器

// 定義函數
void init_lcd(void);
void display_voltage(void);
void display_current(void);
void check_button(void);
void check_over_current(void);
void check_over_voltage(void);
void start_charge(void);
void stop_charge(void);

// 主函數
void main(void)
{
  // 初始化單片機
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);   // 將主時鐘頻率設置為16MHz
  GPIO_DeInit(GPIOA);
  GPIO_DeInit(GPIOB);
  LCD_DeInit();
  TIM1_DeInit();
  ADC1_DeInit();
  
  // 初始化GPIO口
  GPIO_Init(GPIOA, BUTTON_PIN, GPIO_MODE_IN_PU_NO_IT);   // 配置按鈕口為上拉輸入
  GPIO_Init(GPIOA, CHARGE_PIN, GPIO_MODE_OUT_PP_LOW_FAST);  // 配置充電器控制口為推挽輸出
  GPIO_Init(GPIOB, LCD_RS_PIN, GPIO_MODE_OUT_PP_LOW_FAST);   // 配置LCD RS口為推挽輸出
  GPIO_Init(GPIOB, LCD_RW_PIN, GPIO_MODE_OUT_PP_LOW_FAST);   // 配置LCD RW口為推挽輸出
  GPIO_Init(GPIOB, LCD_E_PIN, GPIO_MODE_OUT_PP_LOW_FAST);    // 配置LCD E口為推挽輸出
  GPIO_Init(GPIOB, LCD_D4_PIN, GPIO_MODE_OUT_PP_LOW_FAST);   // 配置LCD D4口為推挽輸出
  GPIO_Init(GPIOB, LCD_D5_PIN, GPIO_MODE_OUT_PP_LOW_FAST);   // 配置LCD D5口為推挽輸出
  GPIO_Init(GPIOB, LCD_D6_PIN, GPIO_MODE_OUT_PP_LOW_FAST);   // 配置LCD D6口為推挽輸出
  GPIO_Init(GPIOB, LCD_D7_PIN, GPIO_MODE_OUT_PP_LOW_FAST);   // 配置LCD D7口為推挽輸出
  
  // 初始化LCD顯示器
  init_lcd();
  
  // 初始化定時器1,用於ADC采樣
  TIM1_TimeBaseInit(0, TIM1_COUNTERMODE_UP, 63, 0);
  TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
  TIM1_Cmd(ENABLE);
  
// 測量充電器輸出電壓和電流
while (1)
{
if (charging)
{
// 檢查是否過流或過壓
check_over_current();
check_over_voltage();


  if (over_current || over_voltage)
  {
    // 如果過流或過壓,停止充電
    stop_charge();
  }
  else
  {
    // 否則繼續充電
    GPIO_WriteHigh(GPIOA, CHARGE_PIN);   // 打開充電器
    ADC1_StartConversion();
    while (!ADC1_GetFlagStatus(ADC1_FLAG_EOC))
    {
      // 等待ADC轉換完成
    }
    charge_voltage = ADC1_GetConversionValue();   // 獲取充電器輸出電壓
    display_voltage();
    charge_current = ADC1_GetConversionValue();   // 獲取充電器輸出電流
    display_current();
    if (charge_current < CHARGE_CURRENT_THRESHOLD && charge_voltage >= CHARGE_VOLTAGE_THRESHOLD)
    {
      // 如果充電電流小於閾值且充電電壓大於閾值,表示充滿電了
      charged = true;
      stop_charge();
    }
  }
}
else
{
  // 檢查按鈕是否按下,如果按下就開始充電
  check_button();
  if (button_pressed)
  {
    start_charge();
  }
}
}
}

// 初始化LCD顯示器
void init_lcd(void)
{
LCD_Init(LCD_DISPLAY_ON_CURSOR_OFF_BLINK_OFF);
LCD_Clear();
LCD_GotoXY(0, 0);
LCD_SendString("Charge voltage:");
LCD_GotoXY(0, 1);
LCD_SendString("Charge current:");
}

// 顯示充電器輸出電壓
void display_voltage(void)
{
char buffer[16];
LCD_GotoXY(15, 0);
sprintf(buffer, "%d.%02dV", charge_voltage / 100, charge_voltage % 100);
LCD_SendString(buffer);
}

// 顯示充電器輸出電流
void display_current(void)
{
char buffer[16];
LCD_GotoXY(15, 1);
sprintf(buffer, "%d.%02dA", charge_current / 100, charge_current % 100);
LCD_SendString(buffer);
}

// 檢查按鈕是否按下
void check_button(void)
{
if (GPIO_ReadInputPin(GPIOA, BUTTON_PIN) == RESET)
{
button_pressed = true;
while (GPIO_ReadInputPin(GPIOA, BUTTON_PIN) == RESET)
{
// 等待按鈕釋放
}
}
else
{
button_pressed = false;
}
}

// 檢查是否過流
void check_over_current(void)
{
if (charge_current > OVER_CURRENT_THRESHOLD)
{
over_current_count++;
if (over_current_count > OVER_CURRENT_COUNT_THRESHOLD)
{
over_current = true;
over_current_count = 0;
}
}
else
{
over_current_count = 0;
}

// 檢查是否過壓
void check_over_voltage(void)
{
if (charge_voltage > OVER_VOLTAGE_THRESHOLD)
{
over_voltage_count++;
if (over_voltage_count > OVER_VOLTAGE_COUNT_THRESHOLD)
{
over_voltage = true;
over_voltage_count = 0;
}
}
else
{
over_voltage_count = 0;
}
}

// 停止充電
void stop_charge(void)
{
GPIO_WriteLow(GPIOA, CHARGE_PIN); // 關閉充電器
charging = false;
over_current = false;
over_voltage = false;
}

// 開始充電
void start_charge(void)
{
charged = false;
charging = true;
}

// 初始化ADC
void init_adc(void)
{
ADC1_DeInit();
ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, ADC1_CHANNEL_2, ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL2, DISABLE);
ADC1_Cmd(ENABLE);
}

// 初始化按鈕和充電器引腳
void init_pins(void)
{
GPIO_Init(BUTTON_PORT, BUTTON_PIN, GPIO_MODE_IN_FL_NO_IT);
GPIO_Init(GPIOA, CHARGE_PIN, GPIO_MODE_OUT_PP_LOW_FAST);
}

// 初始化計時器
void init_timer(void)
{
TIM4_TimeBaseInit(TIM4_PRESCALER_128, 124);
TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
TIM4_Cmd(ENABLE);
}

// 計時器中斷處理函數
INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
{
TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
if (charging && !charged)
{
time_count++;
if (time_count > CHARGE_TIME_THRESHOLD)
{
stop_charge();
}
}
}

// 主程序
void main(void)
{
// 初始化
init_pins();
init_adc();
init_timer();
enableInterrupts();

// 主循環
while (1)
{
// 檢查按鈕是否按下
if (GPIO_ReadInputPin(BUTTON_PORT, BUTTON_PIN) == RESET)
{
// 開始充電
start_charge();
GPIO_WriteHigh(GPIOA, CHARGE_PIN); // 開啟充電器
}
// 檢查是否充滿
if (charged)
{
  stop_charge();
}

// 檢查是否過電流
check_over_current();

// 檢查是否過壓
check_over_voltage();
}
}


至於具體的硬體連接腳位,可以根據所使用的萬用板或硬體模組進行對應設置。
需要注意的是,由於不同的硬體模組或萬用板可能采用不同的引腳定義方式,因此需要根據具體的情況進行修改。
收藏收藏0 推0 噓0


把本文推薦給朋友或其他網站上,每次被點擊增加您在本站積分: 1骰子
複製連結並發給好友,以賺取推廣點數
簡單兩步驟,註冊、分享網址,即可獲得獎勵! 一起推廣文章換商品、賺$$
高級模式
B Color Image Link Quote Code Smilies |上傳

廣告刊登意見回饋關於我們職位招聘本站規範DMCA隱私權政策

Copyright © 2011-2024 冰楓論壇, All rights reserved

免責聲明:本網站是以即時上載留言的方式運作,本站對所有留言的真實性、完整性及立場等,不負任何法律責任。

而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。

小黑屋|手機版|冰楓論壇

GMT+8, 2024-5-7 14:59

回頂部