|
//新時鐘芯片搞定,讀寫都可以,在OLED屏和串口正常顯示,溫濕度參數(shù)和時間日期參數(shù)
制作出來的實物圖如下:
SSS.jpg (87.89 KB, 下載次數(shù): 42)
下載附件
2023-12-8 16:00 上傳
888.jpg (65.73 KB, 下載次數(shù): 42)
下載附件
2023-12-8 15:59 上傳
777.jpg (176.22 KB, 下載次數(shù): 40)
下載附件
2023-12-8 15:59 上傳
1.jpg (239.34 KB, 下載次數(shù): 39)
下載附件
2023-12-8 17:25 上傳
電路原理圖如下:
666.jpg (134.49 KB, 下載次數(shù): 42)
下載附件
2023-12-8 15:59 上傳
STC15W4K56S4單片機源程序如下:
- //** Descriptions:
- //------------------------------------------------------------------------------------
- #define MAIN_Fosc 11059200L //定義主時鐘
- #include "15W4KxxS4.H"
- #include <intrins.h> // 加入此頭文件后,可使用_nop_庫函數(shù)
- #include <string.h> // 加入此頭文件后,可使用strstr庫函數(shù)
- #include "oled.h"
- #include "bmp.h"
- #include "AHT20.h"
- #include "stdio.h"
- #define uint8 unsigned char //0-256
- #define uint16 unsigned int //0-65535
- #define uint32 unsigned long //-100億--+100億
- #define BAUD 9600
- #define TM (65536 - (MAIN_Fosc/4/BAUD))
- #define Buf_Max 20 //串口7S1這里要設(shè)定到34,日期就可以正常顯示了
- #define S2_S 0x01
- #define S2RI 0x01
- #define S2TI 0x02
- #define S3RI 0x01
- #define S3TI 0x02
- #define S4RI 0x01
- #define S4TI 0x02
- #define Write 0X64
- #define Read 0X65
- uint8 xdata Rec_Buf1[Buf_Max];//4個串口的接收緩存
- uint8 xdata Rec_Buf2[Buf_Max];
- uint8 xdata Rec_Buf3[Buf_Max];
- uint8 xdata Rec_Buf4[Buf_Max];
- uint8 i = 0; //串口3數(shù)組計數(shù)器
- uint8 j = 0; //串口4數(shù)組計數(shù)器
- #define ACK 0
- #define NOACK 1
- sbit RX8025SCL = P0^2;
- sbit RX8025SDA = P0^3;
- //extern u8 xdata RX8025TimeBuffH[];RX8025SDA
- u8 xdata RX8025YMD[]="2020-12-07"; //這里不設(shè)定參數(shù),下面數(shù)組設(shè)
- u8 xdata RX8025HMS[]="12:34:56";
- u8 xdata RX8025TimeBuffH[]={11,24,9,4,8,12,23};//修改日期時鐘,中間的是星期
- u8 xdata RX8025TImeBuffB[]={0X01,0X02,0X03,0X04,0X05,0X06,0X07};
- //----------------------------------------------------------------------------------------
- //-----------------------串口1初始化函數(shù).注意該芯片有4個串口,1口中斷優(yōu)先級最高
- void Uart1_Init(void)
- {
- SCON = 0x50; //8位數(shù)據(jù),可變波特率
- AUXR |= 0x40; //定時器時鐘1T模式
- AUXR &= 0xFE; //串口1選擇定時器1為波特率發(fā)生器
- TMOD &= 0x0F; //設(shè)置定時器模式
- TL1 = 0xE0; //設(shè)置定時初始值
- TH1 = 0xFE; //設(shè)置定時初始值
- ET1 = 0; //禁止定時器中斷
- TR1 = 1; //定時器
- }
- //---------------------------------- 串口1發(fā)送數(shù)據(jù)函數(shù)
- void SendDataByUart1(uint8 dat)
- {
- SBUF = dat; //寫數(shù)據(jù)到UART數(shù)據(jù)寄存器
- while(TI == 0); //在停止位沒有發(fā)送時,TI為0即一直等待
- TI = 0; //清除TI位(該位必須軟件清零)
- }
- //------------------------===========串口1發(fā)送字符串函數(shù)
- void SendStringByUart1(uint8 *s)
- {
- while(*s)
- {
- SendDataByUart1(*s++);//將字符串中的字符一個一個發(fā)送
- }
- }
- //----------------------清除串口1緩存內(nèi)容函數(shù)
- void CLR_Buf1(void)
- {
- uint8 k;
- for(k=0;k<Buf_Max;k++) //將串口1緩存數(shù)組的值都清為零
- {
- Rec_Buf1[k] = 0;
- }
- i = 0;
- }
- //-----------------------------------串口1握手判斷函數(shù)
- bit Hand1(uint8 *a)
- {
- if(strstr(Rec_Buf1,a)!=NULL) //判斷字符串a(chǎn)是否是字符串Rec_Buf1的子串
- return 1; //如果字符串a(chǎn)是字符串Rec_Buf1的子串
- else
- return 0; //如果字符串a(chǎn)不是字符串Rec_Buf1的子串
- }
- //------------------------------------下面串口1接收中斷-----------------------
- void Uart1() interrupt UART1_VECTOR using 1
- {
- ES = 0; // 串口1中斷關(guān)閉
- if (RI) //串行接收到停止位的中間時刻時,該位置1
- {
- RI = 0; //清除RI位 (該位必須軟件清零)
- Rec_Buf1[i] = SBUF; //把串口1緩存SBUF寄存器數(shù)據(jù)依次存放到數(shù)組Rec_Buf1中
- i++;
- if(i>Buf_Max) //接收數(shù)大于定義接收數(shù)組最大個數(shù)時,覆蓋接收數(shù)組之前值
- {
- i = 0;
- }
- }
- ES = 1; // 串口1中斷打開
- }
- //================================================================================
- //----------------------------------------------------------------------------------------
- /*********BCD碼轉(zhuǎn)十六進制************/
- u8 BCDtoHEX(u8 BCD )
- {
- return ( ( (BCD/16)*10) +BCD%16 );
- }
- /**********十六進制轉(zhuǎn)BCD碼*************/
- u8 HEXtoBCD(u8 Hex)
- {
- return ( ((Hex/10)<<4) +Hex%10 );
- }
- /*********I2C延時***********/
- void I2CWait()
- {
- u8 i;
- for(i=0;i<10;i++)
- {
- _nop_();_nop_();_nop_();_nop_();
- }
- }
- bit I2C_Start2()
- {
- RX8025SDA = 1; //釋放總線
- RX8025SCL = 1;
- I2CWait();
- if(!RX8025SDA) return 0; //總線忙退出
- RX8025SDA = 0;
- I2CWait();
- while(RX8025SDA) return 0; //總線為高電平則總線出錯,退出
- RX8025SCL = 0;
- I2CWait();
- //return 1;
- }
- void I2C_Stop()
- {
- RX8025SCL = 0;
- RX8025SDA = 0;
- I2CWait();
- RX8025SCL = 1;
- I2CWait();
- RX8025SDA = 1;
- }
- /********主機向從機發(fā)送ACK****
- a=0,發(fā)送ACk a=1,發(fā)送NO ACK
- ******************************/
- void I2CSendACK(u8 a)
- {
- RX8025SDA = a;
- RX8025SCL = 0;
- I2CWait();
- RX8025SCL = 1;
- I2CWait();
- RX8025SCL = 0;
- }
- /*********主機讀取從機ACK信號***/
- bit I2CReceivedACK()
- {
- u8 errtime=255;
- RX8025SCL = 0;
- RX8025SDA = 1; //釋放總線
- I2CWait();
- RX8025SCL = 1;
- I2CWait();
- while(RX8025SDA) //讀取 SDA上的電平,變?yōu)榈碗娖剑从袕臋C回復(fù)ACK信號
- {
- errtime--;
- if(!errtime) //超時退出
- {
- RX8025SCL=0;
- return 0;
- }
- }
- RX8025SCL=0;
- return 1;
- }
- /******************************************
- 主機向從機發(fā)送一字節(jié)數(shù)據(jù)-->dat
- order=0:先發(fā)送LSB,最后發(fā)送MSB
- order=1:先發(fā)送MSB;最后發(fā)送LSB
- 之所以設(shè)置order這個入口參數(shù),是為了程序方便
- 移植,適應(yīng)多個IIC芯片,只需設(shè)置order就能改變
- 數(shù)據(jù)傳輸方向,RX8025芯片 order 一直為 1
- ******************************************/
- void IIC_Send_Byte(u8 dat, bit order)
- {
- u8 i;
- if(order)
- {
- for(i=0;i<8;i++)
- {
- RX8025SDA = dat&0X80;
- RX8025SCL = 1;
- I2CWait();
- RX8025SCL = 0;
- dat<<=1;
- I2CWait();
- }
- }
- else
- {
- for(i=0;i<8;i++)
- {
- RX8025SDA = dat&0X01;
- RX8025SCL = 1;
- I2CWait();
- RX8025SCL = 0;
- dat>>=1;
- I2CWait();
- }
- }
- }
- /*********讀取一字節(jié)數(shù)據(jù)*********
- order=0:先讀取LSB,最后讀取MSB
- order=1:先去讀MSB,最后讀取LSB
- ********************************/
- u8 IIC_Receive_Byte(bit order)
- {
- u8 i,j,Rdat;
- RX8025SDA = 1; //釋放總線
- if(order) //MSB-->LSB
- {
- for(i=0;i<8;i++)
- {
- RX8025SCL = 0;
- I2CWait();
- Rdat =( Rdat<<1 )| RX8025SDA;
- RX8025SCL = 1;
- I2CWait();
- }
- }
- else //LSB-->MSB
- {
- for(i=0;i<8;i++)
- {
- RX8025SCL = 0;
- I2CWait();
- j=RX8025SDA;
- Rdat =( Rdat>>1 )| (j<<7);
- RX8025SCL = 1;
- I2CWait();
- }
- }
- RX8025SCL=0;
- return Rdat;
- }
- /******讀取RX8025一個寄存器的數(shù)據(jù)*****/
- //u8 Read_RX8025_Byte(u8 add)
- //{
- // u8 Ridat;
- // I2C_Start2();
- // IIC_Send_Byte(Write,1);
- // if(!I2CReceivedACK()) //判斷有無ACK信號
- // I2C_Stop();
- // IIC_Send_Byte(add,1);
- // if(!I2CReceivedACK()) //判斷有無ACK信號
- // I2C_Stop();
- //
- // I2C_Start2();
- // IIC_Send_Byte(Read,1);
- // if(!I2CReceivedACK()) //判斷有無ACK信號
- // I2C_Stop();
- // Ridat = IIC_Receive_Byte(1); //讀取數(shù)據(jù)
- // I2CSendACK(1);
- // I2C_Stop();
- // return Ridat;
- //}
- //--單獨向一個寄存器寫數(shù)據(jù)
- void Write_RX8025_Byt(u8 add,u8 dat)
- {
- u8 Bdat;
- Bdat = dat;
- //Bdat = HEXtoBCD(dat); //將十六進制轉(zhuǎn)換為BCD碼
- //---開始寫入數(shù)據(jù)
- I2C_Start2();
- IIC_Send_Byte(Write,1);
- if(!I2CReceivedACK()) //判斷有無ACK信號
- I2C_Stop();
- IIC_Send_Byte(add<<4,1); //--根據(jù)手冊在寫入時地址要右移4位
- if(!I2CReceivedACK()) //判斷有無ACK信號
- I2C_Stop();
- IIC_Send_Byte(Bdat,1);
- I2CReceivedACK();
- I2C_Stop();
- }
- //--連續(xù)讀取時間、日歷數(shù)據(jù)--
- //--add:讀取的起始地址
- //--Num:讀取數(shù)據(jù)的個數(shù)
- //--標(biāo)準(zhǔn)IIC連續(xù)讀寄存器時序
- void Read_RX8025_Dat(u8 add, u8 Num)
- {
- u8 i;
- //---先寫讀寄存器地址
- I2C_Start2();
- IIC_Send_Byte(Write,1);
- if(!I2CReceivedACK()) //判斷有無ACK信號
- I2C_Stop();
- IIC_Send_Byte(add,1); //秒寄存器地址
- if(!I2CReceivedACK()) //判斷有無ACK信號
- I2C_Stop();
- //---連續(xù)讀取數(shù)據(jù)
- I2C_Start2();
- IIC_Send_Byte(Read,1);
- if(!I2CReceivedACK()) //判斷有無ACK信號
- I2C_Stop();
- for(i=0;i<Num;i++)
- {
- RX8025TImeBuffB[i] = IIC_Receive_Byte(1); //讀取數(shù)據(jù)
- if(i!=6)I2CSendACK(0);
- }
- I2CSendACK(1);
- I2C_Stop();
- for(i=0;i<Num;i++)
- {
- RX8025TimeBuffH[i] = BCDtoHEX(RX8025TImeBuffB[i]);
- }
- }
- /*****向RX8025連續(xù)寫num個數(shù)據(jù)******/
- void Write_RX8025_Byte(u8 add,u8 *Buff)
- {
- u8 i;
- //---先寫讀寄存器地址
- I2C_Start2();
- IIC_Send_Byte(Write,1);
- if(!I2CReceivedACK()) //判斷有無ACK信號
- I2C_Stop();
- IIC_Send_Byte(add<<4,1);
- if(!I2CReceivedACK()) //判斷有無ACK信號
- I2C_Stop();
- for(i=0;i<7;i++) //--連續(xù)寫入7個時間日歷數(shù)據(jù)
- {
- Buff[i] = HEXtoBCD(Buff[i]);
- IIC_Send_Byte(Buff[i],1);
- I2CReceivedACK();
- }
- I2C_Stop();
- }
- void RX8025_Init()
- {
- //--12/24小時寄存器地址為0X0E,
- Write_RX8025_Byt(0X0E,0X20); //RX8025-T 24小時制
- // Write_RX8025_Byt(0X0E,0X00); //RX8025-T 12小時制
- }
- void DisplayTime()
- {
- //--顯示RX8025的時間
- Read_RX8025_Dat(0,7);
- RX8025YMD[2] = RX8025TimeBuffH[6]/10; //+0X30; 年
- RX8025YMD[3] = RX8025TimeBuffH[6]%10; //+0X30;
-
- RX8025YMD[5] = RX8025TimeBuffH[5]/10; //+0X30; 月
- RX8025YMD[6] = RX8025TimeBuffH[5]%10; //+0X30;
-
- RX8025YMD[8] = RX8025TimeBuffH[4]/10;// +0X30; 日
- RX8025YMD[9] = RX8025TimeBuffH[4]%10; //+0X30;
-
- RX8025HMS[0] = RX8025TimeBuffH[2]/10;// +0X30; 時
- RX8025HMS[1] = RX8025TimeBuffH[2]%10; //+0X30;
-
- RX8025HMS[3] = RX8025TimeBuffH[1]%100/10; //+0X30; 分
- RX8025HMS[4] = RX8025TimeBuffH[1]%10;// +0X30;
-
- RX8025HMS[6] = RX8025TimeBuffH[0]%100/10; //+0X30; 秒
- RX8025HMS[7] = RX8025TimeBuffH[0]%10; //+0X30;
- // Write_ASCII3X16_N(0,7,0,"T3:RX8025");
- // Write_ASCII3X16_N(0,8,0,RX8025YMD);
- // Write_ASCII3X16_N(2,9,0,RX8025HMS); Write_6x16Font_N(12,9,0,WeekD);
- }
- //==============================================================================
- int main()
- {
- uint32 CT_data[2];
- volatile float c1,t1;
- //
- P0M0=0x00,P0M1=0x00;//我自己加的代碼 3
- P2M0=0x00,P2M1=0x00;//我自己加的代碼 3
- P1M0=0x00,P1M1=0x00;//我自己加的代碼 3
- P4M0=0x00,P4M1=0x00;//我自己加的代碼 3
- P5M0=0x00,P5M1=0x00;//我自己加的代碼
- Uart1_Init();
- delay_msT(500);//①剛上電,產(chǎn)品芯片內(nèi)部就緒需要時間,延時100~500ms,建議500ms
- WDT_CONTR = 0x35;//
- OLED_Init(); //注意OLED的數(shù)據(jù)線正好在15W4K56的P06,P07端口,先等這兩個IO打開才能正常啟動OLED
- RX8025_Init();
- Write_RX8025_Byte(0,RX8025TimeBuffH);//RX8025時鐘芯片里寫入日期時間參數(shù),2020-5-1-12:00:00,
- if((AHT20_Read_Status()&0x18)!=0x18)//②上電第一次發(fā)0x71讀取狀態(tài)字,判斷狀態(tài)字是否為0x18,如果不是0x18,進行寄存器初始化
- {
- AHT20_Start_Init(); //重新初始化寄存器
- delay_msT(10);
- }
-
- while(1)//③根據(jù)客戶自己需求發(fā)測量命令讀取溫濕度數(shù)據(jù),當(dāng)前while(1)循環(huán)發(fā)測量命令讀取溫濕度數(shù)據(jù),僅供參考
- { WDT_CONTR = 0x35;//
- AHT20_Read_CTdata_crc(CT_data); //crc校驗后,讀取AHT20的溫度和濕度數(shù)據(jù)
- c1 = ((float)CT_data[0]/1024/1024)*100; //計算得到濕度值c1放大10倍
- t1 = ((float)CT_data[1]/1024/1024)*200-50;//計算得到溫度值t1放大10倍
-
- DisplayTime();
- OLED_ShowString(0,0,"T=",8);//
- OLED_ShowString(60,0,"H=",8);//
- OLED_ShowNum(16,0,t1,4,12);//溫度
- OLED_ShowNum(76,0,c1,4,12);//濕度
-
-
- OLED_ShowNum(0,1,2,1,12);// 年 2
- OLED_ShowNum(8,1,0,1,12);// 年 0
- OLED_ShowNum(16,1,RX8025YMD[2],1,12);// 年 2
- OLED_ShowNum(24,1,RX8025YMD[3],1,12);// 年 3
-
- OLED_ShowNum(32,1,RX8025YMD[5],1,12);// 月
- OLED_ShowNum(40,1,RX8025YMD[6],1,12);// 月
- OLED_ShowNum(48,1,RX8025YMD[8],1,12);// 日 3
- OLED_ShowNum(56,1,RX8025YMD[9],1,12);// 日 3
- OLED_ShowString(64,1,"-",8);//
-
- OLED_ShowNum(76,1,RX8025HMS[0],1,12);// 時 十位 1
- OLED_ShowNum(84,1,RX8025HMS[1],1,12);// 時 個位 2
- OLED_ShowNum(92,1,RX8025HMS[3],1,12);// 分 十位 3
- OLED_ShowNum(100,1,RX8025HMS[4],1,12);//分 個位 4
- OLED_ShowNum(108,1,RX8025HMS[6],1,12);//秒 十位 5
- OLED_ShowNum(116,1,RX8025HMS[7],1,12);//秒 個位 6
-
- SendDataByUart1(0x32);
- SendDataByUart1(0x30);
- SendDataByUart1(RX8025YMD[2]+0x30);//串口發(fā) 年
- SendDataByUart1(RX8025YMD[3]+0x30);
- SendDataByUart1(0x20);//發(fā)空格
- SendDataByUart1(RX8025YMD[5]+0x30);//串口發(fā) 月
- SendDataByUart1(RX8025YMD[6]+0x30);
- SendDataByUart1(0x20);
- SendDataByUart1(RX8025YMD[8]+0x30);//串口發(fā) 日
- SendDataByUart1(RX8025YMD[9]+0x30);
- SendDataByUart1(0x20);
- SendDataByUart1(RX8025HMS[0]+0x30);//串口發(fā) 時
- SendDataByUart1(RX8025HMS[1]+0x30);//
- SendDataByUart1(0x3a);//發(fā)冒號
- SendDataByUart1(RX8025HMS[3]+0x30);//串口發(fā) 分
- SendDataByUart1(RX8025HMS[4]+0x30);//
- SendDataByUart1(0x3a);
- SendDataByUart1(RX8025HMS[6]+0x30);//串口發(fā) 秒
- SendDataByUart1(RX8025HMS[7]+0x30);//
-
-
- delay_msT(4000);
- delay_msT(4000);
- }
- }
復(fù)制代碼 STC15W單片機同時驅(qū)動溫濕度AHT20 時鐘RX8025
原理圖: 無
仿真: 無
代碼:
程序.7z
(74.71 KB, 下載次數(shù): 53)
2023-12-8 17:23 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|