TA的每日心情 | 怒 2023-7-25 22:49 |
---|
签到天数: 385 天 连续签到: 1 天 [LV.9]以坛为家II
|
有段日子没有更新了,我就不给自己找原因了,今天更新下下位机的代码。
下位机的思想就是在收到上位机发送的开始捕获指令后,启动两个定时器来进行捕获计时和测量脉宽。
在串口通讯时,往上位机传输数据时使用USART+DMA的方式传输,节省CPU资源。这个DMA传输花费了不少时间,原因是GD32的例子误导了很长时间,最后还是自己看手册试出的。
下位机实物图:PB2接HS0038的Out引脚,然后就是一个电源,一个地。
下位机代码:- #include "gd32f4xx.h" // Device header
- #include "stddef.h"
- #include "ir_typedef.h"
- #define LED_ON gpio_bit_set(LED4PORT,LED4)
- #define LED_OFF gpio_bit_reset(LED4PORT,LED4)
- #define LEDx_ON gpio_bit_set(LED5PORT,LED5)
- #define LEDx_OFF gpio_bit_reset(LED5PORT,LED5)
- #define MeasureTimer TIMER6
- #define CountTimer TIMER5
- //红外数据
- IrDataType IrDat = {
- .datBuffer1 = {0},
- .i = 0
- };
- //能否上传
- BOOL CanTransfer;
- //开始捕获
- BOOL StartCapture;
- //
- uint32_t PulseWidth_us;
- //
- uint32_t ElapseTime;
- int main()
- {
- InitLED();
- InitIR();
- InitUsart();
- InitMeasureTimer();
- InitCountTimer();
-
-
- while(TRUE)
- {
- if(CanTransfer)
- {
- if(IrDat.i != 0)
- {
- dma_transfer_number_config(DMA0,DMA_CH3,IrDat.i);
- dma_channel_enable(DMA0,DMA_CH3);
- }
- CanTransfer = FALSE;
- }
- }
- }
- /*!
- \brief initialize LED Pin
- \param[in] none
- \param[out] none
- \retval none
- */
- void InitLED(void)
- {
- rcu_periph_clock_enable(RCU_GPIOB);
- rcu_periph_clock_enable(RCU_GPIOD);
-
- gpio_deinit(GPIOB);
- gpio_deinit(GPIOD);
-
- gpio_mode_set(LED4PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,LED4|LED6);
- gpio_output_options_set(LED4PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,LED4|LED6);
-
- gpio_mode_set(LED5PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,LED5);
- gpio_output_options_set(LED5PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,LED5);
-
- gpio_bit_reset(LED4PORT,LED4);
- gpio_bit_reset(LED6PORT,LED6);
- gpio_bit_reset(LED5PORT,LED5);
- }
- /*!
- \brief initialize IR Pin and Exit2
- \param[in] none
- \param[out] none
- \retval none
- */
- void InitIR(void)
- {
- rcu_periph_clock_enable(RCU_GPIOB);
- rcu_periph_clock_enable(RCU_SYSCFG);
-
- gpio_mode_set(IRPORT,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,IR_PIN);
-
- //initialize Exti Interrupt(PB2)
- nvic_irq_enable(EXTI2_IRQn,0,1);
- exti_init(EXTI_2,EXTI_INTERRUPT,EXTI_TRIG_BOTH);
- syscfg_exti_line_config(EXTI_SOURCE_GPIOB,EXTI_SOURCE_PIN2);
- exti_interrupt_flag_clear(EXTI_2);
- }
- /*!
- \brief initialize Timer to Measuring pulse width; 10 us
- \param[in] none
- \param[out] none
- \retval none
- */
- void InitMeasureTimer(void)
- {
- rcu_periph_clock_enable(RCU_TIMER6);
- timer_deinit(TIMER6);
-
- timer_parameter_struct timer_initpara;
- timer_initpara.prescaler = 99;
- timer_initpara.period = 9;
-
- timer_init(TIMER6,&timer_initpara);
- timer_auto_reload_shadow_enable(TIMER6);
- timer_interrupt_enable(TIMER6,TIMER_INT_UP);
-
- nvic_irq_enable(TIMER6_IRQn,0,0);
-
- }
- /*!
- \brief initialize Timer,100 ms
- \param[in] none
- \param[out] none
- \retval none
- */
- void InitCountTimer(void)
- {
- rcu_periph_clock_enable(RCU_TIMER5);
- timer_deinit(TIMER5);
-
- timer_parameter_struct timer_initpara;
- timer_initpara.prescaler = 9999;
- timer_initpara.period = 999;
-
- timer_init(TIMER5,&timer_initpara);
- timer_auto_reload_shadow_enable(TIMER5);
- timer_interrupt_enable(TIMER5,TIMER_INT_UP);
-
- nvic_irq_enable(TIMER5_DAC_IRQn,0,1);
- }
- /*!
- \brief initialize USART2
- \param[in] none
- \param[out] none
- \retval none
- */
- void InitUsart(void)
- {
- rcu_periph_clock_enable(RCU_USART2);
-
- gpio_af_set(GPIOD,GPIO_AF_7,USART_TX_PIN);
- gpio_af_set(GPIOD,GPIO_AF_7,USART_RX_PIN);
-
- gpio_mode_set(GPIOD,GPIO_MODE_AF,GPIO_PUPD_PULLUP,USART_TX_PIN);
- gpio_output_options_set(GPIOD,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,USART_TX_PIN);
-
- gpio_mode_set(GPIOD,GPIO_MODE_AF,GPIO_PUPD_PULLUP,USART_RX_PIN);
- gpio_output_options_set(GPIOD,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,USART_RX_PIN);
-
- usart_deinit(USART2);
- usart_baudrate_set(USART2,115200);
- usart_parity_config(USART2,USART_PM_NONE);
- usart_word_length_set(USART2,USART_WL_8BIT);
- usart_stop_bit_set(USART2,USART_STB_1BIT);
- usart_transmit_config(USART2,USART_TRANSMIT_ENABLE);
- usart_receive_config(USART2,USART_RECEIVE_ENABLE);
- usart_interrupt_enable(USART2,USART_INTEN_RBNEIE);
- usart_dma_transmit_config(USART2,USART_DENT_ENABLE);
- usart_enable(USART2);
- usart_flag_clear(USART2,USART_FLAG_TC);
-
- rcu_periph_clock_enable(RCU_DMA0);
- dma_deinit(DMA0,DMA_CH3);
- dma_transfer_direction_config(DMA0,DMA_CH3,DMA_MEMORY_TO_PERIPH);
- dma_transfer_number_config(DMA0,DMA_CH3,IRBUF_LEN);
- dma_memory_address_config(DMA0,DMA_CH3,DMA_MEMORY_0,(uint32_t)IrDat.datBuffer1);
- dma_memory_width_config(DMA0,DMA_CH3,DMA_MEMORY_WIDTH_8BIT);
- dma_memory_address_generation_config(DMA0,DMA_CH3,DMA_MEMORY_INCREASE_ENABLE);
- dma_periph_address_config(DMA0,DMA_CH3,(uint32_t)&USART_DATA(USART2));
- dma_periph_width_config(DMA0,DMA_CH3,DMA_PERIPH_WIDTH_8BIT);
- dma_peripheral_address_generation_config(DMA0,DMA_CH3,DMA_PERIPH_INCREASE_DISABLE);
- dma_priority_config(DMA0,DMA_CH3,DMA_PRIORITY_ULTRA_HIGH);
- dma_circulation_disable(DMA0,DMA_CH3);
- dma_channel_subperipheral_select(DMA0,DMA_CH3,DMA_SUBPERI4);
- dma_interrupt_enable(DMA0,DMA_CH3,DMA_CHXCTL_FTFIE);
-
-
- nvic_irq_enable(USART2_IRQn,0,2);
- nvic_irq_enable(DMA0_Channel3_IRQn,0,3);
- }
- /*!
- \brief Exti2 Interrupt(PB2) Handler for ir input
- \param[in] none
- \param[out] none
- \retval none
- */
- void EXTI2_IRQHandler(void)
- {
- exti_interrupt_flag_clear(EXTI_2);
- //判断是否开始捕获
- if(!StartCapture)
- return;
-
- StopTiming();
- uint32_t us = 0;
- if(gpio_input_bit_get(GPIOB,GPIO_PIN_2) == SET)
- {
- //上升沿触发(读取低电平的时间)
- us = (PulseWidth_us * 10) & 0x7FFFFFFF;
- LEDx_OFF;
- }
- else
- {
- //T下降沿触发(读取高电平的时间)
- us = (PulseWidth_us * 10) | 0x80000000;
- LEDx_ON;
- }
- StartTiming();
- if(IrDat.i >= IRBUF_LEN)
- {
- CanTransfer = TRUE;
- return;
- }
- IrDat.datBuffer1[IrDat.i] = us;
- IrDat.i++;
- }
- /*!
- \brief TIMER6 interrupt Handler for measuring pulse width
- \param[in] none
- \param[out] none
- \retval none
- */
- void TIMER6_IRQHandler(void)
- {
- PulseWidth_us++;
- timer_interrupt_flag_clear(TIMER6,TIMER_INT_UP);
- }
- /*!
- \brief TIMER5 interrupt Handler,5 second timer
- \param[in] none
- \param[out] none
- \retval none
- */
- void TIMER5_DAC_IRQHandler(void)
- {
- timer_interrupt_flag_clear(TIMER5,TIMER_INT_UP);
- if(ElapseTime >= 50)
- {
- StartCapture = FALSE;
- LED_OFF;
- timer_disable(TIMER5);
- StopTiming();
- CanTransfer = TRUE;
- return;
- }
- ElapseTime++;
- }
- /*!
- \brief USART2 interrupt Handler
- \param[in] none
- \param[out] none
- \retval none
- */
- void USART2_IRQHandler()
- {
- if(usart_interrupt_flag_get(USART2,USART_INT_RBNEIE) == SET)
- {
- uint16_t dat = usart_data_receive(USART2);
- if(dat == 's' || dat == 'S')
- {
- if(StartCapture) return;
- IrDat.i = 0;
- LED_ON;
- Start_Capture();
- StartTiming();
- }
- }
- }
- void DMA0_Channel3_IRQHandler(void)
- {
- if(dma_interrupt_flag_get(DMA0,DMA_CH3,DMA_INTC_FTFIFC) == SET)
- {
- dma_interrupt_flag_clear(DMA0,DMA_CH3,DMA_INTF_FTFIF);
- CanTransfer = FALSE;
- }
- }
- /*!
- \brief Start capture ir data
- \param[in] none
- \param[out] none
- \retval none
- */
- void Start_Capture(void)
- {
- StartCapture = TRUE;
- ElapseTime = 0;
- timer_enable(TIMER5);
- }
- /*!
- \brief Start capture ir data
- \param[in] none
- \param[out] none
- \retval none
- */
- void StartTiming(void)
- {
- PulseWidth_us = 0;
- timer_enable(TIMER6);
- }
- void StopTiming(void)
- {
- timer_disable(TIMER6);
- }
复制代码 代码已经做了很详细的注释。有感兴趣的同学可以参考,有任何疑问可以提出来。
|
|