【冉冰的成长日记002】
没鸽,but,出问题了,我觉得程序所有出问题的地方逻辑上都是正确的,可惜就是不对,问题已用数字标出,如果有大哥闲来无事,麻烦帮弟弟解决一下吧QAQ万分感谢
另外,真的累啊,比上一篇累多了,代码也写得很繁杂,不够精简
看文章吧,不多废话
```c
#include
#include"ds1302.h"
#include"onewire.h"
unsigned char LED[] =
{
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF ,0xFF ,0xC6
}; //数码管真值表
unsigned char LEDbuff[] =
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
}; //数码管缓冲区
extern unsigned char Time_Get[7];//ds的外部数据存放
unsigned char flag=0,S7_flag=0,S6_flag=0;//falg用来判断时钟模式还是闹钟模式和温度
unsigned char clock_shi=0,clock_fen=0,clock_miao=0;//闹钟模式的初值
unsigned char T;//温度的获取
unsigned cnt=0,num=0;//中断计时
bit check_S7=0,check_S6=0,check_S5=0,check_S4=0;//check用来按键消抖。
sbit S4=P3^3; //按键定义
sbit S5=P3^2;
sbit S6=P3^1;
sbit S7=P3^0;
void Timer0Init(); //定时器0,1ms
void Initial(); //模块初始化
void KEY(); //按键模块,包括S7.S6.S5.S4
void DisPlay(); //数码管模块,两个模式,每个模式四个状态
void DisPlay_Temp();//温度显示(存在问题)
void main()
{
Timer0Init();
DS1302_Init();
Initial();
while(1)
{
KEY();
DisPlay();
if(cnt>=1000) //每一秒获取一次温度
{
DS18B20_Start();
T=DS18B20_Get();
cnt=0;
}
DS1302_Get();
}
}
void delay(unsigned int x) //延时函数,ms单位
{
if(num>=x)
{
num=0;
}
}
void Initial() //初始化函数
{
P2 = (P2&0x1F)|0x80;
P0 = 0xFF; //初始化LED
P2 = (P2&0x1F)|0xA0;
P0 = 0x00; //初始化继电器和蜂鸣器
P2 = (P2&0x1F)|0xC0;
P0 = 0xFF;
P2 = (P2&0x1F)|0xE0;
P0 = 0xFF; //初始化数码管
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA = 1;
ET0 = 1;
}
void KEY_S7()
{
if(S7==0)
{
delay(10);
if(S7==0)
check_S7=1;
}
if((S7==1)&&(check_S7==1))
{
flag=0; //时钟模式
check_S7=0;
S7_flag++; //时钟模式的四个状态切换
if(S7_flag>=4)
S7_flag=0;
}
}
void KEY_S6()
{
if(S6==0)
{
delay(10);
if(S6==0)
check_S6=1;
}
if((S6==1)&&(check_S6==1))
{
flag=1; //闹钟模式
check_S6=0;
S6_flag++; //闹钟模式的四个状态切换
if(S6_flag>=4)
S6_flag=0;
}
}
void KEY_S5()
{
if(S5==0)
{
delay(10);
if(S5==0)
check_S5=1;
}
if((S5==1)&&(check_S5==1))
{
check_S5=0;
if(flag==0)
{
if(S7_flag==1)
1. //这个数组地方加一不知道哪出了问题,感觉逻辑上没问题呀,有大哥麻烦解答一下
{
Time_Get[2]=Time_Get[2]+1;if(Time_Get[2]>23) Time_Get[2]=0;}
if(S7_flag==2)
{
Time_Get[1]=Time_Get[1]+1;if(Time_Get[1]) Time_Get[1]=0;}
if(S7_flag==3)
{
Time_Get[0]=Time_Get[0]+1;if(Time_Get[0]) Time_Get[0]=0;}
}
if(flag==1) //闹钟模式正常
{
if(S6_flag==1)
{
clock_shi++;if(clock_shi>23) clock_shi=0;}
if(S6_flag==2)
{
clock_fen++;if(clock_fen>59) clock_fen=0;}
if(S6_flag==3)
{
clock_miao++;if(clock_miao>59) clock_miao=0;}
}
}
}
void KEY_S4()
{
if(S4==0)
{
delay(10);
if(S4==0)
{
check_S4=1;
1. //这里没写按下显示温度,可以用while(S4==0)判断实现按下显示温度,弹起返回,但是在com6数码选中上keil显示Target not created ,不知道是什么情况
}
}
if((S4==1)&&(check_S4==1))
{
check_S4=0;
if(flag==0)
{
if(S7_flag==1) //时钟模式问题同上
{
Time_Get[2]--;if(Time_Get[2]<0) Time_Get[2]=23;}
if(S7_flag==2)
{
Time_Get[1]--;if(Time_Get[1]<0) Time_Get[1]=59;}
if(S7_flag==3)
{
Time_Get[0]--;if(Time_Get[0]<0) Time_Get[0]=59;}
}
if(flag==1)
{
if(S6_flag==1)
{
clock_shi--;if(clock_shi<0) clock_shi=23;}
if(S6_flag==2)
{
clock_fen--;if(clock_fen<0) clock_fen=59;}
if(S6_flag==3)
{
clock_miao--;if(clock_miao<0) clock_miao=59;}
}
}
}
void KEY()
{
KEY_S7();
KEY_S6();
KEY_S5();
KEY_S4();
}
void DisPlay_S7()
{
if(S7_flag==0)
{
LEDbuff[0] = LED[Time_Get[0]%10];
LEDbuff[1] = LED[Time_Get[0]/10];
LEDbuff[2] = LED[10];
LEDbuff[3] = LED[Time_Get[1]%10];
LEDbuff[4] = LED[Time_Get[1]/10];
LEDbuff[5] = LED[10];
LEDbuff[6] = LED[Time_Get[2]%10];
LEDbuff[7] = LED[Time_Get[2]/10];
}
if(S7_flag==1)
{
LEDbuff[0] = LED[Time_Get[0]%10];
LEDbuff[1] = LED[Time_Get[0]/10];
LEDbuff[2] = LED[10];
LEDbuff[3] = LED[Time_Get[1]%10];
LEDbuff[4] = LED[Time_Get[1]/10];
LEDbuff[5] = LED[10];
if(Time_Get[0]%2==0) //对秒进行取余,偶数显示,奇数熄灭,达到每一秒闪烁的效果,看b站学的,感觉up好聪明
{
LEDbuff[6] = LED[Time_Get[2]%10];
LEDbuff[7] = LED[Time_Get[2]/10];
}
else
{
LEDbuff[6] = LED[11];
LEDbuff[7] = LED[11];
}
}
if(S7_flag==2)
{
LEDbuff[0] = LED[Time_Get[0]%10];
LEDbuff[1] = LED[Time_Get[0]/10];
LEDbuff[2] = LED[10];
LEDbuff[5] = LED[10];
LEDbuff[6] = LED[Time_Get[2]%10];
LEDbuff[7] = LED[Time_Get[2]/10];
if(Time_Get[0]%2==0)
{
LEDbuff[3] = LED[Time_Get[1]%10];
LEDbuff[4] = LED[Time_Get[1]/10];
}
else
{
LEDbuff[3] = LED[11];
LEDbuff[4] = LED[11];
}
}
if(S7_flag==3)
{
LEDbuff[2] = LED[10];
LEDbuff[3] = LED[Time_Get[1]%10];
LEDbuff[4] = LED[Time_Get[1]/10];
LEDbuff[5] = LED[10];
LEDbuff[6] = LED[Time_Get[2]%10];
LEDbuff[7] = LED[Time_Get[2]/10];
if(Time_Get[0]%2==0)
{
LEDbuff[0] = LED[Time_Get[0]%10];
LEDbuff[1] = LED[Time_Get[0]/10];
}
else
{
LEDbuff[0] = LED[11];
LEDbuff[1] = LED[11];
}
}
}
void DisPlay_S6()
{
if(S6_flag==0)
{
LEDbuff[0] = LED[Time_Get[0]%10];
LEDbuff[1] = LED[Time_Get[0]/10];
LEDbuff[2] = LED[10];
LEDbuff[3] = LED[Time_Get[1]%10];
LEDbuff[4] = LED[Time_Get[1]/10];
LEDbuff[5] = LED[10];
LEDbuff[6] = LED[Time_Get[2]%10];
LEDbuff[7] = LED[Time_Get[2]/10];
}
if(S6_flag==1)
{
LEDbuff[0] = LED[clock_miao%10];
LEDbuff[1] = LED[clock_miao/10];
LEDbuff[2] = LED[10];
LEDbuff[3] = LED[clock_fen%10];
LEDbuff[4] = LED[clock_fen/10];
LEDbuff[5] = LED[10];
if(Time_Get[0]%2==0)
{
LEDbuff[6] = LED[clock_shi%10];
LEDbuff[7] = LED[clock_shi/10];
}
else
{
LEDbuff[6] = LED[11];
LEDbuff[7] = LED[11];
}
}
if(S6_flag==2)
{
LEDbuff[0] = LED[clock_miao%10];
LEDbuff[1] = LED[clock_miao/10];
LEDbuff[2] = LED[10];
LEDbuff[5] = LED[10];
LEDbuff[6] = LED[clock_shi%10];
LEDbuff[7] = LED[clock_shi/10];
if(Time_Get[0]%2==0)
{
LEDbuff[3] = LED[clock_fen%10];
LEDbuff[4] = LED[clock_fen/10];
}
else
{
LEDbuff[3] = LED[11];
LEDbuff[4] = LED[11];
}
}
if(S6_flag==3)
{
LEDbuff[2] = LED[10];
LEDbuff[3] = LED[clock_fen%10];
LEDbuff[4] = LED[clock_fen/10];
LEDbuff[5] = LED[10];
LEDbuff[6] = LED[clock_shi%10];
LEDbuff[7] = LED[clock_shi/10];
if(Time_Get[0]%2==0)
{
LEDbuff[0] = LED[clock_miao%10];
LEDbuff[1] = LED[clock_miao/10];
}
else
{
LEDbuff[0] = LED[11];
LEDbuff[1] = LED[11];
}
}
}
void DisPlay()
{
if(flag==0)
DisPlay_S7();
if(flag==1)
DisPlay_S6();
}
void Flash()
{
static unsigned char i;
if((Time_Get[0]==clock_miao)&&(Time_Get[1]==clock_fen)&&(Time_Get[2]==clock_shi))
1. //这个地方,闹钟模式和时钟模式时,分,秒相同时闪烁,在我板子上也出现问题不知道为啥,我依旧觉得程序逻辑没问题QAQ求助
{
P2=0x80;
for(i=0;i<11;i++)
{
P2 = (P2&0x1F)|0x80;
P0 = 0xFE;
delay(200);
P2 = (P2&0x1F)|0x80;
P0 = 0xFF;
delay(200);
}
P2 = (P2&0x1F)|0x80;
P0 = 0xFE;
delay(200);
P2 = (P2&0x1F)|0x80;
P0 = 0xFF;
}
}
void InterruptTimer0() interrupt 1
{
static unsigned char i=0;
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
switch(i)
{
case 0:P2 = 0xC0;P0=0x80;P2=0xE0;P0=LEDbuff[0];i++;break;
case 1:P2 = 0xC0;P0=0x40;P2=0xE0;P0=LEDbuff[1];i++;break;
case 2:P2 = 0xC0;P0=0x20;P2=0xE0;P0=LEDbuff[2];i++;break;
case 3:P2 = 0xC0;P0=0x10;P2=0xE0;P0=LEDbuff[3];i++;break;
case 4:P2 = 0xC0;P0=0x08;P2=0xE0;P0=LEDbuff[4];i++;break;
case 5:P2 = 0xC0;P0=0x04;P2=0xE0;P0=LEDbuff[5];i++;break;
case 6:P2 = 0xC0;P0=0x02;P2=0xE0;P0=LEDbuff[6];i++;break;
case 7:P2 = 0xC0;P0=0x01;P2=0xE0;P0=LEDbuff[7];i=0;break;
default : break;
}
num++;
cnt++;
Flash(); //闹钟模式闪烁
}
main函数,这次写的这么长就突出了拆分成多个c文件的重要性,我写的好乱emmm
/*
程序说明: DS1302驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include
#include"ds1302.h"
#include
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
unsigned char Time_Init[7]={
50, 59, 23, 1, 1, 1, 1};
unsigned char Time_Get[7];
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
SDA=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302((dat/10<<4)|(dat%10));
RST=0;
}
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char dat1,dat2;
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
dat1=temp/16;
dat2=temp%16;
temp=dat1*10+dat2;
return (temp);
}
void DS1302_Init()
{
unsigned char add=0x80,i=0;
Write_Ds1302_Byte(0x8E,0);
for(i=0;i<7;i++)
{
Write_Ds1302_Byte(add,Time_Init[i]);
add = add +2;
}
Write_Ds1302_Byte(0x8E,0x80);
}
void DS1302_Get()
{
unsigned char add=0x81,i=0;
Write_Ds1302_Byte(0x8E,0x80);
for(i=0;i<7;i++)
{
Time_Get[i] = Read_Ds1302_Byte(add);
add = add +2;
}
Write_Ds1302_Byte(0x8E,0x80);
}
以上是ds1302.c的文件
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
日 期: 2011-8-9
*/
#include
#include"onewire.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
t=10*t;
while(t--);
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
void DS18B20_Start()
{
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0x44);
Delay_OneWire(200);
}
unsigned char DS18B20_Get()
{
char temp=0;
unsigned char high=0,low=0;
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE);
low=Read_DS18B20();
high=Read_DS18B20();
temp = high<<4;
temp = temp|(low>>4);
return temp;
}
以上是DS18B20.c的文件
#ifndef __DS1302_H
#define __DS1302_H
void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
void DS1302_Init();
void DS1302_Get();
#endif
ds1302.h的文件
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
unsigned char rd_temperature(void); //; ;
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
void DS18B20_Start();
unsigned char DS18B20_Get();
#endif
ds18b20.h的文件
这次的题真的是让我写的又臭又长,真的拉跨,这水平基本告别比赛了,散会散会,咕咕咕~~
感谢大佬观看,烦请请指正错误,
QAQ希望我还有良心,趁着这两天把这写问题解决一下吧