📄 batcharge.c
字号:
#include <msp430x11x2.h>
#include "batCharge.h"
unsigned int AdcData[3] = {0};
// 恒流/恒压判别阶段
unsigned int const_volt = 0;
unsigned int timedelay = 0;
unsigned int timercounts = 0;
unsigned int delayflag = 0;
void main(void)
{
//停止看门狗
WDTCTL = WDTPW + WDTHOLD;
//初始化端口
init_Port();
init_Clk();
init_PWM();
init_ADC();
_BIS_SR(LPM0_bits+GIE);
if(timedelay == 1)
{
delayflag = 1;
WDTCTL = WDT_ADLY_1000;
//使能WDT中断
IE1 |= WDTIE;
//进入LPM3模式
LPM3;
}
}
void init_PWM(void)
{
//PWM周期
CCR0 = 256-1;
// CCR1 reset/set
CCTL1 = OUTMOD_7;
//CCR1 PWM占空比
CCR1 = 80;
//CCR2 reset/set
CCTL2 = OUTMOD_7;
//CCR2 PWM 占空比
CCR2 = 128;
//SMCLK,IP模式
TACTL = TASSEL_2 + MC_1;
}
void init_Port(void)
{
//P1.0 P1.3为输出
P1DIR |= BIT0;
P1OUT = 0;
//P2.3为输出
P2DIR |= BIT3;
//特殊功能管脚
P2SEL |= BIT3;
}
//时钟初始化
void init_Clk (void)
{
unsigned int Compare, Oldcapture = 0;
// ACLK= LFXT1CLK/8
BCSCTL1 |= DIVA_3;
CCTL2 = CM_1 + CCIS_1 + CAP;
// SMCLK
TACTL = TASSEL_2 + MC_2 + TACLR;
while (1)
{
//等待捕获发生
while (!(CCIFG & CCTL2)) ;
//清除标志
CCTL2 &= ~CCIFG;
//得到当前的SMCLK
Compare = CCR2;
//SMCLK的差
Compare = Compare - Oldcapture;
//保存
Oldcapture = CCR2;
if (DELTA == Compare) break;
else if (DELTA < Compare)
{
DCOCTL--;
if (DCOCTL == 0xFF)
{
if (!(BCSCTL1 == (XT2OFF + DIVA_3)))
{
BCSCTL1--;
}
}
}
else
{
DCOCTL++;
if (DCOCTL == 0x00)
{
if (!(BCSCTL1 == (XT2OFF + DIVA_3 + 0x07)))
{
BCSCTL1++;
}
}
}
}
//停止CCR2
CCTL2 = 0;
//停止定时器A
TACTL = 0;
}
void init_ADC(void)
{
//停止转换
ADC10CTL0 &= ~ENC;
//模拟输入使能
ADC10AE |= 0x07;
//模拟采集设置
ADC10CTL0 = SREF_1 + ADC10SHT_3
+ ADC10ON + ADC10IE + REFON + REFOUT;
//采集通道设置
ADC10CTL1 = INCH_2 + SHS_3 + CONSEQ_3;
//清除BUSY位
while( ADC10CTL1 & BUSY ){}
ADC10DTC0 |= ADC10CT;
//ADC块大小
ADC10DTC1 = 3;
//ADC块的开始地址
ADC10SA = (unsigned int)AdcData;
//打开转换
ADC10CTL0 |= ENC;
}
//采集判断程序
#if __VER__ < 200
interrupt [ADC10_VECTOR] void adc10_ISR(void)
#else
#pragma vector=ADC10_VECTOR
__interrupt void adc10_ISR(void)
#endif
{
if (AdcData[0] < 355)
{
// 温度是否过高
TACTL = 0;
P1SEL = 0;
P1OUT = 0x01;
ADC10CTL0 = 0;
timercounts = 0;
timedelay = 0;
delayflag = 0;
//停止看门狗
WDTCTL = WDTPW + WDTHOLD;
}
if (const_volt == 0)
{
if (AdcData[2] < 100 | AdcData[2] > 1021)
{
// Vout < 1V or >4.3V, 报警
P1OUT |= BIT0;
}
}
if ((AdcData[2] < 890) && const_volt == 0)
{
// Vout < 3.6V, 慢充阶段
if (AdcData[1] > 300)
{
//调整PWM
CCR1--;
}
else
{
CCR1++;
CCR1 &= 0xFF;
}
}
else if((AdcData[2] > 1022)| const_volt == 1)
{
// Vout >4.1V, 恒压充电
const_volt=1;
CCR1--;
}
if (const_volt == 1)
{
if ((AdcData[1] < 1) && (delayflag == 0) )
{
// Current < 0.1C, 延时30分钟后,停止充电
timedelay = 1;
LPM0_EXIT;
}
if (AdcData[2] < 1021)
{
// 4.1 < Vout < 4.2
CCR1++;
}
}
else if ((AdcData[2] >= 890) && const_volt == 0)
{
// Vout > 3.6 V, 快充阶段
if (AdcData[1] > 500)
{
CCR1--;
}
else
{
CCR1++;
CCR1 &= 0xFF;
}
}
_NOP();
}
//延时程序
#if __VER__ < 200
interrupt [WDT_VECTOR] void watchdog_timer(void)
#else
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
#endif
{
P1OUT ^= 0x01;
if(timercounts == 110)
{
TACTL = 0;
P1SEL = 0;
P1OUT = 0;
ADC10CTL0 = 0;
timercounts = 0;
timedelay = 0;
delayflag = 0;
//停止看门狗
WDTCTL = WDTPW + WDTHOLD;
}
timercounts++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -