第一次接触嵌入式,看了几天代码,还是稀里糊涂的,不甚清晰。请大神多指教。 我的需求: 从串口接收固定长度的字符字节。 不是该长度的放弃掉不管。符合长度的处理。下面是我的代码: //芯片是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.超长的数据没有找到啥好办法控制。 |
2、在上面没有看到你设置波特率的代码,拿我自己的举个例子(HAL库和标准库差不多)
3、用串口传输超长的数据,如果你要提速,尤其是对上位机通信,用串口显然是不合适的,建议换usb2.0。
如果是要保证准确率,由于串口一次一般发8bit,如果你的数据是16bit,那么就要对数据进行分割。你可以在每次发送最后设置校验位,对每次发送是否OK,进行校验。
以及,硬件上串口千万不要接线接太长,串口的RX\TX最多接30cm的线,否者误码率会提高不少。
评分
查看全部评分
多谢解答。
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字节长的数据。 超过这个长度的我不收, 有办法控制吗?
你按照这个和你的程序配置比对一下,算是HAL库的标准设置:
这里的接收,是用上位机软件接收还是同样的芯片USART接收?两者通信的波特率一定要匹配,9600就都要设置成9600。
超长数据的处理,我给个思路:你可以__HAL_UART_ENABLE_IT(huart,UART_IT_RXNE); ,在接收中断里面做个计数,接收200次之后关闭USART的接收功能。(PS:不只一种方法)
评分
查看全部评分