|
- /*
- 主程序如下
- main.c
- 使用中斷+DMA數(shù)據(jù)搬運(yùn)實(shí)現(xiàn)驅(qū)動RS-458
- */
- #include "gd32f4xx.h"
- #include "systick.h"
- #define USART1_DATA_ADDRESS ((uint32_t)&USART_DATA(USART1))
- #define RS485BufferSize 256
- uint8_t RS485RxBuffer[RS485BufferSize]={0}; //485數(shù)據(jù)接收緩沖區(qū)
- uint8_t RS485RxP = 0; //485接收緩沖區(qū)接收位置指示
- uint8_t RS485RxPre = 0; //485幀頭指示
- uint8_t RS485TxBuffer[RS485BufferSize]={0}; //485數(shù)據(jù)發(fā)送緩沖區(qū)
- uint8_t RS485TxP = 0; //485發(fā)送緩沖區(qū)發(fā)送位置指示
- uint8_t RS485RxFrameBuffer[RS485BufferSize]; //485接收幀緩沖
- uint8_t RS485RxCount = 0; //485接收計(jì)數(shù)
- uint8_t RS485RxFlag = 0; //RS485幀接收完成標(biāo)志,邏輯1有效
- /*485OE使用PE15引腳,高電平發(fā)送,低電平接收*/
- void Drv_485OE_Init(void)
- {
- /* 打開GPIOE時鐘 */
- rcu_periph_clock_enable(RCU_GPIOE);
- /* 配置PE15口為推挽輸出,無上下拉 */
- gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_15);
- gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
- /* 默認(rèn)485處于接受模式 */
- Drv_485_RxEn();
- }
- // 485 RX_EN
- void Drv_485_RxEn(void)
- {
- gpio_bit_reset(GPIOE, GPIO_PIN_15);
- }
- // 485 TX_EN
- void Drv_485_TxEn(void)
- {
- gpio_bit_set(GPIOE, GPIO_PIN_15);
- }
- //Rs_485初始化
- void Drv_Rs_485_Init(void)
- {
- dma_single_data_parameter_struct dma_init_struct;
- /* enable GPIO clock */
- rcu_periph_clock_enable(RCU_GPIOB);
- /* enable UART clock */
- rcu_periph_clock_enable(RCU_USART2);
- /* configure the USART2 TX pin and USART2 RX pin */
- gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_10); //Tx
- gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_11); //Rx
- /* configure USART2 TX as alternate function push-pull */
- gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
- gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
- /* configure USART2 RX as alternate function push-pull */
- gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_11);
- gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
- /* USART configure */
- usart_deinit(USART2); //取消初始化USART2
- usart_baudrate_set(USART2, 38400U); //波特率38400U
- usart_receive_config(USART2, USART_RECEIVE_ENABLE);
- usart_transmit_config(USART2, USART_TRANSMIT_ENABLE);
- usart_enable(USART2);
-
- usart_interrupt_flag_clear(USART2, USART_INT_FLAG_ERR_ORERR);
- usart_interrupt_enable(USART2, USART_INT_ERR);
-
- /* USART interrupt configuration */
- nvic_irq_enable(USART2_IRQn, 2, 0); //優(yōu)先級為2
-
- /* deinitialize DMA0 channel2 (USART0 RX) */
- rcu_periph_clock_enable(RCU_DMA0);
- dma_deinit(DMA0, DMA_CH1);
- dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
- dma_init_struct.memory0_addr = (uint32_t)RS485RxBuffer;
- dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
- dma_init_struct.number = sizeof(RS485RxBuffer);
- dma_init_struct.periph_addr = (uint32_t)&USART_DATA(USART2);
- dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
- dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
- dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
- dma_single_data_mode_init(DMA0, DMA_CH1, &dma_init_struct);
- /* configure DMA mode */
- dma_circulation_enable(DMA0, DMA_CH1); //啟用DMA循環(huán)模式
- dma_channel_subperipheral_select(DMA0, DMA_CH1, DMA_SUBPERI4);
- /* enable DMA0 channel5 */
- dma_channel_enable(DMA0, DMA_CH1);
- usart_dma_receive_config(USART2, USART_RECEIVE_DMA_ENABLE);
- usart_interrupt_enable(USART2,USART_INT_IDLE); //IDLE線檢測中斷
-
- /*485 OE引腳初始化*/
- Drv_485OE_Init();
- }
- /*
- void Drv_rs485_Tx(uint8_t *buffer,uint16_t Longth):485發(fā)送數(shù)據(jù)函數(shù)
- buffer:數(shù)據(jù)緩沖區(qū)
- Longth:發(fā)送數(shù)據(jù)長度,單位:字節(jié)
- */
- void Drv_rs485_Tx(uint8_t *buffer,uint16_t Longth)
- {
- uint16_t i = 0;
- Drv_485_TxEn();
- for(i=0;i<Longth;i++)
- {
- usart_data_transmit(USART2, buffer);
- while(RESET == usart_flag_get(USART2, USART_FLAG_TC));
- }
- Drv_485_RxEn();
-
- }
- //中斷服務(wù)函數(shù)
- void USART2_IRQHandler(void)
- {
- uint16_t i = 0;
- //UART1接收空閑中斷處理函數(shù)
- if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_IDLE)){ //總線空閑
- /* clear IDLE flag */
- usart_data_receive(USART2);
- if(RS485RxFlag == 0) //僅在數(shù)據(jù)處理完成的情況下接收新的幀
- {
- RS485RxCount = RS485BufferSize - (dma_transfer_number_get(DMA0, DMA_CH1));
- for(i=0;i<RS485RxCount;i++)
- {
- RS485RxFrameBuffer = RS485RxBuffer; //將接收緩沖區(qū)數(shù)據(jù)導(dǎo)入幀緩沖區(qū)
- }
- if(RS485RxCount > 0)
- {
- RS485RxFlag = 1; //標(biāo)記收到1幀數(shù)據(jù)
- }
- }
- //重啟DMA
- dma_channel_disable(DMA0, DMA_CH1);
- dma_flag_clear(DMA0, DMA_CH1, DMA_FLAG_FTF);
- dma_transfer_number_config(DMA0, DMA_CH1, RS485BufferSize);
- dma_channel_enable(DMA0, DMA_CH1);
- }
- if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_RBNE))
- {
- usart_interrupt_flag_clear(USART2, USART_INT_FLAG_RBNE);
- }
- if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_RBNE_ORERR))
- {
- usart_interrupt_flag_clear(USART2, USART_INT_FLAG_RBNE_ORERR);
- }
- if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_ERR_NERR))
- {
- usart_interrupt_flag_clear(USART2, USART_INT_FLAG_ERR_NERR);
- }
- if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_ERR_FERR))
- {
- usart_interrupt_flag_clear(USART2, USART_INT_FLAG_ERR_FERR);
- }
-
- }
- int main(void)
- {
- /**************系統(tǒng)初始化部分**********************/
- SystemInit(); //系統(tǒng)初始化
- systick_config(); //系統(tǒng)時鐘加載
- Drv_485OE_Init(); //RS-485驅(qū)動初始化
- }
復(fù)制代碼
|
評分
-
查看全部評分
|