郞性人生

导航

GD32F103 IR红光驱动,发送

1_头文件.h

#ifndef __IR_TX_DRIVER_H__
#define __IR_TX_DRIVER_H__


#define IR_PIN_RCC                  RCU_GPIOA
#define IR_SIGNAL_PORT              GPIOA
#define IR_SIGNAL_PIN               GPIO_PIN_11
#define IR_AF_RCC_CLK()             rcu_periph_clock_enable(RCU_AF);

#define IR_TIMER_38K_RCC            RCU_TIMER2
#define IR_TIMER_SIGNAL_RCC         RCU_TIMER1
#define IR_TIMER_38K                TIMER2
#define IR_TIMER_SIGNAL             TIMER1
#define IR_TIMER_CH                 TIMER_CH_3

#define IR_TIMER_SIGNAL_IRQn       TIMER1_IRQn 

#define IR_TIMER_SIGNAL_IRQHandler   TIMER1_IRQHandler #endif //end __IR_TX_DRIVER_H__

 2.原文件.c

#include "gd32f10x.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "event_groups.h"
#include "bsp_ir_tx_driver.h"
#include "Midea_RN02D_BG_IR_CODE.h"
/*
功能要求:根据不同的控制码,定时器控制38KHz的脉冲输出,1输出脉冲,0不输出脉冲;
1.使用单片机定时器IR_TIMER_38K产生38Khz红外载波信号,使用定时器IR_TIMER_SIGNAL产生遥控信号时序;
2.遥控信号时序:同步头+信号+5.3mm+同步头+信号
2.1).逻辑1怎么表示:    底电平560us脉冲+1680us高电平
2.2).逻辑0怎么表示:    底电平560us脉冲+560us高电平
2.3).同步怎么表示:    底电平4.5m脉冲+4.5ms高电平
2.4).初始电平:    初始电平高电平,此时无输出
3.使用单片机管脚产后控制信号,
*/

void ir_tx_init(void)
{
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(IR_PIN_RCC);
    rcu_periph_clock_enable(IR_TIMER_38K_RCC);
    rcu_periph_clock_enable(IR_TIMER_SIGNAL_RCC);
    IR_AF_RCC_CLK();
    gpio_init(IR_SIGNAL_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, IR_SIGNAL_PIN);

    timer_deinit(IR_TIMER_38K);
    timer_deinit(IR_TIMER_SIGNAL);
    /* IR_TIMER_38K configuration */
    timer_initpara.prescaler         = 107;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 25;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(IR_TIMER_38K,&timer_initpara);

    /* IR_TIMER_SIGNAL configuration */
    timer_initpara.prescaler         = 107;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_DOWN;
    timer_initpara.period            = 1;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(IR_TIMER_SIGNAL,&timer_initpara);

    /*CH3 configuration in PWM mode1 */
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_LOW;
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_LOW;
    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;

    timer_channel_output_config(IR_TIMER_38K,IR_TIMER_CH,&timer_ocintpara);

    timer_channel_output_pulse_value_config(IR_TIMER_38K,IR_TIMER_CH,12);
    timer_channel_output_mode_config(IR_TIMER_38K,IR_TIMER_CH,TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(IR_TIMER_38K,IR_TIMER_CH,TIMER_OC_SHADOW_DISABLE);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_disable(IR_TIMER_SIGNAL);
    timer_interrupt_flag_clear(IR_TIMER_SIGNAL, TIMER_INT_FLAG_UP);
    timer_interrupt_enable(IR_TIMER_SIGNAL, TIMER_INT_UP);
    nvic_irq_enable(IR_TIMER_SIGNAL_IRQn, 1, 0);
    /* IR_TIMER_SIGNAL counter enable */
//    timer_enable(IR_TIMER_SIGNAL);

//    timer_primary_output_config(IR_TIMER_38K, ENABLE);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(IR_TIMER_38K);
    timer_enable(IR_TIMER_38K);
}
/*启动一次遥控控制码发送
参数:

IR_CONTROL_COM IrTxCom 空调控制码
AIR_BRAND brand          空调品牌
*/
void ir_tx_start(IR_CONTROL_COM TxCom, AIR_BRAND brand)
{
    IrTxCom = TxCom;
    irTxbrand = brand;
    timer_counter_value_config(IR_TIMER_SIGNAL, 1);
    timer_enable(IR_TIMER_SIGNAL);
    timer_enable(IR_TIMER_38K);
}

/**
  * @brief  This function handles TIMER3 interrupt request.
  * @param  None
  * @retval None
  */
/*
功能:控制红个载波的输出时序,输出空调需要的控制码信息
输出的控制码由全局变量 IrTxCom 决定;
*/
static uint8_t ir_bit_i=0;
uint8_t IrTxCenterCount = 0;    //两帧之间连接码发送计数据标志
uint8_t index_code = 0;         //引导码发送数据标志
uint8_t Logic_Level_Send = 0;   //逻辑电平判断标志
uint8_t IrTxCodeCount = 0;      //控制码发送计数
uint8_t  IrTxCodeSize = 6;      //控制码长度
uint8_t FirstSend = 0;          //一帧数据发完成标志
IR_CONTROL_COM IrTxCom = 0;   //控制指令只能通过 ir_tx_start() 修改,控制指令在ir_tx_driver.h中,控制码在Midea_RN02D_BG_IR_CODE.h中
AIR_BRAND irTxbrand = 0;        //空调品牌只能通过 ir_tx_start() 修改,没有启用
void IR_TIMER_SIGNAL_IRQHandler(void)
{
    UBaseType_t uxSavedInterruptStatus;
    uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); /* 进入临界区 */
    timer_disable(IR_TIMER_SIGNAL);
    timer_interrupt_flag_clear(IR_TIMER_SIGNAL, TIMER_INT_FLAG_UP);

    if ((index_code == 2) && (IrTxCodeCount<IrTxCodeSize))
    {
        if (ir_bit_i==8)
        {
            IrTxCodeCount++;
            ir_bit_i=0;
        }
        if((Logic_Level_Send == 0) && (IrTxCodeCount<IrTxCodeSize))
        {
            timer_primary_output_config(IR_TIMER_38K, ENABLE);
            timer_counter_value_config(IR_TIMER_SIGNAL, 490);
            timer_enable(IR_TIMER_SIGNAL);
            Logic_Level_Send=1;
        }
        else if(((Logic_Level_Send==1)&&(RNO2D_BG_IR_CONTROL_CODE[IrTxCom][IrTxCodeCount]&(1<<ir_bit_i)) == 0) && (IrTxCodeCount<IrTxCodeSize))    //逻辑电平判断
//        else if((Logic_Level_Send==1) &&((test_data[IrTxCodeCount]&(1<<ir_bit_i))==0) && (IrTxCodeCount<IrTxCodeSize))
        {
            timer_primary_output_config(IR_TIMER_38K, DISABLE);
            timer_counter_value_config(IR_TIMER_SIGNAL, 600);
            timer_enable(IR_TIMER_SIGNAL);
            Logic_Level_Send=0;
            ir_bit_i++;
        }
        else if(((Logic_Level_Send==1)&&(RNO2D_BG_IR_CONTROL_CODE[IrTxCom][IrTxCodeCount]&(1<<ir_bit_i)) != 0) && (IrTxCodeCount<IrTxCodeSize))
//        else if((Logic_Level_Send==1) &&((test_data[IrTxCodeCount]&(1<<ir_bit_i))!=0)&& (IrTxCodeCount<IrTxCodeSize))
        {
            timer_primary_output_config(IR_TIMER_38K, DISABLE);
            timer_counter_value_config(IR_TIMER_SIGNAL, 1700);
            timer_enable(IR_TIMER_SIGNAL);
            Logic_Level_Send=0;
            ir_bit_i++;
        }

    }

    if(index_code == 0) //引导码 高电平
    {
        timer_primary_output_config(IR_TIMER_38K, ENABLE);
        timer_counter_value_config(IR_TIMER_SIGNAL, 4500);
        timer_enable(IR_TIMER_SIGNAL);
        index_code = 1;
    }
    else if(index_code == 1)
    {
        timer_primary_output_config(IR_TIMER_38K, DISABLE);
        timer_counter_value_config(IR_TIMER_SIGNAL, 4500);
        timer_enable(IR_TIMER_SIGNAL);
        index_code = 2;
        IrTxCodeCount = 0;
        IrTxCenterCount = 0;
        Logic_Level_Send = 0;
        ir_bit_i=0;
    }
    if ((IrTxCodeCount == IrTxCodeSize)&&(index_code == 2) &&(FirstSend == 0)) //完成第一次发送
    {
        if(IrTxCenterCount == 0)
        {
            timer_primary_output_config(IR_TIMER_38K, ENABLE);
            timer_counter_value_config(IR_TIMER_SIGNAL, 490);
            timer_enable(IR_TIMER_SIGNAL);
            IrTxCenterCount = 1;
        }
        else if(IrTxCenterCount == 1)
        {
            timer_primary_output_config(IR_TIMER_38K, DISABLE);
            timer_counter_value_config(IR_TIMER_SIGNAL, 5200);
            timer_enable(IR_TIMER_SIGNAL);
            index_code = 0;
            FirstSend = 1;
        }
    }
    else if((IrTxCodeCount == IrTxCodeSize)&&(index_code == 2) &&(FirstSend == 1))
    {
        timer_primary_output_config(IR_TIMER_38K, ENABLE);
        timer_counter_value_config(IR_TIMER_SIGNAL, 490);
        timer_enable(IR_TIMER_SIGNAL);
        FirstSend = 2;;
    }
    else if((IrTxCodeCount == IrTxCodeSize)&&(index_code == 2) &&(FirstSend == 2))
    {
        timer_primary_output_config(IR_TIMER_38K, DISABLE);
        timer_disable(IR_TIMER_SIGNAL);
        timer_disable(IR_TIMER_38K);
        IrTxCodeCount = 0;
        IrTxCenterCount = 0;
        FirstSend = 0;
        index_code = 0;
        Logic_Level_Send=0;
        ir_bit_i=0;
    }
    portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); /* 退出临界区 */
}



/********** end of file ***********/

 

posted on 2018-12-28 13:52  郞性人生  阅读(646)  评论(0)    收藏  举报