📄 main.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 + -