你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

串口输入几个细节问题请求帮助下。

[复制链接]
lvfeng123 提问时间:2019-5-3 08:02 /
第一次接触嵌入式,看了几天代码,还是稀里糊涂的,不甚清晰。请大神多指教。

我的需求: 从串口接收固定长度的字符字节。  不是该长度的放弃掉不管。符合长度的处理。下面是我的代码:
//芯片是L496
#include "main.h"
#include <stdint.h>
#define DLen 8 //用长度8测试

//定义了几个函数,写安卓,java,erlang多了,所以大括号习惯请多包涵。
void Start_Recieve(UART_HandleTypeDef *luart);
void ready_next(UART_HandleTypeDef *luart);
HAL_StatusTypeDef Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

int main(void){
        UART_HandleTypeDef Lpuart1; //虚拟串口LPUSART1

//一些初始化
  HAL_Init();
  SystemClock_Config();
  LPUART1_Init(&Lpuart1);
  LED_Init();
        if(HAL_UART_Init(&Lpuart1) == HAL_OK){
                HAL_UART_Transmit(&Lpuart1,(uint8_t *)&"\r\nInit ok!\r\n",12,0xffff);       
                while(1) Start_Recieve(&Lpuart1); //开始接收数据 (问题1????)
        }
}

void Start_Recieve(UART_HandleTypeDef *luart){
        uint8_t res[DLen];
        while(HAL_UART_GetState(luart) == HAL_UART_STATE_BUSY_RX){};
  if(Receive(luart,res,DLen,2000U) == HAL_OK) //2秒超时,不符合长度的就按照超时不管了。
                HAL_UART_Transmit(luart,res,DLen,0xFFFF);  //接收到数据的处理函数,就先输出到终端测试了。
        ready_next(luart);   //处理完,继续等待接收数据
}

//这是接收函数, 从示例代码里面模仿写的。8bit数据, 无校验,1停止
HAL_StatusTypeDef Receive(UART_HandleTypeDef *luart, uint8_t *pData, uint16_t Size, uint32_t Timeout){
  uint16_t uhMask;
  uint32_t tickstart;

  if (huart->RxState == HAL_UART_STATE_READY){
    if ((pData == NULL) || (Size == 0U))
      return  HAL_ERROR;

    __HAL_LOCK(huart);

    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->RxState = HAL_UART_STATE_BUSY_RX;
    tickstart = HAL_GetTick();
    luart->RxXferSize  = Size;
    luart->RxXferCount = Size;
    UART_MASK_COMPUTATION(huart);
    uhMask = luart->Mask;
               
    while (luart->RxXferCount > 0U){
      if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
        return HAL_TIMEOUT;
      *pData = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
      pData++;
      luart->RxXferCount--;
    }
               
    __HAL_UNLOCK(huart);

    return HAL_OK;
  }else
    return HAL_BUSY;
}

//重新把系统置为等待接收数据状态
void ready_next(UART_HandleTypeDef *luart){
        HAL_UART_IRQHandler(luart);
        __HAL_UART_ENABLE_IT(luart, UART_IT_RXNE);
        luart->RxState = HAL_UART_STATE_READY;
}



上面跑起来没有问题, 测试也正常。有几个疑问解不开:

1. while这样一直搞, 不耗电吗? 有什么好办法,比如唤醒怎么用?

2. 我设置波特率不生效, 现在设置的是115200  换成9600就不行了。 要怎么更换呢?
我这样更换不行, huart->Init.BaudRate       = 9600U;
3.超长的数据没有找到啥好办法控制。
收藏 评论3 发布时间:2019-5-3 08:02

举报

3个回答
xiaolingoei 回答时间:2019-5-3 09:21:17
1、while(1){}这里面的程序是需要重复执行的。唤醒你可以参考一下RTC、STM32休眠与唤醒
2、在上面没有看到你设置波特率的代码,拿我自己的举个例子(HAL库和标准库差不多)
  1.         //UART 初始化设置
  2.         UART1_Handler.Instance=USART1;                                            //USART1
  3.         UART1_Handler.Init.BaudRate=ui32Bound;                                //波特率
  4.         UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
  5.         UART1_Handler.Init.StopBits=UART_STOPBITS_1;            //一个停止位
  6.         UART1_Handler.Init.Parity=UART_PARITY_NONE;                    //无奇偶校验位
  7.         UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
  8.         UART1_Handler.Init.Mode=UART_MODE_TX_RX;                    //收发模式
  9.         HAL_UART_Init(&UART1_Handler);                                            //HAL_UART_Init()会使能UART1
复制代码
要更改波特率,更改UART1_Handler.Init.BaudRate=ui32Bound,中的ui32Bound即可。你写的9600U是不对的,就是9600。
3、用串口传输超长的数据,如果你要提速,尤其是对上位机通信,用串口显然是不合适的,建议换usb2.0。
如果是要保证准确率,由于串口一次一般发8bit,如果你的数据是16bit,那么就要对数据进行分割。你可以在每次发送最后设置校验位,对每次发送是否OK,进行校验。
以及,硬件上串口千万不要接线接太长,串口的RX\TX最多接30cm的线,否者误码率会提高不少。

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

lvfeng123 回答时间:2019-5-3 14:37:41
xiaolingoei 发表于 2019-5-3 09:21
1、while(1){}这里面的程序是需要重复执行的。唤醒你可以参考一下RTC、STM32休眠与唤醒
2、在上面没有看 ...

多谢解答。
void LPUART1_Init(UART_HandleTypeDef *huart){
  huart->Instance            = LPUART1;
  huart->Init.BaudRate       = 115200U;
  huart->Init.WordLength     = UART_WORDLENGTH_8B;
  huart->Init.StopBits       = UART_STOPBITS_1;
  huart->Init.Parity         = UART_PARITY_NONE;
  huart->Init.HwFlowCtl      = UART_HWCONTROL_NONE;
  huart->Init.Mode           = UART_MODE_TX_RX;
  huart->Init.OverSampling   = UART_OVERSAMPLING_16;
  huart->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  
        GPIO_InitTypeDef          GPIO_InitStruct;
  
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_LPUART1_CLK_ENABLE();
//__HAL_UART_ENABLE_IT(huart,UART_IT_RXNE);
  GPIO_InitStruct.Pin       = GPIO_PIN_7 | GPIO_PIN_8;
  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull      = GPIO_PULLUP;
  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1;
  
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);  
}
这是我的初始化配置, 115200就可以, 我修改成9600就不行了,收不到数据。不知道为什么。

超长数据,我的意思是: 如果我就指定接收200字节长的数据。 超过这个长度的我不收, 有办法控制吗?
xiaolingoei 回答时间:2019-5-4 09:13:02
你代码里面可能是有宏定义?且先撇开LPUART1、115200U这些定义不谈,在配置了UART之后,没有对它进行使能。
你按照这个和你的程序配置比对一下,算是HAL库的标准设置:
  1. void MX_USART1_UART_Init(void)
  2. {
  3.    huart1.Instance = USART1;
  4.    huart1.Init.BaudRate = 115200;
  5.    huart1.Init.WordLength = UART_WORDLENGTH_8B;
  6.    huart1.Init.StopBits = UART_STOPBITS_1;
  7.    huart1.Init.Parity = UART_PARITY_NONE;
  8.    huart1.Init.Mode = UART_MODE_TX_RX;
  9.    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  10.    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  11.    huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
  12.    huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  13.    HAL_HalfDuplex_Init(&huart1);
  14. }
复制代码
这里的接收,是用上位机软件接收还是同样的芯片USART接收?两者通信的波特率一定要匹配,9600就都要设置成9600。
超长数据的处理,我给个思路:你可以__HAL_UART_ENABLE_IT(huart,UART_IT_RXNE); ,在接收中断里面做个计数,接收200次之后关闭USART的接收功能。(PS:不只一种方法)



评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版