![]() |
發(fā)布時間: 2017-6-9 13:26
正文摘要:STC12系列單片機擁有雙串口,所以我用串口一與電表通信,串口二與電腦通信,以單片機為樞紐,把串口一收到到數(shù)據(jù)再從串口二發(fā)送給電腦,同樣電腦端發(fā)送查詢數(shù)據(jù),hex模式,通過串口二傳遞給串口一再發(fā) ... |
老哥,你解決了嗎,我也碰到同樣的問題,能講下嗎 |
dzbj 發(fā)表于 2017-6-10 19:50 總之還是要謝謝您能在工作之余還能幫我分析問題,真的非常感謝,一個人的思路畢竟是有局限的,謝謝前輩的幫助,有機會再一起討論 ![]() |
dzbj 發(fā)表于 2017-6-10 19:50 通信規(guī)約上沒應(yīng)答之類,此類通訊應(yīng)該是半雙工通信,數(shù)據(jù)的發(fā)送和接收都有起始符,結(jié)束符,和校驗碼,我在發(fā)送和接收中加了判斷起止結(jié)束位和校驗碼,奇偶校驗位(以前沒加,因為校驗碼都計算好了沒有問題,所以本不想判斷了),對比和參考了一下前人寫的液晶顯示的51與電表通信。最后通信成功,將返回數(shù)據(jù)處理后與電表電量一致。但問題真正原因還是沒找到,不加判斷起始結(jié)束就沒法接收嗎(例如,判斷起始位68H,如果不判斷是不是68H,來的數(shù)據(jù)我都接收也應(yīng)該可以啊,又不是應(yīng)答之類的),我覺得問題不是出在這里。 |
寧采塵 發(fā)表于 2017-6-10 11:24 大致掃了一下你的程序 我覺得沒什么問題 有個建議是 s1_send_char(uart_2[a]); 這種函數(shù)盡量不放在中斷里 你這里這么用沒問題 但是沖斷的優(yōu)先級都高于正常程序 以后寫別的有可能有影響 養(yǎng)成個好習慣 你這段程序的意思是把串口2收到的東西用串口1轉(zhuǎn)發(fā)出來是么 如果是 先不進行這個 還是我之前說的 你直接把上位機并在單片機和模塊之間的通訊上 看它們之間聊的怎么樣 昨天看你說那個協(xié)議的時候 也是匆匆一掃 它好象有什么對位或者應(yīng)答之類的要求 你這程序里有么 |
dzbj 發(fā)表于 2017-6-9 21:13 串口一接收不到反饋信息,我現(xiàn)在也不確定是電表沒接收到數(shù)據(jù),還是我的接收數(shù)據(jù)程序有問題。我可以確定的是我再電腦端的串口助手能收到我發(fā)送的查詢數(shù)據(jù)。而且這串查詢數(shù)據(jù)我用抄表軟件發(fā)送時沒問題的,唯獨放到我程序里沒有回應(yīng)。您看一下我的發(fā)送和接收有問題嗎? //發(fā)送函數(shù),在主函數(shù)中,截取相關(guān)部分 while(1) { if(k==0) //按鍵按下一次發(fā)送一次查詢命令 { delay(20); if(k==0) { flag=0; } } if(flag==0) { for(m=0;m<15;m++) { s1_send_char(uart[m]); } flag=1; } // uchar code uart[]={0xFE,0x68,0x74,0x27,0x12,0x00, // 0x80,0x13,0x68,0x01,0x02,0x43,0xC3,0x19,0x16}; //讀正向有功總電能命令幀 } //接收函數(shù),截取相關(guān)部分,已將串口1并連電腦和電表。 /*串口一發(fā)送程序*/ void s1_send_char(uchar dat)//?發(fā)送端(發(fā)送的是字符) { SBUF=dat; while(!TI); TI=0; //清零標志 } void UART1() interrupt 4 //串口1中斷函數(shù) { if(RI==1) { uart_2[a]=SBUF; s1_send_char(uart_2[a]); a++; RI=0; if(a>14) { a=0; // flag=1; } } } |
寧采塵 發(fā)表于 2017-6-9 17:22 我大概看了一下你說的DLT645-1997 這是個通訊協(xié)議 從你說的情況感覺不是單片機串口的問題 是和DLT645-1997通訊沒成功 你可以這樣 先不用串口2 直接把上位機并聯(lián)到串口1上 相當于三機互連 然后看單片機發(fā)送給電表和電表反饋的數(shù)據(jù)是什么 根據(jù)反饋修改程序 直到調(diào)通它們后 再考慮串口2轉(zhuǎn)發(fā)的問題 |
dzbj 發(fā)表于 2017-6-9 14:22 我串口一波特率發(fā)生器用的T1,串口二用的獨立的波特率發(fā)生器。因為DLT645-1997通信規(guī)約要求,與電表通信波特率為1200bps,為方便,我兩個都設(shè)了1200bps。發(fā)送數(shù)據(jù),模塊RXD指示燈會亮,但是TXD指示燈一直都不會亮,應(yīng)該是通訊沒有成功。我沒有設(shè)奇偶校驗,單純的發(fā)送查詢命令幀后等待串口一接收中斷,好像一直沒有觸發(fā)。您有時間再幫我在看看吧,我也嘗試其他方法。方便加QQ交流嗎875576671 |
lshhjx 發(fā)表于 2017-6-9 14:37 串口一能正常通訊我確定,但是和電表通訊沒有成功,我每次發(fā)送數(shù)據(jù),模塊的發(fā)送指示燈都會亮,但是接收指示燈一直沒有亮,應(yīng)該是通訊沒有成功。 |
首先問一下樓主,你串口一能夠正常和電表通訊嗎? |
另 附上我用的串口1和2初始化 基本上是用STC-ISP生成的 你對比一下看看 也許有幫助 void Init_UART1(); //串口初始化 1T/定時器1作波特率發(fā)生器 void Init_UART1() //串口初始化 1T/定時器1作波特率發(fā)生器 { PCON |= 0x80; //使能波特率倍速位SMOD SCON = 0x50; //8位數(shù)據(jù),可變波特率 AUXR |= 0x40; //定時器1時鐘為Fosc,即1T AUXR &= 0xFE; //串口1選擇定時器1為波特率發(fā)生器 TMOD &= 0x0F; //清除定時器1模式位 // TMOD |= 0x21; //設(shè)定定時器1為8位自動重裝方式 TMOD |= 0x20; //設(shè)定定時器1為8位自動重裝方式 TL1=TH1=BAUD1; //設(shè)定定時初值 ET1 = 0; //禁止定時器1中斷 TR1 = 1; //啟動定時器1 ES=1; //開串口中斷 } void Init_UART2(); //串口2初始化 1T/獨立波特率發(fā)生器(串口2只能使用獨立波特率發(fā)生器) void Init_Uart2() //串口2初始化 115200bps@11.0592MHz@獨立波特率發(fā)生器 { AUXR |= 0x08; //使能波特率倍速位S2SMOD 0000 1000 S2CON = 0x50; //8位數(shù)據(jù),可變波特率 0101 0000 AUXR |= 0x04; //獨立波特率發(fā)生器時鐘為Fosc,即1T 0000 0100 BRT = BAUD2; //設(shè)定獨立波特率發(fā)生器重裝值 AUXR |= 0x10; //啟動獨立波特率發(fā)生器 0001 0000 IE2=0X01; //允許串口2中斷 } |
請大家?guī)蛶头治龇治?/td> |
上班呢 程序沒看 你說的應(yīng)用我用過 沒有任何問題 你堅信一定會成功吧 我用12c5a做顯示屏 屏幕是串口屏 用uart2和屏通訊 uart1+485和其它模塊通訊 和你的應(yīng)用差不多 1. uart2可以用計時器做波特率發(fā)生器也可以用獨立波特率發(fā)生器 如果用兩個串口 盡量各自用一個波特率發(fā)生器 我是因為兩個串口速率不一樣 其它模塊是57600 屏是115200 2. 485完全無需轉(zhuǎn)其它方式 直接ttl到485就沒問題 這個我用過很多很多很多 但485片子不同廠家有時候會出各種莫名其妙的不通訊問題 要注意485的電源濾波電容大小 按你買品牌的手冊要求高 我遇到過要求1.5uf的我用0.1uf就不行 3. uart1和2的轉(zhuǎn)發(fā) 你直接在內(nèi)存開個緩沖區(qū) 如果第一位不是0或者ff或者你定義的什么東西 就直接發(fā) 實驗的時候 你可以不斷的用串口1往上位機發(fā)緩沖區(qū)內(nèi)容 觀察串口2是否正常工作了 這樣有利于找到問題 我就是寫了個雙向直接轉(zhuǎn)發(fā)的程序 連串口屏自動聯(lián)機都可以 |
Powered by 單片機教程網(wǎng)