赞
踩
在物联网产品的开发过程中经常需要基于无线的简单交互通讯,红外通讯比较适合近距离低速的
交换数据场景,红外协议比较多,比如NEC,RC5,NRC17等。
NEC红外协议,GPIO口的输出时序,
1.逻辑0为脉冲时间560us低电平+560us高电平,1.12ms周期 ,逻辑1为脉冲时间560us低电平+1690us高电平, 2.25ms周期。
2.命令格式 9ms低电平引导码+4.5ms高电平结果码+地址码+地址反码+命令码+命令反码 (经测试必须32BIT(4个字节))+560us低电平作为结束,经测试接收管自动反向,注意这四个字节为(A,~A,B,~B)。
3.占空比1/4到1/3载波为38KHZ的PWM。
4.命令格式的电平反向形式。
使用GD32F4XX串口3作为红外编解码通讯接口,
USART3_RX接收BC7120A的红外解码数据,波特率9600。
USART3_TX作为普通IO输出因引脚与外部38KHZ振荡电路通过与门输出调制脉冲到红外发射管。
delay.c软件延时
- #ifndef __DELAY_H__
- #define __DELAY_H__
-
- #include "gd32f4xx.h"
-
- #define delay_us Delay_US
- #define delay_ms Delay_MS
-
- #define HAL_Delay Delay_MS
-
-
- void Delay_US(uint32_t time);
-
- void Delay_MS(uint32_t time);
-
-
- #endif
-
-
- #include "delay.h"
-
- #define CURRENT_CPU_FREQ (SystemCoreClock / 1000000)
-
- void Delay_US(uint32_t time)
- {
- while(time--)
- {
- #if (CURRENT_CPU_FREQ == 120)
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- #elif (CURRENT_CPU_FREQ == 168)
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
-
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- #elif (CURRENT_CPU_FREQ == 200)
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
-
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- #else
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- #endif
- }
- }
-
-
- void Delay_MS(uint32_t time)
- {
-
- Delay_US(time * 11000);
- }
timer1.c定时器硬件延时
- #ifndef __TIMER1_H__
- #define __TIMER1_H__
-
- #include "gd32f4xx.h"
- #include "it_config.h"
-
-
- void Timer_Init(void);
-
- void Timer_Dly_Wait(uint32_t time);
-
-
- #endif
-
-
-
- #include "timer1.h"
-
-
- #define TIMx TIMER0
- #define RCU_TIMx_CLK RCU_TIMER0
-
- #define TIMx_IRQn TIMER0_UP_TIMER9_IRQn
- #define TIMx_IRQHandler TIMER0_UP_TIMER9_IRQHandler
-
-
- /**100us时基*/
- static __IO uint32_t timer1_100us_cnt = 0;
-
-
-
- void Timer_Init(void)
- {
-
- timer_parameter_struct timer_initpara;
-
- rcu_periph_clock_enable(RCU_TIMx_CLK);
-
- timer_deinit(TIMx);
- /* initialize TIMER init parameter struct */
- timer_struct_para_init(&timer_initpara);
-
-
- /* TIMER1 configuration 配置出来中断为100us 168MHZ下*/
- timer_initpara.prescaler = 168 - 1;
- timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
- timer_initpara.counterdirection = TIMER_COUNTER_UP;
- timer_initpara.period = 100;
- timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
-
- nvic_irq_enable(TIMx_IRQn, TIMER1_NVIC_PREEMPTIONPRIORITY, TIMER1_NVIC_SUBPRIORITY);
-
-
- timer_init(TIMx, &timer_initpara);
-
- timer_interrupt_enable(TIMx, TIMER_INT_UP);
- timer_enable(TIMx);
-
- }
-
-
-
-
- /**
- * @brief This function handles TIMER1 interrupt request.
- * @param None
- * @retval None
- */
- void TIMx_IRQHandler(void)
- {
-
- if(SET == timer_interrupt_flag_get(TIMx, TIMER_INT_FLAG_UP)){
- /* clear channel 0 interrupt bit */
- timer_interrupt_flag_clear(TIMx, TIMER_INT_FLAG_UP);
-
- timer1_100us_cnt++;
-
- }
- }
-
-
-
- //定时器防止uint32_t溢出延时函数
- void Timer_Dly_Wait(uint32_t time)
- {
- uint32_t cur_cnt = timer1_100us_cnt;
-
- if(cur_cnt + time <= 0xFFFFFFFF)
- {
- while(timer1_100us_cnt - cur_cnt < time);
- }
- else
- {
-
- while(timer1_100us_cnt < 0xFFFFFFFF);
-
- time = time - (0xFFFFFFFF - cur_cnt);
- while(1 + timer1_100us_cnt < time);
- }
- }
-
-
-
infrared.c红外软编码硬解码实现
- #ifndef __INFRARED_H__
- #define __INFRARED_H__
-
- #include <string.h>
- #include "cmsis_os.h"
- #include "gd32f4xx.h"
- #include "config.h"
- #include "comtypes.h"
- #include "delay.h"
- #include "timer1.h"
- #include "raygunled.h"
- #include "mode.h"
-
-
- #define IR_TX_FUNC
- #define IR_RX_FUNC
-
-
-
- void IR_Init(void);
-
- void IR_Send(uint8_t*buf, uint8_t len);
-
-
-
- #endif
-
-
-
-
- #include "infrared.h"
-
-
- #define USART2_DATA_ADDRESS ((uint32_t)&USART_DATA(USART2))
- #define USART3_DR_ADDR USART2_DATA_ADDRESS
-
- #define USARTx USART2
- #define RCU_GPIO_CLK RCU_GPIOC
- #define RCU_USARTx_CLK RCU_USART2
- #define USART_GPIO_AF GPIO_AF_7
-
- #define USARTx_TX_GPIO_PORT GPIOC
- #define USARTx_TX_PIN GPIO_PIN_10
- #define USARTx_RX_GPIO_PORT GPIOC
- #define USARTx_RX_PIN GPIO_PIN_11
-
- #define DMAx DMA0
- #define RCU_DMAx_CLK RCU_DMA0
- #define USARTx_TX_DMA_CHANNEL DMA_CH3
- #define USARTx_RX_DMA_CHANNEL DMA_CH1
- #define USARTx_DMA_SUBPERI4 DMA_SUBPERI4
-
- #define USARTx_IRQn USART2_IRQn
- #define USARTx_IRQHandler USART2_IRQHandler
-
- #define USART3_RECV_BUFF_LEN (3)
-
- #define TX_PIN_SET gpio_bit_set(USARTx_TX_GPIO_PORT,USARTx_TX_PIN)
- #define TX_PIN_RESET gpio_bit_reset(USARTx_TX_GPIO_PORT,USARTx_TX_PIN)
- #define IR_TX(x) ((x) ? TX_PIN_SET : TX_PIN_RESET)
-
-
- static dma_single_data_parameter_struct dma_init_struct;
-
- //DMA接收缓冲区
- static __IO uint8_t usart3_recv_buf[USART3_RECV_BUFF_LEN];
-
- __IO BOOLEAN is_be_shooted = FALSE;
- __IO int shooted_bullet = 0;
-
-
-
- #ifdef IR_TX_FUNC
- static __INLINE void IR_DELAY(uint8_t tm)
- {
- uint8_t tmp;
-
- tmp = tm / 10;
- if(tmp)
- {
- osDelay(tmp);
- }
-
- tmp = tm % 10;
- if(tmp)
- {
- Timer_Dly_Wait(tmp);
- }
- }
- #endif
-
-
-
-
- void IR_Init(void)
- {
-
- rcu_periph_clock_enable(RCU_GPIO_CLK);
-
- /* enable USART clock */
- rcu_periph_clock_enable(RCU_USARTx_CLK);
-
- /* connect port to USARTx_Tx */
- //gpio_af_set(USARTx_TX_GPIO_PORT, USART_GPIO_AF, USARTx_TX_PIN);
-
- /* connect port to USARTx_Rx */
- gpio_af_set(USARTx_RX_GPIO_PORT, USART_GPIO_AF, USARTx_RX_PIN);
-
- /* configure USART Tx push-pull */
- gpio_mode_set(USARTx_TX_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP,USARTx_TX_PIN);
- gpio_output_options_set(USARTx_TX_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,USARTx_TX_PIN);
-
- gpio_bit_set(USARTx_TX_GPIO_PORT,USARTx_TX_PIN);
-
- /* configure USART Rx as alternate function push-pull */
- gpio_mode_set(USARTx_RX_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP,USARTx_RX_PIN);
- gpio_output_options_set(USARTx_RX_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,USARTx_RX_PIN);
-
-
- /* USART configure */
- usart_deinit(USARTx);
-
- //注意该波特率
- usart_baudrate_set(USARTx, 9600U);
- usart_word_length_set(USARTx, USART_WL_8BIT);
- usart_stop_bit_set(USARTx, USART_STB_1BIT);
- usart_parity_config(USARTx, USART_PM_NONE);
-
- usart_hardware_flow_rts_config(USARTx, USART_RTS_DISABLE);
- usart_hardware_flow_cts_config(USARTx, USART_CTS_DISABLE);
-
- usart_receive_config(USARTx, USART_RECEIVE_ENABLE);
- //usart_transmit_config(USARTx, USART_TRANSMIT_ENABLE);
-
- ///
- /* enable DMA1 */
- rcu_periph_clock_enable(RCU_DMAx_CLK);
-
- dma_deinit(DMAx, USARTx_RX_DMA_CHANNEL);
-
- dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
- dma_init_struct.memory0_addr = (uint32_t)usart3_recv_buf;
- dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
- dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
- dma_init_struct.number = USART3_RECV_BUFF_LEN;
- dma_init_struct.periph_addr = USART3_DR_ADDR;
- dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
- dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
-
- dma_single_data_mode_init(DMAx, USARTx_RX_DMA_CHANNEL, &dma_init_struct);
-
- /* configure DMA mode */
- dma_circulation_enable(DMAx, USARTx_RX_DMA_CHANNEL);
-
- dma_channel_subperipheral_select(DMAx, USARTx_RX_DMA_CHANNEL, USARTx_DMA_SUBPERI4);
-
-
- nvic_irq_enable(USARTx_IRQn, USART3_NVIC_PREEMPTIONPRIORITY, USART3_NVIC_SUBPRIORITY);
-
- usart_dma_receive_config(USARTx, USART_DENR_ENABLE);
- dma_channel_enable(DMAx, USARTx_RX_DMA_CHANNEL);
-
- usart_interrupt_enable(USARTx,USART_INT_IDLE);
- usart_enable(USARTx);
- }
-
-
-
-
-
- //NEC协议软编码
- void IR_Send(uint8_t*buf, uint8_t len)
- {
- #ifdef IR_TX_FUNC
- uint8_t i = 0;
- uint8_t j = 0;
- uint8_t tmp = 0;
-
-
- //发送9ms引导码 低电平
- IR_TX(0);
- IR_DELAY(90);
-
-
- //发送4.5ms结果码 高电平
- IR_TX(1);
- IR_DELAY(45);
- IR_TX(0);
-
-
- for(i=0;i < len;i++)
- {
-
- tmp = buf[i];
-
- //数据从低位向高位发送
- for(j=0;j < 8;j++)
- {
- //发送逻辑1
- if(tmp & 0x01)
- {
- IR_TX(0);
- IR_DELAY(5);
- Delay_US(60);
- //共计560us 低电平
-
- IR_TX(1);
- IR_DELAY(16);
- Delay_US(90);
- IR_TX(0);
- //共计1.690ms 高电平
- }
- //发送逻辑0
- else
- {
- IR_TX(0);
- IR_DELAY(5);
- Delay_US(60);
- //共计560us 低电平
-
- IR_TX(1);
- IR_DELAY(5);
- Delay_US(60);
- IR_TX(0);
- //共计560us 高电平
- }
-
- tmp >>= 1;
- }
- }
-
-
- //最后发送一个结束560us低电平,实验得到非常重要
- IR_TX(0);
- IR_DELAY(5);
- Delay_US(60);
-
- //波形两端拉高
- IR_TX(1);
- #endif
- }
-
-
-
-
-
- //串口3DMA空闲中断处理函数,用于接收BC7120A硬解码的红外数据。
- void USARTx_IRQHandler(void)
- {
- uint16_t tmp;
-
- dma_channel_disable(DMAx, USARTx_RX_DMA_CHANNEL);
- usart_interrupt_flag_clear(USARTx,USART_INT_FLAG_IDLE);
- usart_data_receive(USARTx);
-
-
- if(USART3_RECV_BUFF_LEN != dma_transfer_number_get(DMAx,USARTx_RX_DMA_CHANNEL)) goto USART3_IRQEND;
-
- tmp = usart3_recv_buf[0];
- if(usart3_recv_buf[1] != (uint8_t)~tmp) goto USART3_IRQEND;
- usart3_recv_buf[2] ^= (uint8_t)(tmp * 5);
-
-
- if(!Is_Raygunled_Hurt(usart3_recv_buf[2],&tmp)) goto USART3_IRQEND;
-
- shooted_bullet = tmp;
-
- is_be_shooted = TRUE;
-
-
- USART3_IRQEND:
-
- dma_deinit(DMAx, USARTx_RX_DMA_CHANNEL);
- dma_single_data_mode_init(DMAx, USARTx_RX_DMA_CHANNEL, &dma_init_struct);
- dma_circulation_enable(DMAx, USARTx_RX_DMA_CHANNEL);
- dma_channel_subperipheral_select(DMAx, USARTx_RX_DMA_CHANNEL, USARTx_DMA_SUBPERI4);
- dma_channel_enable(DMAx, USARTx_RX_DMA_CHANNEL);
- }
-
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。