研究了两天cube就发现一个问题,HAL库中UART的操作,有DMA和IT两种方式,发送数据时没有问题,接收数据时的函数 HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 和HAL_UART_Receive_IT(&UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE)中都必须提供接收个数这个参数,接收时谁能确定究竟是收多少个,这个参数没法提供,那这就没法用了,改他的HAL也不是好办法,这就决定了cube这个东西没法用了. 有碰到这个问题的吗,想用cube,但是诸如此类的问题解决不了就没法用啊 |
大家好,这是我在这个社区第一次发言,我开始也遇到这个问题,后来在百度和google都没有查到好的解决办法,我用的是串口中断,如果单纯按照大家说的去做代码会是这样的:
void test_task(void const * argument)
{
uint8_t abyte[1] ;
uc1_init();
uc1_sendbyte(0xAA);
for(;;)
{
while(HAL_OK != HAL_UART_Receive_IT(&huart1,abyte,1));
uc1_sendbyte(abyte[0]);
}
}
但是这样单纯用串口工具一次发送一个byte是没问题的,如果是发送多个Byte就有问题了,我看了一下
HAL_UART_Receive_IT的实现方式,采用了以下解决方法:
软件硬件环境:
STM32F030XXX
软件环境:
MDK5.0, STM32Cube,FreeRTOS
在串口部分需要添加串口的信号量,如下代码所示:
void uc1_init(void)
{
/*创建串口信号量*/
uc1sem_id = osSemaphoreCreate(0,1);
/*让串口信号量耗尽*/
while(osOK != osSemaphoreWait(uc1sem_id,0));
}
让串口信号量先耗尽的原因是好让串口接收任务第一次请求该信号量的时候就挂起任务
随后,在接收任务中代码是这样的:
void test_task(void const * argument)
{
uint8_t abyte[1] ;
uc1_init();
for(;;)
{
//请求打开接收中断,每次接收1个字节,该函数一般会立即返回
while(HAL_OK != HAL_UART_Receive_IT(&huart1,abyte,1));
//等待信号量被唤醒
while(osOK != osSemaphoreWait(uc1sem_id,0)); //打印本次接收到的数据
uc1_sendbyte(abyte[0]);
}
}
那么uc1sem_id一般在哪里唤醒呢,就是在HAL_UART_RxCpltCallback回调函数中,代码如下:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
if(UartHandle == &huart1)
{
osSemaphoreRelease(uc1sem_id);
}
}另外,sendbyte代码如下:
void uc1_sendbyte(uint8_t dat)
{
while(HAL_OK != HAL_UART_Transmit_IT(&huart1,&dat,1));
}
这样就可以一次发送多个连续byte了
写在这里给遇到有同样问题的朋友,希望能帮到大家
STM32Cube的资料比较少,但是设计的很合理,以后用的人也越来越多
有时候对我们国人追求真知的态度真是不敢恭维,一个论坛的问题的回复,大多数都是什么沙发,板凳之类的糟粕,让人有些失望,大家加油吧!
回复:stm32cube中的HAL库用UART时的问题
回复:stm32cube中的HAL库用UART时的问题
基于stm32cubef4带协议的串口通信在407运行成功
https://www.stmcu.org.cn/module/ ... &fromuid=130604
(出处: 意法半导体STM32/STM8技术社区)
感谢!正在头疼这个接收问题
很明显楼主是在不带操作系统的情况使用串口。
不好意思,我比较笨,没有明显看出来楼主是否带操作系统,其实带不带操作系统又有什么区别呢!
osSemaphoreCreate()函数没找到 不带操作系统是不是没用这个函数啊?
劳动节才开始认识stm32