用AM2483这款485芯片时,芯片DIR方向控制脚随便定义(跟硬件连接不一样),用485发数据电脑都可以收到,这是什么情况。硬件上定义的是P10,但程序中定义P11,P12都可以
[mw_shl_code=c,true]#include "RS485.H"
sbit RS485_DIR = P1^1; //RS485方向选择引脚
unsigned char pdata bufRxd[40]; //串口接收缓冲区
unsigned char cntRxd = 0;
void ConfigUART(unsigned int baud) //串口配置函数,baud为波特率
{
RS485_DIR = 0; //RS485设置为接收方向
SCON = 0x50; //配置串口为模式1
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x20; //配置T1为模式2
TH1 = 256 - (11059200/12/32) / baud; //计算T1重载值
TL1 = TH1; //初值等于重载值
ET1 = 0; //禁止T1中断
ES = 1; //使能串口中断
TR1 = 1; //启动T1
}
unsigned char UartRead(unsigned char *buf, unsigned char len) //串口数据读取函数,数据接收指针buf,读取数据长度len,返回值为实际读取到的数据长度
{
unsigned char i;
if (len > cntRxd) //读取长度大于接收到的数据长度时,
{
len = cntRxd; //读取长度设置为实际接收到的数据长度
}
for (i=0; i<len; i++) //拷贝接收到的数据
{
*buf = bufRxd[ i];
buf++;
}
cntRxd = 0; //清零接收计数器
return len; //返回实际读取长度
}
void DelayX10us(unsigned char t) //软件延时函数,延时时间(t*10)us
{
do {
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
} while (--t);
}
void UartWrite(unsigned char *buf, unsigned char len) //串口数据写入函数,即串口发送函数,待发送数据指针buf,数据长度len
{
RS485_DIR = 1; //RS485设置为发送
while (len--) //发送数据
{
SysFLag.flagOnceTxd = FALSE;
SBUF = *buf;
buf++;
while (!SysFLag.flagOnceTxd);
}
DelayX10us(5); //等待最后的停止位完成,延时时间由波特率决定
RS485_DIR = 0; //RS485设置为接收
}
void UartRxMonitor(unsigned char ms) //串口接收监控函数
{
static unsigned char cntbkp = 0;
static unsigned char idletmr = 0;
if (cntRxd > 0) //接收计数器大于零时,监控总线空闲时间
{
if (cntbkp != cntRxd) //接收计数器改变,即刚接收到数据时,清零空闲计时
{
cntbkp = cntRxd;
idletmr = 0;
}
else
{
if (idletmr < 5) //接收计数器未改变,即总线空闲时,累积空闲时间
{
idletmr += ms;
if (idletmr >= 5) //空闲时间超过4个字节传输时间即认为一帧命令接收完毕
{
SysFLag.cmdArrived = TRUE; //设置命令到达标志
}
}
}
}
else
{
cntbkp = 0;
}
}
void InterruptUART() interrupt 4 //UART中断服务函数
{
if (RI) //接收到字节
{
RI = 0; //手动清零接收中断标志位
if (cntRxd < sizeof(bufRxd)) //接收缓冲区尚未用完时,
{
bufRxd[cntRxd++] = SBUF; //保存接收字节,并递增计数器
}
}
if (TI) //字节发送完毕
{
TI = 0; //手动清零发送中断标志位
SysFLag.flagOnceTxd = 1; //设置单次发送完成标志
}
}
[/mw_shl_code]
|