有个关于预装载ARPE的问题我一直没弄懂。希望未来的的我能搞明白并且回来完善这篇文章。
不过我也不是什么都没做,我找了一篇挺棒的博客,虽然看的似懂非懂,但是有点感觉了,不过让我表述出来还是不行的。
博客
其实内容很简单,控制计数器从0到ARR(预设置的值),再设置一个用来比较的值CCRx,如果比CCRx小就输出低电平,反之高电平。
从这个例子很轻松就可以看出ARR控制频率(当然是在相同的时钟条件下)
CCRx控制占空比
CCR1:捕获比较(值)寄存器(x=1,2,3,4):设置比较值。
CCMR1: OC1M[2:0]位:
对于PWM方式下,用于设置PWM模式1【110】或者PWM模式2【111】
CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。
CCER:CC1E位:输入/捕获1输出使能。0:关闭,1:打开。
捕获/ 比较模式寄存器(TIMx_CCMR1~2)
捕获/比较使能寄存器(TIMx_CCER)
捕获/比较寄存器(TIMx_CCR1~4)
typedef struct
{
uint16_t TIM_OCMode; //PWM模式1或者模式2
uint16_t TIM_OutputState; //输出使能 OR失能
uint16_t TIM_OutputNState;
uint16_t TIM_Pulse; //比较值,写CCRx
uint16_t TIM_OCPolarity; //比较输出极性
uint16_t TIM_OCNPolarity;
uint16_t TIM_OCIdleState;
uint16_t TIM_OCNIdleState;
} TIM_OCInitTypeDef;
void TIM_OCxInit(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
设置比较值函数:
void TIM_SetCompareX(TIM_TypeDef* TIMx, uint16_t Compare2);
使能输出比较预装载:
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
使能自动重装载的预装载寄存器允许位:
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
ARPE:
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period=899;
TIM_TimeBaseInitStruct.TIM_Prescaler=0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse=0;
TIM_OC2Init(TIM3,&TIM_OCInitStruct);
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_Cmd(TIM3,ENABLE);
补充:
delay_ms(10);
if(t==0)
dir=1;
if(t>100)
dir=0;
if(dir==1)
{
t++;
TIM_SetCompare2(TIM3,t);
}
else
{
t--;
TIM_SetCompare2(TIM3,t);
}
没想到这东西居然让我想了半天。
第一点:
while(1)里delay函数很重要,很重要,很重要。
不管你定时器设置周期是长是短。
定时器设置的周期只影响看上去是不是有明显的颗粒感,如果定时器时间长就很有闪烁,时间短就很丝滑。
但是没有delay函数就没有渐变的效果,占空比乱飞。
所以delay很重要,一定要加,不管什么情况。
第二点:上下拉
pwm1 pwm2选择有效使能。
然后我们再设置有效使能是高电平还是低电平。
下面结论仅限于我的观察推理,并没有理论依据:
如果有效使能是后半段,那么前半段一定是下拉的。
如果有效使能是前半段,那么后半段一定是上拉的。
麻蛋,就是这个该死的东西害我想了半天,一直在找bug,疯狂调试!!!
(2020/3/8)
第二个结论存疑,是假的!!