久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

基于單片機、DS1302、DS1602的電子時鐘,可以設置時間日期

作者:佚名   來源:不詳   點擊數:  更新時間:2014年08月17日   【字體:

 

 
 
 這是DS1602+DS1302完整程序,其中P1口接獨立鍵盤。
 
DS1602部分:
 
# include "SYSTEM.H"             
 
//#ifndef __LCD1602_8_H__
//#define __LCD1602_8_H__
 
 
 
//LCD接口定義     
sfr   io = 0x80;    //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0;
sbit  rs = P2^6;    //LCD數據/命令選擇端(H/L)
sbit  rw = P2^5;    //LCD讀/寫選擇端(H/L)
sbit  ep = P2^7;    //LCD使能控制
sbit     bz = io^7;    //LCD忙標志位
 
 
//函數聲明  
void lcd_busy(void);     //測試LCD忙碌狀態程序
void lcd_wcmd(unsigned char cmd);  //寫入指令到LCD程序
void lcd_wdat(unsigned char dat);  //寫入數據到LCD程序
void lcd_pos (unsigned char x, bit y); //LCD數據指針位置程序
void lcd_sef_chr();
//void printc(unsigned char CHAR);  //顯示字符
 
void lcd_init(void);     //LCD初始化設定程序
 
 
//測試LCD忙碌狀態
void lcd_busy(void)
 do{
  ep = 0;
  rs = 0;  //指令
  rw = 1;  //讀出
  io = 0xff;
  ep = 1;
  _nop_(); //高電平讀出 1us 
 }while(bz);  //bz=1表示忙,bz=0表示空閑
 ep = 0;  
}
 
 
//寫入指令到LCD
void lcd_wcmd(unsigned char cmd)
{       
 lcd_busy(); //檢測忙
 rs = 0;  //指令
 rw = 0;  //寫入
 ep = 1; 
 io = cmd; //指令
 ep = 0;  //下降沿有效 
}
 
 
//寫入數據函數
void lcd_wdat(unsigned char Data)
{
 lcd_busy();  //檢測忙
 rs = 1;   //數據
 rw = 0;   //寫入
 ep = 1;
 io = Data;  //數據
 ep = 0;   //下降沿有效
}
 
 
//LCD數據指針位置程序
void lcd_pos(unsigned char x, bit y)
{      
 if(y)lcd_wcmd(x|0xc0); //y=1,第二行顯示;y=0,第一行顯示  0<=x<16
 else lcd_wcmd(x|0x80); //數據指針=80+地址碼(00H~27H,40H~67H)
  
}
 
 
//顯示字符
//
void printc(unsigned char CHAR)
{
 lcd_wdat(CHAR);
}
//
 
 
//顯示字符串
void prints(unsigned char //string)
{
 //unsigned char i;
 //do{lcd_wdat(string[i]);i++;}while(string[i]!='\0');//生成代碼比for循環大
 for(i=0;string[i]!='\0';i++)lcd_wdat(string[i]);  //有時用for循環也好哈//
 
 while(//string) {lcd_wdat(//string);string++;}
 
}
 
 
 
 
//LCD初始化設定
void lcd_init()
{      
 lcd_wcmd(0x38);  //設置LCD為16X2顯示,5X7點陣,八位數據接口
 lcd_wcmd(0x06);  //LCD顯示光標移動設置(光標地址指針加1,整屏顯示不移動)
 lcd_wcmd(0x0c);  //LCD開顯示及光標設置(光標不閃爍,不顯示"_")
 lcd_wcmd(0x01);  //清除LCD的顯示內容
 
}
 
 
DS1302部分:
 
# include "SYSTEM.H"
 
 
//#ifndef __DS1302_A_H__
//#define __DS1302_A_H__
 
 
 
//引腳及位的定義
sbit DS1302_CLK = P3^6;   //時鐘引腳
sbit DS1302_IO  = P3^4;   //數據引腳
sbit DS1302_RST = P3^5;   //復位引腳
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
 
 
//函數聲明
void DS1302_InputByte(unchar Data);           //寫入一個字節(內部函數)
unchar DS1302_OutputByte(void);               //讀取一個字節(內部函數)
void Write1302(unchar Address, unchar Data);  //在指定地址寫入指定的數據
unchar Read1302(unchar Address);              //讀取DS1302指定地址中的數據
void DS1302_SetProtect(bit Flag);             //DS1302是否寫入保護
void DS1302_SetTime(unchar Address, unchar Value);//設置時間函數
void DS1302_GetTime(SYSTEMTIME *Time);        //讀出時間
void DateToStr(SYSTEMTIME *Time);             //日期轉化成字符
void TimeToStr(SYSTEMTIME *Time);             //時間轉化成字符
void DS1302_Initial (void);                   //DS1302初始化
 
//寫入一個字節(內部函數)
void DS1302_InputByte(unchar Data) 
{
 unchar i;
 ACC = Data;
 for(i=8; i>0; i--)
 { 
  DS1302_CLK = 0;  
  DS1302_IO = ACC0; //由低位到高位  
  DS1302_CLK = 1;  //上升沿寫入數據
  ACC >>= 1;
 }
}
 
 
 
//讀取一個字節(內部函數)
unchar DS1302_OutputByte(void)
{
 unchar i;
 for(i=8; i>0; i--)
 {   
  DS1302_CLK = 0;      //下降沿讀出DS1302的數據
  ACC >>= 1;    //讀出由低到高位,只能移7次有效位!!!
  ACC7 = DS1302_IO;  //第一個數據           
  DS1302_CLK = 1;         
 }      
 return (ACC);
}
 
 
//在指定地址寫入指定的數據
void Write1302(unchar Address, unchar Data)
{
 DS1302_RST = 0;
 DS1302_CLK = 0;
 DS1302_RST = 1;
 DS1302_InputByte(Address);
 DS1302_InputByte(Data);
 DS1302_CLK = 1;
 DS1302_RST = 0;
}
 
 
//讀取1302指定地址中的數據
unchar Read1302(unchar Address)
{
 unchar Data;
 DS1302_RST = 0;
 DS1302_CLK = 0;
 DS1302_RST = 1;       //RST拉高,啟動數據傳送
 DS1302_InputByte(Address|0x01);//讀取指定地址數據指令
 Data = DS1302_OutputByte();
 DS1302_CLK = 1;
 DS1302_RST = 0;
 return (Data);
}
 
//是否寫入保護
void DS1302_SetProtect(bit Flag)
{
 if(Flag)
  Write1302(0x8E,0x80);  //0x8e控制字節地址,bit7=WP WP=1 禁止數據寫入DS1302
 else
  Write1302(0x8E,0x00);  //WP=0 允許數據寫入DS1302
}
 
 
//設置時間函數
void DS1302_SetTime(unchar Address, unchar Value)
{
 DS1302_SetProtect(0);
 Write1302(Address,((Value/10)<<4|(Value)));
 DS1302_SetProtect(1);
 
}
 
 
//讀出時間
void DS1302_GetTime(SYSTEMTIME *Time)
{
 unchar ReadValue;
 ReadValue = Read1302(DS1302_SECOND);
 Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_MINUTE);
 Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_HOUR);
 Time->Hour   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_DAY);
 Time->Day    = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_WEEK);
 Time->Week   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_MONTH);
 Time->Month  = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_YEAR);
 Time->Year   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
}
 
 
//日期轉化成字符
void DateToStr(SYSTEMTIME *Time)
{
 Time->DateString[0] = Time->Year/10 + '0';
 Time->DateString[1] = Time->Year + '0';
 Time->DateString[2] = '-';
 Time->DateString[3] = Time->Month/10 + '0';
 Time->DateString[4] = Time->Month + '0';
 Time->DateString[5] = '-';
 Time->DateString[6] = Time->Day/10 + '0';
 Time->DateString[7] = Time->Day + '0';
 Time->DateString[8] = '\0';
}
 
 
//時間轉化成字符
void TimeToStr(SYSTEMTIME *Time)
{
 Time->TimeString[0] = Time->Hour/10 + '0';
 Time->TimeString[1] = Time->Hour + '0';
 Time->TimeString[2] = ':';
 Time->TimeString[3] = Time->Minute/10 + '0';
 Time->TimeString[4] = Time->Minute + '0';
 Time->TimeString[5] = ':';
 Time->TimeString[6] = Time->Second/10 + '0';
 Time->TimeString[7] = Time->Second + '0';
 Time->TimeString[8] = '\0';
}
 
 
//初始化DS1302
void DS1302_Initial (void)
{
 unchar Second=Read1302(DS1302_SECOND);
 if(Second&0x80)//bit7=CH CH=0 振蕩器允許工作,CH=1振蕩器停止工作
 DS1302_SetTime(DS1302_SECOND,0);
 
}
 
函數聲明SYSTEM.H:
 
 
//包含頭文件
#include<REG52.H>
#include <intrins.h>
//#include"LCD1602_8.H"
//#include"DS1302_A.H"
 
//P0 Bit Registers
 
sbit P0_0 = 0x80;
sbit P0_1 = 0x81;
sbit P0_2 = 0x82;
sbit P0_3 = 0x83;
sbit P0_4 = 0x84;
sbit P0_5 = 0x85;
sbit P0_6 = 0x86;
sbit P0_7 = 0x87;
 
 
//P1 Bit Registers
 
sbit P1_0 = 0x90;
sbit P1_1 = 0x91;
sbit P1_2 = 0x92;
sbit P1_3 = 0x93;
sbit P1_4 = 0x94;
sbit P1_5 = 0x95;
sbit P1_6 = 0x96;
sbit P1_7 = 0x97;
 
//P2 Bit Registers
sbit P2_0 = 0xA0;
sbit P2_1 = 0xA1;
sbit P2_2 = 0xA2;
sbit P2_3 = 0xA3;
sbit P2_4 = 0xA4;
sbit P2_5 = 0xA5;
sbit P2_6 = 0xA6;
sbit P2_7 = 0xA7;
 
 
//P3 Bit Registers (Mnemonics & Ports)
sbit P3_0 = 0xB0;
sbit P3_1 = 0xB1;
sbit P3_2 = 0xB2;
sbit P3_3 = 0xB3;
sbit P3_4 = 0xB4;
sbit P3_5 = 0xB5;
sbit P3_6 = 0xB6;
sbit P3_7 = 0xB7;
 
 
//宏定義便于理解
#define unchar unsigned char
#define unint  unsigned int
#define DS1302_SECOND      0x80
#define DS1302_MINUTE      0x82
#define DS1302_HOUR        0x84
#define DS1302_WEEK        0x8A
#define DS1302_DAY         0x86
#define DS1302_MONTH       0x88
#define DS1302_YEAR        0x8C
#define DS1302_RAM(X)      (0xC0+(X)*2) 
//用于計算RAM地址的宏運算
 
//定義時間類型
typedef struct _SYSTEMTIME_
{
 unchar Second;
 unchar Minute;
 unchar Hour;
 unchar Week;
 unchar Day;
 unchar Month;
 unchar Year;
 unchar DateString[9];
 unchar TimeString[9];
}SYSTEMTIME;   
 
 
 
//LCD1602外部引用函數
extern void lcd_init(void);  //LCD初始化設定程序
extern void prints(unsigned char *string); //顯示字符串
extern void lcd_pos (unsigned char x, bit y); //LCD數據指針位置程序
extern void lcd_sef_chr() ;
extern void lcd_wcmd(unsigned char cmd);//寫入指令到LCD程序
 
 
//*DS1302外部引用函數
extern void DS1302_SetTime(unchar Address, unchar Value);  //設置時間函數
extern void DS1302_Initial (void);                         //DS1302初始化
extern void DS1302_GetTime(SYSTEMTIME *Time);              //讀出時間
extern void DateToStr(SYSTEMTIME *Time);                   //日期轉化成字符
extern void TimeToStr(SYSTEMTIME *Time);                   //時間轉化成字符
 
 
 
 
MAIN函數部分:
 
#include "SYSTEM.H"
SYSTEMTIME CurrentTime;
 
unsigned char k = 0; //鍵值
unsigned char K1,K2,K3,M1,M2,M3,K1J,K2J,K3J,K4J; //鍵值
unsigned char Set; //調整值
char Set_Mode = 0;
 
void Keysan(void);
void delay200ms(void);
//主函數
void main(void)
 lcd_init();
 //lcd_sef_chr(); //寫入自定義字符號
 DS1302_Initial();
 
  lcd_pos(0,0);
  prints("Date:");
  lcd_pos(0,1);
     prints("Time:");
 k = 6;  //不改變時間 
    while(1)
 {
   Keysan();
     DS1302_GetTime(&CurrentTime);
  DateToStr(&CurrentTime);
  TimeToStr(&CurrentTime);  
  lcd_pos(6,0);
  prints(CurrentTime.DateString);
  lcd_pos(6,1);
  prints(CurrentTime.TimeString);
 
  //lcd_pos(7,0);
     //lcd_wcmd(0x0E);
 
  delay200ms();
  
 }
}
 
//鍵盤掃描
void Keysan(void)
{
 
    if(~P1_2&K1J)   { k++;  }
   K1J=~(~P1_2);
 
    if(~P1_3&K2J)    { Set++; }
    K2J=~(~P1_3);
 
 if(~P1_4&K3J)    { Set--; }
   K3J=~(~P1_4);
 
    if(k == 7) {k = 0; }
 
 switch(k)
 {
   case 0: DS1302_SetTime(DS1302_SECOND, Set&0x3f); break;
   case 1: DS1302_SetTime(DS1302_MINUTE, Set&0x3f); break;
   case 2: DS1302_SetTime(DS1302_HOUR  , Set&0x1f); break;
   case 3: DS1302_SetTime(DS1302_DAY   , Set&0x0f); break;
   case 4: DS1302_SetTime(DS1302_MONTH , Set&0x0f); break;
   case 5: DS1302_SetTime(DS1302_YEAR  , Set&0x7f); break;
   default: break;
 }
}
//延時200000+0us 函數定義
void delay200ms(void)
{
   unsigned char i,j,k;
   for(i=201;i>0;i--)
   for(j=32;j>0;j--)
   for(k=14;k>0;k--);
}
 
 
 
 
關閉窗口
主站蜘蛛池模板: 国产高清在线精品 | 国产精品久久久久久久久久久免费看 | 91久久北条麻妃一区二区三区 | 欧美性网 | 日本久久精品 | 欧产日产国产精品99 | 亚洲一区播放 | 麻豆亚洲| 99精品视频一区二区三区 | 黄免费观看 | 成人欧美一区二区三区黑人孕妇 | 亚洲在线 | 在线观看免费高清av | 亚洲成人av在线播放 | 欧美激情在线精品一区二区三区 | 精品久久久久久久久久久久久久 | 91av视频在线 | 欧美综合一区二区 | 日韩精品无码一区二区三区 | 羞羞视频在线观免费观看 | 亚洲成人av | 国产美女一区二区三区 | 欧美国产精品 | 亚洲www.| 91久久久久久 | 国产1区 | 精品视频在线观看 | 国产一区精品 | 美国a级毛片免费视频 | 成人黄色在线观看 | 日韩欧美一区在线 | 精品免费国产视频 | 国产区精品在线观看 | 国产在线一区二区三区 | 麻豆av在线免费观看 | 日本高清精品 | 欧美极品在线播放 | 欧美精品在线免费观看 | 日韩在线不卡视频 | 国产精品亚洲一区二区三区在线 | 国产一区二区视频免费在线观看 |