51单片机串口设置7位数据,奇偶校验问题

weixin_42471950 2018-07-02 06:03:46
51单片机串口想设置成9600,7,E,2;跟PLC串口匹配通讯,可是单片机串口是8位的,怎么通过程序改变成7位,奇偶位怎么校验,新手请指导谢谢!能否有程序指点一下!
...全文
1330 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
SupermanTm 2018-07-13
  • 打赏
  • 举报
回复
你是 MCS-51 的片子,那么把串口模式为“1”,每次加载到SBUF的时候,先把数据放A,清掉bit7,然后读取PSW的P位,送到ACC.7,再把ACC送SBUF
weixin_42471950 2018-07-06
  • 打赏
  • 举报
回复 1
引用 6 楼 bakw 的回复:

51系列不支持2位停止位,好象还不好做啊。。。。


8051好像没有,8052有:sbit P = PSW^0; //8052 only,我用的是8052,之前是我临时写的。


[quote=引用 7 楼 bakw 的回复:]
void UartInit(void) //9600bps@11.0592MHz
{
PCON |= 0x80; //使能波特率倍速位SMOD
SCON = 0xD0; //9位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFA; //设定定时初值
TH1 = 0xFA; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
void SendOneByte(unsigned char c)
{
ACC=c;
c=P<<7 & c;
SBUF = c;
while(!TI);
TI = 0;
}


你给我写的程序我再试试,不懂再像你请教!!
weixin_42471950 2018-07-06
  • 打赏
  • 举报
回复
引用 9 楼 of123 的回复:
这样做:

1 首先把单片机串口设置成 9600, 8, Mark。这里校验位始终为 1,充当一个附加的停止位。
2 发送时,程序中编码计算 7 个 bit 的奇偶,然后将得到的 0 或 1 写到一个字节的最高位。它在串口发送时,是最后发出的,看作奇偶位。
3 接收时,计算低 7 比特的奇偶,与 bit 8 比对。



有什么简单的程序提供参考吗?新手请多指教!!!
weixin_42471950 2018-07-06
  • 打赏
  • 举报
回复
引用 7 楼 bakw 的回复:
void UartInit(void) //9600bps@11.0592MHz
{
PCON |= 0x80; //使能波特率倍速位SMOD
SCON = 0xD0; //9位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFA; //设定定时初值
TH1 = 0xFA; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
void SendOneByte(unsigned char c)
{
ACC=c;
c=P<<7 & c;
SBUF = c;
while(!TI);
TI = 0;
}
大概这个样子吧,随手写的。。。


我在你的基础上进行改动,测试了,一开始发送还行PLC有反馈,可单片机接受时会出现乱码,循环时间一长就不行了,一堆乱码,类似死机。接收是不是还的处理成7位数据。还有就是 我设置SCON = 0x50;设置成0xD0跟PLC通讯就没有响应,设置别的方式也不好使,跟停止位有关系吗?
c=r<<7|c;这个语句我改成或了,用与,就什么也没有,查看16进制全是00。我也不知道改的对不对,还是需要注意什么,我没改对?

unsigned int r;
void InitUART(void) //串口初始化
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xFD;
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;

}

void SendOneByte(unsigned char c) //字节发送
{
r=P;

c=r<<7|c;


SBUF = c;
while(!TI);
TI = 0;
}

void sendstring(unsigned char *p) //串口发送字符串
{
while(*p)
{
SendOneByte(*p++);
}


}
of123 2018-07-06
  • 打赏
  • 举报
回复
这样做:

1 首先把单片机串口设置成 9600, 8, Mark。这里校验位始终为 1,充当一个附加的停止位。
2 发送时,程序中编码计算 7 个 bit 的奇偶,然后将得到的 0 或 1 写到一个字节的最高位。它在串口发送时,是最后发出的,看作奇偶位。
3 接收时,计算低 7 比特的奇偶,与 bit 8 比对。
weixin_42471950 2018-07-05
  • 打赏
  • 举报
回复
引用 4 楼 bakw 的回复:
51没有7位通讯功能,你把单片机设置成 9600,8,N,2的通讯模式
然后每个数据的第八个字节,手动计算一下校验位,填进去就好了

起始位+7数据位+1校验位+2停止位=11位
起始位+8数据位+2停止位=11位

通讯长度上面一样就差不多了。



比如下面这个简单的串口通信C语言程序,波特率9600,晶振11.0592,怎么往字节里加,怎么更改
#include <reg51.h>

void InitUART(void)
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xFD;
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}

void SendOneByte(unsigned char c)
{
SBUF = c;
while(!TI);
TI = 0;
}

void main(void)
{
InitUART();
}

void UARTInterrupt(void) interrupt 4
{
if(RI)
{
RI = 0;
//add your code here!
}
else
TI = 0;
}

笨狗先飞 2018-07-05
  • 打赏
  • 举报
回复
51没有7位通讯功能,你把单片机设置成 9600,8,N,2的通讯模式
然后每个数据的第八个字节,手动计算一下校验位,填进去就好了

起始位+7数据位+1校验位+2停止位=11位
起始位+8数据位+2停止位=11位

通讯长度上面一样就差不多了。
weixin_42471950 2018-07-05
  • 打赏
  • 举报
回复
引用 2 楼 zgl7903 的回复:
还是按8位处理, 一个字节的低7位(bit6~bit0)作为数据,Bit7作为校验, 校验可借助P(PSW.0)
2位停止位,只要保证两个字节之间的时间超过1个位的时间即可


c语言程序怎么去处理,是通过TI中断标志位控制时间吗?这个时间怎么去掌握?有简单程序提示一下吗?
笨狗先飞 2018-07-05
  • 打赏
  • 举报
回复
void UartInit(void) //9600bps@11.0592MHz
{
PCON |= 0x80; //使能波特率倍速位SMOD
SCON = 0xD0; //9位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFA; //设定定时初值
TH1 = 0xFA; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
void SendOneByte(unsigned char c)
{
ACC=c;
c=P<<7 & c;
SBUF = c;
while(!TI);
TI = 0;
}
大概这个样子吧,随手写的。。。
笨狗先飞 2018-07-05
  • 打赏
  • 举报
回复

51系列不支持2位停止位,好象还不好做啊。。。。
zgl7903 2018-07-04
  • 打赏
  • 举报
回复
还是按8位处理, 一个字节的低7位(bit6~bit0)作为数据,Bit7作为校验, 校验可借助P(PSW.0)
2位停止位,只要保证两个字节之间的时间超过1个位的时间即可
Votangroom 2018-07-03
  • 打赏
  • 举报
回复
找找有没有相应的协议转换器

27,377

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧