搜索
bottom↓
回复: 26

有谁做过STM32串口通信使用7位数据位的?

[复制链接]

出1070入962汤圆

发表于 2009-12-2 14:20:28 | 显示全部楼层 |阅读模式
昨晚写代码时查手册,好像STM32只支持串口8位数据位和9位数据位,吐血......   想确认一下是否如此。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出1070入962汤圆

 楼主| 发表于 2009-12-2 15:52:17 | 显示全部楼层
自己顶一下

出0入0汤圆

发表于 2009-12-2 15:56:07 | 显示全部楼层
是啊
控制寄存器 1(USART_CR1) 位12  M: 字长
该位定义了数据字的长度,由软件对其置位和清零操作
0:一个起始位,8个数据位,n个停止位;
1:一个起始位,9个数据位,一个停止位。

出0入0汤圆

发表于 2009-12-2 16:05:20 | 显示全部楼层
8位字长,再设定一位校验位,就是7位了。

出1070入962汤圆

 楼主| 发表于 2009-12-2 17:09:31 | 显示全部楼层
答案应该是这个了:

(原文件名:1.JPG)

出0入0汤圆

发表于 2009-12-2 21:51:29 | 显示全部楼层
是哦

出0入0汤圆

发表于 2009-12-2 22:50:43 | 显示全部楼层
如果要发送7位数据,只需要设置为8位数据,在发送时把最高位始终置为'1'即可,接收方将把这个'1'当成1个停止位。

出1070入962汤圆

 楼主| 发表于 2009-12-2 23:17:46 | 显示全部楼层
现在问题应该解决了,具体还要测试,用户的三菱PLC是7位数据位的,有个校验位,正好是8位,这个也在STM32手册上找到了答案。我在做测试的时候发现,PC机可以发出5位,6位,7位的数据,前后就是开始位和停止位,当时我就晕菜了,后来仔细看PLC还有偶校验,再看手册上也确实这么说的,才松了一口气。

__STM32__ :你的办法不错,发送解决了,如果对方真的就是7位,接收数据就麻烦了,停止位就错过了。

出0入0汤圆

发表于 2009-12-4 21:52:16 | 显示全部楼层
__STM32__ :你的办法不错,发送解决了,如果对方真的就是7位,接收数据就麻烦了,停止位就错过了。

-------------------------------------第八位冒充停止位,真的停止位就当空闲了吧,好比发送间隔长一点,

出0入0汤圆

发表于 2010-1-25 15:43:18 | 显示全部楼层
Appcat 苹果猫  老师
怎么设置,我也需要7位 偶校验,1停止位  设置如下
  USART_InitStructure.USART_BaudRate            = 9600;
  USART_InitStructure.USART_WordLength          = USART_WordLength_8b;                   //7,1 ,EVEN
  USART_InitStructure.USART_StopBits            = USART_StopBits_1;
  USART_InitStructure.USART_Parity              = USART_Parity_Even ;//USART_Parity_EVEN
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;
设置后。单片机发送按数据位7位,但接受就出现了错误(按8位接受的),请帮下忙看看,

出0入0汤圆

发表于 2010-1-25 15:49:02 | 显示全部楼层
【7楼】 Appcat 苹果猫

如果对方真的就是7位,那么就让对方发送长一点(超过1位)的停止位就可以,比如使用1.5个停止位或2个停止位,而STM32这边会把一个停止位当成第8位数据,另外的0.5位或1个停止位识别为真正的停止位。

出0入0汤圆

发表于 2010-1-25 16:09:49 | 显示全部楼层
__STM32__  老师  能否帮我解决下,
串口1  7位 偶校验,1停止位

出0入0汤圆

发表于 2010-1-25 16:25:09 | 显示全部楼层
【11楼】 jiayushu

什么问题?什么错误?什么现象?

出1070入962汤圆

 楼主| 发表于 2010-1-28 19:20:54 | 显示全部楼层
串口1  7位 偶校验,1停止位,在串口接收到每个字节时做一下 & 0x7F,这样接收就OK了。

至于为什么,这个是不是头疼医头脚疼医脚的做法,还望权威人士来说说。

出0入0汤圆

发表于 2010-1-28 21:21:50 | 显示全部楼层
【11楼】 jiayushu
【13楼】 Appcat 苹果猫

请问你们是否是按照4楼贴出的部分, 配置为M=0、PCE=1?

这样的配置就是能够产生“串口1  7位 偶校验 1停止位”,并不需要“在串口接收到每个字节时做一下 & 0x7F”

出0入0汤圆

发表于 2010-1-28 21:25:06 | 显示全部楼层
其实说STM32的串口不支持7位数据,是指不支持“7位数据并且没有奇偶校验”的格式。

如果确实是需要“7位数据并且没有奇偶校验”的格式,则可以使用我在6、10楼介绍的方法。

出1070入962汤圆

 楼主| 发表于 2010-1-28 22:23:52 | 显示全部楼层
我使用的库是2.0.1版本的,自己的程序如下:
============================================
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_Even;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;       
USART_Init(USART1, &USART_InitStructure);
......
============================================

从stm32f10x_usart.h文件中摘录出来的定义:

/* USART Word Length ---------------------------------------------------------*/
#define USART_WordLength_8b                  ((u16)0x0000)
#define USART_WordLength_9b                  ((u16)0x1000)

/* USART Parity --------------------------------------------------------------*/
#define USART_Parity_No                      ((u16)0x0000)
#define USART_Parity_Even                    ((u16)0x0400)
#define USART_Parity_Odd                     ((u16)0x0600)
......
=================================================

从stm32f10x_usart.c里边的USART_Init函数中找出来的:
/*---------------------------- USART CR1 Configuration -----------------------*/
  tmpreg = USARTx->CR1;
  /* Clear M, PCE, PS, TE and RE bits */
  tmpreg &= CR1_CLEAR_Mask;

  /* Configure the USART Word Length, Parity and mode ----------------------- */
  /* Set the M bits according to USART_WordLength value */
  /* Set PCE and PS bits according to USART_Parity value */
  /* Set TE and RE bits according to USART_Mode value */
  tmpreg |= (u32)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity |
            USART_InitStruct->USART_Mode;

  /* Write to USART CR1 */
  USARTx->CR1 = (u16)tmpreg;
=======================================================================


下面是从数据手册里边摘出来的:

(原文件名:1.JPG)


(原文件名:2.JPG)

============================================
从上面这些,应该可以清楚的看出,我的程序已经将M设为0,PCS设为1,PS设为0,正是7位数据,偶校验,实际上的运行效果就是那个串口接收中断里边收到的字节最高位时不时的会变成1,具体啥规律没注意看过。

下面就是2.0.1库里边接收串口数据的函数。
/*******************************************************************************
* Function Name  : USART_ReceiveData
* Description    : Returns the most recent received data by the USARTx peripheral.
* Input          : - USARTx: Select the USART or the UART peripheral.
*                    This parameter can be one of the following values:
*                     - USART1, USART2, USART3, UART4 or UART5.
* Output         : None
* Return         : The received data.
*******************************************************************************/
u16 USART_ReceiveData(USART_TypeDef* USARTx)
{
  /* Check the parameters */
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  
  /* Receive Data */
  return (u16)(USARTx->DR & (u16)0x01FF);
}

上面全部的代码都来自于2.0.1的库。

所以,这个是不是要& 0x7F的问题我到现在还是无解呢。

出0入0汤圆

发表于 2010-1-28 22:36:46 | 显示全部楼层
哦, 原来你说的是这个意思!

“收到的字节最高位时不时的会变成1”,你看看这个最高位应该就是那个偶校验位。

如果是这样的话,你说的对:是要操作(data & 0x7F)

出1070入962汤圆

 楼主| 发表于 2010-1-28 22:46:19 | 显示全部楼层
哦, 原来你说的是这个意思!

“收到的字节最高位时不时的会变成1”,你看看这个最高位应该就是那个偶校验位。

如果是这样的话,你说的对:是要操作(data & 0x7F)
==========================================================
汗!看来windows的超级终端是不会理会那个校验位了,一律当作数据位处理了!一直是坚持用它的!虽然那么难用......

问题来了:用户手里的PLC必须要屏蔽这个最高位,否则也不正常,难道这里也是一个伪校验?

出0入0汤圆

发表于 2010-1-28 22:54:00 | 显示全部楼层
STM里字长可以设置为8位或9位的意思,就是含奇偶较验位的长度。如果没有较验位是8-9位数据长,有奇偶较验位就是7-8位数据长+1个奇偶位。
  当有奇偶位,并且长为8位时,奇偶位就在这8位数据里一起收到了。硬件不会为你清除。所以要自己对接收的数据进行data & 0x7F。不过发送时是怎样一种情况?没有试过。谁有空试试,这个奇偶位该不会也要软件设置吧?

出1070入962汤圆

 楼主| 发表于 2010-1-28 22:56:58 | 显示全部楼层
发送时不用管,硬件自动产生了校验位。

出1070入962汤圆

 楼主| 发表于 2010-1-30 10:43:16 | 显示全部楼层
唉!绕了半天,还是把自己绕进去了!晕死了......

windows的超级终端包括客户手里的三菱PLC都是没有问题的,能够发出带有校验信息的数据,也能够接收带有校验信息的数据,不需要我来做任何处理,而STM32在16楼那个配置下,收到的带有校验信息的字节后就直接甩给用户了,当然我没测试故意发出错误校验的数据,但无论如何,还是要用户去&0x7F的,这点17楼也说了。
类似的,我在avr M128上做了一下7位,偶校验的测试,不需要&0x7F,最高位一直为0.

出0入0汤圆

发表于 2012-1-8 16:50:19 | 显示全部楼层
STM32串口通信使用7位数据位的
        //USART1模块配置
        USART_InitStructure.USART_BaudRate = 9600;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        //USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_Parity = USART_Parity_Even;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

这样配置,再对接收的数据进行&0x7F,,最后得到的数据出现乱码

出0入0汤圆

发表于 2012-2-25 15:13:21 | 显示全部楼层
【21楼】 Appcat 苹果猫
【22楼】 kxx80802680
用的V2.03,测试:

USART_InitStructure.USART_BaudRate = BaudRate;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_Even ;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART1,&USART_InitStructure);

接收不需要&0x7f,最高位始终为0

出0入0汤圆

发表于 2012-2-25 15:55:49 | 显示全部楼层
学习了。

出0入0汤圆

发表于 2012-10-13 14:46:05 | 显示全部楼层
也碰到了这个问题2400,7b,1T,Even

出0入0汤圆

发表于 2015-6-7 20:13:28 | 显示全部楼层
Appcat 发表于 2010-1-30 10:43
唉!绕了半天,还是把自己绕进去了!晕死了......

windows的超级终端包括客户手里的三菱PLC都是没有问题的 ...

我试了下,我在电脑上收到的数据也是要用0X7F与才正常,这个问题您当时怎么解决的?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 23:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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