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

【STM32F051K8U6】串口中断发送数据影响float运算.

[复制链接]
andrewz 提问时间:2016-9-26 17:36 /
最近在做一个项目.
整个任务是1.5ms的大循环,其中分成6个250us的小任务.
有几个小任务里面用到了几个float运算.
然后1.5ms大循环循环了1s之后,由串口中断发送一次系统时间.
现在发现的问题是:
每次只要用 串口中断发送这一条信息,就必然导致 浮点运算的值出错,全部变成了 1.#QNAN.
出错后,由于没有错误检测,程序其他的部分仍然正常运行,浮点相关部分就都没用了.

改成用阻塞式发送的话,不会出现浮点出错的问题,但是阻塞式发送,需要耗时1.48ms.这样的话,系统的大循环时间就变成差不多两倍了.

不知道这是哪方面的问题,求助~
收藏 1 评论41 发布时间:2016-9-26 17:36

举报

41个回答
andrewz 回答时间:2016-9-27 14:22:33
下面贴程序了.

unsigned char g_o_buf_0[UART1_O_BUF_SIZE];

void Uart::init_UART1(void){
    SET_BIT(RCC->APB2ENR,RCC_APB2ENR_USART1EN);
    SET_BIT(RCC->AHBENR,RCC_AHBENR_GPIOAEN);
    GPIOA->AFR[1]|=(1<<4)|(1<<8);
    GPIOA->PUPDR|=GPIO_PUPDR_PUPDR9_0|GPIO_PUPDR_PUPDR10_0;
    GPIOA->OSPEEDR|=GPIO_OSPEEDR_OSPEEDR9|GPIO_OSPEEDR_OSPEEDR10;
    GPIOA->MODER|=GPIO_MODER_MODER9_1|GPIO_MODER_MODER10_1;
    USART1->BRR=F_CPU/UART1_BAUDRATE;
    NVIC_EnableIRQ(USART1_IRQn);
    SET_BIT(USART1->CR1,USART_CR1_RE|USART_CR1_TE|USART_CR1_RXNEIE|USART_CR1_UE);
    Dma::config(DMA1_Channel2,(unsigned long)&USART1->TDR,(unsigned long)g_o_buf_0);
}


extern "C"{
    void DMA1_Channel2_3_IRQHandler(void){
        while(CHK_BIT(USART1->ISR,USART_ISR_TC));
        SET_BIT(DMA1->IFCR,DMA_IFCR_CGIF2);
        CLR_BIT(DMA1_Channel2->CCR,DMA_CCR_EN);
        CLR_BIT(USART1->CR3,USART_CR3_DMAT);
    }
}


void Dma::config(
    DMA_Channel_TypeDef *dma_chx,
    unsigned long periphera_address,
    unsigned long memory_address
){
        SET_BIT(RCC->AHBENR,RCC_AHBENR_DMAEN);
    Timer::delay_stuck(1000);
        dma_chx->CPAR=periphera_address;    //DMA1 ÍâÉèµØÖ·
        dma_chx->CMAR=memory_address;       //DMA1,´æ´¢Æ÷µØÖ·
        SET_REG(dma_chx->CCR,DMA_CCR_PL_0|DMA_CCR_MINC|DMA_CCR_DIR|DMA_CCR_TCIE);
    SET_BIT(DMA1->IFCR,DMA_IFCR_CGIF2);
    NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
}

void Dma::enable(DMA_Channel_TypeDef *dma_chx,unsigned short size){
        dma_chx->CNDTR=size;                //DMA1,´«ÊäÊý¾ÝÁ¿
    SET_REG(USART1->CR3,USART_CR3_DMAT);
    SET_BIT(dma_chx->CCR,DMA_CCR_EN);
}


andrewz 回答时间:2016-9-29 16:23:48
目前问题已经规避了.
在C下面不会出现由于串口导致的float崩溃问题.
但是在更加高端的F407上面,即使用C++也没有发现float崩溃.

DMA在C语言下面可能又不是一个好的选择.或许是自己用得还不习惯.
现在每10ms发送8个byte,接收还有float运算都能正常工作.

andrewz 回答时间:2016-9-28 10:17:59
是这样的,
最开始,在DMA的TCIE中断里面清除发送标志,结果偶尔会进入不了中断.
后面改为USART的TCIE来判断发送是否完成,这样就可以正常的检测发送结束了.

然后,由于接收数据时中断导致float失效,float数据全为#QNAN.相关操作失效,感觉就像没有发送一样.
高二毛 回答时间:2016-9-26 17:38:27
优化级别?是否在中断中使用FLOAT变量?如果使用,注意变量定义加上volaitile 修饰符
andrewz 回答时间:2016-9-26 17:39:25
高二毛 发表于 2016-9-26 17:38
优化级别?是否在中断中使用FLOAT变量?如果使用,注意变量定义加上volaitile 修饰符
...

没有开优化.
中断内没有float变量.
andrewz 回答时间:2016-9-26 17:58:34
把问题描述更清楚点,系统时钟是1s的timer15中断做的.
串口中断发送,开启的是TXEIE中断,发送一个byte进入一次.
埃斯提爱慕 回答时间:2016-9-26 19:01:47
提示: 作者被禁止或删除 内容自动屏蔽
车厘子 回答时间:2016-9-27 08:34:02
关注一下这个问题
zhangdaijin 回答时间:2016-9-27 08:44:52
andrewz 回答时间:2016-9-27 08:53:46
dsjsjf 发表于 2016-9-26 19:01
是不是重入问题

串口波特率设置的是115200.
大概100us进入一次中断.
之前没有浮点运算任务的时候不会出问题.
风子 回答时间:2016-9-27 09:08:27
用DMA发送吧

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

andrewz 回答时间:2016-9-27 09:17:06


这么复杂,还要用DMA...
DMA不是会占用数据总线吗?
风子 回答时间:2016-9-27 09:21:10
andrewz 发表于 2016-9-27 09:17
这么复杂,还要用DMA...
DMA不是会占用数据总线吗?

呵呵,频繁进中断,计算不受影响才怪了
andrewz 回答时间:2016-9-27 09:24:14
风子 发表于 2016-9-27 09:21
呵呵,频繁进中断,计算不受影响才怪了

哦,这样,一次发送十几个字节,确实也可以算得上是比较频繁了.
用DMA试试了..
DMA,貌似很复杂的..
高二毛 回答时间:2016-9-27 10:19:25
贴个代码,大家看看吧。都分析学习一下。
andrewz 回答时间:2016-9-27 11:57:14
风子 发表于 2016-9-27 09:21
呵呵,频繁进中断,计算不受影响才怪了

修改成DMA之后,确实没有再出现#1.QNAN问题.
原本以为MCU会非常勤劳的切换,现在看,也有累趴下的时候。。
andrewz 回答时间:2016-9-27 13:52:04
坑又来了,开了DMA之后,发数据正常了,之前的用USART_CR1_RXNEIE的接收数据中断没响应了.
123下一页

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版