找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 207|回复: 0
打印 上一主题 下一主题
收起左侧

GD32F470系列Rs-485驱动程序

[复制链接]
跳转到指定楼层
楼主
ID:1075158 发表于 2024-2-27 13:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. /*
  2. 主程序如下
  3. main.c
  4. 使用中断+DMA数据搬运实现驱动RS-458
  5. */
  6. #include "gd32f4xx.h"
  7. #include "systick.h"

  8. #define USART1_DATA_ADDRESS      ((uint32_t)&USART_DATA(USART1))
  9. #define RS485BufferSize 256
  10. uint8_t RS485RxBuffer[RS485BufferSize]={0};         //485数据接收缓冲区
  11. uint8_t RS485RxP = 0;                                          //485接收缓冲区接收位置指示
  12. uint8_t RS485RxPre = 0;                                       //485帧头指示
  13. uint8_t RS485TxBuffer[RS485BufferSize]={0};                                                                                                        //485数据发送缓冲区
  14. uint8_t RS485TxP = 0;                                                                                                                                                                                                //485发送缓冲区发送位置指示
  15. uint8_t RS485RxFrameBuffer[RS485BufferSize];                                                                                                //485接收帧缓冲
  16. uint8_t RS485RxCount = 0;                                                                                                                                                                                //485接收计数
  17. uint8_t RS485RxFlag = 0;                                                                                                                                                                                //RS485帧接收完成标志,逻辑1有效



  18. /*485OE使用PE15引脚,高电平发送,低电平接收*/
  19. void Drv_485OE_Init(void)
  20. {
  21.           /* 打开GPIOE时钟 */
  22.     rcu_periph_clock_enable(RCU_GPIOE);
  23.     /* 配置PE15口为推挽输出,无上下拉 */
  24.     gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_15);
  25.     gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
  26.     /* 默认485处于接受模式 */
  27.     Drv_485_RxEn();
  28. }


  29. //        485 RX_EN
  30. void Drv_485_RxEn(void)
  31. {
  32.                 gpio_bit_reset(GPIOE, GPIO_PIN_15);
  33. }


  34. //        485 TX_EN
  35. void Drv_485_TxEn(void)
  36. {
  37.                 gpio_bit_set(GPIOE, GPIO_PIN_15);
  38. }


  39. //Rs_485初始化
  40. void Drv_Rs_485_Init(void)
  41. {

  42.                 dma_single_data_parameter_struct dma_init_struct;
  43.     /* enable GPIO clock */
  44.     rcu_periph_clock_enable(RCU_GPIOB);
  45.     /* enable UART clock */
  46.     rcu_periph_clock_enable(RCU_USART2);

  47.     /* configure the USART2 TX pin and USART2 RX pin */
  48.     gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_10);            //Tx
  49.     gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_11);                        //Rx

  50.     /* configure USART2 TX as alternate function push-pull */
  51.     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
  52.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);

  53.     /* configure USART2 RX as alternate function push-pull */
  54.     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_11);
  55.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);

  56.     /* USART configure */
  57.     usart_deinit(USART2);                                                                                                                                                                //取消初始化USART2
  58.     usart_baudrate_set(USART2, 38400U);                                                                                                  //波特率38400U
  59.     usart_receive_config(USART2, USART_RECEIVE_ENABLE);
  60.     usart_transmit_config(USART2, USART_TRANSMIT_ENABLE);
  61.     usart_enable(USART2);
  62.                
  63.                 usart_interrupt_flag_clear(USART2, USART_INT_FLAG_ERR_ORERR);
  64.                 usart_interrupt_enable(USART2, USART_INT_ERR);
  65.                
  66.                 /* USART interrupt configuration */
  67.     nvic_irq_enable(USART2_IRQn, 2, 0);                                                                                                                                                                        //优先级为2

  68.                
  69.                 /* deinitialize DMA0 channel2 (USART0 RX) */
  70.                 rcu_periph_clock_enable(RCU_DMA0);
  71.     dma_deinit(DMA0, DMA_CH1);
  72.     dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
  73.     dma_init_struct.memory0_addr = (uint32_t)RS485RxBuffer;
  74.     dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  75.     dma_init_struct.number = sizeof(RS485RxBuffer);
  76.     dma_init_struct.periph_addr = (uint32_t)&USART_DATA(USART2);
  77.     dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  78.     dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
  79.     dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  80.     dma_single_data_mode_init(DMA0, DMA_CH1, &dma_init_struct);

  81.     /* configure DMA mode */
  82.     dma_circulation_enable(DMA0, DMA_CH1);                                                                                                                                                        //启用DMA循环模式
  83.     dma_channel_subperipheral_select(DMA0, DMA_CH1, DMA_SUBPERI4);

  84.                 /* enable DMA0 channel5 */
  85.     dma_channel_enable(DMA0, DMA_CH1);
  86.                 usart_dma_receive_config(USART2, USART_RECEIVE_DMA_ENABLE);
  87.                 usart_interrupt_enable(USART2,USART_INT_IDLE);                                                                                                            //IDLE线检测中断
  88.                
  89.                 /*485 OE引脚初始化*/
  90.                 Drv_485OE_Init();


  91. }

  92. /*
  93. void Drv_rs485_Tx(uint8_t *buffer,uint16_t Longth):485发送数据函数
  94. buffer:数据缓冲区
  95. Longth:发送数据长度,单位:字节
  96. */
  97. void Drv_rs485_Tx(uint8_t *buffer,uint16_t Longth)
  98. {
  99.         uint16_t i = 0;
  100.         Drv_485_TxEn();
  101.         for(i=0;i<Longth;i++)
  102.         {
  103.                 usart_data_transmit(USART2, buffer);
  104.                 while(RESET == usart_flag_get(USART2, USART_FLAG_TC));
  105.         }
  106.         Drv_485_RxEn();
  107.       
  108. }


  109. //中断服务函数
  110. void USART2_IRQHandler(void)
  111. {
  112.         uint16_t i = 0;
  113.         //UART1接收空闲中断处理函数
  114.         if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_IDLE)){                                                //总线空闲
  115.                 /* clear IDLE flag */
  116.     usart_data_receive(USART2);
  117.                 if(RS485RxFlag == 0)                                                                                                                                                                                                                                //仅在数据处理完成的情况下接收新的帧
  118.                 {
  119.                         RS485RxCount = RS485BufferSize - (dma_transfer_number_get(DMA0, DMA_CH1));
  120.                         for(i=0;i<RS485RxCount;i++)
  121.                         {
  122.                                 RS485RxFrameBuffer = RS485RxBuffer;                                                                                                                                //将接收缓冲区数据导入帧缓冲区
  123.                         }
  124.                         if(RS485RxCount > 0)
  125.                         {
  126.                                 RS485RxFlag = 1;                                                                                                                                                                                                                                //标记收到1帧数据      
  127.                         }
  128.                 }

  129.                 //重启DMA
  130.                 dma_channel_disable(DMA0, DMA_CH1);
  131.                 dma_flag_clear(DMA0, DMA_CH1, DMA_FLAG_FTF);
  132.                 dma_transfer_number_config(DMA0, DMA_CH1, RS485BufferSize);
  133.                 dma_channel_enable(DMA0, DMA_CH1);      
  134.         }
  135.         if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_RBNE))
  136.         {
  137.                 usart_interrupt_flag_clear(USART2, USART_INT_FLAG_RBNE);
  138.         }
  139.         if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_RBNE_ORERR))
  140.         {
  141.                 usart_interrupt_flag_clear(USART2, USART_INT_FLAG_RBNE_ORERR);
  142.         }
  143.         if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_ERR_NERR))
  144.         {
  145.                 usart_interrupt_flag_clear(USART2, USART_INT_FLAG_ERR_NERR);
  146.         }      
  147.         if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_ERR_FERR))
  148.         {
  149.                 usart_interrupt_flag_clear(USART2, USART_INT_FLAG_ERR_FERR);
  150.         }
  151.       
  152. }


  153. int main(void)
  154. {
  155. /**************系统初始化部分**********************/
  156.         SystemInit();                                //系统初始化
  157.         systick_config();                                //系统时钟加载
  158.         Drv_485OE_Init();                 //RS-485驱动初始化

  159. }

复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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