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

📄 main.c

📁 使用Atmega8单片机开发的一个激光治疗仪的人机接口程序
💻 C
字号:
/*******************************************************

	"激光治疗仪"程序

	Designed by easyfly_step

	2006.10.28
********************************************************/

#include "main.h"

volatile uchar Can_read=0,AllState=0,LevelState=1,OutState=0,ChargeState=0,
LedSec=0,Time_minu=0,mh=0,ml=0,SwitchTimes=0,AdjustTimes=0,Time_sec=0;
volatile uchar times=0,ChargeTimes=0,KeyState=0,ChargeFlag=0,LedFlag=0,
ChargeFlagTimes=0,VoltageTimes=0,WorkFlag=0,Flag=1,FlagTimes=0,FirstFlag=0,
DelayFlag=0,AdjustTimesFlag=0,KeyOld=0,Adj=1,AlarmFlag=0,AbandonFlag=0;
volatile uint mid=0,ADTimes=0,VoltageResult_AD=0,ChargeResult_AD=0;
volatile uchar Seg[4];

int main(void)
{
 	//cli();
	Init_Device();
	Init_Flag();
	//Reset_Source();
	//AbandonFlag=0;
	DelayMs(1500);
	sei();
	//wdt_enable(WDTO_2S);
	//wdt_reset();
	
		while((PINB&(1<<POWER))==0)
	{
		//FirstFlag=0;
		//wdt_reset();
		DelayMs(100);
	}
	
	while(1)
	{
	//wdt_reset();
	//AD_Shift();
	AllState&=0b01000000;
	AllState|=(uchar)(AdjustTimes<<3)+LevelState;
	if(Can_read)
	{
		Can_read=0;
		//if(AbandonFlag==1)
		//{
		Voltage_Check();
		Charge_Check();
		//}
	}

	TaskTurn ();
	/*********A/D转换测试**********
	if(LevelState==0){puts("LevelState=");puts("0\n");}
	else if(LevelState==1){puts("LevelState=");puts("1\n");}
	else if(LevelState==2){puts("LevelState=");puts("2\n");}
	else if(LevelState==3){puts("LevelState=");puts("3\n");}
	else if(LevelState==4){puts("LevelState=");puts("4\n");}
	if(((AllState&0b01000000)>>6)==1){puts("充电中\n");}
	else if(((AllState&0b01000000)>>6)==0){puts("未充电\n");}
	DelayMs(300);
	****************************/
	}
}
/********
SIGNAL(SIG_OVERFLOW0)
{
}
SIGNAL(SIG_OVERFLOW1)
{
}
**********/

SIGNAL(SIG_OUTPUT_COMPARE1A)		//1ms中断一次//用于精确记时
{										
//	sbi(PORTB,PB0);
	TCNT1H=0x00;
	TCNT1L=0x00;	
	mid++;
	if(mid>=500)
	{
	Time_sec++;
	mh=Time_sec/10;
	ml=Time_sec%10;
	mid=0;
	LedSec++;
	} 
	if(Time_sec>=60) //秒判断 
		{ 
			Time_sec=0;
			Time_minu++;
			if(Time_minu>=30) //分判断 
					{ 
					Time_minu=0;
					//Beep_short(15,300);
					//Close();	//关机
					} 
		} 
	Show_State();  
	if(++FlagTimes>=10){FlagTimes=0;KeyState=KeyScan(KeyState);}//10ms扫描一次键盘
	if(++ADTimes>=100){AD_Shift();ADTimes=0;}//100ms进行一次A/D转换
	//if(LedSec>=10){LedSec=0;PORTC&=~(1<<6);}
}


/*********
SIGNAL(SIG_OUTPUT_COMPARE1B)
{

}
*********/
/*********
SIGNAL(SIG_OUTPUT_COMPARE2)		
{
static uchar BeepFlag;
if(BeepFlag)
PORTB&=~_BV(PB2);
	else
	PORTB|=_BV(PB2);
	BeepFlag=!BeepFlag;
}
*********/
/*******
SIGNAL(SIG_ADC)
{
//	ADC_data=ADCW;
}
*********/
void Reset_Source(void)
{
	if (MCUCSR & PORF)
	{
	// Power-on Reset
	MCUCSR=0;
	// Place your code here
	}
	else if(MCUCSR & EXTRF)
	{
	// External Reset
	MCUCSR=0;
	// Place your code here
	}
	else if(MCUCSR & BORF)
	{
	// Brown-Out Reset
	MCUCSR=0;
	// Place your code here
	}
	else if(MCUCSR & WDRF)
	{
	// Watchdog Reset
	MCUCSR=0;
	// Place your code here
	}
}



void Init_Flag(void)   //从EEPROM中读出当前功率状态
{
	eeprom_busy_wait();
	AdjustTimes=eeprom_read_byte(0);
	if(AdjustTimes==0xFF)AdjustTimes=1;
}

void Save_Flag(void)	//将调整后的功率状态存入EEPROM中
{
	eeprom_busy_wait();
	eeprom_write_byte(0,AdjustTimes);
}


void AD_Shift(void)	//开始进行A/D转换
{

/********
	//ADCH=0;ADCL=0;
	ADCSRA=0xD7;
	ADMUX=0x47;//ADMUX=0x44;//DIP-M8-UART测试
	ADCSRA|=(1<<ADSC);
	_delay_loop_1(60);
	while(ADCSRA&(1<<ADSC))
	_delay_loop_1(60);
	ChargeResult_AD=ADCL;
	ChargeResult_AD|=(uint)(ADCH<<8);
	
	//ADCH=0;ADCL=0;
	ADCSRA=0xD7;
	ADMUX=0x46;//ADMUX=0x45;//DIP-M8-UART测试
	ADCSRA|=(1<<ADSC);
	_delay_loop_1(60);
	while(ADCSRA&(1<<ADSC))
	_delay_loop_1(60);
	VoltageResult_AD=ADCL;
	VoltageResult_AD|=(uint)(ADCH<<8);
************/
	AD_init();
	VoltageResult_AD=BT_V();
	ChargeResult_AD=BT_C();
	Can_read=1;
}

void Voltage_Check(void)	//当前工作电压监测
{
	if(VoltageResult_AD>=VREFH){LevelState=4;alarm_n_short(1);}//Beep_middle(1,200);}
	else if((VoltageResult_AD>=VREFMH)&&(VoltageResult_AD<VREFH)){LevelState=4;}
	else if((VoltageResult_AD>=VREFML)&&(VoltageResult_AD<VREFMH)){LevelState=3;}
	else if((VoltageResult_AD>=VREFL)&&(VoltageResult_AD<VREFML)){LevelState=2;}
	else if((VoltageResult_AD>=VREFC)&&(VoltageResult_AD<VREFL)){LevelState=0;}
	else {LevelState=1;KeyState=0;SwitchTimes=1;alarm_n_short(1);Close();}
	AllState=(AllState&0b11111000)+LevelState;
}


void Charge_Check(void)	//充电状态监测
{
	//if(ChargeResult_AD>=VREFH_CHARGE){ChargeState=2;Beep_long(1,200);}
	//else 
	if(ChargeResult_AD>=VREFL_CHARGE)//&&ChargeResult_AD<VREFH_CHARGE)
		{
			//if(++ChargeFlagTimes>3)
			//{
			//ChargeFlagTimes=0;
			ChargeState=1;
			AllState|=(1<<6);
			LedSec=0;
			PORTC|=(1<<6);//}//LED背光给电10秒
			if(ChargeFlag==0){alarm_n_short(1);ChargeFlag=1;}//Beep_short(1,200);ChargeFlag=1;}
			//}
		}
		else 
		{
			//ChargeFlagTimes=0;
			ChargeState=0;
			AllState&=~(1<<6); 
			ChargeFlag=0;
		}
		
}

void Close(void)	//关机
{
//Beep_short(3,200);   //关机前报警
//Reset_Source();//PORTC&=~(1<<6);
PORTB&=~(1<<7);//PORTB|=(1<<7);   //置高,使POWER断开,关机	
wdt_enable(WDTO_1S);
wdt_reset();
/*****
DelayMs(1000);
cli();
Can_read=0;AllState=0;LevelState=1;OutState=0;ChargeState=0;Time_minu=0;mh=0;ml=0;SwitchTimes=0;AdjustTimes=0;Time_sec=0;
times=0;ChargeTimes=0;KeyState=0;ChargeFlag=0;ChargeFlagTimes=0;VoltageTimes=0;FlagTimes=0;DelayFlag=0;AdjustTimesFlag=0;KeyOld=0;Adj=1;AlarmFlag=0;
AbandonFlag=0;mid=0;ADTimes=0;VoltageResult_AD=0;ChargeResult_AD=0;
Init_Device();
Init_Flag();
//Reset_Source();
//AbandonFlag=0;
sei();
******/
}

void TaskTurn (void)
{
/**********
Flag 用于按下WORK时,ADJUST的屏蔽
SwitchTimes 用于开关机记数
DelayFlag 用于开机后待机状态显示稳定及扬声器发声及laserpower给电
AdjustTimesFlag为有按键进行调整的标志
*********/
switch(KeyState)
	{
	case 0x00:       //POWER/RA5键-PB6//待机状态
			//AllState&=0b01000000;
			//AllState|=(uchar)(AdjustTimes<<3)+LevelState; 
			if(DelayFlag==0)
				{
				//wdt_reset();
				if(((AllState&0b01000000)>>6)==1)ChargePOWERState_Display(10);
				else POWERState_Display(10);
				alarm_n_short(1);//Beep_middle(1,200);
				DelayFlag=1;
				}
			else 
				{
				if(((AllState&0b01000000)>>6)==1)ChargePOWERState_Display(10);
				else POWERState_Display(10);
				}
			
			if((Flag==0)&&(KeyState==0))//if((FirstFlag==1)&&(Flag==0)&&(KeyState==0))
				{
				//FirstFlag=0;
				KeyState=0;
				if(((AllState&0b01000000)>>6)==1)ChargePOWERState_Display(10);
				else POWERState_Display(10);
				DelayMs(1000);
				SwitchTimes=1;
				}//长按关机
			
			 if(SwitchTimes==1)
				{
				//wdt_reset();
				alarm_n_short(3);//Beep_middle(3,200);  
				Flag=1;
				SwitchTimes=0;
				Close();   
				} 
			
		break;
	case 0x01:		 //WORK键-PC4//工作状态
		PORTB&=~(1<<5);//laserpower给电 PB5置0
		//AllState&=0b01000000;
		//AllState|=(uchar)(AdjustTimes<<3)+LevelState;
		if(WorkFlag==0){alarm_n_short(1);WorkFlag=1;}//Beep_short(1,200);WorkFlag=1;}
		if(((AllState&0b01000000)>>6)==1)ChargeWORKState_Display(10,(uchar)((AllState&0b00111000)>>3),(uchar)(AllState&0b00000111));
		 else WORKState_Display(10,(uchar)((AllState&0b00111000)>>3),(uchar)(AllState&0b00000111));
		if(AdjustTimes==1){PORTB&=~(1<<0);PORTB&=~(1<<3);PORTB&=~(1<<4);}//PB0:PB3:PB4:->000	//给激光器调整功率状态
			else if(AdjustTimes==2){PORTB&=~(1<<0);PORTB&=~(1<<3);PORTB|=(1<<4);}//PB0:PB3:PB4:->001
				else if(AdjustTimes==3){PORTB&=~(1<<0);PORTB|=(1<<3);PORTB&=~(1<<4);}//PB0:PB3:PB4:->010
					else if(AdjustTimes==4){PORTB|=(1<<0);PORTB&=~(1<<3);PORTB&=~(1<<4);}//PB0:PB3:PB4:->100
		if((Time_minu==15)&&(AlarmFlag==0)){alarm_n_short(5);AlarmFlag=1;}//Beep_middle(5,200);AlarmFlag=1;}
		else if((Time_sec>=58)&&(Time_sec<=60)&&(Time_minu==29)&&(AlarmFlag==1)){alarm_n_short(15);AlarmFlag=0;SwitchTimes=1;KeyState=0;Close();  }//Beep_middle(15,200);AlarmFlag=0;SwitchTimes=0;}
		/*************
		if((Flag==1)&&(KeyState==1))
		{KeyState=0;//wdt_reset();
		DelayMs(1000);SwitchTimes=1;}//长按关机
		***********/
		break;
		
	case 0x02:		//ADJUST_P键-PC5//功率调整状态
		//wdt_reset();
		if(AdjustTimesFlag==1)
			{
			if(((AllState&0b01000000)>>6)==1)ChargeADJUSTState_Display(10,(uchar)((AllState&0b00111000)>>3),(uchar)(AllState&0b00000111));
				else ADJUSTState_Display(10,(uchar)((AllState&0b00111000)>>3),(uchar)(AllState&0b00000111));
			
			AdjustTimesFlag=0;
			/*********
			//AdjustTimes++;		//AdjustTimes为功率状态(第几格)
			//wdt_reset();
			AdjustTimes=(++Adj)/2;
			//AllState&=0b01000000;
			//AllState|=(uchar)(AdjustTimes<<3)+LevelState;
			Save_Flag();	
			if(Adj>8)Adj=1;
			if(Adj%2)alarm_n_short(1);//Beep_short(1,200);
			DelayMs(500);//延时消抖,防止AdjustTimes重复++
			*********/
			while((PINC&(1<<ADJUST))==0)
			{
			DelayMs(1);
			}	
			AdjustTimes=(++Adj)/2;
			if(Adj>8)Adj=1;
			Save_Flag();
			if(Adj%2)alarm_n_short(1);//Beep_short(1,200);
			}
		else if(AdjustTimesFlag==0)
		{
		if(((AllState&0b01000000)>>6)==1)ChargeADJUSTState_Display(10,(uchar)((AllState&0b00111000)>>3),(uchar)(AllState&0b00000111));
			else ADJUSTState_Display(10,(uchar)((AllState&0b00111000)>>3),(uchar)(AllState&0b00000111));
		}
		/**********
		if((Flag==1)&&(KeyState==2))
		{KeyState=0;//wdt_reset();
		DelayMs(1000);SwitchTimes=1;}//长按关机
		************/
		break;
	case 0x03:	
	Can_read=0,AllState=0,LevelState=1,OutState=0,ChargeState=0,LedSec=0,Time_minu=0,mh=0,ml=0,SwitchTimes=0,AdjustTimes=0,Time_sec=0;
	times=0,ChargeTimes=0,KeyState=0,ChargeFlag=0,LedFlag=0,ChargeFlagTimes=0,VoltageTimes=0,WorkFlag=0,Flag=1,FlagTimes=0,FirstFlag=0,DelayFlag=0,AdjustTimesFlag=0,KeyOld=0,Adj=1,AlarmFlag=0,AbandonFlag=0;
	mid=0,ADTimes=0,VoltageResult_AD=0,ChargeResult_AD=0;
	Init_Device();
	Init_Flag();
	AllState&=0b01000000;
	AllState|=(uchar)(AdjustTimes<<3)+LevelState;
		default:
		break;
	}
}   


uchar KeyScan (uchar ret)
{
//puts("KeyScanT");
/****
#define POWER PB6
#define WORK PC4
#define ADJUST PC5
#define RESET PC6
***/
	if((PINB&(1<<POWER))==0)
	{
		//DelayMs(1);
		
		if((PINB&(1<<POWER))==0)
		{
		ret=0;
		//AbandonFlag=1;
		//break;
		//puts("ret=");puts("0x00#");
		 // if(LedFlag==0){
		 LedSec=0;
		 Flag=0;
		 //FirstFlag=1;
		 PORTC|=(1<<6);//}//LED背光给电10秒
		}
		
	}
		else if((PINC&(1<<WORK))==0)
		{
		
			//DelayMs(1);
			if((Flag==1)&&(PINC&(1<<WORK))==0)
			{
			ret=1;
			//AbandonFlag=1;
			//break;
			//puts("ret=");puts("0x01#");
			// if(LedFlag==0){
			LedSec=0;
			PORTC|=(1<<6);//}//LED背光给电10秒
			}
		}
			else if((PINC&(1<<ADJUST))==0)
			{
			
				//DelayMs(1);
				if((Flag==1)&&(PINC&(1<<ADJUST))==0)
				{
				ret=2;
				//break;
				//puts("ret=");puts("0x02#");
				AdjustTimesFlag=1;
				//AbandonFlag=1;
				// if(LedFlag==0){
				LedSec=0;
				PORTC|=(1<<6);//}//LED背光给电10秒
				}
			}
			
			else if((PINB&(1<<RESET))==0)
			{
			
				//DelayMs(1);
				if((PINB&(1<<RESET))==0)
				{
				ret=3;
				PORTC|=(1<<6);//}//LED背光给电10秒
				}
			}

			
/******
	while(((PINB&_BV(POWER))!=_BV(POWER))||((PINC&(_BV(WORK)|_BV(ADJUST)))!=(_BV(WORK)|_BV(ADJUST))))	//
	{ DelayMs(1);}
********/

	if(ret!=KeyOld)
		{
		if((PINB&(1<<POWER))==0)
			{
			DelayFlag=0;
			Flag=0;
			//FirstFlag=1;
			}
			else 
			if((PINC&(1<<WORK))==0)
				{
				Flag=0;
				Time_minu=0;
			    Time_sec=0;
				}
		KeyOld=ret;
		return KeyOld;
		}
	else 
	{
	/***
		if(ret=2)	
		{
		while((PINB&_BV(ADJUST))!=_BV(ADJUST))
		{asm("nop"::);}	
		AdjustTimesFlag=1;
		}
		******/
		return ret;
	}

}
void putc(uchar c)
{
while(!(UCSRA&(1<<UDRE)));
UDR=c;
}
uchar getc(void)
{
while(!(UCSRA&(1<<RXC)));
return UDR;
}

void puts(char *ptr)
{
    while (*ptr)
        putc(*ptr++);
}

void AD_init(void)
{   	
    ADCSRA=0X00; 
	ACSR|=(1<<ACD);//关闭模拟比较器   
    ADMUX|=(1<<REFS0)|(6&0x0F); //
    ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1);//ADC转换 64分频
}

unsigned int read_adc (uchar r,uchar m)
{
 unsigned int adc_rel;
 ADMUX=0;
 ADMUX |=(m&0x0F);//选择通道
 ADMUX |=(r<<6);//选择基准
 ADCSRA|=(1<<ADSC);//启动AD转换
 DelayUs(125);
 adc_rel=ADC&0x3FF;
  return(adc_rel);
}

unsigned int BT_V(void)
{
 unsigned char i;
 unsigned int a=0;
 unsigned int BT_V;//电池电压
     i=read_adc(1,6);//第一次转换,不要
     for (i=0;i<16;i++)
		    {
			  a+=read_adc(1,6);//内部基准(3.3V),ADC6		 
			}
	  BT_V=(a>>4);
	  if(BT_V>65530)
	    BT_V=0;
		return BT_V;
}

unsigned int BT_C(void)
{
 unsigned char i;
 unsigned int a=0;
 unsigned int BT_C;//电池电压
     i=read_adc(1,7);//第一次转换,不要
     for (i=0;i<16;i++)
		    {
			  a+=read_adc(1,7);//内部基准(3.3V),ADC7		 
			}
	  BT_C=(a>>4);
	  if(BT_C>65530)
	    BT_C=0;
		return BT_C;
}

⌨️ 快捷键说明

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