#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "beep.h"
#include "oled7pin.h"
#include "BaseTim6.h"
#include "key.h"
#include "MPU6050.h"
#include "IOI2C.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "inv_mpu.h"
#include "TB6612.h"
#include "encoder.h"
#include "stepper.h"
#include "stepper_T_curve.h"
#include "at24iic.h"
#include "at24cxx.h"
#include "servo1servo2.h"
#include "time9pwm.h"
int main(void)
{
u8 keyv=0;
Nvic_Init(NVIC_PriorityGroup_4);//中断分组第四组 高优先打断低优先
Set_Nvic_Irq(USART1_IRQn,3,3);//设置串口1的中断等级;
Set_Nvic_Irq(TIM6_DAC_IRQn,0,3);//设置串口1的中断等级;
Set_Nvic_Irq(TIM1_UP_TIM10_IRQn,0,3);//设置TIM10的中断等级;
Set_Nvic_Irq(TIM1_TRG_COM_TIM11_IRQn,0,3);//设置串口1的中断等级;
Set_Nvic_Irq(TIM8_CC_IRQn,0,3);//设置串口1的中断等级;
Delay_Init();//延时函数默认中断优先级是最低的。
LED_Init();//LED灯初始化
BEEP_Init();//蜂鸣器初始化
uart1_init(115200);//设置串口1的波特率是115200
Usart_SendByte(USART1,'a');//测试单字节发送函数
Usart_SendByte(USART1,'b');//测试单字节发送函数
Usart_SendString(USART1,"tab\r\n");//测试字符串发送函数
printf("hello world\r\n");//这个也能用,测试printf函数
printf("LED=2222\r\n");//这个也能用,测试printf函数
Printf(USART1,"LED=2222,\r\n");//这个也能用,测试大写的Printf函数
OLED_Init();
OLED_Clear();
OLED_ShowChar816(0,0,'H');
KEY_Init();
Servo1Servo2Timer9_init();//初始化
BaseTim6_Init(1);//初始化定时器,同时使能定时器,在定时器中断中,读取编码器数据,打印数据
while(1)
{
keyv=KEY_Read_Short();//读取按键
if(keyv == KEY8_Short)//正方向
{
Servo2_move(0,1);
LED2=0;
}
else if(keyv==KEY7_Short)//停止
{
Servo2_move(90,1);
LED2=1;
}
else if(keyv == KEY6_Short)//正方向
{
Servo2_move(225,1);
LED3=0;
}
else if(keyv==KEY5_Short)//停止
{
Servo2_move(270,1);
LED3=1;
}
}
}
#include "time9pwm.h"
void TIM9_PWM_Init(u32 arr,u32 psc)//E5++E6
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//这个特别注意,RCC_APB2Periph_TIM9,这是RCC_APB2,而不是其他的apb1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9,ENABLE); //TIM9 时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //使能 PORTF 时钟
GPIO_PinAFConfig(GPIOE,GPIO_PinSource5,GPIO_AF_TIM9); //GF9 复用为 TIM14
GPIO_PinAFConfig(GPIOE,GPIO_PinSource6,GPIO_AF_TIM9); //GF9 复用为 TIM14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 ; //GPIOF9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度 50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE,&GPIO_InitStructure); //初始化 PF9
//
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM9,&TIM_TimeBaseStructure);//初始化定时器 14
//初始化 TIM14 Channel1 PWM 模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM 调制模式 1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性低 TIM_OCPolarity_High TIM_OCPolarity_Low
TIM_OC1Init(TIM9, &TIM_OCInitStructure); //初始化外设 TIM1 4OC1
TIM_OC1PreloadConfig(TIM9, TIM_OCPreload_Enable); //使能预装载寄存器
TIM_OC2Init(TIM9, &TIM_OCInitStructure); //初始化外设 TIM1 4OC1
TIM_OC2PreloadConfig(TIM9, TIM_OCPreload_Enable); //使能预装载寄存器
TIM_ARRPreloadConfig(TIM9,ENABLE);//ARPE 使能
TIM_Cmd(TIM9, DISABLE); //使能 TIM14
}
#ifndef __time9PWM_H
#define __time9PWM_H
#include "sys.h"
#include "stm32f4xx.h"
#include "delay.h"
void TIM9_PWM_Init(u32 arr,u32 psc);//E5++E6
#endif
#ifndef __servo1servo2_H
#define __servo1servo2_H
#include "sys.h"
#include "time9pwm.h"
extern int Servo1_LastAngle;
extern int Servo2_LastAngle;
#define ServoTimer9Arr 19999 //这个和168-1配对,20ms(20000-1) //199
#define ServoTimer9Psc 167 //168-1 ,,,168mhz/168=1mhz===1us
#define Servo1kkk 0.0111f //(0.5/45.0) 就是45度需要0.5ms,这个需要根据实际修改
#define Servo1class 1 //以1度为分辨率,最小是1度。越大,分割越少
//**********针对的是180度舵机
#define Servo2kkk 0.0111f //(0.5/45.0) 就是45度需要0.5ms,这个需要根据实际修改
#define Servo2class 1 //以1度为分辨率,最小是1度。越大,分割越少
//**********针对的是270度舵机,0---2.5ms对应0--270度,那么每个45度一个间隔,有6个间隔,2.5/6=0.4167ms
#define Servo2kkk270 0.00925f //(0.4167/45.0) 就是45度需要0.4167ms,这个需要根据实际修改
#define Servo2class270 1 //以1度为分辨率,最小是1度。越大,分割越少
//初始化
void Servo1Servo2Timer9_init(void);
//移动到目标角度,延时的时间
void Servo1_move(int anglepos,int ServoDalayms);
//移动到目标角度,延时的时间
void Servo2_move(int anglepos,int ServoDalayms);
#endif
#include "servo1servo2.h"
int Servo1_LastAngle=0;
int Servo2_LastAngle=0;
//初始化
void Servo1Servo2Timer9_init(void)//初始化
{
Servo1_LastAngle=0;
Servo2_LastAngle=0;
TIM9_PWM_Init(ServoTimer9Arr,ServoTimer9Psc);//E5++E6
TIM_Cmd(TIM9, ENABLE);
}
//舵机1运动,角度的延时函数
void Servo1_move(int anglepos,int ServoDalayms)
{
int dangle=0;
u8 i=0;
u8 angleclass=0;
u8 angleyushu=0;
u32 ttt=0;
dangle=anglepos-Servo1_LastAngle;
if(dangle<0)
dangle=(-1)*dangle;
angleclass=dangle/Servo1class;//50
angleyushu=dangle%Servo1class;//0
//10/2=5 11/2=5余数1,走4次2度,然后后面的走2+1=3
if(angleyushu==0)
{
if((anglepos-Servo1_LastAngle)>0)//50
{
for(i=0;i<angleclass;i++)
//这个1000怎么来呢?ttt是高电平的时间对应的加法树量,角度对应的占空比时间tw/20ms =占空比,再乘以20ms对应的加法数量20000
//tw/20*20000=tw*1000
{
ttt=(0.5+Servo1kkk*(Servo1_LastAngle+i*Servo1class))*1000;
TIM_SetCompare1(TIM9,ttt);// 除以20,乘以20 000
delay_ms(ServoDalayms);
}
}
else if((anglepos-Servo1_LastAngle)<0)
{
for(i=0;i<angleclass;i++)
{
ttt=(0.5+Servo1kkk*(Servo1_LastAngle-i*Servo1class))*1000;
TIM_SetCompare1(TIM9,ttt);
delay_ms(ServoDalayms);
}
}
}
else if(angleyushu!=0) //存在余数
{
if((anglepos-Servo1_LastAngle)>0)
{
for(i=0;i<(angleclass-1);i++)
{
ttt=(0.5+Servo1kkk*(Servo1_LastAngle+i*Servo1class))*1000;
TIM_SetCompare1(TIM9,ttt);
delay_ms(ServoDalayms);
}
TIM_SetCompare1(TIM9,(0.5+Servo1kkk*anglepos)*1000);
delay_ms(ServoDalayms);
}
else if((anglepos-Servo1_LastAngle)<0)
{
for(i=0;i<angleclass;i++)
{
ttt=(0.5+Servo1kkk*(Servo1_LastAngle-i*Servo1class))*1000;
TIM_SetCompare1(TIM9,ttt);
delay_ms(ServoDalayms);
}
TIM_SetCompare1(TIM9,(0.5+Servo1kkk*anglepos)*1000);
delay_ms(ServoDalayms);
}
}
Servo1_LastAngle=anglepos;
}
//舵机2运动,角度的延时函数
//Servo2kkk270
void Servo2_move(int anglepos,int ServoDalayms)
{
int dangle=0;
int i=0;
int angleclass=0;
int angleyushu=0;
float ttt=0;
dangle=anglepos-Servo2_LastAngle;
// printf("dangle=%d,anglepos=%d\r\n",dangle,anglepos);
if(dangle<0)
dangle=(-1)*dangle;
angleclass=abs(dangle)/Servo2class;//50
// printf("angleclassWWW=%d\r\n",angleclass);
// angleyushu=dangle%Servo2class;//0
//10/2=5 11/2=5余数1,走4次2度,然后后面的走2+1=3
if((anglepos-Servo2_LastAngle)>0)//50
{
for(i=0;i<angleclass;i++)
{
ttt = 500+7.4*(Servo2_LastAngle+i);
TIM_SetCompare2(TIM9,(int)ttt);// 除以20,乘以20 000
printf("i=%d\r\n",i);
delay_ms(ServoDalayms);
}
}
else if((anglepos-Servo2_LastAngle)<0)
{
for(i=0;i<angleclass;i++)
{
//ttt=(0.5+Servo2kkk270*(Servo2_LastAngle-i*Servo2class))*1000;
ttt=500+7.4*(Servo2_LastAngle-i);
TIM_SetCompare2(TIM9,(int)ttt);
delay_ms(ServoDalayms);
}
}
// if(angleyushu==0)
// {
// if((anglepos-Servo2_LastAngle)>0)//50
// {
// for(i=0;i<angleclass;i++)
// //这个1000怎么来呢?ttt是高电平的时间对应的加法树量,角度对应的占空比时间tw/20ms =占空比,再乘以20ms对应的加法数量20000
// //tw/20*20000=tw*1000
// {
ttt=(0.5+Servo2kkk270*(Servo2_LastAngle+i*Servo2class))*1000;
TIM_SetCompare2(TIM9,ttt);// 除以20,乘以20 000
delay_ms(ServoDalayms);
// //ttt=(0.5+0.0074f*(Servo2_LastAngle+i))*1000;//化简得到下面的公式
// ttt = 500+7.4*(Servo2_LastAngle+i);
// TIM_SetCompare2(TIM9,(int)ttt);// 除以20,乘以20 000
// delay_ms(ServoDalayms);
//
// }
// }
// else if((anglepos-Servo2_LastAngle)<0)
// {
// for(i=0;i<angleclass;i++)
// {
// //ttt=(0.5+Servo2kkk270*(Servo2_LastAngle-i*Servo2class))*1000;
// ttt=500+7.4*(Servo2_LastAngle-i*Servo2class);
// TIM_SetCompare2(TIM9,(int)ttt);
// delay_ms(ServoDalayms);
// }
// }
// }
//
// else if(angleyushu!=0) //存在余数
// {
// if((anglepos-Servo2_LastAngle)>0)
// {
// for(i=0;i<(angleclass-1);i++)
// {
// ttt=500+7.4*(Servo2_LastAngle+i);
// TIM_SetCompare2(TIM9,(int)ttt);
// delay_ms(ServoDalayms);
// }
// TIM_SetCompare2(TIM9,500+7.4*anglepos);
// delay_ms(ServoDalayms);
// }
// else if((anglepos-Servo2_LastAngle)<0)
// {
// for(i=0;i<angleclass;i++)
// {
// ttt=500+7.4*(Servo2_LastAngle-i);
// TIM_SetCompare2(TIM9,(int)ttt);
// delay_ms(ServoDalayms);
// }
// TIM_SetCompare2(TIM9,500+7.4*anglepos);
// delay_ms(ServoDalayms);
// }
// }
Servo2_LastAngle = anglepos;
}