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

📄 main.c

📁 这个是个航模产品的锂电测试器
💻 C
字号:
/********************************************************************************/
//		
// 		builder : 2007-04-10
// 		Target  : ATMEAG 48V
// 		Crystal : 内部 8.00 MHz
//
//		快速充电器
		
/********************************************************************************/

#include <iom48v.h>
#include <macros.h>

#include "adc.h"


#define		uchar		unsigned char
#define		uint		unsigned int


#define		SET_LED1		PORTD |=  (1<<PD4)
#define		CLR_LED1		PORTD &= ~(1<<PD4)

#define		SET_LED2		PORTD |=  (1<<PD3)
#define		CLR_LED2		PORTD &= ~(1<<PD3)

#define		SET_LED3		PORTD |=  (1<<PD1)
#define		CLR_LED3		PORTD &= ~(1<<PD1)

#define		SET_LED4		PORTD |=  (1<<PD0)
#define		CLR_LED4		PORTD &= ~(1<<PD0)


#define		SET_COM1		PORTD |=  (1<<PD7)
#define		CLR_COM1		PORTD &= ~(1<<PD7)

#define		SET_COM2		PORTD |=  (1<<PD6)
#define		CLR_COM2		PORTD &= ~(1<<PD6)

#define		SET_COM3		PORTD |=  (1<<PD5)
#define		CLR_COM3		PORTD &= ~(1<<PD5)

#define		SET_OUT			PORTD |=  (1<<PD2)
#define		CLR_OUT			PORTD &= ~(1<<PD2)



static const uchar Char_tab[10] ={0x7D,0x41,0xEC,0xE5,0xD1,0xB5,0xBD,0x61,0xFD,0xF5};

union	
{	uint	temp;
	uchar  	data[2];		
}CH;

uint	V[4];

uchar	flag_2ms;
uchar	flag_20ms;

uint	ad_temp;
uchar	adc_num,adc_ch=0;
uchar	batt;

uchar	dip_bit;
uint	batt_num;

uchar	mode,out_time;
uint	key,key1,key2;
uchar	pulse;

uchar	dp=0x02;
uchar	down,delay;

uchar	led_time,led_flag;
uchar	flas1,flas2,flas3,flas4;




/*---------------------------------------------------------------
   			初始化
----------------------------------------------------------------*/

void timer0_init(void)
{
 	TCCR0B = 0x00; //stop
 	TCNT0  = 0x06; //set count
 	TCCR0A = 0x00; 
 	TCCR0B = 0x03; //start timer
}


void timer1_init(void)
{
	TCCR1A = 0x00;
	TCCR1B = 0x00;					
}



void init_devices(void)
{
	CLI();
	
	DDRB  = 0xFF;
 	PORTB = 0x00;
 	
 	DDRC  = 0x00;
 	PORTC = 0x0C; 
 	
 	DDRD  = 0xFF;
 	PORTD = 0x00; 
 	
 	adc_int();
 	timer0_init();
	timer1_init();

  	TIMSK0 = 0x01; 	//timer 0 interrupt sources
 	TIMSK1 = 0x00; 	//timer 1 interrupt sources
 	TIMSK2 = 0x00; 	//timer 2 interrupt sources
 	
 	SEI();
}



void bubble_sort(uint *a,uchar len)
{
     int j,k;
     int temp;
     int change=1;
     
     for (j=0;(j<len-1)&&change;j++)
     {
         change=0;
         for (k=j+1;k<len;k++)
         {
             if (a[k-1]>a[k])
             {
                change=1;
                temp=a[k-1];
                a[k-1]=a[k];
                a[k]=temp;
             }
         }
     }
}




void abcd(void)
{
	uint  temp[4];
	
	if(batt==4) 
	{
		temp[0] = V[0];
		temp[1] = V[1]-V[0];
		temp[2] = V[2]-V[1];
		temp[3] = V[3]-V[2];
	}
	else if(batt==3)
	{
		temp[0] = V[0];
		temp[1] = V[1]-V[0];
		temp[2] = V[2]-V[1];
	}
	else if(batt==2)
	{
		temp[0] = V[0];
		temp[1] = V[1]-V[0];
	}
	else if(batt==1)
	{
		temp[0] = V[0];
	} 
	else return;
	
	
	if(temp[1]<131) flas2 = 1;
	if(temp[2]<131) flas3 = 1;
	if(temp[3]<131) flas4 = 1;
	
	bubble_sort(temp, batt);
	
	if(batt==4) 
	{
		if( (temp[0]-temp[3])>10 )
		{
			flas1 = 1;
			flas2 = 1;
			flas3 = 1;
			flas4 = 1;
		}
	}
	else if(batt==3)
	{
		if(temp[0]> (temp[2]+5))
		{
			flas1 = 1;
			flas2 = 1;
			flas3 = 1;
		}
	}
	else if(batt==2)
	{
		if( (temp[0]-temp[1])>10 )
		{
			flas1 = 1;
			flas2 = 1;
		}
	}
	
}




/*---------------------------------------------------------------
   			A/D 转换
----------------------------------------------------------------*/

void ADC_count(void)
{
	uint temp;
	
	ad_temp += AD_CH(adc_ch);
	adc_num ++;
	if(adc_num>=16)
	{
		adc_num = 0;
		temp    = ad_temp>>4;
		ad_temp = 0;

		if(adc_ch==0) 	   
		{
			V[1]   = temp;
			adc_ch = 1; 
		}
		else if(adc_ch==1) 
		{
			V[0]   = temp;
			adc_ch = 6; 
		}
		else if(adc_ch==6) 
		{
			V[3]   = temp ;
			adc_ch = 7; 
		}
		else if(adc_ch==7) 
		{
			V[2]   = temp ;
			adc_ch = 0;
		}
		
		//abcd();	
	}
	
}




/*---------------------------------------------------------------
   			电池组数检测
----------------------------------------------------------------*/

void batt_test(void)
{
	if(AD_CH(1)>60)  batt =1;
	if(AD_CH(0)>120) batt =2;
	if(AD_CH(7)>180) batt =3;
	if(AD_CH(6)>240) batt =4;
		
}



 
/*---------------------------------------------------------------
   			LED 显示
----------------------------------------------------------------*/

void LED_display(void)
{
	uint	temp,temp1;
	uchar	h,m,l;
	
	if(mode==0)
	{
		if(batt_num<=1000)
		{
			temp   = V[0];
			
			if(V[0]<131) flas1 = 1;
			else flas1 = 0;
			
			if(led_time<80 && flas1)
			{
				CLR_LED1;
				CLR_LED2;
				CLR_LED3;
				CLR_LED4;
			}
			else 
			{
				SET_LED1;
				CLR_LED2;
				CLR_LED3;
				CLR_LED4;
			}
		}
		
		else if(batt_num>1000&&batt_num<=2000)
		{
			temp = V[1]-V[0];
			if(temp<101) flas2 = 1;
			else flas2 = 0;
			
			if(led_time<80 && flas2)
			{
				CLR_LED1;
				CLR_LED2;
				CLR_LED3;
				CLR_LED4;
			}
			else 
			{
				CLR_LED1;
				SET_LED2;
				CLR_LED3;
				CLR_LED4;
			}
		}
		else if(batt_num>2000&&batt_num<=3000)
		{
			temp   = V[2]-V[1];
			if(temp<101) flas3 = 1;
			else flas3 = 0;
						
			if(led_time<80 && flas3)
			{
				CLR_LED1;
				CLR_LED2;
				CLR_LED3;
				CLR_LED4;
			}
			else 
			{
				CLR_LED1;
				CLR_LED2;
				SET_LED3;
				CLR_LED4;
			}
			
		}
		else if(batt_num>3000)
		{
			temp   = V[3]-V[2];
			if(temp<101) flas4 = 1;
			else flas4 = 0;
			
			if(led_time<80 && flas4)
			{
				CLR_LED1;
				CLR_LED2;
				CLR_LED3;
				CLR_LED4;
			}
			else 
			{
				CLR_LED1;
				CLR_LED2;
				CLR_LED3;
				SET_LED4;
			}
			
		}
		
		temp = ((temp*125)/256)*5;
	
	}
	else if(mode==1)
	{
		SET_LED1;
		SET_LED2;
		CLR_LED3;
		CLR_LED4;
		temp = out_time;
	}
	else if(mode==2)
	{
		SET_LED1;
		SET_LED2;
		SET_LED3;
		CLR_LED4;
		temp = out_time;
	}
	else if(mode==3)
	{
		SET_LED1;
		SET_LED2;
		SET_LED3;
		SET_LED4;
		temp = (CH.temp+5)/10;
	}
	
	h = temp/100;
	m = temp%100/10;
	l = temp%100%10;
	
	dip_bit ++;
	
	if(dip_bit==2)
	{
		SET_COM1;
		CLR_COM2;
		CLR_COM3;
		PORTB = Char_tab[h] | dp;
	}	
	else if(dip_bit==4)
	{
		CLR_COM1;
		SET_COM2;
		CLR_COM3;
		PORTB = Char_tab[m];
	}
	else if(dip_bit==6)
	{
		CLR_COM1;
		CLR_COM2;
		SET_COM3;
		PORTB = Char_tab[l];
		dip_bit = 0;
	}
}


/*---------------------------------------------------------------
   		按键扫描
----------------------------------------------------------------*/

void key_scan(void)
{
	uchar temp;
	
	PORTC |= 0x0C;
	
	asm("nop"); asm("nop");
	
	temp = PINC & 0x0C;

	if(temp==0x00) 	// 双键
	{	
		key ++;
		if(key>=400)
		{
			key = 0;
			mode ++;

			if(mode==1||mode==2)
			{
				DDRD   = 0xFF;
				TIMSK1 = 0x01; 	// 开T1中断
				EIMSK  = 0x00;
				out_time = 150;
				dp	   = 0x00;
				
			}
			else if(mode==3)
			{
				DDRD   = 0xFB;
				TIMSK1 = 0x00; 	// 开T1中断
 				EICRA  = 0x03; //extended ext ints
 				EIMSK  = 0x01;
				dp	   = 0x00;
			}
			else if(mode>=4) 
			{
				TIMSK1 = 0x00; 	// 关T1中断
				EIMSK  = 0x00;
				mode   = 0;
				dp	   = 0x02;
			}	
		}
	}
	else key = 0 ;
	
	if(temp==0x08&&mode==1) 	// k1
	{	
		if(key1<500) 	
		{	
			key1 ++;
			if(key1==5)		// 短按
			{
				if(out_time<210) out_time ++;
			}
		}
		else 		// 长按
		{	
			key1 = 490;
			if(out_time<210) out_time ++;
		}
	}
	else key1 = 0;
	
	if(temp==0x04&&mode==1) 	// k2
	{	
		if(key2<500) 	
		{	
			key2 ++;
			if(key2==5)		// 短按
			{
				if(out_time>90) out_time --;
			}
		}
		else 		// 长按
		{	
			key2 = 490;
			if(out_time>90) out_time --;
		}
	}
	else key2 = 0;
}



/*---------------------------------------------------------------
   			main
----------------------------------------------------------------*/

void main(void)
{	
	init_devices();
			
	batt_test();
		
	while(1)
	{	
		asm("WDR");	
		if(flag_2ms)
		{
			flag_2ms = 0;
			
			led_time ++;
			if(led_time>=200) led_time = 0;

			ADC_count();
			LED_display();
			key_scan();
			
		}
	}
}


/*---------------------------------------------------------------
   			timer0 2ms 中断
----------------------------------------------------------------*/

#pragma interrupt_handler timer0_ovf_isr:17
void timer0_ovf_isr(void)
{
 	TCNT0 = 0x04; 	// reload counter value
 	
 	flag_2ms = 1;
 	
 	batt_num ++;
 	if(batt==2)
 	{
 		if(batt_num>=2000) batt_num = 0;
 	}
 	else if(batt==3)
 	{
 		if(batt_num>=3000) batt_num = 0;
 	}
 	else if(batt==4)
 	{
 		if(batt_num>=4000) batt_num = 0;
 	}
 		
 	if(mode==1||mode==2)
 	{
 		flag_20ms ++;
		if(flag_20ms>=10)
		{
	  		flag_20ms = 0;
	   
	 		TCNT1	= 0xFD00;	//预留512条指令时间
	    	TCCR1B	= 0x01;		//启动time1产生脉冲串	
	    	pulse   = 0;
	    	
	    	if(delay<100) delay ++;
	    	
	    	if(mode==2)
	    	{
	    		if(!down)
	    		{
	    			if(out_time<210) 
	    			{
	    				if(delay>30) out_time ++;
	    			}
	    			else  
	    			{
	    				down  = 1;
	    				delay = 0;
	    			}
	    		}
	    		else 
	    		{
	    			if(out_time>90) 
	    			{
	    				if(delay>30) out_time --;
	    			}
	    			else 
	    			{
	    				down  = 0;
	    				delay = 0;
	    			}
	    		}
	    	}
		}
	}
}

/*---------------------------------------------------------------
   			T1 产生各通道的脉宽
----------------------------------------------------------------*/

#pragma interrupt_handler timer1_ovf_isr:14
void timer1_ovf_isr(void)	
{
	if(!pulse)
	{
		pulse  = 1;
		TCNT1  = 0xffff - out_time*80;
		SET_OUT;
	}
	else 
	{
		CLR_OUT;
		TCCR1B = 0;		// STOP T1
	}
}

/****************************************************************
		INT0 interrupt
/****************************************************************/

#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
	if(EICRA==0x03)
	{
		TCNT1H = 0x00; 
 		TCNT1L = 0x00; 
 		TCCR1B = 0x02;  //start Timer1
 		
 		EICRA  = 0x02;
	}
	else if(EICRA==0x02)
	{
		CH.data[0] = TCNT1L;
		CH.data[1] = TCNT1H;
	
		TCCR1B = 0x00;  //start Timer1
		EICRA  = 0x03;
	}
}


/*--------------------   the end ------------------------------------*/

⌨️ 快捷键说明

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