一、输出比较(OC)
在stm32中,输出比较即OC(Output Compare),输出比较可以通过比较CNT(计数器)与CCR(捕获/比较寄存器)寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。
一、PWM
PWM(脉冲宽度调制)
在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟,常用于电机控制速度等领域。
在stm32中,用于输出pwm的方式有很多,第一种是可以用普通IO口输出pwm,第二种是利用定时器的pwm的IO口或复用IO口。
①pwm端口:
STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出
②普通IO口:
一般能够输出PWM的端口都会在主要功能那一栏出现CHx的标志,而普通定时器没有出现这种标志。
我们可以通过改变灯的有效电压占空比来实现呼吸灯效果。其中我们要用到PWM(脉宽调制),通过pwm我们可以来改变高电平的占空比
·占空比:在一个周期中,高电平所占整个周期的百分比
具体如图:
当我们用pwm来生成呼吸灯时,因为在stm32f103rct6中PA8LED灯是通过给PA8输入一个低电平点亮的,所以低电平在一个周期中维持的时间越长,灯越亮。
具体实现看代码:
void Pwm_Init()
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
/*1、使能时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA |RCC_APB2Periph_TIM1,ENABLE);
/*2、配置GPIO*/
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8; //引脚8 LED1
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //复用
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //速度
GPIO_Init(GPIOA,&GPIO_InitStruct);
//4、初始化定时器,配置ARR,PSC。
TIM_TimeBaseInitStruct.TIM_Prescaler = psc; //分频系统 ,每秒数多少个数
TIM_TimeBaseInitStruct.TIM_Period = per; //重装值
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //分频因子
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0x00;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);
/*配置pwm*/
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; //PWM1模式
TIM_OCInitStruct.TIM_OutputState= TIM_OutputState_Enable;//输出使能
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; //极性低
TIM_OCInitStruct.TIM_Pulse = 0x00;
TIM_OC1Init(TIM1,&TIM_OCInitStruct);
//5、使能预装载寄存器:
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
//6、使能自动重装载的预装载寄存器允许位
TIM_ARRPreloadConfig(TIM1,ENABLE);
/*pwm输出通道使能*/
TIM_CtrlPWMOutputs(TIM1,ENABLE);
//7、使能定时器。
TIM_Cmd(TIM1,ENABLE);
}
主函数:
void HardWare_Init(void)
{
SysTick_Init(72);
Pwm_Init(100-1,7200-1);
}
int main(void)
{
u8 cnt = 0;
u8 fx = 1;
HardWare_Init();
while(1)
{
if(fx)
{
cnt++;
if(cnt>99)
{
fx = 0;
}
}
else
{
cnt--;
if(cnt < 1)
{
fx = 1;
}
}
TIM_SetCompare1(TIM1,cnt);
delay_ms(20);
}
}