OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3250|回复: 2

F429VG 使用HAL库 串口2使用DMA方式通过485芯片通信只能单模式

[复制链接]

6

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2016-12-14
在线时间
37 小时
发表于 2020-8-29 13:06:16 | 显示全部楼层 |阅读模式
5金钱
F429VG 使用HAL库 串口2使用DMA方式通过485芯片通信只能收或者只能发用USB转TTL可以正常收发,找不到合适的地方来拉高或拉低485芯片的控制脚

串口2驱动函数
  1. void usart2_init(u32 bound)
  2. {       
  3.         //UART 初始化设置
  4.         UART2_Handler.Instance=USART2;                                            //USART1
  5.         UART2_Handler.Init.BaudRate=bound;                                    //波特率
  6.         UART2_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
  7.         UART2_Handler.Init.StopBits=UART_STOPBITS_1;            //一个停止位
  8.         UART2_Handler.Init.Parity=UART_PARITY_NONE;                    //无奇偶校验位
  9.         UART2_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
  10.         UART2_Handler.Init.Mode=UART_MODE_TX_RX;                    //收发模式
  11.         HAL_UART_Init(&UART2_Handler);                                            //HAL_UART_Init()会使能UART1
  12. /*不使用中断处理回调函数*/
  13. //        HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,
  14.                                                                              //并且设置接收缓冲以及接收缓冲接收最大数据量
  15. /*使用DMA不使能串口中断*/
  16. //  __HAL_UART_ENABLE_IT(&UART2_Handler,UART_IT_RXNE);    //使能串口2接收中断
  17.         __HAL_UART_ENABLE_IT(&UART2_Handler,UART_IT_IDLE);    //使能串口2空闲中断
  18.         HAL_UART_Receive_DMA(&UART2_Handler,usart2_rxbuf,USART2_REC_LEN);//防止接收到的第一帧数据为空,并且长度为默认长度
  19.        
  20.         usart2_en_init();      //使能脚初始化
  21. }
复制代码


串口2MSPinit
  1. if(huart->Instance==USART2)
  2.         {
  3.                 /* Peripheral clock enable */
  4.                 __HAL_RCC_GPIOD_CLK_ENABLE();                        //使能GPIOD时钟
  5.                 __HAL_RCC_USART2_CLK_ENABLE();                        //使能USART2时钟
  6.                 /**USART2 GPIO Configuration   
  7.     PD5     ------> USART2_TX
  8.     PD6     ------> USART2_RX
  9.     */
  10.                 GPIO_Initure.Pin=GPIO_PIN_5;                        //PD5
  11.                 GPIO_Initure.Mode=GPIO_MODE_AF_PP;                //复用推挽输出
  12.                 GPIO_Initure.Pull=GPIO_PULLUP;                        //上拉
  13.                 GPIO_Initure.Speed=GPIO_SPEED_FAST;                //高速
  14.                 GPIO_Initure.Alternate=GPIO_AF7_USART2;        //复用为USART1
  15.                 HAL_GPIO_Init(GPIOD,&GPIO_Initure);                   //初始化PD5
  16.                
  17.                 GPIO_Initure.Pin=GPIO_PIN_6;                        //PD6
  18.                 HAL_GPIO_Init(GPIOD,&GPIO_Initure);                   //初始化PD6
  19.                
  20.                 /* USART2 DMA Init */
  21.                 /* DMA controller clock enable */
  22.                 __HAL_RCC_DMA1_CLK_ENABLE();
  23.     /* USART2_TX Init */
  24.                 USART2TxDMA_Handler.Instance = DMA1_Stream6;                          //数据流选择
  25.     USART2TxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                     //通道选择
  26.     USART2TxDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;            //存储器到外设
  27.     USART2TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                //外设非增量模式
  28.     USART2TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                    //存储器增量模式
  29.     USART2TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;   //外设数据长度:8位
  30.     USART2TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;      //存储器数据长度:8位
  31.     USART2TxDMA_Handler.Init.Mode = DMA_NORMAL;                           //外设普通模式
  32.     USART2TxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;              //中等优先级
  33.     USART2TxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  34.                 USART2TxDMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;
  35.                 USART2TxDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                   //存储器突发单次传输
  36.                 USART2TxDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;                //外设突发单次传输
  37.                
  38.                 HAL_DMA_Init(&USART2TxDMA_Handler);
  39.                
  40.                 __HAL_LINKDMA(huart,hdmatx,USART2TxDMA_Handler);
  41.                
  42.                 /* USART2_RX Init */
  43.     USART2RxDMA_Handler.Instance = DMA1_Stream5;
  44.     USART2RxDMA_Handler.Init.Channel = DMA_CHANNEL_4;
  45.     USART2RxDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;
  46.     USART2RxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;
  47.     USART2RxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;
  48.     USART2RxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  49.     USART2RxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  50.     USART2RxDMA_Handler.Init.Mode = DMA_NORMAL;
  51.     USART2RxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;
  52.     USART2RxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  53.     HAL_DMA_Init(&USART2RxDMA_Handler);

  54.     __HAL_LINKDMA(huart,hdmarx,USART2RxDMA_Handler);
  55.                
  56.                 HAL_NVIC_EnableIRQ(USART2_IRQn);                                //使能USART2中断通道
  57.                 HAL_NVIC_SetPriority(USART2_IRQn,0,2);                        //抢占优先级0,子优先级2
  58.                 /* DMA interrupt init */
  59.                 /* DMA1_Stream5_IRQn interrupt configuration */
  60.                 HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 1, 2);
  61.                 HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
  62.                 /* DMA1_Stream6_IRQn interrupt configuration */
  63.                 HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 1, 3);
  64.                 HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
  65.         }
复制代码
接收中断内的数据处理函数
  1. void UsartReceive_IDLE(void)
  2. {
  3.         u32 temp;
  4.         if(__HAL_UART_GET_FLAG(&UART2_Handler,UART_FLAG_IDLE) != RESET)  //空闲中断
  5.         {
  6.   usart2_rev_flag = 1;     //标志位置1
  7.                 __HAL_UART_CLEAR_IDLEFLAG(&UART2_Handler);           //清空闲中断标志位
  8.                 HAL_UART_DMAStop(&UART2_Handler);                 //停止DMA
  9.                 temp = __HAL_DMA_GET_COUNTER(&USART2RxDMA_Handler);// 获取DMA中未传输的数据个数
  10.                 usart2_con = USART2_REC_LEN - temp;                //获取长度
  11.                 HAL_UART_Receive_DMA(&UART2_Handler,usart2_rxbuf,USART2_REC_LEN);//接收数据
  12.         }
  13. }
复制代码


3个中断函数
  1. /*串口2中断处理函数*/
  2. void USART2_IRQHandler(void)
  3. {
  4.        
  5. #if SYSTEM_SUPPORT_OS                 //使用OS
  6.         OSIntEnter();   
  7. #endif

  8.         UsartReceive_IDLE();
  9.         HAL_UART_IRQHandler(&UART2_Handler);
  10.        
  11. #if SYSTEM_SUPPORT_OS                 //使用OS
  12.         OSIntExit();                                                                                           
  13. #endif
  14. }
复制代码
  1. void DMA1_Stream6_IRQHandler(void)
  2. {
  3.         if(__HAL_DMA_GET_FLAG(&USART2TxDMA_Handler,DMA_IT_TC) != RESET )
  4.         {
  5.                 USART2_EN = 0;                                   //改为接收模式
  6.         }
  7.        
  8.         HAL_DMA_IRQHandler(&USART2TxDMA_Handler);
  9. //        USART2_EN = 0;                                   //改为接收模式
  10. }

  11. void DMA1_Stream5_IRQHandler(void)
  12. {
  13.        
  14.         HAL_DMA_IRQHandler(&USART2TxDMA_Handler);      //调试时该中断从未进入过
  15. }
复制代码
串口发送函数
  1. /*串口2发送函数*/
  2. void usart2_send(u8 *ch,u16 len)
  3. {

  4.         OS_CPU_SR cpu_sr;

  5.         OS_ENTER_CRITICAL();          //关中断
  6.        
  7.         HAL_UART_Transmit_DMA(&UART2_Handler,ch,len);   //串口DMA发送函数
  8.         USART2_EN = 1;                                  //发送模式
  9.         OS_EXIT_CRITICAL();  //开中断
  10. }
复制代码
麻烦有经验的看一下问题在哪里

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2016-12-14
在线时间
37 小时
 楼主| 发表于 2020-8-29 13:33:47 | 显示全部楼层
将DMA1数据流6中断函数改为如下485可以正常接收发送,但是发送完一个字节就转为接收模式
void DMA1_Stream6_IRQHandler(void)
{
        if(__HAL_DMA_GET_FLAG(&USART2TxDMA_Handler,DMA_FLAG_TCIF2_6) != RESET )
        {
                USART2_EN = 0;                                   //改为接收模式
        }
       
        HAL_DMA_IRQHandler(&USART2TxDMA_Handler);
//        USART2_EN = 0;                                   //改为接收模式
}
回复

使用道具 举报

6

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2016-12-14
在线时间
37 小时
 楼主| 发表于 2020-8-29 14:46:08 | 显示全部楼层
在发送函数最后地方打断点可以发完,全速跑就发不完。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-30 11:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表