STM32红外接收与发送实战一(发射红外信号):利用定时器产生一个38KHZ的载波来发送红外信号

        在上一篇博客《STM32红外接收与发送实战一》中,我们了解到大多数红外信号遵循的是 NEC 协议。该协议的核心组成部分包括 引导码用户码用户码反码按键键码键码反码。此外,还明白了红外发射信号是通过调制在一个 38kHz 的载波上发射出去的。

因此,如果我们要实现红外信号的发送,首先需要生成一个 38kHz 的载波信号,然后按照 NEC 协议的格式将数据编码并发射出去。这个载波信号的存在决定了红外发射管何时打开或关闭,而数据则通过载波的脉冲来传递。

首先,要通过定时器产生一个38KHZ的脉冲信号。先进行定时器的初始化(因为我的红外发射管连接着定时器3的CH3通道,所以来初始化这个IO口)

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽复用输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    // 3. 配置TIM3的时钟频率和周期
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_TimeBaseStructure.TIM_Prescaler = 70;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = 25;      
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    // 4. 配置PWM模式,首先初始化占空比为0%
    TIM_OCInitTypeDef TIM_OCInitStruct;
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_Pulse = 0;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC3Init(TIM3,&TIM_OCInitStruct);
    // 5. 使能或者失能 TIMx 在 CCR1 上的预装载寄存器
    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
    // 6. 启动定时器
    TIM_Cmd(TIM3, ENABLE);

因为我初始化占空比为0,要产生一个38KHZ的载波信号,占空比需要为三分之一,所以使用这行代码可以产生一个38KHZ的载波信号(当占空比为零时,可以认为,不产生信号)

TIM_SetCompare3(TIM3, 8);

我们发送红外信号是遵循NEC协议来发送的,

当为高电平时,我们的38KHZ的载波信号发射,当为低电平时,关闭载波信号。

//发送引导码
void RED_Send_Boot(void){
    TIM_SetCompare3(TIM3, 8);
    Delay_us(9000);
    TIM_SetCompare3(TIM3, 0);
    Delay_us(4500);
}
//发送数据码,0还是1;
void RED_Send_Data(uint8_t data){
    if(data==0){
        TIM_SetCompare3(TIM3, 8);
        Delay_us(560);
        TIM_SetCompare3(TIM3, 0);
        Delay_us(560);
    }
    else{
        TIM_SetCompare3(TIM3, 8);
        Delay_us(560);
        TIM_SetCompare3(TIM3, 0);
        Delay_us(1690);
    }
}
//发送数据
void RED_Send_Data_all(uint8_t* data,uint8_t len){
    RED_Send_Boot();
    for(int i=0;i<len;i++){
        for(int j=7;j>=0;j--){
            uint8_t qwe =(data[i]>>j)&0x01;
            RED_Send_Data(qwe);
        }
    }
}

在主函数中,通过调用RED_Send_Data_all函数来发射红外数据。(注意,这里没有发送用户编码,其实要是自己玩玩的话,协议可以自已设定,只要发送方和接收方约定好就行)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值