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

📄 discharger.c

📁 单片机 mega16L 电池放电器源码
💻 C
字号:
//项目名称:电池容量测试器V2.0
//功能描述:通过对电池放电,测量出电池的容量
//外部模块:1602LCD
//开发人员:李卓生
//开发日期:2006年2月16日
//最后修正:  2006年2月27日
//*********************************************************
#include <iom8v.h>
#include <macros.h>
#include "discharge.h"
#include "LCD_1602.h"
#include "eeprom.h"

#define   key_delay                 64
#define   keyboard_scan         16
#define   lcd_write                   32
#define   timer_dealy              125

const char *Menu[]=//系统菜单
{"Menu","Discharging","D882","Record","Clear","USART","#"};

unsigned char path_top,path;
//系统参数
unsigned char sec=0;
unsigned char min=0;
unsigned char hour=0;
unsigned char keyboard;
unsigned char RunTab=1;
unsigned char RunTab_old;

unsigned char sc_timer_dealy,sc_keyboard_scan,sc_lcd_write,sc_key_delay;//定时小于255*31.25ms的
unsigned int sc_bt1,sc_bt_ctrl,sc_eeprom,sc_discharge,sc_bt1_record,sc_bt1_v_temp;
/*//LED灯控制参数
  unsigned int G_led,G_led_cy,G_led_ht;
  unsigned int sc_G_cy,sc_G_ht;
  
  unsigned int R_led,R_led_cy,R_led_ht;
  unsigned int sc_R_cy,sc_R_ht;
  */
   // discharge
  unsigned char BT1_state;
  unsigned int BT1_V;
  unsigned int BT1_I;
  unsigned int BT1_T;
  unsigned int BT1_V_num;
  unsigned int BT1_V_num_temp;
  unsigned int bt1_v_temp;
  unsigned int bt1_v_temp_1;
  
  unsigned int BT1_I_SET;
  unsigned int PWM;
  unsigned long BT1_mAh;
  unsigned long BT1_time;
  unsigned int mAh;
  unsigned int D882_P;
  
  unsigned int mAh_set=1000;
  unsigned char speed=10;
  unsigned int BT1_P;
//T2溢出中断服务程序 8ms
#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
 TCNT2 = 0x06;//重装计时值0xFF=32us  0x00=8.192ms
 system_clock();//系统定时器
 system();//系统后台服务程序
 //Green_led(); Red_led();
  if(RunTab_old!=RunTab)
	   {LCD_clear();RunTab_old=RunTab;}
}
/*----------------------------------
    系统后台服务程序
-----------------------------------*/
void system(void)
{ 
 if(sc_timer_dealy==0){timer(); sc_timer_dealy=timer_dealy;}
 if((sc_key_delay==0)&&(keyboard!=0)){sc_key_delay=key_delay;}
 if(sc_key_delay==1){keyboard=0;}
 if(sc_keyboard_scan==0)
   {keyboard=key(keyboard);sc_keyboard_scan=keyboard_scan;}
 if(sc_lcd_write==0)
   {Run_Turn();LCD_write_new();sc_lcd_write=lcd_write;}

 if((BT1_I_SET)/*&&(sc_bt1_record==0)*/)
	{
 if(sc_bt1==0)
  {BT1_mAh+=BT1_I;sc_bt1=450;}//容量统计,每3.6秒计一次
 if(sc_discharge==0)
  {BT1_time++;sc_discharge=125;}//放电时间统计
 if(sc_bt1_v_temp==0)
    {bt1_v_temp+=BT1_V;sc_bt1_v_temp=500;}
 if(sc_bt1_record==0)
    {bt1_v_record();sc_bt1_record=7500;}//每分钟记录一次电压
 if(sc_eeprom==0) 
  {
   if(BT1_V<2000)
	{discharge_stop();} 
    EEPROM_WRITE(0x01F0,BT1_mAh);
    EEPROM_WRITE(0x01F4,BT1_time);
    sc_eeprom=1250;//每10秒保存一次
	}
	}
  if(sc_bt_ctrl==0)
    {
	 BT1_I_Ctrl();
      if((BT1_I>BT1_I_SET+5)||(BT1_I<BT1_I_SET-5))
	    sc_bt_ctrl=2;//PWM高速调节
		else sc_bt_ctrl=48;//PWM低速调节
	 }
}

void system_clock(void)
  {  //每个节拍为8ms
     if(sc_timer_dealy!=0)  sc_timer_dealy--;
     if(sc_keyboard_scan!=0)  sc_keyboard_scan--;
	 if(sc_key_delay!=0)  sc_key_delay--;
	 if(sc_lcd_write!=0)  sc_lcd_write--;
/*	 
     if(sc_G_ht!=0)  sc_G_ht--;
	 if(sc_G_cy!=0)  sc_G_cy--;
	 if(sc_R_ht!=0)  sc_R_ht--;
	 if(sc_R_cy!=0)  sc_R_cy--;
*/
	 if(sc_bt1!=0)  sc_bt1--; 
	 if(sc_discharge!=0)  sc_discharge--; 
	 if(sc_eeprom!=0)  sc_eeprom--; 
	 if(sc_bt1_record!=0)  sc_bt1_record--;
	 if(sc_bt1_v_temp!=0)  sc_bt1_v_temp--;
	 if(sc_bt_ctrl!=0)  sc_bt_ctrl--;
  }
  
/*----------------------------------
        任务调度程序
----------------------------------*/
void Run_Turn(void)
  {
   
    switch(RunTab)
	  {
	    case 1:desktop();break;
		case 2:system_menu();break;
		case 11:Discharging();break;
		case 12:D882();break;
		case 13:Record();break;
		case 14:Clear();break;
		case 15:usart();break;
		case 20:Capacitance_setting();break;
		case 21:discharge_speed();break;
		case 22:record_setting();break;
	  }
  }
  
void bt1_v_record(void)
  {  
     bt1_v_temp/=15;
     EEPROM_READ(0x01F8,BT1_V_num);
     EEPROM_WRITE(BT1_V_num*2,bt1_v_temp);
	 put_number(BT1_V_num,"  ",' '); 
	 put_number(bt1_v_temp," mV",'\n'); 
	if(BT1_V_num<249)
	   {BT1_V_num++;EEPROM_WRITE(0x01F8,BT1_V_num);} 
	  
	 bt1_v_temp=0;
  }
/*------------------------------------
          主程序
-------------------------------------*/
void main(void)
  {   
	 init_devices();
	 system_menu_init();
	 while(1)
	   {
	     discharge_init();
		 discharge();
		 delay_nms(100);
	   }
  }

void desktop(void)
 {
    unsigned char ID=1;
	  if(RunTab==ID)
	    {  
		   if(keyboard==up){keyboard=0;RunTab=2;}
		   LCD_write_string(0,1,"Start",10);
		   LCD_write_time(11,1,hour,min,sec,5);
		}
 }

void Discharging(void)
 {
   unsigned char ID=11;
	  if(RunTab==ID)
	    {  
		   if(keyboard!=0)
		     { 
			   if(keyboard==back){RunTab=2;}
			   
			   keyboard=0;
			 } 
		    //LCD_write_string(0,0,Menu[path],15);
			LCD_write_number(0,0,3,BT1_V,"V",6);
			LCD_write_number(0,1,3,BT1_I,"A",6);
			if(BT1_state&(1<<2))
			LCD_write_string(7,0,"Finish",15);
			  else
			LCD_write_number(7,0,0,PWM,"PWM",0);
			LCD_write_number(7,1,1,BT1_mAh/100,"mAh",15);
		}
 }
 
void D882(void)
 {
   unsigned char ID=12;
	  if(RunTab==ID)
	    {  
		   if(keyboard!=0)
		     { 
			   if(keyboard==back){RunTab=2;}
			   
			   keyboard=0;
			 } 
		    LCD_write_string(0,0,Menu[path],6);
			LCD_write_number(7,0,0,BT1_time,"sec",10);	
			LCD_write_number(0,1,1,BT1_T,"C",0); 
			LCD_write_number(7,1,0,D882_P,"mW",0);
		}
 }
 
void Record(void)
  {     
     unsigned char ID=13; //程序标识
		 if(RunTab==ID)
		 {  
		   if(keyboard!=0)
		   {
		    if(keyboard==back){RunTab=2;}
		    if((BT1_V_num_temp<BT1_V_num-1)&&BT1_V_num!=0)
			 {
			   if(keyboard==up)
			    { 
				  BT1_V_num_temp++;
				  EEPROM_READ(BT1_V_num_temp*2,bt1_v_temp_1);
				 }
			  }

			if(BT1_V_num_temp>0)
			 {
			   if(keyboard==down)
			    { 
				  BT1_V_num_temp--;
				  EEPROM_READ(BT1_V_num_temp*2,bt1_v_temp_1);
				 }
			  }
			   keyboard=0;
			}
			LCD_write_number(0,1,3,bt1_v_temp_1,"V",8);
			LCD_write_number(0,0,0,BT1_V_num_temp,"min",8);
		    LCD_write_number(10,0,0,BT1_V_num,"min",15);
	        LCD_write_number(10,1,3,BT1_V,"V",15);
		 }
} 

void Clear (void)
 {   
    unsigned char ID=14;
	  if(RunTab==ID)
	    {  
		   if(keyboard!=0)
		     { 
			   if(keyboard==back){RunTab=2;}
			   if(keyboard==enter_long)
	             { 
	              BT1_mAh=0;
			 	  BT1_time=0;
		     	  EEPROM_WRITE(0x01F0,BT1_mAh);
		    	  EEPROM_WRITE(0x01F4,BT1_time);
		     	  BT1_V_num=0;BT1_V_num_temp=0;
		      	  EEPROM_WRITE(0x01F8,BT1_V_num);
		     	  sc_bt1_record=7500;
	           	  }
			      keyboard=0;
			 } 
		    LCD_write_string(0,0,Menu[path],15);
			LCD_write_number(7,1,1,BT1_mAh/100,"mAh",15);
		}      
 }
 
void usart(void)
 { 
   unsigned char ID=15;
	  if(RunTab==ID)
	    {  
		   if(keyboard!=0)
		     { 
			   if(keyboard==back){RunTab=2;}
			   if((keyboard==enter)&&BT1_V_num!=0)
			    {
				  BT1_state|=(1<<7);
				  BT1_V_num_temp=0;
				 }
			   
			   keyboard=0;
			 } 
			if(BT1_state&(1<<7))
			     {
				   EEPROM_READ(BT1_V_num_temp*2,bt1_v_temp_1);
	               put_number(BT1_V_num_temp,"  ",' '); 
	               put_number(bt1_v_temp_1," mV",'\n');
				   BT1_V_num_temp++; 
				 if(BT1_V_num_temp>BT1_V_num-1)
		           {
				    put_number(mAh_set,"mAh @",' ');
					put_number(mAh_set/100*speed,"mA    ",' ');
				    put_number(BT1_mAh/1000,"mAh",'\n');
					BT1_state&=~(1<<7);}        
				 }
		  LCD_write_string(0,0,Menu[path],15);
		}
 }
 
void put_number(unsigned int dat,const unsigned char *s,signed char n)
  {
    signed char  i;
	unsigned char b=0;
	unsigned char uart[5]={0};
	G_N;
	for (i=0;i<=4;i++) 
      {
        uart[i]=dat%10+48;
		dat=dat/10;
      }
	i=4;
  while((uart[i]==48)&&i!=0){i--;}
	for(;i>=0;i--)
	  { 
	    while(!(UCSRA&(1<<UDRE)));
	     UDR=uart[i];
	   }
	while (*s) 
      {
        while(!(UCSRA&(1<<UDRE)));
	     UDR=*s;//要显示的数据存入显存
	       s ++;//指针加1
      } 
	   while(!(UCSRA&(1<<UDRE)));
	     UDR=n;
		 G_F;
  }

void system_menu_init(void)
 {
   path=1;
   for(path_top=0;Menu[path_top]!="#";path_top++){;}
	path_top--; //计算当前菜单的项目数
 }
 
void system_menu(void)
 {
   unsigned char ID=2;
     if(RunTab==ID)
	   {
	    if(keyboard!=0)
		 {
	     if(keyboard==back){RunTab=1;path=1;}
		 if(keyboard==down){if(path<path_top){path++;}else path=1;}
		 if(keyboard==up){if(path>1){path--;}else path=path_top;}
		 if(keyboard==enter){RunTab=path+10;}
			keyboard=0;
		  }
		  LCD_write_string(0,0,Menu[0],10); 
		  LCD_write_string(0,1,Menu[path],15);
		  LCD_write_number(12,0,0,path_top,"-",10);
		  LCD_write_number(13,2,0,path,"",15);
	   }
 }

void discharge_stop(void)
  {
     BT1_I_SET=0;BT1_I=0;
	 BT1_state&=~(1<<1);//已停止放电
	 BT1_state|=(1<<2);//已放完电
	 PWM_OFF;R_F;
	 PWM=100;
  }
  
void discharge_init(void)
  {   
     /* PWM_ON;
      OCR1A=700;
	  delay_nms(100);
	  PWM_OFF;*/
      BT1_V=T_BT1_V();
	  if((BT1_V>2000)&&BT1_state==0)//
	    {
		  BT1_state|=(1<<0);
		  RunTab=20;
		}
  }
void Capacitance_setting(void)
  {
    unsigned char ID=20; 
    if(RunTab==ID)
		  {     
		    if((keyboard==up)&&mAh_set<4000)
		     {keyboard=0;mAh_set+=100;}
		    else if((keyboard==down)&&mAh_set>100)
		     {keyboard=0;mAh_set-=100;}
			else if(keyboard==back)
	        { 
			 keyboard=0;
             EEPROM_READ(0x01F0,BT1_mAh);	
	         EEPROM_READ(0x01F4,BT1_time);
			 EEPROM_READ(0x01FC,mAh_set);
			 EEPROM_READ(0x01FE,speed);
			 RunTab=22;
	        }
			else if(keyboard==enter){keyboard=0;RunTab++;}
			LCD_write_string(0,0,"Capacitance",0);
			LCD_write_number(0,1,0,mAh_set,"mAh",8);
			LCD_write_number(10,1,3,BT1_V,"V",15);
		  }
  }
void discharge_speed(void)
  {
      unsigned char ID=21; 
      if(RunTab==ID)
		  { 
		    LCD_write_string(0,0,"speed",0);
			LCD_write_number(9,0,0,6000/speed,"min",15);
			LCD_write_number(0,1,2,speed,"C",8);
			LCD_write_number(9,1,3,mAh_set/100*speed,"A",15);
		     
		    if((keyboard==up)&&speed<120)
		     {keyboard=0;speed+=5;}
		    else if((keyboard==down)&&speed>5)
		     {keyboard=0;speed-=5;}
			else if(keyboard==back)
	        {keyboard=0;RunTab--;}
			else if(keyboard==enter)
			{keyboard=0;RunTab++;BT1_V_num=0;}
		  }
  }
void record_setting(void)
  {
      unsigned char ID=22; 
      if(RunTab==ID)
		  {     
		    EEPROM_WRITE(0x01FC,mAh_set);
			EEPROM_WRITE(0x01FE,speed);
			PWM=500;sc_bt1_record=7500;
			sc_eeprom=1250;sc_bt1_v_temp=500;
	        BT1_I_SET=mAh_set/100*speed;
	        PWM_ON;R_N; 
			BT1_state|=(1<<1);
			RunTab=1;
		  }
  }

/*---------------------------------------
             放电程序
----------------------------------------*/
void discharge (void)
  {    
      unsigned long v_temp,i_temp,t_temp;
	  unsigned char v,i,t;
	 
	  while(BT1_state&(1<<1))
	  {
		if(i<16)
		 {i_temp+=T_BT1_I();i++;delay_nms(1);}
		else
		 {i=0;BT1_I=i_temp>>4;i_temp=0;}
		 
		if(v<64)
		 {v_temp+=T_BT1_V()+(BT1_I>>1); v++;	
		delay_nms(1);}
		else 
		 {v=0;BT1_V=v_temp>>6;v_temp=0;}
		 
		if(t<16)
		 {t_temp+=T_BT1_T(); t++;	
		delay_nms(1);}
		else 
		 {t=0;BT1_T=t_temp>>4;t_temp=0;}
		D882_P=(BT1_V-(BT1_I>>1))/100;
		D882_P*=(BT1_I/10);
		}
  }
    
void BT1_I_Ctrl (void)
  { 
   if(BT1_I_SET!=0)
   {
     if(BT1_I>BT1_I_SET+1)
	  {
	  if(PWM!=0)
	  PWM-=1;
	  OCR1A=PWM;
	  }
	  else if(BT1_I<BT1_I_SET-1)
	  {
	  if(PWM!=1900)
	  PWM+=1;
	  OCR1A=PWM;
	  }
	  }
	  else
	   {PWM=300;OCR1A=PWM;}
  }
/*-------------------------
        实时时钟
--------------------------*/
void timer(void)
{
     ++sec; 
	 if(sec==60)
	 {
	   sec=0;
	   min++;
	   if(min==60)
	   {
	     min=0;
		 hour++;		
		 if(hour==24)
		 {
		   hour=0;		   
		 }
	   }
	 }
}
/* 
void Green_led(void)
  {     
     if(G_led||sc_G_cy)
	    {  
		   if(sc_G_cy==0)
		     {sc_G_cy=G_led_cy;sc_G_ht=G_led_ht;G_led--;}	   
		   if(sc_G_ht)G_N;else G_F;    
		}
  }
  
void G_init(unsigned int t,unsigned int cy,unsigned char ht)
  {  
    CLI();
     if((G_led==0)&&(sc_G_cy==0))
	  {
	    G_led=t;//
        G_led_cy=(cy>>3);
        G_led_ht=(G_led_cy*ht/10);
		if(G_led==1){G_led_cy++;}
		G_led--;
		DDRC|=(1<<4);G_N;
        sc_G_cy=G_led_cy;
		sc_G_ht=G_led_ht;
	  }
    SEI(); 
  }

void Red_led(void)
  {     
     if(R_led||sc_R_cy)
	    {  
		   if(sc_R_cy==0)
		     {sc_R_cy=R_led_cy;sc_R_ht=R_led_ht;R_led--;}	   
		   if(sc_R_ht)R_N;else R_F;    
		}
  }
  
void R_init(unsigned int t,unsigned int cy,unsigned char ht)
  {  
    CLI();
     if((R_led==0)&&(sc_R_cy==0))
	  {
	    R_led=t;//
        R_led_cy=(cy>>3);
        R_led_ht=(R_led_cy*ht/10);
		if(R_led==1){R_led_cy++;}
		R_led--;
		DDRC|=(1<<5);R_N;
        sc_R_cy=R_led_cy;
		sc_R_ht=R_led_ht;
	  }
    SEI();
  }
*/

⌨️ 快捷键说明

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