题目
电子钟总结:
问题:
间隔亮灭:
遇到的问题:数码管不是真的1秒间隔亮灭,只是微微的抖动。
主要原因:读题不仔细条件没全部看清,思路没理清楚就开始写代码了,注意细节不到位!!!
边界数据(时间):
加的话就是基本没问题,减的时候注意它的数据越界问题,unsigned char 是0-255;减为小于0的时候越界了;
因此我们可以先判断在进行减法操作
代码实现如下:
if(time_mode==1) { if(time[2]==0)time[2]=23; else time[2]--; Set_Time(time); } else if(time_mode==2) { if(time[1]==0)time[1]=59; else time[1]--; Set_Time(time); } else if(time_mode==3) { if(time[0]==0)time[0]=59; else time[0]--; Set_Time(time); }
闹钟条件:
遇到的问题是上电后秒一直显示0,注意:可能是在判断闹钟条件时把 “==” 写成了 “=”如下所示这种
最垃圾的错误,我做到了!!!!
if((time[0]=arm_time[0])&&(time[1]=arm_time[1])&&(time[2]=arm_time[2])) { LED_flag=1; }
正确写法:
if((time[0]==arm_time[0])&&(time[1]==arm_time[1])&&(time[2]==arm_time[2])) { LED_flag=1; }
实现小灯功能代码:
关闭小灯只需要每个按键让LED_flag等于0就可以了
if(LED_flag) { led_5000ms++; if(led_5000ms!=5000) { if(led_flash_flag) { LED|=1; }else{ LED&=~1; } }else{ led_5000ms=0; LED&=~1; LED_flag=0; } }else{ LED&=~1; }
DAC
一定要按公式带!!!基本没问题,误差一定会在官方要求内
代码:
#include <stc15f2k60s2.h>
#include <iic.h>
#include <onewire.h>
#include <ds1302.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={ //标准字库
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};
uchar code wei[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
uchar temp[]={16,16,16,16,16,16,16,16};
uchar trg,cont;
uint temper;
char s=23,f=59,m=50;
char alarm_s=0,alarm_f=0,alarm_m=0;
uchar display_mode,set_mode,led;
bit key_flag;
bit temper_flag; //温度标志位
bit da_flag; //电压输出标志位
bit time_flag; //读时间标志位
bit light_flag; //数码管闪烁标志
bit time_stop; //时间暂停标志
bit temper_show; //温度显示标志
bit alarm_flag; //闹钟标志位
void init(){
P2=0xa0;P0=0;P2=0x00;
P2=0x80;P0=0XFF;P2=0x00;
}
void read_key(){
unsigned char readData=P3^0xff;
trg=readData&(readData^cont);
cont=readData;
}
void led_set(){
P2=0x80;P0=~led;P2=0x00;
if(s==alarm_s&&f==alarm_f&&m==alarm_m){ //判断达到闹钟时间
alarm_flag=1;
}
}
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x20; //设置定时初值
TH0 = 0xD1; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
void time0() interrupt 1{
static int key_count=0,seg_count=0,temper_count=0,da_count=0,time_count=0,light_count=0,led_count=0;
if(key_count%2){
P2=0xe0;P0=0;P2=0x00;
P2=0xc0;P0=wei[seg_count];P2=0x00;
P2=0xe0;P0=~table[temp[seg_count++]];P2=0x00;
if(seg_count==8) seg_count=0;
}
if(++key_count>=10){
key_flag=1;
key_count=0;
}
if(++temper_count>=100){ //温度读取间隔100ms
temper_flag=1;
temper_count=0;
}
if(++da_count>=200){ //电压输出间隔200ms
da_count=0;
da_flag=1;
}
if(++time_count>=200){ //时钟读取间隔200ms
time_count=0;
time_flag=1;
}
if(set_mode!=0){
if(++light_count>=1000){ //数码管1s闪烁
light_count=0;
light_flag=~light_flag;
}
}
if(alarm_flag){ //闹钟时间
light_count++;
if(light_count==200) led|=1; //0.2s闪烁L1
if(light_count==400){
led&=~1;
light_count=0;
}
if(++led_count==5000){ //闪烁5s后关闭
led&=~1;
alarm_flag=0;
led_count=0;
}
}
}
void get_time(){ //读取时间
static int flag=1;
if(flag){
flag=0;
write_time(s,f,m);
}
if(time_flag&&!time_stop){ //在非暂停状态下才读取时间
time_flag=0;
s=read_time(0x85);
f=read_time(0x83);
m=read_time(0x81);
}
}
void table_set(){
if(temper_show){ //显示温度状态
temp[7]=16;temp[6]=16;temp[5]=16;temp[4]=16;temp[3]=16;
temp[2]=temper/10;temp[1]=temper%10;temp[0]=12;
}
else{ //非温度显示状态
if(display_mode==0){ //显示当前时间
temp[0]=m%10;temp[1]=m/10;temp[2]=17;
temp[3]=f%10;temp[4]=f/10;temp[5]=17;
temp[6]=s%10;temp[7]=s/10;
}
else if(display_mode==1){ //设置当前时间
if(set_mode==1){
if(light_flag){
temp[0]=m%10;temp[1]=m/10;temp[2]=17;
temp[3]=f%10;temp[4]=f/10;temp[5]=17;
temp[6]=16;temp[7]=16;
}
else{
temp[0]=m%10;temp[1]=m/10;temp[2]=17;
temp[3]=f%10;temp[4]=f/10;temp[5]=17;
temp[6]=s%10;temp[7]=s/10;
}
}
else if(set_mode==2){
if(light_flag){
temp[0]=m%10;temp[1]=m/10;temp[2]=17;
temp[3]=16;temp[4]=16;temp[5]=17;
temp[6]=s%10;temp[7]=s/10;
}
else{
temp[0]=m%10;temp[1]=m/10;temp[2]=17;
temp[3]=f%10;temp[4]=f/10;temp[5]=17;
temp[6]=s%10;temp[7]=s/10;
}
}
else if(set_mode==3){
if(light_flag){
temp[0]=16;temp[1]=16;temp[2]=17;
temp[3]=f%10;temp[4]=f/10;temp[5]=17;
temp[6]=s%10;temp[7]=s/10;
}
else{
temp[0]=m%10;temp[1]=m/10;temp[2]=17;
temp[3]=f%10;temp[4]=f/10;temp[5]=17;
temp[6]=s%10;temp[7]=s/10;
}
}
}
else if(display_mode==2){ //设置当前闹钟
if(set_mode==1){
if(light_flag){
temp[0]=alarm_m%10;temp[1]=alarm_m/10;temp[2]=17;
temp[3]=alarm_f%10;temp[4]=alarm_f/10;temp[5]=17;
temp[6]=16;temp[7]=16;
}
else{
temp[0]=alarm_m%10;temp[1]=alarm_m/10;temp[2]=17;
temp[3]=alarm_f%10;temp[4]=alarm_f/10;temp[5]=17;
temp[6]=alarm_s%10;temp[7]=alarm_s/10;
}
}
else if(set_mode==2){
if(light_flag){
temp[0]=alarm_m%10;temp[1]=alarm_m/10;temp[2]=17;
temp[3]=16;temp[4]=16;temp[5]=17;
temp[6]=alarm_s%10;temp[7]=alarm_s/10;
}
else{
temp[0]=alarm_m%10;temp[1]=alarm_m/10;temp[2]=17;
temp[3]=alarm_f%10;temp[4]=alarm_f/10;temp[5]=17;
temp[6]=alarm_s%10;temp[7]=alarm_s/10;
}
}
else if(set_mode==3){
if(light_flag){
temp[0]=16;temp[1]=16;temp[2]=17;
temp[3]=alarm_f%10;temp[4]=alarm_f/10;temp[5]=17;
temp[6]=alarm_s%10;temp[7]=alarm_s/10;
}
else{
temp[0]=alarm_m%10;temp[1]=alarm_m/10;temp[2]=17;
temp[3]=alarm_f%10;temp[4]=alarm_f/10;temp[5]=17;
temp[6]=alarm_s%10;temp[7]=alarm_s/10;
}
}
}
}
}
void key_function(){
if(cont&0x08){ //在时钟显示状态下按住S4后显示温度
if(display_mode==0) //判断时钟显示状态
temper_show=1;
}
else temper_show=0;
if(trg&0x01){ //S7设置当前时间
alarm_flag=0; //关闭L1闪烁
led&=~1;
if(display_mode==0){
time_stop=1;
display_mode=1;
}
if(display_mode==1){
set_mode++;
if(set_mode==4){
set_mode=0;
display_mode=0;
write_time(s,f,m);
time_stop=0;
}
}
}
else if(trg&0x02){ //S6设置闹钟
alarm_flag=0; //关闭L1闪烁
led&=~1;
if(display_mode==0){
display_mode=2;
}
if(display_mode==2){
set_mode++;
if(set_mode==4){
set_mode=0;
display_mode=0;
}
}
}
else if(trg&0x04){ //S5按下时间++
alarm_flag=0;
led&=~1;
if(display_mode==1){
if(set_mode==1){
s++;
if(s>23) s=0;
}
else if(set_mode==2){
f++;
if(f>59) f=0;
}
else if(set_mode==3){
m++;
if(m>59) m=0;
}
}
else if(display_mode==2){
if(set_mode==1){
alarm_s++;
if(alarm_s>23) alarm_s=0;
}
else if(set_mode==2){
alarm_f++;
if(alarm_f>59) alarm_f=0;
}
else if(set_mode==3){
alarm_m++;
if(alarm_m>59) alarm_m=0;
}
}
}
else if(trg&0x08){ //S4按下时间--
alarm_flag=0;
led&=~1;
if(display_mode==1){
if(set_mode==1){
s--;
if(s<0) s=23;
}
else if(set_mode==2){
f--;
if(f<0) f=59;
}
else if(set_mode==3){
m--;
if(m<0) m=59;
}
}
else if(display_mode==2){
if(set_mode==1){
alarm_s--;
if(alarm_s<0) alarm_s=23;
}
else if(set_mode==2){
alarm_f--;
if(alarm_f<0) alarm_f=59;
}
else if(set_mode==3){
alarm_m--;
if(alarm_m<0) alarm_m=59;
}
}
}
}
void main(){
init();
Timer0Init();
while(85==rd_temper()/100); //等待默认85结束
write_time(s,f,m); //初始设置时间
while(1){
if(key_flag){
read_key();
key_function();
key_flag=0;
}
if(temper_flag){
temper_flag=0;
temper=rd_temper()/100;
}
if(da_flag){
da_out(255.0/5.0*(m/12+1)); //电压输出
da_flag=0;
}
table_set();
get_time();
led_set();
}
}