用字節讀取模式可以正常讀取,burst模式能寫,但是讀出來是亂碼。
一下是代碼,哪位學長有空幫忙看下。
- /*********************************************************************
- VyoMeng 51單片機實習訓練
-
- **********************************************************************
- 程序名稱:DS1302 Burst模式讀寫
- 程序版本:V1.0
- 作 者: VyoMeng
- 編寫時間:2021年09月11日
- 硬件支持:
- 接口說明:
- 修改日志:
- N0.1:
- **********************************************************************/
- /*
- **********************************************************************
- * 頭文件包含/SFR定義
- **********************************************************************
- */
- #include<reg52.h>
- /*
- **********************************************************************
- * 本地數據類型/宏定義
- **********************************************************************
- */
- typedef signed char int8; //8位有符號字符型
- typedef signed int int16; //16位有符號整型
- typedef signed long int32; //32位有符號長整型
- typedef unsigned char uint8; //8位無符號字符型
- typedef unsigned int uint16; //16位無符號整型
- typedef unsigned long uint32; //32位無符號長整型
- /*
- **********************************************************************
- * 單片機IO口位定義
- **********************************************************************
- */
- sbit DS1302_CE = P2^3; //定義DS1302芯片CE引腳 使能引腳
- sbit DS1302_IO = P2^4; //定義DS1302芯片IO引腳 數據讀寫引腳
- sbit DS1302_SCLK = P2^5; //定義DS1302芯片SCLK引腳 鎖存引腳
- sbit DX = P2^1; //定義數碼管顯示內容
- sbit WX = P2^2; //定義數碼管顯示位置
- /*
- **********************************************************************
- * 本地全局變量/數組定義
- **********************************************************************
- */
- uint8 code zifu[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x7f,0xbf,0xc8}; //數碼管所有顯示情況加入數組
- uint8 Time_Set[7] = {0x00,0x01,0x02,0x03,0x04,0x05,0x21}; //設置初始時間 2021年9月8日23點59分50秒周3
- uint8 tm[8]; //定義數組放讀取出的時間數據
- /*
- **********************************************************************
- * 函數原型聲明
- **********************************************************************
- */
- void DS1302Init();
- void delay(uint16 x_ms); //延遲 x_ms*1 毫秒
- void xiaoying();
- void DS1302ByteWrite(uint8 dat);
- uint8 DS1302ByteRead();
- void DS1302TimeWrite();
- void DS1302TimeRead(uint8 *time);
- /*********************************************************************
- *函數名稱:main
- *函數功能:主函數
- *函數調用:
- *參數列表:無
- *返 回 值:無
- *結 果:
- *備 注:
- *********************************************************************/
- void main()
- {
- DS1302Init(); //初始化DS1302芯片
-
- while(1)
- {
- DS1302TimeRead(tm);
- //////////////////// 數碼管第1位
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=0X01; //顯示位置在數碼管 第1位
- WX=1; //給高電平
- WX=0; //給低電平 電平下衍 將顯示位置寫入數碼管位置顯示鎖存器
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=zifu[tm[3] >> 4]; //寫入數字
- DX=1; //給高電平
- DX=0; //給低電平 電平下衍 將顯示內容寫入數碼管內容顯示鎖存器
- xiaoying(); //數碼管消影
-
- //////////////////// 數碼管第2位
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=0X02; //顯示位置在數碼管 第2位
- WX=1; //給高電平
- WX=0; //給低電平 電平下衍 將顯示位置寫入數碼管位置顯示鎖存器
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=zifu[tm[3] & 0x0F]; //寫入數字
- DX=1; //給高電平
- DX=0; //給低電平 電平下衍 將顯示內容寫入數碼管內容顯示鎖存器
- xiaoying(); //數碼管消影
-
- //////////////////// 數碼管第3位
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=0X04; //顯示位置在數碼管 第3位
- WX=1; //給高電平
- WX=0; //給低電平 電平下衍 將顯示位置寫入數碼管位置顯示鎖存器
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=zifu[tm[4] >> 4]; //寫入數字
- DX=1; //給高電平
- DX=0; //給低電平 電平下衍 將顯示內容寫入數碼管內容顯示鎖存器
- xiaoying(); //數碼管消影
-
- //////////////////// 數碼管第4位
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=0X08; //顯示位置在數碼管 第4位
- WX=1; //給高電平
- WX=0; //給低電平 電平下衍 將顯示位置寫入數碼管位置顯示鎖存器
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=zifu[tm[4] & 0x0F]; //寫入數字
- DX=1; //給高電平
- DX=0; //給低電平 電平下衍 將顯示內容寫入數碼管內容顯示鎖存器
- xiaoying(); //數碼管消影
- //////////////////// 數碼管第5位
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=0X10; //顯示位置在數碼管 第5位
- WX=1; //給高電平
- WX=0; //給低電平 電平下衍 將顯示位置寫入數碼管位置顯示鎖存器
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=zifu[tm[5] >> 4]; //寫入數字
- DX=1; //給高電平
- DX=0; //給低電平 電平下衍 將顯示內容寫入數碼管內容顯示鎖存器
- xiaoying(); //數碼管消影
-
- //////////////////// 數碼管第6位
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=0X20; //顯示位置在數碼管 第6位
- WX=1; //給高電平
- WX=0; //給低電平 電平下衍 將顯示位置寫入數碼管位置顯示鎖存器
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=zifu[tm[5] & 0x0F]; //寫入數字
- DX=1; //給高電平
- DX=0; //給低電平 電平下衍 將顯示內容寫入數碼管內容顯示鎖存器
- xiaoying(); //數碼管消影
-
- //////////////////// 數碼管第7位
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=0X40; //顯示位置在數碼管 第7位
- WX=1; //給高電平
- WX=0; //給低電平 電平下衍 將顯示位置寫入數碼管位置顯示鎖存器
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=zifu[tm[6] >> 4]; //寫入數字
- DX=1; //給高電平
- DX=0; //給低電平 電平下衍 將顯示內容寫入數碼管內容顯示鎖存器
- xiaoying(); //數碼管消影
-
- //////////////////// 數碼管第8位
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=0X80; //顯示位置在數碼管 第8位
- WX=1; //給高電平
- WX=0; //給低電平 電平下衍 將顯示位置寫入數碼管位置顯示鎖存器
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=zifu[tm[6] & 0x0F]; //寫入數字
- DX=1; //給高電平
- DX=0; //給低電平 電平下衍 將顯示內容寫入數碼管內容顯示鎖存器
- xiaoying(); //數碼管消影
- }
- }
- /*********************************************************************
- *函數名稱:DS1302Init
- *函數功能:初始化DS1302芯片
- *函數調用:DS1302Init();
- *參數列表:
- *返 回 值:無
- *結 果:
- *備 注:初始化DS1302
- *********************************************************************/
- void DS1302Init()
- {
- uint8 state;
- DS1302TimeRead(tm); //讀取時間數據
- state = tm[0]; //讀取秒位
- state = state >> 7; //數據右移7位,將CH值移到右邊最低位
-
- if (state == 0x01) //如果CH值=1,說明時鐘停止了,需要進行初始化
- {
- DS1302_CE = 1; //打開DS1302使能引腳
- DS1302ByteWrite(0x8E); //操作寫保護位
- DS1302ByteWrite(0x00); //關閉寫保護
- DS1302_CE = 0; //關閉DS1302使能引腳
-
- DS1302TimeWrite(); //寫入初始時間
-
- DS1302_CE = 1; //打開DS1302使能引腳
- DS1302ByteWrite(0x8E); //操作寫保護位
- DS1302ByteWrite(0x80); //打開寫保護
- DS1302_CE = 0; //關閉DS1302使能引腳
-
- }
- }
- /*********************************************************************
- *函數名稱:DS1302ByteWrite
- *函數功能:寫入一個字節數據
- *函數調用:DS1302ByteWrite(uint8 dat);
- *參數列表:dat
- *返 回 值:無
- *結 果:
- *備 注:dat為時間日期的數據
- *********************************************************************/
- void DS1302ByteWrite(uint8 dat)
- {
- uint8 i;
- // DS1302_SCLK = 0; //拉低鎖存器電平準備寫入數據
- for(i=0;i<8;i++) //循環8次寫入8組數據
- {
- DS1302_IO = dat & 0x01; //DS1302寫入數據是從最低位開始寫,所以先取最低為數值
- dat = dat >> 1; //取完最低位后將dat右移1位,將原來第2位數移到最低位
- DS1302_SCLK = 1; //拉高鎖存器電平產生上升沿,寫入數據
- DS1302_SCLK = 0; //拉高鎖存器電平產生上升沿,寫入數據
- }
- DS1302_IO =1;
- }
- /*********************************************************************
- *函數名稱:DS1302ByteRead
- *函數功能:讀取一個字節數據
- *函數調用:DS1302ByteRead();
- *參數列表:無
- *返 回 值:dat
- *結 果:返回讀取到的時間數據
- *備 注:
- *********************************************************************/
- uint8 DS1302ByteRead()
- {
- uint8 i;
- uint8 dat=0; //先給dat賦值 0X00 即 0000 0000
- // DS1302_SCLK=0; //拉低鎖存器電平準備寫入數據
- for(i=0;i<8;i++) //循環8次讀取8組數據
- {
- if (DS1302_IO == 0) //判斷IO口數據是否為0
- {
- dat = dat << 1; //如果IO口為0,dat左移1位,左移最低位默認補0
- }
- else
- {
- dat = dat << 1; //如果IO口不為0,dat左移1位,最低位先補個0
- dat = dat | 0x01; //最低位或上0x01,最低位變成1
- }
- DS1302_SCLK = 1; //拉高鎖存器電平產生上升沿,讀入數據
- DS1302_SCLK = 0; //拉高鎖存器電平產生上升沿,讀入數據
- }
- return dat; //返回讀取到的時間數據數組
- }
- /*********************************************************************
- *函數名稱:DS1302TimeWrite
- *函數功能:讀取一個字節數據
- *函數調用:DS1302TimeWrite();
- *參數列表:
- *返 回 值:無
- *結 果:
- *備 注:
- *********************************************************************/
- void DS1302TimeWrite()
- {
- uint8 i;
- DS1302_CE = 1; //打開DS1302使能引腳
- DS1302ByteWrite(0xBE); //開啟burst寫入模式,0XBE為burst寫入地址
- for(i=0;i<7;i++) //循環7次,將 [年月日時分秒周] 七個字節寫入
- {
- DS1302ByteWrite(Time_Set[i]); //從Time_Set數組里提取數值寫入
- }
- DS1302ByteWrite(0x00); //burst模式一次要讀寫8個字節,實際日期總共7個字節,所以最后補充一個無意義的0x00字節
- DS1302_CE = 0; //關閉DS1302使能引腳
- }
- /*********************************************************************
- *函數名稱:DS1302TimeRead
- *函數功能:讀取一個字節數據
- *函數調用:DS1302TimeRead(uint8 *time);
- *參數列表:time
- *返 回 值:無
- *結 果:
- *備 注:
- *********************************************************************/
- void DS1302TimeRead(uint8 *time)
- {
- uint8 i;
- DS1302_CE = 1; //打開DS1302使能引腳
- DS1302ByteWrite(0xBF); //開啟burst讀取模式,0XBF為burst讀取地址
- for (i=0;i<7;i++) //burst模式一次要讀寫8個字節,實際日期總共7個字節,所以最后一個無意義
- {
- time[i]=DS1302ByteRead(); //循環8次,將 [年月日時分秒周] 7個字節及保護字節讀取出來
- }
- delay(3);
- DS1302_CE = 0; //關閉DS1302使能引腳
- }
- /*********************************************************************
- *函數名稱:delay
- *函數功能:延時函數
- *函數調用:delay(uint16 x_ms);
- *參數列表:x_ms
- *返 回 值:無
- *結 果:延遲時間=1* x_ms(毫秒)
- *備 注:
- *********************************************************************/
- void delay(uint16 x_ms) //延遲 x_ms*1 毫秒
- {
- uint16 i,j;
- for(i=x_ms;i>0;i--)
- for(j=114;j>0;j--);
- }
- /*********************************************************************
- *函數名稱:xiaoying
- *函數功能:數碼管掃描延遲及消影函數
- *函數調用:xiaoying();
- *參數列表:無
- *返 回 值:無
- *結 果:數碼管掃描延遲及消影
- *備 注:
- *********************************************************************/
- void xiaoying()
- {
- delay(3); //數碼管掃描延遲時間 毫秒
- DX=0; //顯示內容清空
- WX=0; //顯示位置清空
- P0=0X00; //選擇顯示位置
- WX=1; //給高電平
- WX=0; //給低電平 電平下衍 將顯示位置寫入數碼管位置顯示鎖存器
- }
復制代碼
|