STM32
直播中

辛太励

7年用户 1119经验值
擅长:20153
私信 关注
[问答]

STM32F103CBT6串口1是如何利用DMA发送接收数据的呢

STM32F103CBT6串口1是如何利用DMA发送接收数据的呢?其程序代码该怎样去实现呢?



回帖(1)

巩潇然

2021-12-13 10:14:14
STM32F103CBT6 串口1 DMA 发送接收



  • 采用CUBEMX配置生成,
  • 芯片型号采用的是:STM32F103CBT6,
  • 配置的是串口1PA9,PA10
  • 修改了串口打印函数,采用printf重定义,映射打印串口输出。
  • 开启串口中断条件判断




void USART1_IRQHandler(void)


void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
uint32_t tmp_flag = 0;
    uint32_t temp;
    tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
    if((tmp_flag != RESET))//idle标志被置位
    {
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
                        HAL_UART_DMAStop(&huart1); //进入空闲中断,表示数据接收完成,停止接收
      
        //                temp = huart1.Instance->SR;  //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
//       temp = huart1.Instance->DR; //读取数据寄存器中的数据
        //这两句和上面那句等效
                        temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数   
//        temp  = hdma_usart1_rx.Instance->CNDTR;// 获取DMA中未传输的数据个数,CNDTR寄存器分析见下面
      //这句和上面那句等效
                        rx_len =  sizeof(rx_buffer) - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
        recv_end_flag = 1;        // 接受完成标志位置1       
    }
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */


  /* USER CODE END USART1_IRQn 1 */
}


main.c中的while循环内容
while (1)
  {
    /* USER CODE END WHILE */


    /* USER CODE BEGIN 3 */
                DMA_Usart1_Read(rx_buffer,BUFFER_SIZE);
        //        HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//打开DMA接收,同上
//                HAL_UART_Transmit_DMA        (&huart1,rx_buffer,BUFFER_SIZE);//HAL库自带DMA发送函数
                       
                if(recv_end_flag == 1)  //接收完成标志
                {
                                printf("接收到的数据:");
                        int i;
                        for(i = 0;rx_buffer != '';i++){
                        printf("%c",rx_buffer);
                        }
                       
                                                rx_len = 0;//清除计数
                        recv_end_flag = 0;//清除接收结束标志位
                        memset(rx_buffer,0,sizeof(rx_buffer));//需要引入string.h
//memset()函数原型是memset(void *buffer, int c, int count)
//buffer:为指针或是数组,
//c:是赋给buffer的值,
//count:是buffer的长度.
                        //清空接收数组rx_buffer内的数据
                        //方便下一次接收数据的存放
  }
               
  }
举报

更多回帖

×
20
完善资料,
赚取积分