⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chongdianqi.c

📁 用LPC915单片机做的一个脉冲充电器的程序
💻 C
字号:
//***************************************************************************
//* Charger.c
//* By : 王进
//* Date : March 2009
//* Description :  P89LPC916用于充电器控制部分
//***************************************************************************
#include <reg916.h> // 定义LPC916头文件
#define uchar unsigned char
#define uint unsigned int
//-----------------------------------------------
//定义全局变量
//---------------------------------------------
uchar data RTC_Counter_LED, LED_Flash_Speed; //RTC 用于 LED 延时
uint data RTC_Counter_AD; //RTC 计数用于 AD转换
uint data AD_Convert_Speed; //AD转换间隔时间
uint data RTC_Counter; //RTC定时
uchar data RTC_Counter_Minute; // 延时控制的时间
bit data LED_Flag, AD1_Flag, AD_Flag, Battery_On_Socket;
bit data Pre_Charge_Status, Constant_Current_Charge, Constant_Voltage_Charge;
uint data AD1_1,AD1_2,AD1_3; //AD1.1-检测电压, AD1.2-检测温度., AD1.3-检测电流
uchar data average; // AD 转换的平均时间
/****************************************************************************
各脚位功能:P0.2脚AD采样电压。P0.4脚AD采样电流。P1.2为PWM输出。P0.1为LED输出。
****************************************************************************/
//-----------------------------------------------
//定义常量
//-----------------------------------------------
#define LED_FLASH_FAST 10 // 定义LED灯闪最高频率
#define LED_FLASH_SLOW 200 // 定义LED灯闪最低频率
#define STOP_CHARGE_DELAY 50 // 当电流为1.5A时延时开始,延时X分
//***************************************************************************
//* 声明
//***************************************************************************
void main(void); // 主函数
void init(void); // 初始化函数
void ad_convert(void);//AD控制函数
//***************************************************************************
//* main()
//* Description : 主函数
//***************************************************************************
void main ()
	{
		EA = 0;
		init();
		EA = 1;
		for( RTC_Counter = 1; RTC_Counter < 1700; );
		RTC_Counter = 0;
		for(;;)
			{
				if(LED_Flag == 0) // 控制LED为灯闪
					{
						KB1 = 0;
					}
				else
					{
						KB1 = 1;
					}
				if( ( AD_Flag == 1 ) && ( Battery_On_Socket == 1 ))
				// 开始 AD 转换并控制 PWM, 预设AD转换速度
					{ // AD_Flag 控制 AD 转换速度
						ad_convert();
						AD_Flag = 0;
					}
				if( RTC_Counter_Minute == STOP_CHARGE_DELAY ) // 如果延时结束, 停止 charge
					{
						EA = 0; //关闭中断, 所以无法设置 AD_Flag
						P1 = 0; //关闭 PWM
						LED_Flag = 1; //LED打开
					}
			}
	}
//***************************************************************************
//* init()
//* Description :  P89LPC916 初始化
//***************************************************************************
void init(void)
	{
		//SP = 0x30; //设置 SP 从 50H - 7FH
		//-----------------------------------------------
		//配置 P0 I/O
		//-----------------------------------------------
		P0M1 = 0x1C; // 设置 P0.2/3/4 为输入, 0001 1100
		P0M2 = 0xE3; // 设置 P0.1 for PP, P0^1 用于LED, 1110 0011
		//-----------------------------------------------
		//配置 P1 I/O
		//-----------------------------------------------
		P1M1 = 0x24; // ^5 Input only 0010 0100
		P1M2 = 0xdf; // 设置 P1^2 为开漏输出 1101 1111 
		//-----------------------------------------------
		//配置 P2 I/O (P2 没有使用)
		//-----------------------------------------------
		P2M1 = 0x00; // 设置P2口为推挽输出
		P2M2 = 0xFF;
		KB5 = 0; //设置 p0.5 = 0 
		P1 = 0x00; //设置 p1.2 = 0   TO为PWM
		P2 = 0x00;
		RTC_Counter = 0x00;
		RTC_Counter_LED = 0x00;
		LED_Flag = 0;
		LED_Flash_Speed = LED_FLASH_SLOW;
		AD1_1 = 0;
		AD1_2 = 0;
		AD1_3 = 0;
		AD1_Flag = 0;
		RTC_Counter_LED= 0;
		AD_Flag = 0;
		average = 10;
		Pre_Charge_Status = 0;
		Constant_Current_Charge = 0;
		Constant_Voltage_Charge = 0;
		RTC_Counter_Minute = 0;
		Battery_On_Socket = 1;
		AD_Convert_Speed = 10;
		//-----------------------------------------------
		//初始化 RTC 用于定时器
		//-----------------------------------------------
		WDCON &=0xE0; //关闭 WDT
		RTCH = 0x01; //设置RTC为16bit, 大约8.9ms
		RTCL = 0xFF;
		RTCCON = 0x63; //启用RTC, 使用内部 RC
		EWDRT = 1; //启用 RTC/WD 中断
		//-----------------------------------------------
		//初始化 T0 用于 PWM
		//-----------------------------------------------
		TMOD |= 0x02; //Set T0 mode 6
		TAMOD |= 0x01; //For PWM, 0x01
		TH0 = 255; //Duty cycle = 256 - TH0, for 5v input, set initial charge current very small
		AUXR1 |= 0x10; //Enable toggling pin P1.2
		TR0 = 1; //Enable T0
		//----------------------------------------------------------------------
		//Enable the A/D Converter and use the CPU clock as the A/D clock.
		//----------------------------------------------------------------------
		ADMODA = 0x10; //AD1 single mode no boundary interrupt
		ADMODB = 0x40; //AD "40" for CCLK/3, 7.3728/3=2.4576M. "60" for CLK = CCLK/4, 1.8432M, ADC MODE
		ADINS = 0xE0; //Enable AD11,AD12,AD13
		ADCON1 = 0x04; //Enable AD1 with timer no start occurs mode, no completed & boundary interrupt
	}
//***************************************************************************
//* ad_convert()
//* Description : AD转换控制
//***************************************************************************
void ad_convert ()
	{
		uchar temp = 0;
		ADCON1 |= 0x01; //启用AD转换
		while( !(ADCON1 & 0x08) ); //等待AD转换结果
		ADCON1 &= ~0x08;
		if( average-- == 0) // 每隔10S输出一次转换结果,第一判断以下--
			{
				AD1_1 = AD1_1/10;
				AD1_2 = AD1_2/10;
				AD1_3 = AD1_3/10;
				average = 10;
				//-----------------------------------------------
				//AD11 用于检测电池电压
				//-----------------------------------------------
				if( AD1_1 > 176 ) // If Vout > 4.6v
					{ // 为防止电池损坏或没插插头
						SCL=0;
						Battery_On_Socket = 0; // 关闭AD转换, skip <115, <162, <176, until <38
						RTC_Counter = 5000; //延时15's, 启动 RTC_Interrupt()
						LED_Flash_Speed = LED_FLASH_FAST; // 显示错误状态
					}
				else if( AD1_1 <= 38 ) // If Vout <= 1V, <=(1/3.31*2)*256 = 256/6.66
					{
						SCL=0; // p1.2 = 0, 关闭PWM
						LED_Flash_Speed = LED_FLASH_FAST; // indicate error status
						AD1_1 = 0; // LED关闭
					} // 电池损坏或插头没接
				else if( AD1_1 <= 115) // 如果电压<=115
					{
						SCL=1; // 启动 P1.2 PWN
						TH0 = 250; //预设充电电流为50V输入,约2A。
						LED_Flash_Speed = LED_FLASH_SLOW; // 显示充电状态
						if( Constant_Current_Charge == 0 ) Pre_Charge_Status = 1; // Set Precharge status
					}
				else if( AD1_1 < 162) // 输出电压 = 电池电压 + 0.35*0.75
				// for fullly charged bat,bat vol=4.24,I limit 20mA, 4.24+0.02*0.75=4.26v
				// 为保护电池, 设置输出电压 = 4.26v (162)
					{   // if bat vol=4.2, 仅仅输出 1.5A, 4.2+0.08*0.75=4.26v
						// if bat vol=4.15, 我仅仅是2A, 4.15 + 0.15*0.75 = 4.26v
						// 为保护电池充电电流,4.26-0.35*0.75=4.00v, so Vbat>4.00v,enter cons-vol
						// 第一波充电, charge I= min 20mA,Vbat= 4.26-0.02*0.75=4.24v
						// ( 161-4.252, 162-4.267, 160-4.234 )
						SCL=1;
						LED_Flash_Speed = LED_FLASH_SLOW; // 显示充电状态
						if( Constant_Voltage_Charge == 0)
							{
								Constant_Current_Charge = 1; // 设置为恒流充电
								Pre_Charge_Status = 0; // 禁止预充电状态
							}
					}
				else // If 4.26V < Vout <4.6V
					{
						SCL=1;
						LED_Flash_Speed = LED_FLASH_SLOW; // 显示充电状态
						Constant_Voltage_Charge = 1; // 为恒压充电状态
						Constant_Current_Charge = 0; // 禁止恒流充电
						Pre_Charge_Status = 0; // 禁止预充电
					}
				temp = AD1_1;
				AD1_1 = 0; // 重启 AD1_1
				//-----------------------------------------------
				//AD12 检测温度
				//-----------------------------------------------
				// AD1_2 = AD1_2*83/64; // input x 3.31 x 100 / 256
				// First_Bit = AD1_2/100;
				// AD1_2 = AD1_2%100;
				// Second_Bit = AD1_2/10;
				// Third_Bit = AD1_2%10;
				// DP_Enable = 0;
				AD1_2 = 0; // reset AD1_2
				//-----------------------------------------------
				//AD13 检测电流
				//-----------------------------------------------
				if( Pre_Charge_Status == 1 )
					{
						if( ( AD1_3 > 1 ) && ( TH0 < 250 ) ) // 确保预充电电流 < 65mA
						{ TH0++;}
					}
				else if( Constant_Current_Charge == 1 )
					{
				if( AD1_3 < 17 ) // 260mv,(充电电流 = 350mA)
					{ // 如果充电电流 < 350mA, pwm++
						if( TH0 < 2 )
						{
							TH0 = 1;
							if( RTC_Counter == 0 ) //延时20min结束充电
								{ RTC_Counter = 1; } //电池在这种情况下,if Vout < 2.6v
							//无法实现电流 350mA,  PWM开最大
						}
						else
							{ TH0 = TH0 - 1; }
					}
				else if( AD1_3 > 17)
					{ //如果充电电流 > 350mA, pwm--
						if( TH0 > 253 )
							{ TH0 = 254; }
						else
							{
							TH0 = TH0 + 1;
							}
					}
				}
				else if( Constant_Voltage_Charge == 1 )
					{
						if( AD1_3 <= 1 ) // 充电电流 < 60mA
							{
								if( RTC_Counter == 0 ) { RTC_Counter = 1; } //开始延时50分钟结束充电
							}
						if( temp > 160 ) //temp=AD1_1, if Vout is > 4.23v(达到 4.23v), -- PWM
							{
								if( TH0 < 255)
									{
										TH0++;
									}
							}
						else if( temp < 160 ) // if Vout is < 4.21v (达到 4.21v), ++PWM
							{
								if( TH0 > 1 )
									{
										TH0--;
									}
							}
					}
				AD1_3 = 0; // 重启 AD1_3
			}
		else
			{
				AD1_1 += AD1DAT1;
				AD1_2 += AD1DAT2;
				AD1_3 += AD1DAT3;
			}
	}
//***************************************************************************
//* RTC_Interrupt
//* Description :  RTC 中断
//***************************************************************************
void RTC_Interrupt (void) interrupt 10 using 1
	{
		if( RTC_Counter != 0 ) { RTC_Counter++; }
			{
				RTC_Counter_LED++;
				RTC_Counter_AD++;
			}
		if ( RTC_Counter_LED == LED_Flash_Speed)
			{
				LED_Flag = ~LED_Flag;
				RTC_Counter_LED = 0;
			}
		if ( RTC_Counter_AD == AD_Convert_Speed )
			{
				AD_Flag = 1;
				RTC_Counter_AD = 0;
			}
		if ( RTC_Counter == 6750) // 延时1分钟
			{
				RTC_Counter_Minute++;
				RTC_Counter = 1;
				if( Battery_On_Socket == 0) // 拔掉插座延时15S
					{
						Battery_On_Socket = 1;
						RTC_Counter = 0;
					}
			}
		RTCCON = 0x63; //Clear RTCCON.7-RTCF
	}
/*********************************************END***************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -