找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1133|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

GD32F470系列Rs-485驅(qū)動程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1075158 發(fā)表于 2024-2-27 13:27 | 只看該作者 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
  1. /*
  2. 主程序如下
  3. main.c
  4. 使用中斷+DMA數(shù)據(jù)搬運(yùn)實(shí)現(xiàn)驅(qū)動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數(shù)據(jù)接收緩沖區(qū)
  11. uint8_t RS485RxP = 0;                                          //485接收緩沖區(qū)接收位置指示
  12. uint8_t RS485RxPre = 0;                                       //485幀頭指示
  13. uint8_t RS485TxBuffer[RS485BufferSize]={0};                                                                                                        //485數(shù)據(jù)發(fā)送緩沖區(qū)
  14. uint8_t RS485TxP = 0;                                                                                                                                                                                                //485發(fā)送緩沖區(qū)發(fā)送位置指示
  15. uint8_t RS485RxFrameBuffer[RS485BufferSize];                                                                                                //485接收幀緩沖
  16. uint8_t RS485RxCount = 0;                                                                                                                                                                                //485接收計(jì)數(shù)
  17. uint8_t RS485RxFlag = 0;                                                                                                                                                                                //RS485幀接收完成標(biāo)志,邏輯1有效



  18. /*485OE使用PE15引腳,高電平發(fā)送,低電平接收*/
  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.     /* 默認(rèn)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);                                                                                                                                                                        //優(yōu)先級為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循環(huán)模式
  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發(fā)送數(shù)據(jù)函數(shù)
  94. buffer:數(shù)據(jù)緩沖區(qū)
  95. Longth:發(fā)送數(shù)據(jù)長度,單位:字節(jié)
  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. //中斷服務(wù)函數(shù)
  110. void USART2_IRQHandler(void)
  111. {
  112.         uint16_t i = 0;
  113.         //UART1接收空閑中斷處理函數(shù)
  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)                                                                                                                                                                                                                                //僅在數(shù)據(jù)處理完成的情況下接收新的幀
  118.                 {
  119.                         RS485RxCount = RS485BufferSize - (dma_transfer_number_get(DMA0, DMA_CH1));
  120.                         for(i=0;i<RS485RxCount;i++)
  121.                         {
  122.                                 RS485RxFrameBuffer = RS485RxBuffer;                                                                                                                                //將接收緩沖區(qū)數(shù)據(jù)導(dǎo)入幀緩沖區(qū)
  123.                         }
  124.                         if(RS485RxCount > 0)
  125.                         {
  126.                                 RS485RxFlag = 1;                                                                                                                                                                                                                                //標(biāo)記收到1幀數(shù)據(jù)      
  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. /**************系統(tǒng)初始化部分**********************/
  156.         SystemInit();                                //系統(tǒng)初始化
  157.         systick_config();                                //系統(tǒng)時鐘加載
  158.         Drv_485OE_Init();                 //RS-485驅(qū)動初始化

  159. }

復(fù)制代碼


評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表