谈到38kHz可能大部分人不明白,为什么要配置IO口以38kHz来输出?!
但是如果接触过红外遥控的人想必就会比较清楚,现在市面上售卖的一体化红外接收头只接收38kHz的红外调制信号,一般的红外发射端都是板载455kHz,通过整顿分频,得出了约等于38kHz的频率,再跟数据发射脚进行“与”操作来实现数据发送,这样既可以提高发射效率又可以降低电源功耗。
如果只是编写现成红外模块的程序,网上有比较多的445kHz晶振调制38kHz频率的程序可以借鉴,下面给出M0(stm32f030f4p6)基于外部8M晶振的38kHz调制频率代码~
void User_Infrared_Config()
{
//创建结构体
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//使能GPIO时钟,定时器TIM3时钟
RCC_AHBPeriphClockCmd(Infrared_GPIO_CLK,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
//DPIO配置及初始化 声明引脚复用
GPIO_InitStructure.GPIO_Pin = Infrared_pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(Infrared_GPIO_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(Infrared_GPIO_PORT,GPIO_PinSource1,GPIO_AF_1);
//定时器配置
TIM_TimeBaseStructure.TIM_Period = (SystemCoreClock/38000)-1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_Cmd(TIM3,ENABLE);
//TIM_CH4 PWM配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (SystemCoreClock/38000)/3;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(TIM3,&TIM_OCInitStructure);
//使能PWM
TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);
}
这里要注意一点,代码中的时钟跟引脚都是使用了宏定义的名称,按照个人的设备需要稍作修改。
大概说一下代码配置,38kz频率主要是以引脚PWM模式输出来实现,而且采用了IO口的引脚复用功能,不懂什么是复用功能的同学自行百度一下,配置GPIO时引脚功能选择为复用功能,即
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF
不同于M3、M4的配置的是,M3、M4需要使能复用时钟,然而M0的库函数却始终找不到复用时钟的宏定义,取而代之的是一个引脚复用配置函数
GPIO_PinAFConfig(Infrared_GPIO_PORT,GPIO_PinSource1,GPIO_AF_1)
最后一个参数 GPIO_AF_1
需要对照stm32f030芯片手册的引脚复用表做相应配置
~M0的手册真心不好找~
由上表可见,PB1的TIM3_CH4复用功能是对应AF1列,相应的要复用定时器14的话就是AF0了
接着,定时器配置,设置自动重装载计数值为 (SystemCoreClock/38000)-1
以确保38kHz的波形可以产生
TIM_TimeBaseStructure.TIM_Period = (SystemCoreClock/38000)-1
配置引脚PWM模式,TIM_Pulse
用来配置占空比的大小,需要注意的是 TIM_OC4Init()
和 TIM_OC4PreloadConfig()
这两个函数,用的是定时器的第几通道的函数名都是不一样的,程序中用的第4通道,所以函数名都是TIM_OC4Init
、TIM_OC4PreloadConfig
如果用的第1通道就是TIM_OC1Init
和 TIM_OC1PreloadConfig
以此类推。
配置好在main函数中初始化,然后就可以用示波器看到一个接近完美的波形啦 ~