OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2687|回复: 10

串口利用超时处理接收不定长数据问题

[复制链接]

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
发表于 2018-5-30 14:53:46 | 显示全部楼层 |阅读模式
10金钱
在原子哥的串口蓝牙模块的实例中,采用了定时器超时来确认一帧数据接收完成,这里定时器的设置有个疑问。
[mw_shl_code=applescript,true]        RCC->APB1ENR|=1<<1;        //
        TIM3->ARR=arr;
        TIM3->PSC=psc;
        TIM3->DIER|=1<<0;   //
//        TIM3->CR1|=0x01;          //这里为什么必须先使能定时器
        TIM3->CR1&=~(0x01); //为什么不能直接就不打开定时器,在接收数据后再打开数据?
  MY_NVIC_Init(1,3,TIM3_IRQn,2);        [/mw_shl_code]
程序必须先使能一次定时器,才会正常利用超时处理一帧数据,如果初始化不先使能定时器,那么在接收第一个字节后就会超时。不知道什么原因引起的?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2018-5-30 14:54:33 | 显示全部楼层
TIM3->CR1&=~(0x01); //为什么不能直接就不打开定时器,在接收数据后再打开定时器?
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2018-5-30 14:56:38 | 显示全部楼层
或者说为什么必须先进一次中断,然后才能正常超时处理?
回复

使用道具 举报

117

主题

598

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
1702
金钱
1702
注册时间
2012-5-10
在线时间
439 小时
发表于 2018-5-30 17:02:30 | 显示全部楼层
本帖最后由 xsx127 于 2018-5-30 17:04 编辑

希望你能看明白吧

1,串口中断内容(包含接收中断,发送中断)
if(USART_GetITStatus(UART4 , USART_IT_TXE) == SET)
    {
        /* The interrupt was caused by the THR becoming empty.  Are there any
        more characters to transmit?
        Because FreeRTOS is not supposed to run with nested interrupts, put all OS
        calls in a critical section . */
        portENTER_CRITICAL();
            retstatus = xQueueReceiveFromISR( xTxQueue, &cChar, &xHigherPriorityTaskWoken );
        portEXIT_CRITICAL();

        if (retstatus == pdTRUE)
        {
            /* A character was retrieved from the queue so can be sent to the THR now. */
            USART_SendData(UART4, cChar);
        }
        else
        {
            /* Queue empty, nothing to send so turn off the Tx interrupt. */
            USART_ITConfig(UART4, USART_IT_TXE, DISABLE);
        }
    }

    if(USART_GetITStatus(UART4, USART_IT_RXNE) == SET)
    {
        /* The interrupt was caused by the receiver getting data. */
        cChar = USART_ReceiveData(UART4);

        /* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
        calls in a critical section . */
        portENTER_CRITICAL();
            xQueueSendFromISR(xRxQueue, &cChar, &xHigherPriorityTaskWoken);
        portEXIT_CRITICAL();
    }


2,一个任务的内容函数原型,任务内调用此函数即可

/***************************************************************************************************
*FunctionName:ReceiveDataFromQueue
*Description:从队列中读取有限长度的数据
*Input:queue -- 目标队列
*                mutex -- 此队列的互斥量,可为null
*                receivedstr -- 存放接收数据的地址
*                len -- 接收的数据长度(长度为此队列单元数据大小的个数,与数据接收数据的字节长度无关)
*                readSize -- 实际读取到的数据长度
*                itemsize -- 队列单元数据的大小
*                queueBlockTime -- 队列阻塞时间(超时,则中断接收,处理已经接收的数据)
*                mutexBlockTime -- 互斥量阻塞时间
*Output:None
*Author:xsx,565170595@qq.com
*Data:2016年4月22日15:35:40
***************************************************************************************************/
unsigned char ReceiveDataFromQueue(xQueueHandle queue, xSemaphoreHandle mutex, void *receivedstr , unsigned short len ,
        unsigned short * readSize, unsigned short itemsize, portTickType queueBlockTime, portTickType mutexBlockTime)
{
        unsigned short i=0;
        unsigned char *pdata = (unsigned char *)receivedstr;
        unsigned char statues = pdFAIL;
        
        if(queue == NULL)
                return pdFAIL;
        
        if(mutex != NULL)
        {
                if(pdFAIL == WaittingForMutex(mutex, mutexBlockTime))
                        return pdFAIL;
        }
        
        for(i=0; i<len; i++)
        {
                if(pdPASS == xQueueReceive(queue, pdata , queueBlockTime))
                        pdata += itemsize;
                        
                else
                        break;
        }
        
        if(i > 0)
                statues = pdPASS;
        
        if(readSize)
                *readSize = i;
        
        if(mutex != NULL)
                GivexMutex(mutex);
        
        return statues;
}
如有技术问题,微信扫头像交流,STM32,JAVA,服务器
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2018-5-30 18:49:14 | 显示全部楼层
xsx127 发表于 2018-5-30 17:02
希望你能看明白吧

1,串口中断内容(包含接收中断,发送中断)

不好意思,真没看懂,请问和定时器这里的设置有什么关系呢?
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2018-5-30 18:49:56 | 显示全部楼层
wangmingwei093 发表于 2018-5-30 18:49
不好意思,真没看懂,请问和定时器这里的设置有什么关系呢?

只能看出来是接收数据和数据处理0-0
回复

使用道具 举报

33

主题

215

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2035
金钱
2035
注册时间
2017-12-11
在线时间
454 小时
发表于 2018-5-30 19:10:28 | 显示全部楼层
似乎好像类似modbus协议中的机制。
回复

使用道具 举报

117

主题

598

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
1702
金钱
1702
注册时间
2012-5-10
在线时间
439 小时
发表于 2018-5-30 20:38:31 | 显示全部楼层
wangmingwei093 发表于 2018-5-30 18:49
不好意思,真没看懂,请问和定时器这里的设置有什么关系呢?

为什么需要定时器,用freertos的队列啊
如有技术问题,微信扫头像交流,STM32,JAVA,服务器
回复

使用道具 举报

117

主题

598

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
1702
金钱
1702
注册时间
2012-5-10
在线时间
439 小时
发表于 2018-5-30 20:39:07 | 显示全部楼层
bootblack 发表于 2018-5-30 19:10
似乎好像类似modbus协议中的机制。

接收数据发送到队列,在任务里面阻塞读取队列
如有技术问题,微信扫头像交流,STM32,JAVA,服务器
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2018-5-31 07:57:09 | 显示全部楼层
xsx127 发表于 2018-5-30 20:39
接收数据发送到队列,在任务里面阻塞读取队列

可是我没用操作系统呀。。。。
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2018-5-31 07:57:24 | 显示全部楼层
xsx127 发表于 2018-5-30 20:38
为什么需要定时器,用freertos的队列啊

我没用操作系统呀。。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-6 20:29

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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