📄 rtc.c
字号:
// **************************************************************
// *** 广 州 天 河 双 龙 电 子 公 司 ***
// *** http://www.sl.com.cn ***
// *** 实验: RTC ***
// *** 作者:zxy@sl.com.cn ***
// *** 2006年3月28日 ***
// *** 目标MCU:MEGA169 晶振:内部(INT)8MHZ ***
// **************************************************************
//此实验需具备AD转换知识
//通过按键修改时钟值,S1为选位键,S2为增1,S4为减1
#include <iom169v.h>
#include <macros.h>
//键值定义,以目标实验板际测取键值范围为准
#define s1 (adc_old<0x03)
//200h
#define s2 ((adc_old>0x180)&&(adc_old<0x220))
//2a6h
#define s3 ((adc_old>0x290)&&(adc_old<0x2CF))
//2fbh
#define s4 ((adc_old>0x2D0)&&(adc_old<0x310))
//326h
#define s5 ((adc_old>0x310)&&(adc_old<0x345))
extern const unsigned char seg_table[16];
extern unsigned char led_buff[3];
extern void delay_ms(unsigned int time);
extern void display(void);
unsigned int adc_rel;//AD转换结果
unsigned int i=0,j=0,k=0;
//E、B口初始化
void portE_B(void)
{
DDRE=0xff;//E、B口初始化
PORTE=0xff;
DDRB|=0xf0;
PORTD|=0xf0;
}
//ADC初始化
void adc_init(void)
{
ADCSRA = 0x00; //设置前,先关闭ADC
ADMUX =(1<<REFS0)|(1<<MUX0);//选择内部AVCC为基准,单端输入口为ADC1
ACSR =(1<<ACD);//关闭模拟比较器,禁止位P148
ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1) ;//ADC时钟64分频
}
//定时器初始化
void timer2_init(void)
{
TIMSK2 = 0x00;
ASSR = 1<<AS2; //异步时钟
TCNT2 = 0xE0; //定时时间1秒
TCCR2A = (1<<CS22)|(1<<CS21)|(1<<CS20); //分频比1024,0x07
SEI();
}
#pragma interrupt_handler adc_isr:20 int_isr:6
//ADC完成中断
void adc_isr(void)
{
adc_rel=ADC&0x3ff;
ADMUX=(1<<REFS0)|(1<<MUX0);//选择内部AVCC为基准
ADCSRA|=(1<<ADSC);//启动AD转换
}
//定时器中断
void int_isr(void)
{ int n;
TCNT2 = 0xE0;
led_buff[0]=seg_table[i]; //个位
led_buff[1]=seg_table[j]; //十位
led_buff[2]=seg_table[k]; //百位
i++;
if(i==10) //十进位
{
i=0;
j++;
if(j==6) //六进位
{
j=0;
k++;
if(k==10) //十进位
{i=0;j=0;k=0;}
}
}
}
unsigned int adc_old;
void keyScan(void)
{
if(adc_old!=adc_rel) //是否有键按下
adc_old=adc_rel; //有键按下,读取键值
display();
while(s1) //是否为S1键
{ display();
delay_ms(200); //按键消抖25MS
adc_old=adc_rel; //读取键值
//**********个位处理
while(!s1) //是否为S1键,不是S1时进入等待状态,并选中个位
{
adc_old=adc_rel;
TIMSK2=0x00; //屏蔽定时器中断
PORTE=seg_table[i]&0x7f; //点亮个位及其小数点
PORTB=0xef; //点亮个位
delay_ms(1);
PORTE=seg_table[j]; //点亮十位
PORTB=0XDF; //点亮十位
delay_ms(1);
PORTE=seg_table[k]; //点亮百位
PORTB=0XBF; //点亮百位
delay_ms(1);
adc_old=adc_rel; //读取键值
if(s2) //是否为S3 ,如果是S3,个位加1
{
int x;
for(x=50;x>0;x--) //消抖且保证LED显示正常
{
PORTE=seg_table[i]&0x7f;
PORTB=0xef;
delay_ms(1);
PORTE=seg_table[j];
PORTB=0XDF;
delay_ms(1);
PORTE=seg_table[k];
PORTB=0XBF;
delay_ms(1);
}
i++; //个位加1
if(i==10)
{
i=0;
}
}
if(s4) //是否为S4 ,如果是S4,个位减1
{int x;
for(x=50;x>0;x--) //消抖且保证LED显示正常
{
PORTE=seg_table[i]&0x7f; //点亮个位及其小数点
PORTB=0xef; //点亮个位
delay_ms(1);
PORTE=seg_table[j]; //点亮十位
PORTB=0XDF; //点亮十位
delay_ms(1);
PORTE=seg_table[k]; //点亮百位
PORTB=0XBF; //点亮百位
delay_ms(1);
}
i--; //减1
if(i==-1)
{
i=9;
}
}
}
delay_ms(200);
adc_old=adc_rel;
//********十位处理
while(!s1) //同上
{
adc_old=adc_rel;
TIMSK2=0x00;
PORTE=seg_table[i]; //点亮个位
PORTB=0xef; //点亮个位
delay_ms(1);
PORTE=seg_table[j]&0x7f; //点亮十位及其小数点
PORTB=0XDF; //点亮十位
delay_ms(1);
PORTE=seg_table[k]; //点亮百位
PORTB=0XBF; //点亮百位
delay_ms(1);
adc_old=adc_rel;
if(s2)
{
int x;
for(x=50;x>0;x--)
//display();
{
PORTE=seg_table[i];
PORTB=0xef;
delay_ms(1);
PORTE=seg_table[j]&0x7f;
PORTB=0XDF;
delay_ms(1);
PORTE=seg_table[k];
PORTB=0XBF;
delay_ms(1);
}
j++; //加1
if(j==6)
{
j=0;
}
}
if(s4)
{
int x;
for(x=50;x>0;x--) //消抖且保证LED显示正常
{
PORTE=seg_table[i]; //点亮个位
PORTB=0xef; //点亮个位
delay_ms(1);
PORTE=seg_table[j]&0x7f; //点亮十位及其小数点
PORTB=0XDF; //点亮十位
delay_ms(1);
PORTE=seg_table[k]; //点亮百位
PORTB=0XBF; //点亮百位
delay_ms(1);
}
j--; //减1
if(j==-1)
{
j=5;
}
}
}
delay_ms(200);
adc_old=adc_rel;
//******百位处理
while(!s1) //同上
{
adc_old=adc_rel;
TIMSK2=0x00;
PORTE=seg_table[i]; //点亮个位
PORTB=0xef; //点亮个位
delay_ms(1);
PORTE=seg_table[j]; //点亮十位
PORTB=0XDF; //点亮十位
delay_ms(1);
PORTE=seg_table[k]&0x7f; //点亮百位及其小数点
PORTB=0XBF; //点亮百位
delay_ms(1);
adc_old=adc_rel;
if(s2)
{
int x;
for(x=50;x>0;x--)
{
PORTE=seg_table[i]; //点亮个位及其小数点
PORTB=0xef; //点亮个位
delay_ms(1);
PORTE=seg_table[j]; //点亮十位
PORTB=0XDF; //点亮十位
delay_ms(1);
PORTE=seg_table[k]&0x7f; //点亮百位
PORTB=0XBF; //点亮百位
delay_ms(1);
}
k++; //加1
if(k==10)
{
k=0;
}
}
if(s4)
{int x;
for(x=50;x>0;x--)
{
PORTE=seg_table[i]; //点亮个位及其小数点
PORTB=0xef; //点亮个位
delay_ms(1);
PORTE=seg_table[j]; //点亮十位
PORTB=0XDF; //点亮十位
delay_ms(1);
PORTE=seg_table[k]&0x7f; //点亮百位
PORTB=0XBF; //点亮百位
delay_ms(1);
}
k--; //减1
if(k==-1)
{
k=9;
}
}
}
//***********
while(s1){adc_old=adc_rel;} //跳出
}
}
void main(void)
{
adc_init();//AD初始化
timer2_init();//定时器初始化
portE_B();
TIMSK2=1;
SEI();//使能全局中断
while(1)
{
TIMSK2=1;
display(); //显示
keyScan(); //键值扫描
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -