- #include <reg52.h>
- struct sTime { //日期時間結(jié)構(gòu)體定義
- unsigned int year;
- unsigned char mon;
- unsigned char day;
- unsigned char hour;
- unsigned char min;
- unsigned char sec;
- unsigned char week;
- };
- bit flag200ms = 1; //200ms定時標(biāo)志
- bit reqRefresh = 0; //時間刷新請求
- struct sTime bufTime; //日期時間緩沖區(qū)
- unsigned char T0RH = 0; //T0重載值的高字節(jié)
- unsigned char T0RL = 0; //T0重載值的低字節(jié)
- void ConfigTimer0(unsigned int ms);
- void RefreshTimeShow();
- extern void InitDS1302();
- extern void GetRealTime(struct sTime *time);
- extern void SetRealTime(struct sTime *time);
- extern void UartDriver();
- extern void ConfigUART(unsigned int baud);
- extern void UartRxMonitor(unsigned char ms);
- extern void UartWrite(unsigned char *buf, unsigned char len);
- extern unsigned int GetCRC16(unsigned char *ptr, unsigned char len);
- extern void InitLcd1602();
- extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
- void main()
- {
- unsigned char psec=0xAA; //秒備份,初值A(chǔ)A確保首次讀取時間后會刷新顯示
- EA = 1; //開總中斷
- ConfigTimer0(1); //配置T0定時1ms
- ConfigUART(9600); //配置波特率為9600
- InitDS1302(); //初始化實(shí)時時鐘
- InitLcd1602(); //初始化液晶
- //初始化屏幕上固定不變的內(nèi)容
- LcdShowStr(3, 0, "20 - - ");
- LcdShowStr(4, 1, " : : ");
- while (1)
- {
- UartDriver(); //調(diào)用串口驅(qū)動
- if (flag200ms)
- {
- flag200ms = 0;
- GetRealTime(&bufTime); //獲取當(dāng)前時間
- if (reqRefresh || (psec!=bufTime.sec))
- { //檢測到時間刷新請求或時間有變化時刷新顯示
- RefreshTimeShow();
- psec = bufTime.sec; //用當(dāng)前值更新上次秒數(shù)
- }
- }
- }
- }
- /* 將一個BCD碼字節(jié)顯示到屏幕上,(x,y)-屏幕起始坐標(biāo),bcd-待顯示BCD碼 */
- void ShowBcdByte(unsigned char x, unsigned char y, unsigned char bcd)
- {
- unsigned char str[4];
- str[0] = (bcd >> 4) + '0';
- str[1] = (bcd&0x0F) + '0';
- str[2] = '\0';
- LcdShowStr(x, y, str);
- }
- /* 刷新日期時間的顯示 */
- void RefreshTimeShow()
- {
- ShowBcdByte(5, 0, bufTime.year);
- ShowBcdByte(8, 0, bufTime.mon);
- ShowBcdByte(11, 0, bufTime.day);
- ShowBcdByte(4, 1, bufTime.hour);
- ShowBcdByte(7, 1, bufTime.min);
- ShowBcdByte(10, 1, bufTime.sec);
- }
- /* 串口動作函數(shù),根據(jù)接收到的命令幀執(zhí)行響應(yīng)的動作
- buf-接收到的命令幀指針,len-命令幀長度 */
- void UartAction(unsigned char *buf, unsigned char len)
- {
- unsigned int crc;
- unsigned char crch, crcl;
- if (buf[0] != 0x01) //本例中的本機(jī)地址設(shè)定為0x01,
- { //如數(shù)據(jù)幀中的地址字節(jié)與本機(jī)地址不符,
- return; //則直接退出,即丟棄本幀數(shù)據(jù)不做任何處理
- }
- //地址相符時,再對本幀數(shù)據(jù)進(jìn)行校驗(yàn)
- crc = GetCRC16(buf, len-2); //計(jì)算CRC校驗(yàn)值
- crch = crc >> 8;
- crcl = crc & 0xFF;
- if ((buf[len-2]!=crch) || (buf[len-1]!=crcl))
- {
- return; //如CRC校驗(yàn)不符時直接退出
- }
- //地址和校驗(yàn)字均相符后,解析功能碼,執(zhí)行相關(guān)操作
- switch (buf[1])
- {
- case 0x06: //寫入單個寄存器
- if ((buf[2]==0x00) && (buf[3]<=0x06)) //地址0x0000~0x0006分別對應(yīng)
- { // “年/月/日/時/分/秒/星期”
- GetRealTime(&bufTime); //獲取當(dāng)前時間
- switch (buf[3]) //由寄存器地址決定要修改的時間位
- {
- case 0: bufTime.year = 0x2000 + buf[5]; break;
- case 1: bufTime.mon = buf[5]; break;
- case 2: bufTime.day = buf[5]; break;
- case 3: bufTime.hour = buf[5]; break;
- case 4: bufTime.min = buf[5]; break;
- case 5: bufTime.sec = buf[5]; break;
- case 6: bufTime.week = buf[5]; break;
- default: break;
- }
- SetRealTime(&bufTime); //寫入新修改后的時間
- reqRefresh = 1; //設(shè)置顯示刷新請求
- len -= 2; //長度-2以重新計(jì)算CRC并返回原幀
- break;
- }
- else //寄存器地址不被支持時,返回錯誤碼
- {
- buf[1] = 0x86; //功能碼最高位置1
- buf[2] = 0x02; //設(shè)置異常碼為02-無效地址
- len = 3;
- break;
- }
- default: //其它不支持的功能碼
- buf[1] |= 0x80; //功能碼最高位置1
- buf[2] = 0x01; //設(shè)置異常碼為01-無效功能
- len = 3;
- break;
- }
- crc = GetCRC16(buf, len); //計(jì)算返回幀的CRC校驗(yàn)值
- buf[len++] = crc >> 8; //CRC高字節(jié)
- buf[len++] = crc & 0xFF; //CRC低字節(jié)
- UartWrite(buf, len); //發(fā)送返回幀
- }
- /* 配置并啟動T0,ms-T0定時時間 */
- void ConfigTimer0(unsigned int ms)
- {
- unsigned long tmp; //臨時變量
- tmp = 11059200 / 12; //定時器計(jì)數(shù)頻率
- tmp = (tmp * ms) / 1000; //計(jì)算所需的計(jì)數(shù)值
- tmp = 65536 - tmp; //計(jì)算定時器重載值
- tmp = tmp + 33; //補(bǔ)償中斷響應(yīng)延時造成的誤差
- T0RH = (unsigned char)(tmp>>8); //定時器重載值拆分為高低字節(jié)
- T0RL = (unsigned char)tmp;
- TMOD &= 0xF0; //清零T0的控制位
- TMOD |= 0x01; //配置T0為模式1
- TH0 = T0RH; //加載T0重載值
- TL0 = T0RL;
- ET0 = 1; //使能T0中斷
- TR0 = 1; //啟動T0
- }
- /* T0中斷服務(wù)函數(shù),執(zhí)行按鍵掃描和200ms定時 */
- void InterruptTimer0() interrupt 1
- {
- static unsigned char tmr200ms = 0;
- TH0 = T0RH; //重新加載重載值
- TL0 = T0RL;
- UartRxMonitor(1); //串口接收監(jiān)控
- tmr200ms++;
- if (tmr200ms >= 200) //定時200ms
- {
- tmr200ms = 0;
- flag200ms = 1;
- }
- }
復(fù)制代碼
版權(quán)說明:本文檔由用戶提供并上傳,僅供個人學(xué)習(xí)用途,若內(nèi)容存在侵權(quán),請聯(lián)系我們刪除。
MAX485.pdf
(438.77 KB)
2021-7-6 16:25 上傳
點(diǎn)擊文件名下載附件
版權(quán)說明:本文檔由用戶提供并上傳,僅供個人學(xué)習(xí)用途,若內(nèi)容存在侵權(quán),請聯(lián)系我們刪除。
Modbus通信協(xié)議.pdf
(156.79 KB)
2021-7-6 16:25 上傳
點(diǎn)擊文件名下載附件
版權(quán)說明:本文檔由用戶提供并上傳,僅供個人學(xué)習(xí)用途,若內(nèi)容存在侵權(quán),請聯(lián)系我們刪除。
MODBUS協(xié)議中文版.pdf
(1.11 MB)
2021-7-6 16:25 上傳
點(diǎn)擊文件名下載附件
版權(quán)說明:本文檔由用戶提供并上傳,僅供個人學(xué)習(xí)用途,若內(nèi)容存在侵權(quán),請聯(lián)系我們刪除。
Modbus注意要項(xiàng).pdf
(216.87 KB)
2021-7-6 16:25 上傳
點(diǎn)擊文件名下載附件
【必讀】版權(quán)免責(zé)聲明
1、本主題所有言論和內(nèi)容純屬會員個人意見,與本論壇立場無關(guān)。2、本站對所發(fā)內(nèi)容真實(shí)性、客觀性、可用性不做任何保證也不負(fù)任何責(zé)任,網(wǎng)友之間僅出于學(xué)習(xí)目的進(jìn)行交流。3、對提供的數(shù)字內(nèi)容不擁有任何權(quán)利,其版權(quán)歸原著者擁有。請勿將該數(shù)字內(nèi)容進(jìn)行商業(yè)交易、轉(zhuǎn)載等行為,該內(nèi)容只為學(xué)習(xí)所提供,使用后發(fā)生的一切問題與本站無關(guān)。 4、本網(wǎng)站不保證本站提供的下載資源的準(zhǔn)確性、安全性和完整性;同時本網(wǎng)站也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的損失或傷害。 5、本網(wǎng)站所有軟件和資料均為網(wǎng)友推薦收集整理而來,僅供學(xué)習(xí)用途使用,請務(wù)必下載后兩小時內(nèi)刪除,禁止商用。6、如有侵犯你版權(quán)的,請及時聯(lián)系我們(電子郵箱1370723259@qq.com)指出,本站將立即改正。
|