ST意法半导体
直播中

南中南

8年用户 985经验值
擅长:光电显示
私信 关注
[问答]

STM32F103C8如何使用DMA和IDLE通过USART1接收数据?

大家好,我使用STM32F103C8并尝试使用DMA和IDLE通过USART1接收数据。当我收到 1 个字符并发生 IDLE 时,就会生成 USART1 中断并像这样调用“USART1_IRQHandler”函数。
  • void USART1_IRQHandler(void)
  • {
  •         count = count + 1;
  • }
但计数不增加 1。它的值增加很大。
主程序
  • int count=0;
  • int main()
  • {
  •         system_clock_config();
  •         uart1_rx_Init();
  •         NVIC_EnableIRQ(USART1_IRQn);
  •         DMA1_channel5_init((uint32_t) RES_CMD, (uint32_t) &USART1->DR, 4);
  •         while(1)
  •         {
  •         }
  • }
uart1_rx_Init
  • void uart1_rx_Init(void)
  • {
  •         /*Enable IO Port A*/
  •         RCC->APB2ENR        |=        (1U<<2);
  •         /*Enable UART1*/
  •         RCC->APB2ENR |=         (1U<<14);
  •         /*Set Port A Pin10 As Input Pull-up Pull-down*/
  •         GPIOA->CRH                |=        (1U<<10);
  •         /*Set Buad Rate 9600*/
  •         USART1->BRR                |=        0x1D4C;
  •         /*Enable IDLE Line*/
  •         USART1->CR1        |=        (1U<<4);
  •         /*Enable Receiver*/
  •         USART1->CR1                |=        (1U<<2);
  •         /*Enable UART*/
  •         USART1->CR1                |=        (1U<<13);
  • }
DMA1_channel5_init
  • void DMA1_channel5_init(uint32_t src, uint32_t dst, uint32_t len)
  • {
  •         /*Enable Clock Access To DMA*/
  •         RCC->AHBENR                |=        (1U<<0);
  •         /*Disable DMA1 Channel5*/
  •         DMA1_Channel5->CCR        &= ~(1U<<0);
  •         /*Wait For DMA1 Channel5 is Disable*/
  •         while(DMA1_Channel5->CCR & (1U<<0)){}
  •         /*Clear All Interrupt Flags of Channel5*/
  •         DMA1->IFCR        |=        (1U<<16);
  •         DMA1->IFCR        |=        (1U<<17);
  •         DMA1->IFCR        |=        (1U<<18);
  •         DMA1->IFCR        |=        (1U<<19);
  •         /*Set the Destination Buffer*/
  •         DMA1_Channel5->CPAR                =        dst;
  •         /*Set the Source Buffer*/
  •         DMA1_Channel5->CMAR                =        src;
  •         /*Set Length*/
  •         DMA1_Channel5->CNDTR        =        len;
  •         /*Enable Memory Increment*/
  •         DMA1_Channel5->CCR        |=        (1U<<7);
  •         /*Enable Circular Mode*/
  •         DMA1_Channel5->CCR        &=        ~(1U<<5);
  •         /*Configure Transfer Direction*/
  •         DMA1_Channel5->CCR        &=        ~(1U<<4);
  •         /*Enable DMA Transfer Complete Interrupt*/
  •         //DMA1_Channel5->CCR        |=        (1U<<1);
  •         /*Enable DMA1 Channel5*/
  •         DMA1_Channel5->CCR        |=        (1U<<0);
  •         /*Enable UART1 Transmitter DMA*/
  •         USART1->CR3        |=        (1U<<6);
  • }







回帖(1)

赵羽

2022-12-9 14:34:06
外设 IRQ 处理程序通常会首先通过检查外设寄存器中的对应位来分析调用它的确切原因,最后在离开处理程序之前清除位/标志/中断条件。如果你没有清除正确的位,处理程序将被一次又一次地调用......
举报

更多回帖

发帖
×
20
完善资料,
赚取积分