#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;
}