- #include <reg52.h>
- #include <tm1638.h>
- #include <ds1302.h>
- void main(void)
- {
- unsigned char i;
- init_TM1638(); //初始化TM1638
- Ds1302Init();
- for(i=0;i<8;i++)
- Write_DATA(i<<1,tab[16]); //初始化寄存器
- while(1)
- {
- Ds1302ReadTime();
- i=Read_key(); //读按键值
-
- switch(i)
- {
- case 0:if(i==0)
- {
- temp=4567;
- while(Read_key()==i); //等待按键释放
- Write_allLED(1); //八只LED灯
- Display();
- Write_DATA(0*2,tab[1]);
- Write_DATA(1*2,tab[12]);
- } break;
- case 1:if(i==1)
- {
- while(Read_key()==i);
- Write_allLED(2);
- TimDisplay();
- } break;
- case 2:if(i==2)
- {
- while(Read_key()==i);
- Write_allLED(3);
- for(i=0;i<8;i++)
- Write_DATA(i<<1,tab[16]);
- } break;
- default:break;
- }
-
-
-
-
- }
- }
- ds1302.c
- #include"ds1302.h"
- //---DS1302写入和读取时分秒的地址命令---//
- //---秒分时日月周年 最低位读写位;-------//
- uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
- uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
- //---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---//
- //---存储顺序是秒分时日月周年,存储格式是用BCD码---//
- uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13};
- /*******************************************************************************
- * 函 数 名 : Ds1302Write
- * 函数功能 : 向DS1302命令(地址+数据)
- * 输 入 : addr,dat
- * 输 出 : 无
- *******************************************************************************/
- void Ds1302Write(uchar addr, uchar dat)
- {
- uchar n;
- RST = 0;
- _nop_();
- SCLK = 0;//先将SCLK置低电平。
- _nop_();
- RST = 1; //然后将RST(CE)置高电平。
- _nop_();
- for (n=0; n<8; n++)//开始传送八位地址命令
- {
- DSIO = addr & 0x01;//数据从低位开始传送
- addr >>= 1;
- SCLK = 1;//数据在上升沿时,DS1302读取数据
- _nop_();
- SCLK = 0;
- _nop_();
- }
- for (n=0; n<8; n++)//写入8位数据
- {
- DSIO = dat & 0x01;
- dat >>= 1;
- SCLK = 1;//数据在上升沿时,DS1302读取数据
- _nop_();
- SCLK = 0;
- _nop_();
- }
-
- RST = 0;//传送数据结束
- _nop_();
- }
- /*******************************************************************************
- * 函 数 名 : Ds1302Read
- * 函数功能 : 读取一个地址的数据
- * 输 入 : addr
- * 输 出 : dat
- *******************************************************************************/
- uchar Ds1302Read(uchar addr)
- {
- uchar n,dat,dat1;
- RST = 0;
- _nop_();
- SCLK = 0;//先将SCLK置低电平。
- _nop_();
- RST = 1;//然后将RST(CE)置高电平。
- _nop_();
- for(n=0; n<8; n++)//开始传送八位地址命令
- {
- DSIO = addr & 0x01;//数据从低位开始传送
- addr >>= 1;
- SCLK = 1;//数据在上升沿时,DS1302读取数据
- _nop_();
- SCLK = 0;//DS1302下降沿时,放置数据
- _nop_();
- }
- _nop_();
- for(n=0; n<8; n++)//读取8位数据
- {
- dat1 = DSIO;//从最低位开始接收
- dat = (dat>>1) | (dat1<<7);
- SCLK = 1;
- _nop_();
- SCLK = 0;//DS1302下降沿时,放置数据
- _nop_();
- }
- RST = 0;
- _nop_(); //以下为DS1302复位的稳定时间,必须的。
- SCLK = 1;
- _nop_();
- DSIO = 0;
- _nop_();
- DSIO = 1;
- _nop_();
- return dat;
- }
- /*******************************************************************************
- * 函 数 名 : Ds1302Init
- * 函数功能 : 初始化DS1302.
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Ds1302Init()
- {
- uchar n;
- Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能
- for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
- {
- Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
- }
- Ds1302Write(0x8E,0x80); //打开写保护功能
- }
- /*******************************************************************************
- * 函 数 名 : Ds1302ReadTime
- * 函数功能 : 读取时钟信息
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Ds1302ReadTime()
- {
- uchar n;
- for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
- {
- TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
- }
-
- }
- ds1302.h
- #ifndef __DS1302_H_
- #define __DS1302_H_
- //---包含头文件---//
- #include<reg52.h>
- #include<intrins.h>
- //---重定义关键词---//
- #ifndef uchar
- #define uchar unsigned char
- #endif
- #ifndef uint
- #define uint unsigned int
- #endif
- //---定义ds1302使用的IO口---//
- sbit DSIO=P3^4;
- sbit RST=P3^5;
- sbit SCLK=P3^6;
- //---定义全局函数---//
- void Ds1302Write(uchar addr, uchar dat);
- uchar Ds1302Read(uchar addr);
- void Ds1302Init();
- void Ds1302ReadTime();
- //---加入全局变量--//
- extern uchar TIME[7]; //加入全局变量
- #endif
- tm1638.h
- #ifndef _TM1638_H
- #define _TM1638_H
- #include <reg52.h>
- #include <ds1302.h>
- #define DATA_COMMAND 0X40
- #define DISP_COMMAND 0x80
- #define ADDR_COMMAND 0XC0
- //TM1638模块引脚定义
- sbit DIO=P2^0;
- sbit CLK=P2^1;
- sbit STB=P2^2;
- unsigned char num[8]; //各个数码管显示的值
- unsigned int temp;
- //共阴数码管显示代码
- unsigned char code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
- 0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00,0x40};
- 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; //4个字节数据合成一个字节
- 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 Display()
- {
-
- num[0] = temp % 10000 / 1000;
- num[1] = temp % 1000 / 100;
- num[2] = temp % 100 / 10;
- num[3] = temp % 10;
- Write_DATA(4*2,tab[num[0]]);
- Write_DATA(5*2,tab[num[1]]|0x80);
- Write_DATA(6*2,tab[num[2]]);
- Write_DATA(7*2,tab[num[3]]);
- }
- void TimDisplay()
- {
- Write_DATA( 0*2,tab[num[TIME[0]/16]]);
- Write_DATA( 1*2,tab[num[TIME[0]%16]]);
- Write_DATA( 2*2,tab[17]);
- Write_DATA( 3*2,tab[num[TIME[1]/16]]);
- Write_DATA( 4*2,tab[num[TIME[1]%16]]);
- Write_DATA( 5*2,tab[17]);
- Write_DATA( 6*2,tab[num[TIME[2]/16]]);
- Write_DATA( 7*2,tab[num[TIME[2]%16]]);
- /*LcdWriteData('0'+TIME[2]/16); //时
- LcdWriteData('0'+(TIME[2]&0x0f));
- LcdWriteData('-');
- LcdWriteData('0'+TIME[1]/16); //分
- LcdWriteData('0'+(TIME[1]&0x0f));
- LcdWriteData('-');
- LcdWriteData('0'+TIME[0]/16); //秒
- LcdWriteData('0'+(TIME[0]&0x0f));
- LcdWriteCom(0x80);
- LcdWriteData('2');
- LcdWriteData('0');
- LcdWriteData('0'+TIME[6]/16); //年
- LcdWriteData('0'+(TIME[6]&0x0f));
- LcdWriteData('-');
- LcdWriteData('0'+TIME[4]/16); //月
- LcdWriteData('0'+(TIME[4]&0x0f));
- LcdWriteData('-');
- LcdWriteData('0'+TIME[3]/16); //日
- LcdWriteData('0'+(TIME[3]&0x0f));
- LcdWriteCom(0x8D);
- LcdWriteData('0'+(TIME[5]&0x07)); //星期 */
- }
- /*
- void Write_oneLED(unsigned char num,unsigned char flag) //单独控制一个LED函数,num为需要控制的led序号,flag为0时熄灭,不为0时点亮
- {
- if(flag)
- Write_DATA(2*num+1,1);
- else
- Write_DATA(2*num+1,0);
- } */
- void Write_allLED(unsigned char LED_flag) //控制全部LED函数,LED_flag表示各个LED状态
- {
- unsigned char i;
- for(i=0;i<8;i++)
- {
- if(LED_flag&(1<<i))
- //Write_DATA(2*i+1,3);
- Write_DATA(2*i+1,1);
- else
- Write_DATA(2*i+1,0);
- }
- }
- //TM1638初始化函数
- void init_TM1638(void)
- {
- unsigned char i;
- Write_COM(0x8b); //亮度 (0x88-0x8f)8级亮度可调
- Write_COM(0x40); //采用地址自动加1
- STB=0; //
- TM1638_Write(0xc0); //设置起始地址
- for(i=0;i<16;i++) //传送16个字节的数据
- TM1638_Write(0x00);
- STB=1;
- }
- #endif
复制代码 |