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

2019-07-14 16:12发布

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

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

不知道这是哪方面的问题,求助~
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
18条回答
cauzhxj
1楼-- · 2019-07-16 06:56
 精彩回答 2  元偷偷看……
cauzhxj
2楼-- · 2019-07-16 11:38
而且DMA的时钟在使能之后不能立即操作,要等个一会儿.不然DMA发送也不能正常工作.

越来越欢乐了.
cauzhxj
3楼-- · 2019-07-16 12:12
是我错怪051K8了.刚才串口接线RX端口掉下来了.线没接好自然无法使用.
cauzhxj
4楼-- · 2019-07-16 14:42
下面贴程序了.

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);
}
cauzhxj
5楼-- · 2019-07-16 16:04
还是有问题,在接收与发送之间来回转换几次,DMA会有几次中断不进去.
wenxueshu
6楼-- · 2019-07-16 19:25
 精彩回答 2  元偷偷看……

一周热门 更多>