|
20黑幣
STC12系列單片機(jī)擁有雙串口,所以我用串口一與電表通信,串口二與電腦通信,以單片機(jī)為樞紐,把串口一收到到數(shù)據(jù)再從串口二發(fā)送給電腦,同樣電腦端發(fā)送查詢數(shù)據(jù),hex模式,通過串口二傳遞給串口一再發(fā)送出去,具體請看我程序。問題就出在這,電腦發(fā)送的數(shù)據(jù)發(fā)送出去了,卻沒有收到電表回復(fù)的數(shù)據(jù)。
我單獨(dú)測試過串口一二與電腦通信沒有問題,并將兩串口同時接到電腦,在電腦端打開兩個串口助手,也能完成通信。當(dāng)我把串口一摘下經(jīng)過TTL轉(zhuǎn)232模塊、232轉(zhuǎn)485模塊再接到電表測試時,收不到電表傳回的信息。
一開始我是直接用的TTL轉(zhuǎn)485與電表通信的,也是沒有成功,在論壇看到有位前輩用TTL轉(zhuǎn)232再232轉(zhuǎn)485與電表通信成功了,他是用的51 ,單串口1602顯示的,然后按照他硬件電路試了一下還是沒有成功。我想問題應(yīng)該是出在我程序上了,麻煩各位前輩幫我看一看有什么問題,通信規(guī)約我已經(jīng)仔細(xì)看過了,程序要求不需要太復(fù)雜,只要求發(fā)送同一條指令(我已存到數(shù)組中),能接收到電表返回的數(shù)據(jù)信息就行,具體數(shù)據(jù)我再進(jìn)行處理就好,麻煩大家?guī)臀彝瓿蛇@一步,在下感激不盡,有地方我說的不明白的請?jiān)僭儐栁遥艺娴谋贿@個程序塊搞壞了。。。
下面是我程序,麻煩大家?guī)臀曳治鲆幌隆?br />
/*要實(shí)現(xiàn)功能:通過單片機(jī)兩個串口,串口二連接在電腦端,
串口一連接電表,完成查詢正向有功功率任務(wù)。
目前進(jìn)度: 兩串口均測試可與電腦單獨(dú)通訊沒有問題,
把串口一接入電表無法接收到返回信息
*/
#include <stc12c5a60s2.h>
#include "intrins.h"
#include "uart.h"
uchar flag=0,dat,a=0,b=0;
uchar code uart[]={0xFE,0xFE,0xFE,0x68,0x74,0x27,0x12,0x00,
0x80,0x13,0x68,0x01,0x02,0x43,0xC3,0x19,0x16};
//讀正向有功總電能命令幀,電表
uchar data uart_1[36];
uchar data uart_2[36];
#define S2TI 0x02 // 串口2發(fā)送中斷請求標(biāo)志位
#define S2RI 0x01 // 串口2接收中斷請求標(biāo)志位
sbit REDE=P1^4;
void delay(uint x) // 延時子函數(shù)
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void main()
{
uchar m;
UartInit_1(); //初始化串口一 // 為遵循DLT645-1997與電表通信規(guī)約
UartInit_2(); //初始化串口二 //兩串口 波特率均設(shè)為1200bps
while(1)
{
if(flag=0)
{
for(m=0;m<17;m++) //上電先通過串口一發(fā)送讀正向有功總電能命令幀
{ //根據(jù)DLT645-1997規(guī)約編輯的命令幀,串口波特率1200bps
s1_send_char(uart[m]);
}
flag=1; //標(biāo)志變?yōu)?,等待串口一接收數(shù)據(jù)后標(biāo)志再次變?yōu)?.
//重復(fù)查詢功能暫時不用,先用電腦手動再次發(fā)送
}
delay(1000);
}
}
void UartInit_1(void) //1200bps@12MHz
{
TMOD=0x20; //設(shè)置定時器1位工作方式2
TH1=0xE8; //方式2為8位自動重裝,
//初值查表可得1200波特率
TL1=0xD0;
TR1=1; //打開定時器1
SM0=0; //設(shè)置串口工作方式1,10位固定
SM1=1;
REN=1; //允許串口接收數(shù)據(jù)
EA=1; //打開總中斷
ES=1; //打開串口中斷
}
void UartInit_2(void) //1200bps@12MHz 0xE8
{
AUXR = 0x10; //波特率不倍速
S2CON = 0x50; //8位數(shù)據(jù),可變波特率
BRT = 0xE8; //設(shè)定獨(dú)立波特率發(fā)生器重裝值
IE2 |= 0x01; //充許串口2中斷
//AUXR &= 0xfb; //獨(dú)立波特率發(fā)生器時鐘為Fosc/12,即12T
//AUXR = 0x10; //啟動獨(dú)立波特率發(fā)生器
}
/*串口一發(fā)送程序*/
void s1_send_char(uchar dat)//發(fā)送端(發(fā)送的是字符)
{
SBUF=dat;
while(!TI);
TI=0; //清零標(biāo)志
}
void s1_send_string(uchar *pt) //發(fā)送字符串
{
while(*pt != '\0')
{
s1_send_char(*pt++);
}
}
/*串口二發(fā)送程序*/
void s2_send_char(uchar dat2) // 發(fā)送端(發(fā)送的是字符)
{
S2BUF = dat2;
while(!(S2CON&S2TI));
S2CON &= ~S2TI;
}
void s2_send_string(uchar *pt2) //發(fā)送字符串
{
while(*pt2!='\0')
{
s2_send_char(*pt2++);
}
}
void UART1() interrupt 4 //串口1中斷函數(shù)
{ //串口一收到電表數(shù)據(jù),存入uart2,再通過串口二發(fā)送到電腦
if(RI==1) //接收數(shù)據(jù)
{
uart_2[a]=SBUF;
s2_send_char(uart_2[a]); //串口二發(fā)送到電腦
a++;
RI=0;
if(a>=17) //接收17位
{
a=0;
// flag=0; //先不讓標(biāo)志位=0;想要再發(fā)送查詢正向有功功率可以在電腦端串口二發(fā)送
}
}
// if(RI==1)
// {
// if(a==0&&0x68==SBUF)
// {
// uart_2[0]=SBUF;
// s2_send_char(uart_2[a]);
// }
//
// if(a>0&&uart_2[0]==0x68)
// {
// uart_2[a]=SBUF;
// s2_send_char(uart_2[a]);
//
// }
// a++;
// RI=0;
// }
//
// if(a>=36)
// {
// a=0;
// }
// flag=1;
}
void UART2() interrupt 8 //串口2中斷函數(shù)
{ //如果串口二接收到電腦端發(fā)送的查詢命令幀數(shù)據(jù),
//先存入數(shù)組uart1,再通過串口一發(fā)送給電表
if(S2CON&S2RI)
{
uart_1[b]=S2BUF;
S2CON&=~S2RI;
}
s1_send_char(uart_1[b]); //讓串口一發(fā)送查詢命令幀數(shù)據(jù)
b++;
if(b>=17)
{
b=0;
}
// flag=1;
}
|
|