- #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
復制代碼 |