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

weixin_42471950 2018-07-02 06:03:46
51单片机串口想设置成9600,7,E,2;跟PLC串口匹配通讯,可是单片机串口是8位的,怎么通过程序改变成7位,奇偶位怎么校验,新手请指导谢谢!能否有程序指点一下!
...全文
1319 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
  • 打赏
  • 举报
回复
找找有没有相应的协议转换器
单片机系统设计课程实验二 51单片机与PC机通信实验 实验目的 熟悉51单片机串口功能控制,同时掌握ASCII码的编码方法、16进制数与BCD码之间的转换。 实验内容 设定单片机串口为工作模式1,波特率为9600,数据8,不含奇偶校验,包含1起始、1停止; 从单片机发送字符串"I(空格)Love(空格)China!(回车)",PC机上的串口调试助手进行显示,每3秒钟发送一次,时间间隔可以采用硬件定时器和软件计数器完成; 从PC机上的串口调试助手发送816进制表示的数到单片机,单片机接收到数据后转换为BCD码并在数码管显示,在进行数值显示时,没用到的数码管显示为"0"; 定时器溢出采用中断模式,串口接收和发送完毕采用查询方式。 实验电路 参考实验指导书后面的单片机实验平台电路,包括51单片机电路、数码管显示电路。 编程说明 四数码管为静态显示方式,数码管为共阳极,四个数码管的外部地址空间分别为7FF8H(或0000H)、7FF9H(或0001H)、7FFAH(或0002H)7FFBH(0003H); 串口调试助手软件在接收设置时,选择ASCII显示,否则显示不出字符串,发送设置选择Hex,发送16进制数; 实验板上的时钟频率为11.0592MHz,建议定时器0采用模式1,定时时间比较长,中断溢出的次数少; 单片机系统设计课程实验二单片机与PC机通信实验实验目全文共2页,当前为第1页。显示程序中要把RI清除,否则不能再接收数据。 单片机系统设计课程实验二单片机与PC机通信实验实验目全文共2页,当前为第1页。 程序流程图 主程序 定时器0中断程序 字符串发送程序 单片机系统设计课程实验二单片机与PC机通信实验实验目全文共2页,当前为第2页。 单片机系统设计课程实验二单片机与PC机通信实验实验目全文共2页,当前为第2页。 单片机系统设计课程实验二单片机与PC机通信实验实验目
里面讲了MSComm控件 、 WinAPI 串口通信、CSerial类,例子很详实,每一步操作都有解释。作者是龚建伟,有一个个人主页www.gjwtech.com,讲串口通信的内容比较多,还行,大家可以先看看这个主页。 本书目录 第1章轻松体验串口通信编程与调试 1.1初识串口 1.1.1从外观上了解串口 1.1.2 串口通信的发展前景 1.2 自己制作简单的串口线 1.2.1 三线制串口接线的规定 1.2.2 焊接制作自己的串口连接线 1.3 调试串口通信程序时的几种使用串口的技巧 1.3.1 查看计算机串口资源 1.3.2 常规调试-2个物理串口之间的通信 1.3.3 特殊调试-单个物理串口之间的通信 1.3.4 虚拟串口-为计算机添加取之不尽的串口资源 1.4 使用串口调试助手来体验串口通信 1.5体验Windows环境下Visual C++串口通信编程 1.6体验DOS环境下Turbo C串口通信编程 第2章 VC多线程串口编程工具CSerialPort类 2.1 类功能及成员函数介绍 2.2 应用CSerialPort类编制基于对话框的应用程序 2.3 应用CSerialPort类编制基于单文档的应用程序 2.4对CSerialPort类的改进 2.5 在Visual C++.NET中应用CSerialPort类 第3章 控件MSComm串口编程 3.1 MSComm控件详细介绍 3.1.1 VC中应用MSComm控件编程步骤 3.1.2 MSComm控件串行通信处理方式 3.1.3 MSComm 控件的属性说明 3.1.4 MSComm控件错误信息 3.2使用MSComm控件的几个疑难问题 3.2.1使用VARIANT 和SAFEARRAY 数据类型从串口读写数据 3.2.2 MSComm控件能离开对话框独立存在吗? 3.2.3 如何发送接收ASCII值为0和大于128的字符? 3.2.4 在同一程序中用MSComm控件控制多个串口的具体操作方法 3.2.5解决使用控件编程时程序占用的内存会不断增大的问题 3.2.6在没有安装Visual Studio的计算机上如何使用MSComm控件 3.2.7 在MSComm控件串口编程时遇到的其它问题说明 3.3在基于单文档(SDI)程序中应用MSComm控件 3.4应用MSComm控件控制多个串口实例 第4章 Windows API串口编程 4.1 Windows API串口编程概述 4.2 API串口编程中用到的结构及相关概念说明 4.2.1 DCB(Device Control Block)结构 4.2.2超时设置COMMTIMEOUTS结构 4.2.3 OVERLAPPED异步I/O重叠结构 4.2.4 通信错误与通信设备状态 4.2.5 串行通信事件 4.3 Windows API串行通信函数 4.4 Win32 API串口通信编程的一般流程和特殊实例 4.4.1 Win32 API串口通信编程的一般流程 4.4.2 用查询方式读串口 4.4.3同步I/O读写数据 4.4.4 关于流控制的设置问题 4.5 CSerialPort类中的API函数编程应用剖析 4.6 Win32 API串口编程TTY(虚拟终端)实例 4.7 Windows API串口精简例程 第5章 串口调试助手V2.2详细编程 5.1 建立SCOMM程序工程实现界面功能 5.2 串口的初始化及关闭 5.3串口数据的发送与接收及十六进制数据的处理 5.3.1 十六进数据发送处理 5.3.2 手动发送处理 5.3.3自动发送处理 5.3.4 接收处理及十六进制显示 5.4 其它辅助功能的实现 5.4.1 接收数据的文件保存 5.4.2 实现小文件发送 5.4.3 图钉按钮功能使程序能浮在最上层 5.4.4 对话框动画图标的实现 5.4.5 超链接功能的实现 5.4.6 如何打开帮助网页文件 第6章 DOS环境下的Turbo C串口编程及通用实例GSerial类 6.1 PC机异步通信适配器8250及其编程操作 6.1.1 INS8250内部寄存器及其选择方式 6.1.2 波特率设置 6.1.3数据奇偶校验、停止数据格式设置 6.1.4 查询I/O方式相关设置 6.1.5 中断I/O通信方式相关设置 6.1.6 Modem寄存器 6.2 COMRXTX程序实例

27,372

社区成员

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

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