查看: 4182|回复: 0

基于GD32F450的红外解码--下位机篇

[复制链接]
  • TA的每日心情

    2023-7-25 22:49
  • 签到天数: 385 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2017-6-12 23:46:02 | 显示全部楼层 |阅读模式
    分享到:
    有段日子没有更新了,我就不给自己找原因了,今天更新下下位机的代码。
    下位机的思想就是在收到上位机发送的开始捕获指令后,启动两个定时器来进行捕获计时和测量脉宽。
    在串口通讯时,往上位机传输数据时使用USART+DMA的方式传输,节省CPU资源。这个DMA传输花费了不少时间,原因是GD32的例子误导了很长时间,最后还是自己看手册试出的。
    下位机实物图:PB2接HS0038的Out引脚,然后就是一个电源,一个地。
    IMG_20170612_233924.jpg
    下位机代码:
    1. #include "gd32f4xx.h"                   // Device header
    2. #include "stddef.h"
    3. #include "ir_typedef.h"

    4. #define LED_ON                gpio_bit_set(LED4PORT,LED4)
    5. #define LED_OFF                gpio_bit_reset(LED4PORT,LED4)

    6. #define LEDx_ON                gpio_bit_set(LED5PORT,LED5)
    7. #define LEDx_OFF        gpio_bit_reset(LED5PORT,LED5)

    8. #define MeasureTimer        TIMER6
    9. #define CountTimer                TIMER5

    10. //红外数据
    11. IrDataType IrDat = {
    12.     .datBuffer1 = {0},
    13.     .i = 0
    14. };

    15. //能否上传
    16. BOOL CanTransfer;
    17. //开始捕获
    18. BOOL StartCapture;
    19. //
    20. uint32_t PulseWidth_us;
    21. //
    22. uint32_t ElapseTime;

    23. int main()
    24. {
    25.         InitLED();
    26.         InitIR();
    27.         InitUsart();
    28.         InitMeasureTimer();
    29.         InitCountTimer();
    30.        
    31.        
    32.         while(TRUE)
    33.         {
    34.                 if(CanTransfer)
    35.                 {
    36.                         if(IrDat.i != 0)
    37.                         {
    38.                                 dma_transfer_number_config(DMA0,DMA_CH3,IrDat.i);
    39.                                 dma_channel_enable(DMA0,DMA_CH3);
    40.                         }
    41.                         CanTransfer = FALSE;
    42.                 }                       
    43.         }
    44. }

    45. /*!
    46.     \brief      initialize LED Pin
    47.     \param[in]  none
    48.     \param[out] none
    49.     \retval     none
    50. */
    51. void InitLED(void)
    52. {
    53.         rcu_periph_clock_enable(RCU_GPIOB);
    54.         rcu_periph_clock_enable(RCU_GPIOD);
    55.        
    56.         gpio_deinit(GPIOB);
    57.         gpio_deinit(GPIOD);
    58.        
    59.         gpio_mode_set(LED4PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,LED4|LED6);
    60.         gpio_output_options_set(LED4PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,LED4|LED6);
    61.        
    62.         gpio_mode_set(LED5PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,LED5);
    63.         gpio_output_options_set(LED5PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,LED5);
    64.        
    65.         gpio_bit_reset(LED4PORT,LED4);
    66.         gpio_bit_reset(LED6PORT,LED6);
    67.         gpio_bit_reset(LED5PORT,LED5);
    68. }

    69. /*!
    70.     \brief      initialize IR Pin and Exit2
    71.     \param[in]  none
    72.     \param[out] none
    73.     \retval     none
    74. */
    75. void InitIR(void)
    76. {
    77.         rcu_periph_clock_enable(RCU_GPIOB);
    78.         rcu_periph_clock_enable(RCU_SYSCFG);
    79.        
    80.         gpio_mode_set(IRPORT,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,IR_PIN);
    81.        
    82.         //initialize Exti Interrupt(PB2)       
    83.         nvic_irq_enable(EXTI2_IRQn,0,1);
    84.         exti_init(EXTI_2,EXTI_INTERRUPT,EXTI_TRIG_BOTH);
    85.         syscfg_exti_line_config(EXTI_SOURCE_GPIOB,EXTI_SOURCE_PIN2);
    86.         exti_interrupt_flag_clear(EXTI_2);
    87. }

    88. /*!
    89.     \brief      initialize Timer to Measuring pulse width; 10 us
    90.     \param[in]  none
    91.     \param[out] none
    92.     \retval     none
    93. */
    94. void InitMeasureTimer(void)
    95. {
    96.         rcu_periph_clock_enable(RCU_TIMER6);
    97.         timer_deinit(TIMER6);
    98.        
    99.         timer_parameter_struct timer_initpara;
    100.         timer_initpara.prescaler = 99;
    101.         timer_initpara.period = 9;
    102.        
    103.         timer_init(TIMER6,&timer_initpara);
    104.         timer_auto_reload_shadow_enable(TIMER6);
    105.         timer_interrupt_enable(TIMER6,TIMER_INT_UP);
    106.        
    107.         nvic_irq_enable(TIMER6_IRQn,0,0);
    108.        
    109. }

    110. /*!
    111.     \brief      initialize Timer,100 ms
    112.     \param[in]  none
    113.     \param[out] none
    114.     \retval     none
    115. */
    116. void InitCountTimer(void)
    117. {
    118.         rcu_periph_clock_enable(RCU_TIMER5);
    119.         timer_deinit(TIMER5);
    120.        
    121.         timer_parameter_struct timer_initpara;
    122.         timer_initpara.prescaler = 9999;
    123.         timer_initpara.period = 999;
    124.        
    125.         timer_init(TIMER5,&timer_initpara);
    126.         timer_auto_reload_shadow_enable(TIMER5);
    127.         timer_interrupt_enable(TIMER5,TIMER_INT_UP);
    128.        
    129.         nvic_irq_enable(TIMER5_DAC_IRQn,0,1);
    130. }

    131. /*!
    132.     \brief      initialize USART2
    133.     \param[in]  none
    134.     \param[out] none
    135.     \retval     none
    136. */
    137. void InitUsart(void)
    138. {
    139.         rcu_periph_clock_enable(RCU_USART2);
    140.        
    141.         gpio_af_set(GPIOD,GPIO_AF_7,USART_TX_PIN);
    142.         gpio_af_set(GPIOD,GPIO_AF_7,USART_RX_PIN);
    143.        
    144.         gpio_mode_set(GPIOD,GPIO_MODE_AF,GPIO_PUPD_PULLUP,USART_TX_PIN);
    145.         gpio_output_options_set(GPIOD,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,USART_TX_PIN);
    146.        
    147.         gpio_mode_set(GPIOD,GPIO_MODE_AF,GPIO_PUPD_PULLUP,USART_RX_PIN);
    148.         gpio_output_options_set(GPIOD,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,USART_RX_PIN);
    149.        
    150.         usart_deinit(USART2);
    151.         usart_baudrate_set(USART2,115200);
    152.         usart_parity_config(USART2,USART_PM_NONE);
    153.         usart_word_length_set(USART2,USART_WL_8BIT);
    154.         usart_stop_bit_set(USART2,USART_STB_1BIT);
    155.         usart_transmit_config(USART2,USART_TRANSMIT_ENABLE);
    156.         usart_receive_config(USART2,USART_RECEIVE_ENABLE);
    157.         usart_interrupt_enable(USART2,USART_INTEN_RBNEIE);
    158.         usart_dma_transmit_config(USART2,USART_DENT_ENABLE);
    159.         usart_enable(USART2);
    160.         usart_flag_clear(USART2,USART_FLAG_TC);
    161.        
    162.         rcu_periph_clock_enable(RCU_DMA0);
    163.         dma_deinit(DMA0,DMA_CH3);
    164.         dma_transfer_direction_config(DMA0,DMA_CH3,DMA_MEMORY_TO_PERIPH);
    165.         dma_transfer_number_config(DMA0,DMA_CH3,IRBUF_LEN);
    166.         dma_memory_address_config(DMA0,DMA_CH3,DMA_MEMORY_0,(uint32_t)IrDat.datBuffer1);
    167.         dma_memory_width_config(DMA0,DMA_CH3,DMA_MEMORY_WIDTH_8BIT);
    168.         dma_memory_address_generation_config(DMA0,DMA_CH3,DMA_MEMORY_INCREASE_ENABLE);
    169.         dma_periph_address_config(DMA0,DMA_CH3,(uint32_t)&USART_DATA(USART2));
    170.         dma_periph_width_config(DMA0,DMA_CH3,DMA_PERIPH_WIDTH_8BIT);
    171.         dma_peripheral_address_generation_config(DMA0,DMA_CH3,DMA_PERIPH_INCREASE_DISABLE);
    172.         dma_priority_config(DMA0,DMA_CH3,DMA_PRIORITY_ULTRA_HIGH);
    173.         dma_circulation_disable(DMA0,DMA_CH3);
    174.         dma_channel_subperipheral_select(DMA0,DMA_CH3,DMA_SUBPERI4);
    175.         dma_interrupt_enable(DMA0,DMA_CH3,DMA_CHXCTL_FTFIE);
    176.        
    177.        
    178.         nvic_irq_enable(USART2_IRQn,0,2);
    179.         nvic_irq_enable(DMA0_Channel3_IRQn,0,3);
    180. }


    181. /*!
    182.     \brief      Exti2 Interrupt(PB2) Handler for ir input
    183.     \param[in]  none
    184.     \param[out] none
    185.     \retval     none
    186. */
    187. void EXTI2_IRQHandler(void)
    188. {
    189.         exti_interrupt_flag_clear(EXTI_2);
    190.         //判断是否开始捕获
    191.         if(!StartCapture)
    192.                 return;
    193.        
    194.         StopTiming();
    195.         uint32_t us = 0;
    196.         if(gpio_input_bit_get(GPIOB,GPIO_PIN_2) == SET)
    197.         {
    198.                 //上升沿触发(读取低电平的时间)
    199.                 us = (PulseWidth_us * 10) & 0x7FFFFFFF;
    200.                 LEDx_OFF;
    201.         }
    202.         else
    203.         {
    204.                 //T下降沿触发(读取高电平的时间)
    205.                 us = (PulseWidth_us * 10) | 0x80000000;
    206.                 LEDx_ON;
    207.         }
    208.         StartTiming();
    209.         if(IrDat.i >= IRBUF_LEN)
    210.     {
    211.         CanTransfer = TRUE;
    212.                 return;
    213.     }
    214.         IrDat.datBuffer1[IrDat.i] = us;
    215.         IrDat.i++;
    216. }

    217. /*!
    218.     \brief      TIMER6 interrupt Handler for measuring pulse width
    219.     \param[in]  none
    220.     \param[out] none
    221.     \retval     none
    222. */
    223. void TIMER6_IRQHandler(void)
    224. {
    225.         PulseWidth_us++;
    226.         timer_interrupt_flag_clear(TIMER6,TIMER_INT_UP);
    227. }

    228. /*!
    229.     \brief      TIMER5 interrupt Handler,5 second timer
    230.     \param[in]  none
    231.     \param[out] none
    232.     \retval     none
    233. */
    234. void TIMER5_DAC_IRQHandler(void)
    235. {
    236.         timer_interrupt_flag_clear(TIMER5,TIMER_INT_UP);
    237.         if(ElapseTime >= 50)
    238.         {
    239.                 StartCapture = FALSE;
    240.                 LED_OFF;
    241.                 timer_disable(TIMER5);
    242.                 StopTiming();
    243.                 CanTransfer = TRUE;
    244.                 return;
    245.         }
    246.         ElapseTime++;
    247. }

    248. /*!
    249.     \brief      USART2 interrupt Handler
    250.     \param[in]  none
    251.     \param[out] none
    252.     \retval     none
    253. */
    254. void USART2_IRQHandler()
    255. {
    256.         if(usart_interrupt_flag_get(USART2,USART_INT_RBNEIE) == SET)
    257.         {
    258.                 uint16_t dat = usart_data_receive(USART2);
    259.                 if(dat == 's' || dat == 'S')
    260.                 {
    261.                         if(StartCapture) return;
    262.                         IrDat.i = 0;
    263.                         LED_ON;
    264.                         Start_Capture();
    265.                         StartTiming();
    266.                 }
    267.         }
    268. }

    269. void DMA0_Channel3_IRQHandler(void)
    270. {
    271.         if(dma_interrupt_flag_get(DMA0,DMA_CH3,DMA_INTC_FTFIFC) == SET)
    272.         {
    273.                 dma_interrupt_flag_clear(DMA0,DMA_CH3,DMA_INTF_FTFIF);
    274.                 CanTransfer = FALSE;
    275.         }
    276. }

    277. /*!
    278.     \brief      Start capture ir data
    279.     \param[in]  none
    280.     \param[out] none
    281.     \retval     none
    282. */
    283. void Start_Capture(void)
    284. {
    285.         StartCapture = TRUE;
    286.         ElapseTime = 0;
    287.         timer_enable(TIMER5);
    288. }
    289. /*!
    290.     \brief      Start capture ir data
    291.     \param[in]  none
    292.     \param[out] none
    293.     \retval     none
    294. */
    295. void StartTiming(void)
    296. {
    297.         PulseWidth_us = 0;
    298.         timer_enable(TIMER6);
    299. }

    300. void StopTiming(void)
    301. {
    302.         timer_disable(TIMER6);
    303. }




    复制代码
    代码已经做了很详细的注释。有感兴趣的同学可以参考,有任何疑问可以提出来。



    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-11-15 08:06 , Processed in 0.111736 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.