基于STM8单片机的锂电池电压检测程序

        这里分享一个前一段时间写的一个单片机程序。程序的主要功能是对锂电池充放电模块的锂电池电压和输出电压进行检测,并将检测后的电压用数码管进行显示。

        下图呢就是实际的显示效果,左侧是锂电池的电压,右侧是输出电压。

        程序的主控芯片是STM8S103F3P。用的是下图的最小系统板。

基本参数如下:

        1、核心尺寸:8bit

        2、速度:16MHz

        3、连接性:12C,IrDA,LIN,SPI, UART/USART4、外设:欠压检测/复位,POR,PWM,WDT

        5、I/0数:16

        6、程序存储容量:8KB(8Kx8)

        7、程序存储器类型:闪存FLASH 可擦写一万次

        8、EEPROM容量:640x8

        9、RAM容量:1Kx8

        10、电压-电源(Vcc/Vdd): 2.95V~5.5V

        11、数据转换器:A/D 5x10b

        12、振荡器类型:内部

        13、工作温度:-40°C~85°C(TA)

        数码管显示部分用的是TM1637驱动的数码管模块。该模块是一个12脚的带时钟点的4位共阳数码管(0.36英寸)的显示模块,驱动芯片为TM1637,只需2根信号线即可使单片机控制4位8段数码管。

模块特点如下:

        显示器件为4位共阳红字数码管;

        数码管8级灰度可调;

        控制接口电平可为5V或3.3V;

        4个M2螺丝定位孔,便于安装。

数码管模块的:

        CLK引脚与PB4引脚相连;

        DIO引脚与PB5引脚相连。

        由于本次使用的单片机的ADC部分为3.3V供电,而锂电池电压和输出电压都大于3.3V,所以这里通过串接电阻分压的方式来实现电压的检测。程序中分别使用单片机ADC的通道2、通道3、通道4对输入端电压、锂电池电压及输出端电压进行检测。

        程序中利用单片机的定时器4进行采样周期定时,采样时间到后程序控制ADC进行电压采集和计算,并进行了10次累加求平均值,最后将采集的电压转换为实际电压进行显示。

/**
  ******************************************************************************
  * @file    Project/main.c 
  * @author  MCD Application Team
  * @version V2.1.0
  * @date    18-November-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */ 


/* Includes ------------------------------------------------------------------*/

#include "stm8s.h"
#include "TM1637.h"
#include "math.h"

/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
//#define LED_GPIO_PORT  (GPIOB)
//#define LED_GPIO_PINS  (GPIO_PIN_5)

//定时电压结构体
typedef struct
{
  float in_vol ;
  float out_vol ;
  float bat_vol ;
} voltage ;
uint8_t ad_buf[10] ;
uint16_t sleep_cnt = 0 ;
void Init_ADC(void)
{
        //GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_IN_FL_NO_IT);
        //单次扫描模式
        /*ADC1_DeInit();
        ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, ADC1_CHANNEL_2, ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_ALL, ENABLE);
        ADC1_Cmd(ENABLE);*/
        //连续扫描模式
        ADC1_DeInit();//ADC 相关寄存器恢复默认值
        //初始化 ADC:连续转换/通道 8/时钟分频/关闭事件/数据右对齐/使能施密特触发器
        ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, ADC1_CHANNEL_5, ADC1_PRESSEL_FCPU_D2,
        ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_ALL,ENABLE);//该处在串口发送及接收时需配置为ENABLE,否则会出现无法发送的现象。
        ADC1_ScanModeCmd(ENABLE);
        ADC1_Cmd(ENABLE);//使能 ADC
}
uint16_t i=0;
uint8_t sample_flag = 0 ;
uint8_t sample_cnt = 0 ;
voltage m_state ;
/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void Init_GPIO(void)
{
	GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);
}
void Init_Timer4(void)
{
	/*TIM4_UpdateDisableConfig(ENABLE);//允许更新事件
	TIM4_ARRPreloadConfig(ENABLE);//自动重装
	TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);//中断配置,更新中断
	TIM4_SetCounter(0xff);//计数器初值
	TIM4_SetAutoreload(0xFF);//计数器自动重装的初值
	TIM4_PrescalerConfig(TIM4_PRESCALER_128, TIM4_PSCRELOADMODE_UPDATE);//预分频值
	*/
	TIM4_TimeBaseInit(TIM4_PRESCALER_128, 0x82);
        /* Clear TIM4 update flag */
        TIM4_ClearFlag(TIM4_FLAG_UPDATE);
	 /* Enable update interrupt */
	TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
	TIM4_Cmd(ENABLE);
}



void main(void)
{
   // ErrorStatus clk_return_status;
    //FlagStatus flag_status;
    u16 u16_adc1_value1 ;
    u16 u16_adc1_value2 ;
    u16 u16_adc1_value3 ;
    u16 display_cnt = 0 ;
    float last_input = 0 ;
    float last_output = 0 ;
    /*  Configuration  -----------------------------------------*/
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//不分频
    CLK_HSICmd(ENABLE);         //开始内部高频RC
    Init_ADC();
    Init_Timer4();
    enableInterrupts();
    GPIO_init();
    //TM1637_display(0x00,0x00,0,0x00,0x01);
    sleep_cnt = 0 ;
    while (1)
    {
      
        if(sample_flag==1)
        {
          sample_flag = 0 ;
          /* ADC1_StartConversion();
          flag_status = ADC1_GetFlagStatus(ADC1_FLAG_EOC);
          u16_adc1_value = ADC1_GetConversionValue();*/
          ADC1_StartConversion();//开启一次转换
          while(!ADC1_GetFlagStatus(ADC1_FLAG_EOC));//等待转换完成
          ADC1_ClearFlag(ADC1_FLAG_EOC);//软件清除
          u16_adc1_value1+=(u16)ADC1_GetBufferValue(ADC1_SCHMITTTRIG_CHANNEL2);//读取AIN2的值
          u16_adc1_value2+=(u16)ADC1_GetBufferValue(ADC1_SCHMITTTRIG_CHANNEL3);//读取AIN4的值
          u16_adc1_value3+=(u16)ADC1_GetBufferValue(ADC1_SCHMITTTRIG_CHANNEL4);//读取AIN4的值
          sample_cnt ++ ;
          if(sample_cnt>=10)
          {
            sample_cnt = 0 ;
           
            m_state.in_vol  = (u16_adc1_value1 / 10)*0.03223*1.4545  ;
            m_state.out_vol = (u16_adc1_value2 / 10)*0.03223*3.2 ;
            m_state.bat_vol = (u16_adc1_value3 / 10)*0.03223*2 ;
            u16_adc1_value1 = 0 ;
            u16_adc1_value2 = 0 ;
            u16_adc1_value3 = 0 ;
          }
          display_cnt++;
        }
        
        if(display_cnt>999&&sleep_cnt < 10)
        {
          display_cnt=0;
          TM1637_display((int)m_state.bat_vol/10%10,(int)m_state.bat_vol%10,(int)m_state.out_vol/10%10,(int)m_state.out_vol%10,0x01);
          sleep_cnt ++ ;
        }else if(sleep_cnt>=9)
        {
          
          if(((last_output-m_state.out_vol)>0.5)||((m_state.in_vol-last_input)>0.8))
          {
            sleep_cnt = 0 ;
          }
          last_input = m_state.in_vol ;
          last_output = m_state.out_vol ;
          TM1637_display(21,21,21,21,0);
        }
         
    }
  
}

#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(u8* file, u32 line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

        工程是基于IAR FOR STM创建的。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 首先,STM32F103是一款高性能的32位微控制器,其能够实现多种功能。对于锂电池电量显示STM32F103可以通过读取电池的电压实现电量显示。在此之前,需要对锂电池电压进行采样,常见的采样方式是使用ADC进行模拟信号的转换,将电压转换为数字信号,再通过电量计算公式计算得到电量的百分比。此外,在计算电量时需要考虑锂电池的特性,因为锂电池电压会随着使用时间和充电状态而有变化,因此需要进行校准。 在实际应用中,还可以通过添加显示屏等外设来实现电量显示。可以使用LCD、LED等显示屏来显示电量的百分比值。此外,也可以使用蜂鸣器来进行声音提示,告知用户电量的情况。 总之,STM32F103可以通过读取锂电池电压实现电量显示,并且可以通过各种外设来进行展示。但是,在实际应用中需要注意对锂电池的特性和电量计算公式进行了解和校准,确保电量的准确性。 ### 回答2: stm32f103可以通过ADC(模数转换器)模块来读取锂电池电量,并将读取的电量数值转换为电量百分比进行显示。首先需要将锂电池的正极和负极分别接入ADC模块的输入端口,再通过编程设置ADC模块的工作模式和读取精度。具体而言,可以选择单次或连续采样模式,以及不同的采样周期和采样分辨率。一般来说,为了保证精度和节省功耗,推荐使用低速转换模式和12位精度。读取到电量数值后,可以预先通过工厂校准或手动校准来转换为具体的电量百分比,并显示在LED、LCD等显示器上。此外,为了避免过度放电和过充电等安全问题,还可以设置电量上下限保护,当电量低于或超过阈值时触发报警或自动断电等措施。综上所述,stm32f103可以通过ADC模块来实现锂电池电量的准确测量和可视化显示,为移动设备、车载系统等应用提供了可靠的能源管理解决方案。 ### 回答3: stm32f103可以通过读取锂电池电量电压值来对其电量进行显示。具体来说,stm32f103可以通过内置的10位模数转换器(ADC)读取电池电压值,并通过一定的算法将电压值转换为实际的电量百分比值进行显示。 在实际应用中,可以通过将ADC引脚连接到锂电池的正负极获得电压值,然后通过编程进行转换和显示。为了提高显示的精度和准确性,还可以采用电压分压器等辅助电路进行电压的修正和调整。 当锂电池电量下降时,stm32f103可以持续监测电池电压值,并对其所代表的电量进行动态更新,以实时反映锂电池电量情况。同时,stm32f103还可以通过控制不同的LED灯来显示不同的电量状态,比如绿色表示电量充足,黄色表示电量较低,红色表示电量极低等。 总的来说,stm32f103可以通过其强大的ADC和灵活的编程能力,对锂电池电量进行精确和实时的显示,为锂电池的应用提供了可靠和实用的电量监测方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西天取经的熊猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值