51单片机+TM1638+DS3232驱动数码管按键切换显示时间和日期
- Proteus仿真
AT89C52 、8位共阴数码管、DS3232 、
实例代码
#include <reg51.h>
#include <intrins.h>
#include "tm1638.h"
#define uchar unsigned char
#define uint unsigned int
sbit SDA = P3 ^ 6;
sbit SCL = P3 ^ 7;
sbit INT = P3 ^ 2;
sbit RESET = P3 ^ 3;
sbit led0 = P1 ^ 0;
sbit led1 = P1 ^ 1;
sbit led2 = P1 ^ 2;
sbit led3 = P1 ^ 3;
sbit led4 = P1 ^ 4;
sbit led5 = P1 ^ 5;
sbit led6 = P1 ^ 6;
sbit led7 = P1 ^ 7;
bit ack;
#define DS3231_WriteAddress 0xD0
#define DS3231_ReadAddress 0xD1
#define DS3231_SECOND 0x00
#define DS3231_MINUTE 0x01
#define DS3231_HOUR 0x02
#define DS3231_WEEK 0x03
#define DS3231_DAY 0x04
#define DS3231_MONTH 0x05
#define DS3231_YEAR 0x06
#define DS3231_SALARM1ECOND 0x07
#define DS3231_ALARM1MINUTE 0x08
#define DS3231_ALARM1HOUR 0x09
#define DS3231_ALARM1WEEK 0x0A
#define DS3231_ALARM2MINUTE 0x0b
#define DS3231_ALARM2HOUR 0x0c
#define DS3231_ALARM2WEEK 0x0d
#define DS3231_CONTROL 0x0e
#define DS3231_STATUS 0x0f
#define BSY 2
#define OSF 7
#define DS3231_XTAL 0x10
#define DS3231_TEMPERATUREH 0x11
#define DS3231_TEMPERATUREL 0x12
uchar code dis_code[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
uchar data dis_buf[8];
uchar data dis_index;
uchar data dis_digit;
uchar BCD2HEX(uchar val)
{
return (val >> 4) * 10 + (val & 0x0F);
}
uchar HEX2BCD(uchar val)
{
return ((val / 10) << 4) | (val % 10);
}
void delayus(uint us)
{
while (us--)
;
}
void Start_I2C()
{
SDA = 1;
delayus(1);
SCL = 1;
delayus(5);
SDA = 0;
delayus(5);
SCL = 0;
delayus(2);
}
void Stop_I2C()
{
SDA = 0;
delayus(1);
SCL = 1;
delayus(5);
SDA = 1;
delayus(4);
}
void SendByte(uchar c)
{
uchar BitCnt;
for (BitCnt = 0; BitCnt < 8; BitCnt++)
{
if ((c << BitCnt) & 0x80)
SDA = 1;
else
SDA = 0;
delayus(1);
SCL = 1;
delayus(5);
SCL = 0;
}
delayus(2);
SDA = 1;
delayus(2);
SCL = 1;
delayus(3);
if (SDA == 1)
ack = 0;
else
ack = 1;
SCL = 0;
delayus(2);
}
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc = 0;
SDA = 1;
for (BitCnt = 0; BitCnt < 8; BitCnt++)
{
delayus(1);
SCL = 0;
delayus(5);
SCL = 1;
delayus(3);
retc = retc << 1;
if (SDA == 1)
retc = retc + 1;
delayus(2);
}
SCL = 0;
delayus(2);
return (retc);
}
void Ack_I2C(bit a)
{
if (a == 0)
SDA = 0;
else
SDA = 1;
delayus(3);
SCL = 1;
delayus(5);
SCL = 0;
delayus(2);
}
uchar write_byte(uchar addr, uchar write_data)
{
Start_I2C();
SendByte(DS3231_WriteAddress);
if (ack == 0)
return 0;
SendByte(addr);
if (ack == 0)
return 0;
SendByte(write_data);
if (ack == 0)
return 0;
Stop_I2C();
delayus(10);
return 1;
}
uchar read_current()
{
uchar read_data;
Start_I2C();
SendByte(DS3231_ReadAddress);
if (ack == 0)
return (0);
read_data = RcvByte();
Ack_I2C(1);
Stop_I2C();
return read_data;
}
uchar read_random(uchar random_addr)
{
Start_I2C();
SendByte(DS3231_WriteAddress);
if (ack == 0)
return (0);
SendByte(random_addr);
if (ack == 0)
return (0);
return (read_current());
}
void ModifyTime(uchar yea, uchar mon, uchar da, uchar hou, uchar min, uchar sec)
{
uchar temp = 0;
temp = HEX2BCD(yea);
write_byte(DS3231_YEAR, temp);
temp = HEX2BCD(mon);
write_byte(DS3231_MONTH, temp);
temp = HEX2BCD(da);
write_byte(DS3231_DAY, temp);
temp = HEX2BCD(hou);
write_byte(DS3231_HOUR, temp);
temp = HEX2BCD(min);
write_byte(DS3231_MINUTE, temp);
temp = HEX2BCD(sec);
write_byte(DS3231_SECOND, temp);
}
void TimeDisplay(uchar Dhour, uchar Dmin, uchar Dsec)
{
dis_buf[7] = dis_code[Dhour / 10];
dis_buf[6] = dis_code[Dhour % 10];
dis_buf[4] = dis_code[Dmin / 10];
dis_buf[3] = dis_code[Dmin % 10];
dis_buf[1] = dis_code[Dsec / 10];
dis_buf[0] = dis_code[Dsec % 10];
dis_buf[2] = 0x40;
dis_buf[5] = 0x40;
}
void DateDisplay(uchar Dyear, uchar Dmonth, uchar Dday)
{
dis_buf[7] = dis_code[Dyear / 10];
dis_buf[6] = dis_code[Dyear % 10];
dis_buf[4] = dis_code[Dmonth / 10];
dis_buf[3] = dis_code[Dmonth % 10];
dis_buf[1] = dis_code[Dday / 10];
dis_buf[0] = dis_code[Dday % 10];
dis_buf[2] = 0x40;
dis_buf[5] = 0x40;
}
void get_show_time(void)
{
uchar Htemp1, Htemp2, Mtemp1, Mtemp2, Stemp1, Stemp2;
Htemp1 = read_random(DS3231_HOUR);
Htemp1 &= 0x3f;
Htemp2 = BCD2HEX(Htemp1);
Mtemp1 = read_random(DS3231_MINUTE);
Mtemp2 = BCD2HEX(Mtemp1);
Stemp1 = read_random(DS3231_SECOND);
Stemp2 = BCD2HEX(Stemp1);
TimeDisplay(Htemp2, Mtemp2, Stemp2);
}
void get_show_date(void)
{
uchar Ytemp1, Ytemp2, Mtemp1, Mtemp2, Dtemp1, Dtemp2;
Ytemp1 = read_random(DS3231_YEAR);
Ytemp2 = BCD2HEX(Ytemp1);
Mtemp1 = read_random(DS3231_MONTH);
Mtemp2 = BCD2HEX(Mtemp1);
Dtemp1 = read_random(DS3231_DAY);
Dtemp2 = BCD2HEX(Dtemp1);
DateDisplay(Ytemp2, Mtemp2, Dtemp2);
}
void get_show_Temperature(void)
{
uchar Ttemp1, Ttemp2, Ttemp3, Ttemp4;
Ttemp1 = read_random(DS3231_TEMPERATUREH);
Ttemp2 = BCD2HEX(Ttemp1);
Ttemp3 = read_random(DS3231_TEMPERATUREL);
Ttemp4 = BCD2HEX(Ttemp3);
dis_buf[7] = 0;
dis_buf[6] = 0;
dis_buf[3] = dis_code[Ttemp2 / 10];
dis_buf[2] = dis_code[Ttemp2 % 10] | 0x80;
dis_buf[1] = dis_code[Ttemp4 / 10];
dis_buf[0] = dis_code[Ttemp4 % 10];
dis_buf[5] = 0;
dis_buf[4] = 0;
}
void main()
{
int i;
int status;
RESET = 0x1;
delayus(5000);
led0 = 0;
led1 = 0;
led2 = 0;
led3 = 0;
led4 = 0;
P0 = 0xff;
P2 = 0xff;
dis_digit = 0xfe;
dis_index = 0;
DateDisplay(21,9,8);
if (write_byte(DS3231_CONTROL, 0x1C) == 0)
led0 = 1;
if (write_byte(DS3231_STATUS, 0x00) == 0)
led1 = 1;
ModifyTime(21,9,8,8,29,00);
init_TM1638();
for (i = 0; i < 8; i++)
Write_DATA(i << 1, tab[i]);
status = 0;
while (1)
{
i = Read_key();
if (i < 3)
{
while (Read_key() == i)
;
status = i;
}
switch (status)
{
case 0:
get_show_time();
break;
case 1:
get_show_date();
break;
case 2:
get_show_Temperature();
break;
}
for (i = 0; i < 8; i++)
{
Write_DATA(i << 1, dis_buf[7 - i]);
}
delayus(10000);
}
}
#ifndef _TM1638_H
#define _TM1638_H
#include <REGX51.H>
#define DATA_COMMAND 0X40
#define DISP_COMMAND 0x80
#define ADDR_COMMAND 0XC0
sbit DIO=P2^0;
sbit CLK=P2^1;
sbit STB=P2^2;
unsigned char code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
void TM1638_Write(unsigned char DATA)
{
unsigned char i;
for(i=0;i<8;i++)
{
CLK=0;
if(DATA&0X01)
DIO=1;
else
DIO=0;
DATA>>=1;
CLK=1;
}
}
unsigned char TM1638_Read(void)
{
unsigned char i;
unsigned char temp=0;
DIO=1;
for(i=0;i<8;i++)
{
temp>>=1;
CLK=0;
if(DIO)
temp|=0x80;
CLK=1;
}
return temp;
}
void Write_COM(unsigned char cmd)
{
STB=0;
TM1638_Write(cmd);
STB=1;
}
unsigned char Read_key(void)
{
unsigned char c[4],i,key_value=0;
STB=0;
TM1638_Write(0x42);
for(i=0;i<4;i++)
c[i]=TM1638_Read();
STB=1;
for(i=0;i<4;i++)
key_value|=c[i]<<i;
for(i=0;i<8;i++)
if((0x01<<i)==key_value)
break;
return i;
}
void Write_DATA(unsigned char add,unsigned char DATA)
{
Write_COM(0x44);
STB=0;
TM1638_Write(0xc0|add);
TM1638_Write(DATA);
STB=1;
}
void Write_allLED(unsigned char LED_flag)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(LED_flag&(1<<i))
Write_DATA(2*i+1,1);
else
Write_DATA(2*i+1,0);
}
}
void init_TM1638(void)
{
unsigned char i;
Write_COM(0x8b);
Write_COM(0x40);
STB=0;
TM1638_Write(0xc0);
for(i=0;i<16;i++)
TM1638_Write(0x00);
STB=1;
}
#endif
- intrins.h这个头文件只需包含进去就可以了,在keil库当中,我就不贴代码了,
源程序和资料
baidu链接:https:
提取码:ttlk
|