最近在做一个项目. 整个任务是1.5ms的大循环,其中分成6个250us的小任务. 有几个小任务里面用到了几个float运算. 然后1.5ms大循环循环了1s之后,由串口中断发送一次系统时间. 现在发现的问题是: 每次只要用 串口中断发送这一条信息,就必然导致 浮点运算的值出错,全部变成了 1.#QNAN. 出错后,由于没有错误检测,程序其他的部分仍然正常运行,浮点相关部分就都没用了. 改成用阻塞式发送的话,不会出现浮点出错的问题,但是阻塞式发送,需要耗时1.48ms.这样的话,系统的大循环时间就变成差不多两倍了. 不知道这是哪方面的问题,求助~ |
【STM32F0开发日志/评测/笔记】+互补PWM波的产生
STM32F030 PB14和PB15无法输出PWM求助
【STM32F030探索套件】序列之五 外部中断
【STM32F0开发日志---二】+ucosii.2.92移植在STM32F030
上传个STM32F0+5110+内部温度传感器的菜鸟实例
【STM32F030探索套件使用问题】STM32F030 SPI方式驱动ST7565LCD失败
求一份STM32F051 I2C驱动LCD 12864的例程
STM32F0 M0 向结构体赋值进入HardFault异常
STM32F0 ADC-DMA方式采集2路数据时出现问题
STM32F030C8T6,TIM16定时慢很多问题?
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);
}
在C下面不会出现由于串口导致的float崩溃问题.
但是在更加高端的F407上面,即使用C++也没有发现float崩溃.
DMA在C语言下面可能又不是一个好的选择.或许是自己用得还不习惯.
现在每10ms发送8个byte,接收还有float运算都能正常工作.
最开始,在DMA的TCIE中断里面清除发送标志,结果偶尔会进入不了中断.
后面改为USART的TCIE来判断发送是否完成,这样就可以正常的检测发送结束了.
然后,由于接收数据时中断导致float失效,float数据全为#QNAN.相关操作失效,感觉就像没有发送一样.
没有开优化.
中断内没有float变量.
串口中断发送,开启的是TXEIE中断,发送一个byte进入一次.
串口波特率设置的是115200.
大概100us进入一次中断.
之前没有浮点运算任务的时候不会出问题.
评分
查看全部评分
这么复杂,还要用DMA...
DMA不是会占用数据总线吗?
呵呵,频繁进中断,计算不受影响才怪了
哦,这样,一次发送十几个字节,确实也可以算得上是比较频繁了.
用DMA试试了..
DMA,貌似很复杂的..
修改成DMA之后,确实没有再出现#1.QNAN问题.
原本以为MCU会非常勤劳的切换,现在看,也有累趴下的时候。。