使用查询模式:使用的是disable串口中断
'0’指是是ASCII字符0,不是十六进制
1/9 1/3000
0 1500
45 3000
a度数 x波
a = (x-0.5)90
x=a/90.0+0.5
t = x3000
1/3000
1/9
0 1500 0.5
18 2100 0.7
27 2400 0.8
30.06 2502 0.834 1002
36 2700 0.9
45 3000 1 4.5=(1-0.5)*9
63 3600 1.2 6.3=(1.2-0.5)*9 倒着算
72 3900 1.3
81 4200 1.4
90 4500 1.5 9.0=(1.5-0.5)*9
108 5100 1.7
126 5700 1.9
135 6000 2
162 6900 2.3
180 7500 2.5
利用数据计算出公式,就可以实现无论输入任何角度,舵机都能转出对应的角度
需要usart.h和usart.c串口通信
int main (void){//主程序
vu16 t;
delay_ms(500); //上电时等待其他器件就绪
RCC_Configuration(); //系统时钟初始化
RELAY_Init();//继电器初始化
USART1_Init(115200);
I2C_Configuration();//I2C初始化
TIM3_PWM_Init(59999,23); //设置频率为50Hz,公式为:溢出时间Tout(单位秒)=(arr+1)(psc+1)/Tclk 20MS = (59999+1)*(23+1)/72000000
//Tclk为通用定时器的时钟,如果APB1没有分频,则就为系统时钟,72MHZ
//PWM时钟频率=72000000/(59999+1)*(23+1) = 50HZ (20ms),设置自动装载值60000,预分频系数24
while(1){
//查询方式接收
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET){ //查询串口待处理标志位
a =USART_ReceiveData(USART1);//读取接收到的数据
//将角度转换为占空比
t=(a/90.0+0.5)*3000.0;
TIM_SetCompare3(TIM3,t);
printf("%d ",a);
}
}
}
while(1)里不能写东西
使用定时器中断
需要tim.c和tim.h采用定时器中断while(1)中就不需要写入程序
int main (void){//主程序
vu16 a;
vu16 t;
delay_ms(500); //上电时等待其他器件就绪
RCC_Configuration(); //系统时钟初始化
RELAY_Init();//继电器初始化
USART1_Init(115200);
I2C_Configuration();//I2C初始化
OLED0561_Init(); //OLED初始化
OLED_DISPLAY_8x16_BUFFER(0," YoungTalk "); //显示字符串
OLED_DISPLAY_8x16_BUFFER(3," SG90 TEST2 "); //显示字符串
TOUCH_KEY_Init();//按键初始化
TIM3_PWM_Init(59999,23); //设置频率为50Hz,公式为:溢出时间Tout(单位秒)=(arr+1)(psc+1)/Tclk 20MS = (59999+1)*(23+1)/72000000
//Tclk为通用定时器的时钟,如果APB1没有分频,则就为系统时钟,72MHZ
//PWM时钟频率=72000000/(59999+1)*(23+1) = 50HZ (20ms),设置自动装载值60000,预分频系数24
TIM3_Init(59999,23);//定时器初始化,定时1秒(9999,7199)
while(1){
}
}
void TIM3_IRQHandler(void)TIM3中断处理函数
在这个函数体内写入串口控制舵机的程序即可
#include "tim.h"
//定时器时间计算公式Tout = ((重装载值+1)*(预分频系数+1))/时钟频率;
//例如:1秒定时,重装载值=9999,预分频系数=7199
void TIM3_Init(u16 arr,u16 psc){ //TIM3 初始化 arr重装载值 psc预分频系数
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3
TIM3_NVIC_Init (); //开启TIM3中断向量
TIM_TimeBaseInitStrue.TIM_Period=arr; //设置自动重装载值
TIM_TimeBaseInitStrue.TIM_Prescaler=psc; //预分频系数
TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; //计数器向上溢出
TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1; //时钟的分频因子,起到了一点点的延时作用,一般设为TIM_CKD_DIV1
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue); //TIM3初始化设置
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//使能TIM3中断
TIM_Cmd(TIM3,ENABLE); //使能TIM3
}
void TIM3_NVIC_Init (void){ //开启TIM3中断向量
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x3; //设置抢占和子优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM3_IRQHandler(void){ //TIM3中断处理函数
u16 a;
u16 t;
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){ //判断是否是TIM3中断
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
//此处写入用户自己的处理程序
// GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); //取反LED1
//查询方式接收
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET){ //查询串口待处理标志位
a =USART_ReceiveData(USART1);//读取接收到的数据
//将角度转换为占空比
// i=a/90.0;
// x= a/90.0+0.5;
t=(a/90.0+0.5)*3000.0;
TIM_SetCompare3(TIM3,t);
printf("%d ",a);
}
}
}