1、温度显示不正常,请调试程序,使得程序能正常显示;
2、选中的要修改的时间项目时,显示特效过于简单,请修改相关程序使得显示调整项目时显示亮灭相间;
3、第三个按键的功能请补充,减少选中的调整项目;
4、根据资料,掌握对DS1302的操作方法。
5、根据资料,画出系统的仿真电路图,按要求编写程序,并实现仿真效果
对于第一次通过边画图,边敲代码,而且还用11个数码管显示还是有点挑战的。
下面是我的代码,还有待优化,毕竟定时器都没用上(实训完就期末还是要留点时间复习的)。
main.c
#include "sys.h"
#include "onewire.h"
#include "ds1302.h"
uchar clock[3] = {0,0,0};
void main()
{
uint i;
Write_ds1302();
while(1)
{
spk = 1;
Get_Temper();
Read_ds1302();
if(clock[2] == Time[2] && clock[1] == Time[1] && clock[0] == Time[0])
{
for(i = 0; i < 200; i++)
{
KeyScans();
DisplaySMG();
Delay1ms(1);
Read_ds1302();
spk = !spk;
}
}
KeyScans();
for(i = 0; i < 10; i++)
{
DisplaySMG();
}
}
}
sys.c
#include "sys.h"
#include "onewire.h"
#include "ds1302.h"
static unsigned char wx = 24;
uchar a = 2,b = 0;
void Delay1ms(uint x)
{
uint i,j;
for(i = 0; i < x; i++)
for(j = 0; j <123; j++);
}
void Display1(uchar pos,value)
{
static uchar temp1;
if(pos == wx) // 0 1 2 3 4 5 6 7
{
temp1++;
if(temp1 == 40)
temp1 = 0;
if(temp1 < 20) P1 = 15<<4|0x0f;
else P1 = value << 4|0x0f;
P2 = pos << 4| 0x0f;
Delay1ms(1);
P1 = 0xff;
}
else
{
P1 = value << 4|0x0f;
P2 = pos << 4| 0x0f;
Delay1ms(1);
P1 = 0xff;
}
}
void Display2(uchar pos,value)
{
static uchar temp2;
if(pos + 8 == wx) // 10 11 12 13 14 15
{
temp2++;
if(temp2 == 40)
temp2 = 0;
if(temp2 < 20) P1 = value | 0xf0;
else P1 = 15 | 0xf0;
P2 = pos << 4 | 0x0f;
Delay1ms(1);
P1 = 0xff;
}
else
{
P2 = pos << 4 | 0x0f;
P1 = value | 0xf0;
Delay1ms(1);
P1 = 0xff;
}
}
void Display3(uchar pos,value)
{
static uchar temp3;
if(pos + 16 == wx) // 18 19 20 21 22 23
{
temp3++;
if(temp3 == 40)
temp3 = 0;
if(temp3 < 20) P2 = pos<<4|15;
else P2 = pos << 4 | value;
Delay1ms(1);
P2 = pos << 4 | 0x0f;
}
else
{
P2 = pos << 4| value;
Delay1ms(1);
P2 = pos << 4| 0x0f;
}
}
void DisplaySMG()
{
Display1(0,a);
Display1(1,b);
Display1(2,Time[6] / 10);
Display1(3,Time[6] % 10);
Display1(4,Time[4] / 10);
Display1(5,Time[4] % 10);
Display1(6,Time[3] / 10);
Display1(7,Time[3] % 10);
Display3(2,Time[2] / 10);
Display3(3,Time[2] % 10);
Display3(4,Time[1] / 10);
Display3(5,Time[1] % 10);
Display3(6,Time[0] / 10);
Display3(7,Time[0] % 10);
Display2(2,clock[2] / 10); //ʱ
Display2(3,clock[2] % 10);
Display2(4,clock[1] / 10);
Display2(5,clock[1] % 10);
Display2(6,clock[0] / 10);
Display2(7,clock[0] % 10);
Display2(0,temp / 10);
Display2(1,temp % 10);
}
void KeyScans()
{
bit flag;
if(!k1&& !flag)
{
Delay1ms(10);
if(!k1)
{
flag = 1;
wx = (wx + 1) % 25;
if(wx == 8) wx = 10;
if(wx == 16) wx = 18;
}
else if(k1)
{
flag = 0;
}
}
if(!k2&& !flag)
{
Delay1ms(10);
if(!k2)
{
flag = 1;
switch(wx)
{
case 0: a += 1;if(a > 9) a = 1; break;
case 1: b += 1;if(b > 9) b = 0; break;
case 2: Time[6] = (Time[6]/10 + 1)*10 + Time[6]%10;if(Time[6]>99) Time[6] = 0; Write_ds1302();break;
case 3: Time[6] += 1;if(Time[6] > 99) Time[6] = 0; Write_ds1302(); break;
case 4: Time[4] = (Time[4] / 10 + 1) * 10 + Time[4] % 10;if(Time[4]> 12) Time[4] = 1; Write_ds1302();break;
case 5:Time[4] += 1;if(Time[4] > 12) Time[4] = 1;Write_ds1302();break;
case 6: Time[3] = (Time[3] / 10 + 1)*10 + Time[3]%10; if(Time[3] > 31) Time[3] = 1; Write_ds1302();break;
case 7: Time[3] += 1;if(Time[3] > 31) Time[3] = 1;Write_ds1302();break;
case 10: clock[2] = (clock[2] / 10 + 1)*10 + clock[2] % 10; if(clock[2]>23) clock[2] = 0; break;
case 11: clock[2] += 1;if(clock[2] > 23) clock[2] = 0;break;
case 12: clock[1] = (clock[1] / 10 + 1)*10 + clock[1] % 10; if(clock[1]>59) clock[1] = 0;break;
case 13: clock[1] += 1;if(clock[1]>59) clock[1] = 0;break;
case 14: clock[0] = (clock[0] / 10 + 1)*10 + clock[0] % 10;if(clock[0] > 59) clock[0] = 0;break;
case 15: clock[0] += 1; if(clock[0] > 59) clock[0] = 0;break;
case 18: Time[2] = (Time[2]/10 + 1) * 10 + Time[2] % 10; if(Time[2]>23) Time[2] = 0;Write_ds1302(); break;
case 19: Time[2] += 1;if(Time[2] > 23)Time[2] = 0;Write_ds1302();break;
case 20: Time[1] = (Time[1]/10 + 1) * 10 + Time[1] %10;if(Time[1]>59) Time[1] = 0;Write_ds1302();break;
case 21: Time[1] += 1;if(Time[1] > 59) Time[1] = 0;Write_ds1302();break;
case 22: Time[0] = (Time[0] / 10 + 1) * 10 + Time[0] %10; if(Time[0] > 59) Time[0] = 0; Write_ds1302();break;
case 23: Time[0] += 1; if(Time[0] > 59) Time[0] = 0;Write_ds1302();break;
}
}
else if(k2)
{
flag = 0;
}
}
if(!k3&& !flag)
{
Delay1ms(10);
if(!k3)
{
flag = 1;
switch(wx)
{
case 0:
a -= 1;
if(a < 1)
a = 1;
break;
case 1:
b -= 1;
if(b < 0)
b = 9;
break;
case 2:if((Time[6]) < 10) Time[6] = 109; Time[6] -= 10; Write_ds1302(); break;
case 3:if((Time[6]) < 0) Time[6] = 10; Time[6] -= 1; Write_ds1302(); break;
case 4:if((Time[4]) < 10) Time[4] = 22; Time[4] -= 10; Write_ds1302(); break;
case 5:if((Time[4]) < 0) Time[4] = 2; Time[4] -= 1; Write_ds1302(); break;
case 6:if((Time[3]) < 10) Time[3] = 41;Time[3] -= 10; Write_ds1302();break;
case 7:if(Time[3] < 0) Time[3] = 4;Time[3] -= 1; Write_ds1302(); break;
case 10:if(clock[2] < 10) clock[2] = 33;clock[2] -= 10; break;
case 11:if(clock[2] < 0) clock[2] = 24; clock[2] -= 1; break;
case 12:if(clock[1]< 10) clock[1] = 69; clock[1] -= 10; break;
case 13:if(clock[1] <0) clock[1] = 60;clock[1] -= 1;break;
case 14:if(clock[0] < 10) clock[0] = 69; clock[0] -= 10; break;
case 15: if(clock[0]< 0) clock[0] = 60; clock[0] -= 1; break;
case 18: if(Time[2] < 10) Time[2] = 33; Time[2] -= 10;Write_ds1302();break; //ʱ
case 19:if(Time[2] < 0) Time[2] = 24;Time[2] -= 1;Write_ds1302();break;
case 20: if(Time[1]< 10) Time[1] = 69; Time[1] -= 10;Write_ds1302();break;
case 21: if(Time[1] < 0) Time[1] = 60;Time[1] -= 1;Write_ds1302();break;
case 22: if(Time[0] < 10) Time[0] = 69;Time[0] -= 10;Write_ds1302();break;
case 23: if(Time[0]< 0) Time[0] = 60;Time[0] -= 1;Write_ds1302();break;
}
}
else if(k3)
{
flag = 0;
}
}
// if(k1 == 0)
// {
// Delay1ms(10);
// wx = (wx + 1) % 25;
// if(wx == 8) wx = 10;
// if(wx == 16) wx = 18;
// while(k1 == 0)
// {
// DisplaySMG();
// }
// }
// if(k2 == 0)
// {
// Delay1ms(10);
// switch(wx)
// {
// case 0: a += 1;if(a > 9) a = 1; break;
// case 1: b += 1;if(b > 9) b = 0; break;
// case 2: Time[6] = (Time[6]/10 + 1)*10 + Time[6]%10;if(Time[6]>99) Time[6] = 0; Write_ds1302();break;
// case 3: Time[6] += 1;if(Time[6] > 99) Time[6] = 0; Write_ds1302(); break;
// case 4: Time[4] = (Time[4] / 10 + 1) * 10 + Time[4] % 10;if(Time[4]> 12) Time[4] = 1; Write_ds1302();break;
// case 5:Time[4] += 1;if(Time[4] > 12) Time[4] = 1;Write_ds1302();break;
// case 6: Time[3] = (Time[3] / 10 + 1)*10 + Time[3]%10; if(Time[3] > 31) Time[3] = 1; Write_ds1302();break;
// case 7: Time[3] += 1;if(Time[3] > 31) Time[3] = 1;Write_ds1302();break;
//
// case 10: clock[2] = (clock[2] / 10 + 1)*10 + clock[2] % 10; if(clock[2]>23) clock[2] = 0; break;
// case 11: clock[2] += 1;if(clock[2] > 23) clock[2] = 0;break;
// case 12: clock[1] = (clock[1] / 10 + 1)*10 + clock[1] % 10; if(clock[1]>59) clock[1] = 0;break;
// case 13: clock[1] += 1;if(clock[1]>59) clock[1] = 0;break;
// case 14: clock[0] = (clock[0] / 10 + 1)*10 + clock[0] % 10;if(clock[0] > 59) clock[0] = 0;break;
// case 15: clock[0] += 1; if(clock[0] > 59) clock[0] = 0;break;
//
// case 18: Time[2] = (Time[2]/10 + 1) * 10 + Time[2] % 10; if(Time[2]>23) Time[2] = 0;Write_ds1302(); break;
// case 19: Time[2] += 1;if(Time[2] > 23)Time[2] = 0;Write_ds1302();break;
// case 20: Time[1] = (Time[1]/10 + 1) * 10 + Time[1] %10;if(Time[1]>59) Time[1] = 0;Write_ds1302();break;
// case 21: Time[1] += 1;if(Time[1] > 59) Time[1] = 0;Write_ds1302();break;
// case 22: Time[0] = (Time[0] / 10 + 1) * 10 + Time[0] %10; if(Time[0] > 59) Time[0] = 0; Write_ds1302();break;
// case 23: Time[0] += 1; if(Time[0] > 59) Time[0] = 0;Write_ds1302();break;
// }
// while(k2 == 0)
// {
// DisplaySMG();
// }
// }
// if(k3 == 0)
// {
// Delay1ms(10);
// switch(wx)
// {
// case 0:
// a -= 1;
// if(a < 1)
// a = 1;
// break;
// case 1:
// b -= 1;
// if(b < 0)
// b = 9;
// break;
// case 2:if((Time[6]) < 10) Time[6] = 109; Time[6] -= 10; Write_ds1302(); break;
// case 3:if((Time[6]) < 0) Time[6] = 10; Time[6] -= 1; Write_ds1302(); break;
// case 4:if((Time[4]) < 10) Time[4] = 22; Time[4] -= 10; Write_ds1302(); break;
// case 5:if((Time[4]) < 0) Time[4] = 2; Time[4] -= 1; Write_ds1302(); break;
// case 6:if((Time[3]) < 10) Time[3] = 41;Time[3] -= 10; Write_ds1302();break;
// case 7:if(Time[3] < 0) Time[3] = 4;Time[3] -= 1; Write_ds1302(); break;
//
// case 10:if(clock[2] < 10) clock[2] = 33;clock[2] -= 10; break;
// case 11:if(clock[2] < 0) clock[2] = 24; clock[2] -= 1; break;
// case 12:if(clock[1]< 10) clock[1] = 69; clock[1] -= 10; break;
// case 13:if(clock[1] <0) clock[1] = 60;clock[1] -= 1;break;
// case 14:if(clock[0] < 10) clock[0] = 69; clock[0] -= 10; break;
// case 15: if(clock[0]< 0) clock[0] = 60; clock[0] -= 1; break;
//
// case 18: if(Time[2] < 10) Time[2] = 33; Time[2] -= 10;Write_ds1302();break; //ʱ
// case 19:if(Time[2] < 0) Time[2] = 24;Time[2] -= 1;Write_ds1302();break;
// case 20: if(Time[1]< 10) Time[1] = 69; Time[1] -= 10;Write_ds1302();break;
// case 21: if(Time[1] < 0) Time[1] = 60;Time[1] -= 1;Write_ds1302();break;
// case 22: if(Time[0] < 10) Time[0] = 69;Time[0] -= 10;Write_ds1302();break;
// case 23: if(Time[0]< 0) Time[0] = 60;Time[0] -= 1;Write_ds1302();break;
// }
// while(k3 == 0)
// {
// DisplaySMG();
// }
// }
}
onewire.c
#include "onewire.h"
uint temp;
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
while(t--);
}
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
bit initflag = 0;
DQ = 1;
_nop_();
DQ = 0;
Delay_OneWire(75);
DQ = 1;
Delay_OneWire(4);
initflag = DQ;
Delay_OneWire(10);
DQ=1;
nop_();
return initflag;
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
nop_();
DQ = dat&0x01;
Delay_OneWire(4);
DQ = 1;
nop_();
dat >>= 1;
}
// Delay_OneWire(5);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
uchar i, j, dat;
for(i=0;i<8;i++)
{
DQ = 0;
_nop_();//产生读时序
DQ = 1;
_nop_();//释放总线
j = DQ;
Delay_OneWire(4);//76.95us
DQ = 1;
_nop_();
dat = (j<<7)|(dat>>1);
}
return (dat);
}
void Get_Temper()
{
uchar lsb,msb;
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(200);
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
lsb = Read_DS18B20();
msb = Read_DS18B20();
temp = (msb << 8) | lsb;
if((temp & 0xf8000) == 0x0000)
temp = temp >> 4;
}
ds1302.c
#include "ds1302.h"
uchar WriteReg[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
uchar Time[7] = {55,59,23,7,6,1,22};// 秒 分 时 日 月 星期 年
/*单字节写入一字节数据*/
void Write_Ds1302_Byte(unsigned char dat)
{
unsigned char i;
SCK = 0;
for (i=0;i<8;i++)
{
if (dat & 0x01) // 等价于if((addr & 0x01) ==1)
{
SDA_SET; //#define SDA_SET SDA=1 /*电平置高*/
}
else
{
SDA_CLR; //#define SDA_CLR SDA=0 /*电平置低*/
}
SCK_SET;
SCK_CLR;
dat = dat >> 1;
}
}
/********************************************************************/
/*单字节读出一字节数据*/
unsigned char Read_Ds1302_Byte(void)
{
unsigned char i, dat=0;
for (i=0;i<8;i++)
{
dat = dat >> 1;
if (SDA_R) //等价于if(SDA_R==1) #define SDA_R SDA /*电平读取*/
{
dat |= 0x80;
}
else
{
dat &= 0x7F;
}
SCK_SET;
SCK_CLR;
}
return dat;
}
/********************************************************************/
/*向DS1302 单字节写入一字节数据*/
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
{
unsigned char num;
RST_CLR; /*RST脚置低,实现DS1302的初始化*/
SCK_CLR; /*SCK脚置低,实现DS1302的初始化*/
RST_SET; /*启动DS1302总线,RST=1电平置高 */
addr = addr & 0xFE;
Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是写操作,写之前将最低位置零*/
num=(dat/10<<4)|(dat%10);
Write_Ds1302_Byte(num); /*写入数据:dat*/
RST_CLR; /*停止DS1302总线*/
SDA_CLR;
}
/********************************************************************/
/*从DS1302单字节读出一字节数据*/
unsigned char Ds1302_Single_Byte_Read(unsigned char addr)
{
unsigned char temp,dat1,dat2;
RST_CLR; /*RST脚置低,实现DS1302的初始化*/
SCK_CLR; /*SCK脚置低,实现DS1302的初始化*/
RST_SET; /*启动DS1302总线,RST=1电平置高 */
addr = addr | 0x01;
Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是读操作,写之前将最低位置高*/
temp=Read_Ds1302_Byte(); /*从DS1302中读出一个字节的数据*/
dat1=temp/16;
dat2=temp%16;
temp=dat1*10+dat2;
RST_CLR; /*停止DS1302总线*/
SDA_CLR;
return temp;
}
void Write_ds1302()
{
uchar i;
Ds1302_Single_Byte_Write(0x8e,0x00);
for(i = 0; i < 7; i++)
Ds1302_Single_Byte_Write(WriteReg[i],Time[i]);
Ds1302_Single_Byte_Write(0x8e,0x80);
}
void Read_ds1302()
{
uchar i;
for(i = 0; i < 7; i++)
Time[i] = Ds1302_Single_Byte_Read(WriteReg[i]);
}
sys.h
#ifndef _SYS_H_
#define _SYS_H_
#include <REGX51.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit k1=P0^1;
sbit k2=P0^2;
sbit k3=P0^3;
sbit spk=P0^6; //定时报警输出
extern unsigned char clock[3];
void Delay1ms(unsigned int x);
void Display1(unsigned char pos,value);
void Display2(unsigned char pos,value);
void Display3(unsigned char pos,value);
void DisplaySMG(void);
void KeyScans();
//void Alarm();
#endif
onewire.h
#ifndef _ONEWIRE_H_
#define _ONEWIRE_H_
#include <REGX51.H>
#include <intrins.h>
sbit DQ=P0^7;
#define uchar unsigned char
#define uint unsigned int
extern unsigned int temp;
void Delay_OneWire(unsigned int t);
bit Init_DS18B20(void);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
void Get_Temper();
#endif
ds1302.h
#ifndef _DS1302_H_
#define _DS1302_H_
#include <REGX51.H>
#include <intrins.h>
sbit RST=P3^2; //SPI的复位线
sbit SD=P3^3; //SPI的io线
sbit SCK=P3^4; //SPI的时钟线
/*复位脚*/
#define RST_CLR RST=0 /*电平置低*/
#define RST_SET RST=1 /*电平置高*/
/*双向数据*/
#define SDA_CLR SD=0 /*电平置低*/
#define SDA_SET SD=1 /*电平置高*/
#define SDA_R SD /*电平读取*/
/*时钟信号*/
#define SCK_CLR SCK=0 /*时钟信号*/
#define SCK_SET SCK=1 /*电平置高*/
#define uchar unsigned char
#define uint unsigned int
extern unsigned char Time[7];
void Write_Ds1302_Byte(unsigned char dat) ;
unsigned char Read_Ds1302_Byte(void) ;
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat);
unsigned char Ds1302_Single_Byte_Read(unsigned char addr) ;
void Write_ds1302(void);
void Read_ds1302(void);
#endif