还有一天比赛了,先看原题 很简单,感觉就是前几届不常考的考点,注意那个L10操作
MAIN.C
unsigned char TIME_buffer2[7];
unsigned char TIME_buffer1[7];
unsigned char TIME_buffer[7];
uchar mode;
int temp;
uchar shi;
uchar ge;
uchar shi_p;
uchar ge_p;
int temp2;
uchar count;
uchar count_a;
0 1 2 3 4 5 6 7 8 9 - 全灭 .
unsigned char code shuzi[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0xbf,0xff,0x7f};
/// A b C d E F H L P U n
unsigned char code zimu[]={0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0xc7,0x8c,0xc1,0xc8};
0 1 2 3 4 5 6 7
unsigned char code weizhi[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00};
// 1 2 3 4 5 6 7 8 灭
unsigned char ledweizhi[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};
unsigned char code WRITE_RTC_ADDR[7] =
{0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //定义写操作的日历时钟寄存器地址
unsigned char code READ_RTC_ADDR[7] =
{0x81,0x83,0x85,0x87,0x89,0x8b,0xbd}; //定义读操作的日历时钟寄存器地址
unsigned char TIME[7] =
{0x00,0x00,0x12,0x18,0x02,0x02,0x20}; //定义日历时钟寄存器配置参数(秒、分、时、日、月、星期、年)
unsigned char code SEG_code[18] =
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
0xbf,0x7f}; //定义共阳数码管段码内容:0~F,—,.
sbit R1=P3^0;
sbit R2=P3^1;
sbit R3=P3^2;
sbit R4=P3^3;
sbit Relay= P0^4; //继电器
sbit Buzz=P0^6;//蜂鸣器
void delay_ms(int ms)
{
int q,w;
for(q=0;q<ms;q++){
for(w=845;w>0;w--);
}
}
void ledlight(uchar x)
{
P2=(P2&0X1f)|0x80;
P0=ledweizhi[x];
}
void DS1302_Config()
{
unsigned char n;
Write_Ds1302_Byte(0x8e,0x00); //允许向内存写入数据
for(n=0;n<7;n++)
{
Write_Ds1302_Byte(WRITE_RTC_ADDR[n],TIME[n]); //低位先写
}
Write_Ds1302_Byte(0x8e,0x80); //禁止向内存写入数据
}
void shumaguan_shuzi(uchar a,uchar b)
{
delay_ms(1);
P2=(P2&0X1f)|0xC0;P0=weizhi[a];
P2=(P2&0X1f)|0xE0;P0=shuzi[b];
delay_ms(1);
//消隐
P2 = (P2 & 0x1f) | 0xc0;
P0 = 0x00;
P2 = P2 & 0x1f;
}
//数码管字母显示
void shumaguan_zimu(uchar a,uchar b)
{
delay_ms(1);
P2=(P2&0X1f)|0xC0;P0=weizhi[a];
P2=(P2&0X1f)|0xE0;P0=zimu[b];
delay_ms(1);
//消隐
P2 = (P2 & 0x1f) | 0xc0;
P0 = 0x00;
P2 = P2 & 0x1f;
}
void timer0() //定时模式
{
ET0=1;
EA=1;
TMOD &= 0xF0;
TH0 = (65535-50000)/256;//50000us=50ms
TL0 = (65535-50000)%256;
TF0 = 1;
TR0 = 1;
}
//数字时钟,需要重装载
void Service_timer0() interrupt 1//定时器0
{
TH0 = (65535-50000)/256;//50000us=50ms
TL0 = (65535-50000)%256;
count++;
if(count==20)
{
count=0;
count_a++;
}
}
//读取实时时间
void DS1302_ReadTime()
{
unsigned char n;
for(n=0;n<7;n++)
{
TIME_buffer[n]=TIME[n];
}
for(n=0;n<7;n++)
{
TIME[n] = Read_Ds1302_Byte(READ_RTC_ADDR[n]);
}
}
//数码管延时函数
void Delay_tube(unsigned char t)
{
while(t--);
}
//数码管显示
void Show_tube(unsigned char position,unsigned char value)
{
P2 = (P2 & 0x1f) | 0xc0;//数码管的片选端
P0 = 0x01 << position;
P2 = (P2 & 0x1f) | 0xe0;//数码管的数据
P0 = value;
}
//数码管动态显示
void Display_tube()
{
Show_tube(0,SEG_code[TIME_buffer[2]/16]); //显示时的十位(TIME[n]为16进制数,所以除以16)
Delay_tube(500);
Show_tube(1,SEG_code[TIME_buffer[2]%16]); //显示时的个位
Delay_tube(500);
Show_tube(2,SEG_code[16]); //显示分隔符
Delay_tube(500);
Show_tube(3,SEG_code[TIME_buffer[1]/16]); //显示分的十位
Delay_tube(500);
Show_tube(4,SEG_code[TIME_buffer[1]%16]); //显示分的个位
Delay_tube(500);
Show_tube(5,SEG_code[16]); //显示分隔符
Delay_tube(500);
Show_tube(6,SEG_code[TIME_buffer[0]/16]); //显示秒的十位
Delay_tube(500);
Show_tube(7,SEG_code[TIME_buffer[0]%16]); //显示秒的个位
Delay_tube(500);
P2 = (P2 & 0x1f) | 0xc0;
P0 = 0x00;
P2 = P2 & 0x1f;
}
void jisuan()
{
if(TIME_buffer[2]==10)
{
TIME_buffer2[2]=0;
TIME_buffer1[2]++;
TIME_buffer[2]=TIME_buffer1[2]<<4|(TIME_buffer2[2]&0x0f);//0x10
}
if(TIME_buffer[2]==0x1a)
{
TIME_buffer2[2]=0;
TIME_buffer1[2]++;
TIME_buffer[2]=TIME_buffer1[2]<<4|(TIME_buffer2[2]&0x0f);
}
if(TIME_buffer[2]==0x24)
{
TIME_buffer2[2]=0;
TIME_buffer1[2]=0;
TIME_buffer[2]=0;
}
if(TIME_buffer[1]==10)
{
TIME_buffer2[1]=0;
TIME_buffer1[1]++;
TIME_buffer[1]=TIME_buffer1[1]<<4|(TIME_buffer2[1]&0x0f);//0x10
}
if(TIME_buffer[1]==0x1a)
{
TIME_buffer2[1]=0;
TIME_buffer1[1]++;
TIME_buffer[1]=TIME_buffer1[1]<<4|(TIME_buffer2[1]&0x0f);
}
if(TIME_buffer[1]==0x2a)
{
TIME_buffer2[1]=0;
TIME_buffer1[1]++;
TIME_buffer[1]=TIME_buffer1[1]<<4|(TIME_buffer2[1]&0x0f);
}
if(TIME_buffer[1]==0x3a)
{
TIME_buffer2[1]=0;
TIME_buffer1[1]++;
TIME_buffer[1]=TIME_buffer1[1]<<4|(TIME_buffer2[1]&0x0f);
}
if(TIME_buffer[1]==0x4a)
{
TIME_buffer2[1]=0;
TIME_buffer1[1]++;
TIME_buffer[1]=TIME_buffer1[1]<<4|(TIME_buffer2[1]&0x0f);
}
if(TIME_buffer[1]==0x5a)
{
TIME_buffer2[1]=0;
TIME_buffer1[1]=0;
TIME_buffer[1]=0;
}
}
void display_ds1302()//显示ds1302的时钟
{
DS1302_ReadTime();
Display_tube();
ledlight(0);
}
void Init_Keys()
{
R1=R2=R3=R4=1;
}
void temperature_get()
{
uchar high,low;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
low=Read_DS18B20();
high=Read_DS18B20();
temp=((high<<4)|(low>>4));//不带小数点,注掉后面一行就行
temp2=low&0x0f*100/16;//取小数点两位,注掉上面一行就行
shi=temp%100/10;//不带小数点
ge=temp%10;
shi_p=temp2/10;//带两位小数点
ge_p=temp%10;
}
void display_temp()
{
shumaguan_zimu(0,2);
shumaguan_shuzi(5,shi);
shumaguan_shuzi(6,ge);
shumaguan_shuzi(6,12);//显示小数点
shumaguan_shuzi(7,ge_p);
ledlight(1);
}
void select_mode()
{
switch(mode)
{
case(0):display_ds1302();break;
case(1):temperature_get();display_temp();break;
}
}
void Scan_S4()
{
if(R4==0)
{
while(R4==0);
mode++;
if(mode>1) mode=0;
}
}
void Scan_S5()
{
uchar n;
if(R3==0)
{
while(R3==0)display_ds1302();
TIME_buffer[2]++;
jisuan();
Write_Ds1302_Byte(0x8e,0x00); //允许向内存写入数据
for(n=0;n<7;n++)
{
Write_Ds1302_Byte(WRITE_RTC_ADDR[n],TIME_buffer[n]); //低位先写
}
Write_Ds1302_Byte(0x8e,0x80); //禁止向内存写入数据
}
}
void Scan_S6()
{
uchar n;
if(R2==0)
{
while(R2==0)display_ds1302();
TIME_buffer[1]++;
jisuan();
Write_Ds1302_Byte(0x8e,0x00); //允许向内存写入数据
for(n=0;n<7;n++)
{
Write_Ds1302_Byte(WRITE_RTC_ADDR[n],TIME_buffer[n]); //低位先写
}
Write_Ds1302_Byte(0x8e,0x80); //禁止向内存写入数据
}
}
void Scan_S7()
{
uchar n;
if(R1==0)
{
while(R1==0) display_ds1302();
TIME_buffer[0]=0;
Write_Ds1302_Byte(0x8e,0x00); //允许向内存写入数据
for(n=0;n<7;n++)
{
Write_Ds1302_Byte(WRITE_RTC_ADDR[n],TIME_buffer[n]); //低位先写
}
Write_Ds1302_Byte(0x8e,0x80); //禁止向内存写入数据
}
}
void alarm()
{
if(TIME_buffer[0]==0x00&&TIME_buffer[1]==0x00)
{
P2=0xA0;Relay=1;Buzz=0;
}
else if(count_a%3==0)
{
P2=0xA0;Relay=0;Buzz=0;
}
}
void main()
{
Init_Keys();
DS1302_Config();
timer0();
while(1)
{
temperature_get();
Scan_S7();
Scan_S6();
Scan_S5();
Scan_S4();
select_mode();
alarm();
}
}
写复杂了,大家主要看思路简化
|