一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 2257|回复: 10
收起左侧

[51单片机] stc15校验位的一个问题

[复制链接]
发表于 2020-6-18 14:57 | 显示全部楼层 |阅读模式
本帖最后由 gongzhu 于 2020-6-18 15:29 编辑

调stc15串口,从stc-isp工具中复制了范例改下调试出现关于校验位的一个问题。
范例编译调试都是正常的,其校验位是固定的,使用宏定义 :

  1. #define NONE_PARITY     0       //无校验
  2. #define ODD_PARITY      1       //奇校验
  3. #define EVEN_PARITY     2       //偶校验
  4. #define MARK_PARITY     3       //标记校验
  5. #define SPACE_PARITY    4       //空白校验

  6. #define PARITYBIT NONE_PARITY   //定义校验位
复制代码

为了使其在运行中可变校验位,就将PARITYBIT 改成了全局变量:
  1. BYTE PARITYBIT=NONE_PARITY;//先默认无校验测试
复制代码


初始化也做了相应修改:
  1. /*
  2. #if (PARITYBIT == NONE_PARITY)
  3.     SCON = 0x50;                //8位可变波特率
  4. #elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
  5.     SCON = 0xda;                //9位可变波特率,校验位初始为1
  6. #elif (PARITYBIT == SPACE_PARITY)
  7.     SCON = 0xd2;                //9位可变波特率,校验位初始为0
  8. #endif

  9. */

  10. //改为如下:

  11.     switch(PARITYBIT)
  12.     {
  13.     case NONE_PARITY:
  14.         SCON = 0x50;
  15.         break;//8位可变波特率

  16.     case ODD_PARITY:
  17.     case EVEN_PARITY:
  18.     case MARK_PARITY:
  19.         SCON = 0xda;
  20.         break;     //9位可变波特率,校验位初始为1

  21.     case SPACE_PARITY:
  22.         SCON = 0xd2;
  23.         break; //9位可变波特率,校验位初始为0

  24.     default:
  25.         break;
  26.     }
复制代码
发送程序也改为如下:
  1. void SendData(BYTE dat)
  2. {
  3.     while (busy);               //等待前面的数据发送完成
  4.     ACC = dat;                  //获取校验位P (PSW.0)
  5.     if (P)                      //根据P来设置校验位
  6.     {
  7.         /*
  8. #if (PARITYBIT == ODD_PARITY)
  9.         TB8 = 0;                //设置校验位为0
  10. #elif (PARITYBIT == EVEN_PARITY)
  11.         TB8 = 1;                //设置校验位为1
  12. #endif*/
  13.           if(PARITYBIT == ODD_PARITY)
  14.         TB8 = 0;                //设置校验位为0
  15.       else if(PARITYBIT == EVEN_PARITY)
  16.         TB8 = 1;                //设置校验位为1
  17.     }

  18.     else
  19.     { /*
  20. #if (PARITYBIT == ODD_PARITY)
  21.         TB8 = 1;                //设置校验位为1
  22. #elif (PARITYBIT == EVEN_PARITY)
  23.         TB8 = 0;                //设置校验位为0
  24. #endif */
  25.           if(PARITYBIT == ODD_PARITY)
  26.         TB8 = 1;                //设置校验位为1
  27.       else if(PARITYBIT == EVEN_PARITY)
  28.         TB8 = 0;            //设置校验位为0
  29.     }
  30.     busy = 1;
  31.     SBUF = ACC;                 //写数据到UART数据寄存器
  32. }
复制代码
修改前,程序循环发送字符串:“STC15F2K60S2  Uart Test !”,串口接收显示正常。
修改后,串口接收的数据变成了全部0x00,“\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0”
如将SendData中 if(P)注释掉即不设置校验位,发送即为正常:“STC15F2K60S2  Uart Test !”
2020-06-18_152200.png

源程序发上来,哪位帮忙指点一下SendData中关于校验位设置该如何修改



stc串口

stc串口
发表于 2020-6-18 16:39 | 显示全部楼层
大概可能也行,上位机也要设置校验位吧
发表于 2020-6-18 18:50 | 显示全部楼层
sscom设置校验位

点评

先默认无校验  详情 回复 发表于 2020-6-18 20:34
 楼主| 发表于 2020-6-18 20:34 | 显示全部楼层

先默认无校验
发表于 2020-6-18 22:58 | 显示全部楼层
发送有校验,接收端当然也得有校验,否则相反,要不然位都对不上了,乱七八糟的。
 楼主| 发表于 2020-6-19 08:44 | 显示全部楼层
本帖最后由 gongzhu 于 2020-6-19 08:55 编辑

是我没表达清楚吧,把大家都误解了。我的意思是说把PARITYBIT由宏定义改为全局变量后,仍然还是无校验,导致发送的数据全部变成了0x00。不是说变成奇偶校验后变成的0x00。
都是以上贴出的代码发送出来的数据是0x00
 楼主| 发表于 2020-6-19 09:06 | 显示全部楼层
现在查到的问题如下:
PARITYBIT仍然是无校验NONE_PARITY。
SendData修改为:
  1. void SendData(BYTE dat)
  2. {
  3.     while (busy);               //等待前面的数据发送完成
  4.     ACC = dat;                  //获取校验位P (PSW.0)
  5.   if (P)                      //根据P来设置校验位
  6. {
  7.     if(PARITYBIT == ODD_PARITY)
  8.         TB8 = 0;                //设置校验位为0
  9.   else if(PARITYBIT == EVEN_PARITY)
  10.         TB8 = 1;                //设置校验位为1
  11. }
  12. else
  13.   {
  14.     if(PARITYBIT == ODD_PARITY)
  15.        TB8 = 1;                //设置校验位为1
  16.    else if(PARITYBIT == EVEN_PARITY)
  17.       TB8 = 0;            //设置校验位为0
  18.   }
  19.     busy = 1;
  20.     SBUF = ACC;                 //写数据到UART数据寄存器
  21. }
复制代码
则发送出来的数据用串口工具(无校验)接收显示都是0x00。

如果把SendData中if (P) 部分删除即不要校验位判断则发送正常:
  1. void SendData(BYTE dat)
  2. {
  3.    while (busy);               //等待前面的数据发送完成
  4.   ACC = dat;                  //获取校验位P (PSW.0)
  5.   busy = 1;
  6.    SBUF = ACC;                 //写数据到UART数据寄存器
  7. }
复制代码
我是从C语音角度来看看这个问题,如果PARITYBIT 是无校验,个人觉得以上两段代码是等效的,应该都正常。
发表于 2020-6-19 10:18 | 显示全部楼层
本帖最后由 HFMBFUVR 于 2020-6-19 10:23 编辑

可能是你没改全吧,你看宏定义还有别的代码的。 TB8 要在9位模式下使用用, 所以需要在每次修改 PARITYBIT 变量后都要 重新设置 SCON 里的 里的 SM0 和 SM1, 如果使用校验就工作在 9 位模式, 不校验就工作在8位模式
截图202006191014226857..png

点评

多谢! 初始化这部分我改了,问题是仍然用无校验测试发送都不正常:  详情 回复 发表于 2020-6-19 10:31
 楼主| 发表于 2020-6-19 10:31 | 显示全部楼层
HFMBFUVR 发表于 2020-6-19 10:18
可能是你没改全吧,你看宏定义还有别的代码的。 TB8 要在9位模式下使用用, 所以需要在每次修改 PARITYBIT  ...

多谢!
初始化这部分我改了,问题是仍然用无校验测试发送都不正常:
  1.     switch(PARITYBIT)
  2.     {
  3.     case NONE_PARITY:
  4.         SCON = 0x50;
  5.         break;//8位可变波特率

  6.     case ODD_PARITY:
  7.     case EVEN_PARITY:
  8.     case MARK_PARITY:
  9.         SCON = 0xda;
  10.         break;     //9位可变波特率,校验位初始为1

  11.     case SPACE_PARITY:
  12.         SCON = 0xd2;
  13.         break; //9位可变波特率,校验位初始为0

  14.     default:
  15.         break;
  16.     }
复制代码

点评

先别传递来传递去的,用个常量填上试一试。  详情 回复 发表于 2020-6-19 18:23
发表于 2020-6-19 18:23 | 显示全部楼层
本帖最后由 8055 于 2020-6-19 18:32 编辑
gongzhu 发表于 2020-6-19 10:31
多谢!
初始化这部分我改了,问题是仍然用无校验测试发送都不正常:

在类型犯糊涂的时候,先别传递来传递去的,随便用个常量填上试一试。

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-4-26 11:42 , Processed in 0.078734 second(s), 52 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表