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

📄 main.c

📁 可定时延时断开控制器,优点是:可自行设定时间.
💻 C
字号:
//ICC-AVR application builder : 2008-12-10 9:53:09
// Target : M16
// Crystal: 14.7456Mhz

#include <iom16v.h>
#include <macros.h>
#include "main.h"

void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x0C;
 PORTB = 0x00;
 DDRB  = 0x07;
 PORTC = 0x7F; //m103 output only
 DDRC  = 0xFF;
 PORTD = 0x00;
 DDRD  = 0x00;
}

//TIMER1 initialize - prescale:1024
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Sec
// actual value:  1.000Sec (0.0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xC7; //setup
 TCNT1L = 0xC1;
 OCR1AH = 0x38;
 OCR1AL = 0x3F;
 OCR1BH = 0x38;
 OCR1BL = 0x3F;
 ICR1H  = 0x38;
 ICR1L  = 0x3F;
 TCCR1A = 0x00;
 TCCR1B = 0x00; //start Timer   //通过关闭时钟,取消定时器自启动,启动将在主程序中加入
}

#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
 //TIMER1 has overflowed
  
 TCCR1B = 0x00;   //关闭定时器
  
 TCNT1H = 0xC7; //reload counter high value
 TCNT1L = 0xC1; //reload counter low value
 
 seconds--;   //定时减一秒

}

#pragma interrupt_handler int0_isr:iv_INT0
void int0_isr(void)
{
 //external interupt on INT0
 
  /*************防抖后读取EEPROM定时***************/
 delayms(10);
 if(~(PIND & (1<<PD2)))
 seconds = EEPROM_read(0x4010);
 asm("nop");
 asm("nop");
 asm("nop");
}

#pragma interrupt_handler int1_isr:iv_INT1
void int1_isr(void)
{
 //external interupt on INT1
 
 /*************防抖后读取EEPROM定时***************/
 delayms(10);
 if(~(PIND & (1<<PD3)))
 seconds = EEPROM_read(0x4010);
 asm("nop");
 asm("nop");
 asm("nop");
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 timer1_init();

 MCUCR = 0x0A;
 GICR  = 0xC0;
 TIMSK = 0x04; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

main()
{
 init_devices();
 //EEPROM_write(0x4010,125);
 seconds = 0;

 while(1)
 		 {
		  while(seconds != 0)
		  {   
		   TCCR1B = 0x05;     //定时器1启动,1024分频
		   OUTPUT_HIGH();
		   display_all(seconds); 
		   if(seconds == 0)
		   {
		   			   OUTPUT_LOW();
		   }
		  }
		  display_all(seconds);
		   
		  if((PIND & (1<<PD4)) == 0)    //检测是SET键被按下则进入
		  {
		   		     delayms(10);                //防抖
		   
		   		     while((PIND & (1<<PD4)) == 0)  
		  			  {
		   			  	if((PIND & (1<<PD4)) > 0)         //等待松开按键
						break;
		 			  }     
		   			  setting();
					  seconds = 0;   //设置完成后初始化SECONDS,以防止设置过程中有INT0,1中断请求而造成保存退出后立即执行
		  }
		 } 		 		
}

void delayms(unsigned int t)
{
 unsigned int i,j;
 for(i=0;i<t;i++)
 	{
	for(j=0;j<125;j++);
	}
}

/***********************数码管显示部分**************************/

void display_all(unsigned char num)
{
 display_1(num);
 display_2(num);
 display_3(num);
 
 /*switch(disp_sequ++)
 {
  
  case 1:
  			 display_1(seconds);
			 break;
  case 2:
 			 display_2(seconds);
			 break;
  case 3:		 
 			 display_3(seconds);
			 disp_sequ = 1;
			 break;		
			 
			 default:break;
 }*/

}

void display_1(unsigned char num)
{
  disp_num=(unsigned int)(num/100);
  disp_temp1 = 1;
  if(disp_num == 0)
  {
     disp_temp1 = 0;
	 OFF_DISP();
     PORTC = Leddata[10];  //第一位不显示任何数字
	 ON_DISP1();
  }
  else
  {
  	 OFF_DISP();
	 PORTC = Leddata[disp_num]; //如果不是0,则显示对应的数值
	 ON_DISP1();
  }
}

void display_2(unsigned char num)
{
  unsigned int temp;
  temp = num % 100;
  disp_num=(unsigned int)(temp/10);
  if(disp_temp1 == 0 && disp_num == 0)
  {
	 OFF_DISP();
	 PORTC = Leddata[10];
	 ON_DISP2();
  }
  else
  {
   	   OFF_DISP();
   	   PORTC = Leddata[disp_num];
   	   ON_DISP2();
  }
}

void display_3(unsigned char num)
{
  disp_num=(unsigned int)(num % 10);
  OFF_DISP();
  PORTC = Leddata[disp_num];
  ON_DISP3();
}


/**********************闪烁*********************/
/*void Disp_flick(void)
{
 display_1(num);
 display_2(num);
 display_3(num);
 
 if(disp_flick<500)
 display_all();
 disp_flick++;
 if(disp_flick == 1000)
 disp_flick = 0;
}*/


/********************SETTING 程序*******************/
void setting(void)
{
 setting_flag = 1;       //SETTING运行的必要条件
 seconds_setting = EEPROM_read(0X4010);   //把EEPROM中的值读出,准备修改
 asm("nop");
 asm("nop");
 asm("nop");
 while(setting_flag == 1)
 {
  		/*********************在PD5~PD7中寻找被按下的KEY,并将KEY保存**************/ 
		if(((PIND & (1<<PD5)) == 0) || ((PIND & (1<<PD6)) == 0)|| ((PIND & (1<<PD7)) == 0))
		{
		 		delayms(10);                                              //延时消抖
				while(((PIND & (1<<PD5)) == 0) || ((PIND & (1<<PD6)) == 0) || ((PIND & (1<<PD7)) == 0))
				{
				 		key = (PIND & 0xE0);
						asm("nop");
						asm("nop");
						asm("nop");
						if(((PIND & (1<<PD5)) > 0) && ((PIND & (1<<PD6)) > 0) && ((PIND & (1<<PD7)) > 0))
						{
								  break;
						}
				}				
		}
		
		/******************NUMERIC闪烁刷新*************************/
		if(disp_flick < 45000)
		{
		 			  PORTC = Leddata[10];
					  disp_flick++;
					  //ON_POINT();
		}
		else
		{
		 			  display_all(seconds_setting);
					  disp_flick++;
		}
		
		if(disp_flick > 50000)
		{
		 			  disp_flick = 0;
		}
		
		
		/************************启动相应的KEY的功能********************/
		switch(key)
		{
		 case 0xA0:
					  	   seconds_setting += 1;       //加1
						   key = 0xE0;
						   break;
		 case 0xC0:
					  	   seconds_setting += 10;      //加10
						   key = 0xE0;
						   break;	
		 case 0x60:
					  	   setting_flag = 0;                       //setting状态结束
				           EEPROM_write(0x4010,seconds_setting);     //把设置完的数存入EEPROM
						   asm("nop");
						   asm("nop");
						   asm("nop");
						   key = 0xE0;
						   break;	 
		 case 0xE0:
		 	  	   		   break;
		}
		
		if(seconds_setting > 200)                    //限制最大设定值为200秒
						   seconds_setting = 1;
						   
		
 }
}


/***************EEPROM读写程序***************/

unsigned char EEPROM_read(unsigned int uiAddress)
{
/* 等待上一次写操作结束 */
while(EECR & (1<<EEWE))
;
/* 设置地址寄存器*/
EEAR = uiAddress;
/* 设置EERE 以启动读操作*/
EECR |= (1<<EERE);
/* 自数据寄存器返回数据 */
return EEDR;
}

void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
/* 等待上一次写操作结束 */
while(EECR & (1<<EEWE))
;
/* 设置地址和数据寄存器*/
EEAR = uiAddress;
EEDR = ucData;
/* 置位EEMWE */
EECR |= (1<<EEMWE);
/* 置位EEWE 以启动写操作*/
EECR |= (1<<EEWE);
}

⌨️ 快捷键说明

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