直接上代码
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "pwm.h"
u8 t = 0;
int main()
{
u8 t = 50;
delay_init();
pwm_init(); //PWM初始化
while(1)
{
if(t == 251)
t = 150;
TIM_SetCompare1(TIM3, t++);
}
delay_ms(100);
}
}
pwm初始化各个地方都能找到类似代码,这里不再赘述
舵机用pwm进行驱动,
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;
要注意如下问题
- 必须不断改变占空比才能实现舵机的转动,同一个占空比也就只能转一下
- 那么由此就有了第二个问题,怎沫改变占空比。20ms一个周期,高电平时间为以上那些对应不同角度。所以我们可以TIM_SetCompare1(TIM3, t++);不断改变TIM3->CCR1寄存器的值,就可以改变占空比。以上是一种方法,改一次,进行延时,这样舵机有足够的时间转动。(注意:用正点原子的delay代码,一定要在主函数执行开始进行初始化)还有一种方法,用中断,而且就用TIM3中断,不会影响,他可以既可以输出PWM ,还可以做定时器中断计算时间。时钟就那样,然后可以有四个通道。。。
u8 t = 0;
int main()
{
u8 x = 50;
// tcn = 10000, t = 150;
// delay_init();
pwm_init(); //PWM初始化
while(1)
{
if(t == 1)
{
t = 0;
TIM_SetCompare1(TIM3, x++);//0度
}
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
}
}
pwm.c文件如下
#include "pwm.h"
extern u8 t;
void pwm_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //声明一个结构体变量,用来初始化GPIO
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//声明一个结构体变量,用来初始化定时器
TIM_OCInitTypeDef TIM_OCInitStructure;//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
NVIC_InitTypeDef NVIC_InitTypestrut;
/* 开启时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
/* 配置GPIO的模式和IO口 */
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;// PC6
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
GPIO_Init(GPIOC,&GPIO_InitStructure);
//TIM3定时器初始化
TIM_TimeBaseInitStructure.TIM_Period =1999; //PWM 频率=72000/(199+1)=36Khz//设置自动重装载寄存器周期的值
TIM_TimeBaseInitStructure.TIM_Prescaler =719;//设置用来作为TIMx时钟频率预分频值
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;//设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
NVIC_InitTypestrut.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitTypestrut.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitTypestrut.NVIC_IRQChannelPreemptionPriority = 3;//抢占优先级
NVIC_InitTypestrut.NVIC_IRQChannelSubPriority = 0;//
NVIC_Init(&NVIC_InitTypestrut);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//改变指定管脚的映射 //pC6
//PWM初始化 //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//PWM输出使能
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OC1Init(TIM3,&TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能或者失能TIMx在CCR1上的预装载寄存器
TIM_ARRPreloadConfig(TIM3,DISABLE);
TIM_Cmd(TIM3,ENABLE);//使能或者失能TIMx外设
}
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update) == SET)
{
t = 1;
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
}