主函数文件:
extern uint16_t Distance,Size;
extern uint16_t x_pos,y_pos;
u8 str_buff15[64];
u8 str_buff16[64];
int main(void)
{
OLED_Init();
LED_Init();
Serial_Init();
Servo_Init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组
int i,j;
while (1)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_8);
for(i=0;i<1000;i++)
for(j=0;j<1000;j++);
GPIO_SetBits(GPIOA,GPIO_Pin_8);
for(i=0;i<1000;i++)
for(j=0;j<1000;j++);
OLED_Clear();
sprintf((char *)str_buff15,"MAIN:%d",i);
OLED_ShowString(16,16,str_buff15,16,1);
sprintf((char *)str_buff16,"flash:%d",flash);
OLED_ShowString(16,32,str_buff16,16,1);
OLED_Refresh();
}
}
串口文件:
char Serial_RxPacket1[10]; //"@msg\r\n" pitch_str
char Serial_RxPacket2[10]; //roll_str
uint8_t flash ;
u8 str_buff1[64];
u8 str_buff2[64];
//u8 str_buff3[64];
//u8 str_buff4[64];
uint8_t X1, X2, X3, X4, X5, X6, X7, X8, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y, X;
uint16_t x_pos,y_pos;
float erro1=0 , erro2=0 , Angle1=0 , Angle2=0;
float OUT_Angle1=0 , OUT_Angle2=0;
//uint8_t Serial_RxFlag;
void Serial_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//tx
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//rx
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate =9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1, ENABLE);
USART_ClearFlag(USART1, USART_FLAG_TC);
}
void Serial_SendByte(uint8_t Byte)//////////发送一个字节
{
USART_SendData(USART1, Byte);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
void Serial_SendArray(uint8_t *Array, uint16_t Length)//////////发送一个数组
{
uint16_t i;
for (i = 0; i < Length; i ++)
{
Serial_SendByte(Array[i]);
}
}
void Serial_SendString(char *String)//////////发送一个字符串(字符串用双引号括起来)\r\n 可以换行
{
uint8_t i;
for (i = 0; String[i] != '\0'; i ++)
{
Serial_SendByte(String[i]);
}
}
uint32_t Serial_Pow(uint32_t X, uint32_t Y)//////////次方函数,返回值=X的Y次方
{
uint32_t Result = 1;
while (Y --)
{
Result *= X;
}
return Result;
}
void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
uint8_t i;
for (i = 0; i < Length; i ++)
{
Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
}
}
int fputc(int ch, FILE *f)
{
Serial_SendByte(ch);
return ch;
}
void Serial_Printf(char *format, ...)
{
char String[100];
va_list arg;
va_start(arg, format);
vsprintf(String, format, arg);
va_end(arg);
Serial_SendString(String);
}
void USART1_IRQHandler(void)
{
static uint8_t RxState = 0;//定义一个静态变量RxState并初始化为0,用于跟踪接收状态。
static uint8_t pRxPacket_pitch_str = 0; //跟踪接收包的位置。
static uint8_t pRxPacket_roll_str = 0;
flash = RxState;
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
uint8_t RxData = USART_ReceiveData(USART1); //从USART1接收寄存器中读取数据,并将其存储在变量RxData中。
// USART_ClearITPendingBit(USART1, USART_IT_RXNE);//清除USART1的接收缓冲区非空中断标志位。
if (RxState == 0)
{
flash = RxState;
if (RxData == '@')//检查接收到的数据是否为字符"@"。
{
RxState = 1;
pRxPacket_pitch_str = 0;
pRxPacket_roll_str = 0;
}
}
else if (RxState == 1)//接收pitch_str
{
flash = RxState;
if (RxData == 109) //m
{
RxState = 2;
}
else
{
Serial_RxPacket1[pRxPacket_pitch_str] = RxData;
pRxPacket_pitch_str ++;
}
}
else if (RxState == 2)//接收roll_str
{
flash = RxState;
if (RxData == 65) //A
{
RxState = 3;
}
else
{
Serial_RxPacket2[pRxPacket_roll_str] = RxData;
pRxPacket_roll_str ++;
}
}
else if (RxState == 3) //接收完成
{
flash= RxState;
if (RxData == 70)//F
{
Y1=Serial_RxPacket1[0];//0
Y2=Serial_RxPacket1[1];//X
Y3=Serial_RxPacket1[2];
X1=Serial_RxPacket2[0];
X2=Serial_RxPacket2[1];
X3=Serial_RxPacket2[2];
x_pos=(X1-48)*100+(X2-48)*10+(X3-48);
// printf("%d\r\n",Serial_RxPacket2[0]);
// printf("%d\r\n",Serial_RxPacket2[1]);
// printf("%d\r\n",Serial_RxPacket2[2]);
y_pos=(Y1-48)*100+(Y2-48)*10+(Y3-48);
OLED_Clear();
sprintf((char *)str_buff1,"x_pos:%d",x_pos);//0300
OLED_ShowString(16,16,str_buff1,16,1);
sprintf((char *)str_buff2,"y_pos :%d",y_pos);//0300
OLED_ShowString(16,32,str_buff2,16,1);
OLED_Refresh();
RxState = 4;
}
}
else if (RxState == 4)
{
flash = RxState;
USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭DTSABLE中断
// printf("%d\r\n",Serial_RxPacket[0]);
// printf("%d\r\n",Serial_RxPacket[1]);
printf("%d\r\n",x_pos);
printf("%d\r\n",y_pos);
//erro1 =160-x_pos ;
//erro2 = y_pos-120 ;
erro1 =160-110 ;
erro2 = 163-120 ;
Angle1 = S1_PID(erro1);
Angle2 = S2_PID(erro2);
OUT_Angle1=PWM1_Limt(Angle1);
OUT_Angle2=PWM2_Limt(Angle2);
Servo_SetAngle(OUT_Angle1,OUT_Angle2);
RxState=0;
pRxPacket_pitch_str = 0;
pRxPacket_roll_str = 0;
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
PWM文件:
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimerBaseInitStructure;
TIM_TimerBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimerBaseInitStructure.TIM_CounterMode = TIM_CKD_DIV1;
TIM_TimerBaseInitStructure.TIM_Period = 57600 - 1;//ARR
TIM_TimerBaseInitStructure.TIM_Prescaler = 25 - 1;//PSC
TIM_TimerBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimerBaseInitStructure);
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;//CCR
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM2, ENABLE);
}
void PWM_SetCompare1( int Compare)
{
TIM_SetCompare1(TIM2, Compare);
}
void PWM_SetCompare2( int Compare)
{
TIM_SetCompare2(TIM2, Compare);
}
云台:
float P1=0 , I1=0 , D1=0 ,
P2=0 , I2=0 , D2=0 ;
float now_error = 0 , last_error = 0 , now_error_LeiJi = 0 ,
last_last_error = 0 , Out_posPID = 0 , OUT_PWM1 = 0 , OUT_PWM2 = 0;
float servo1_duty , servo2_duty;
void Servo_Init(void)
{
PWM_Init();
}
void Servo_SetAngle(float Angle1,float Angle2)
{
// Angle1=Angle12;
// Angle2=Angle22;
PWM_SetCompare1(2.88(Angle1 / 180 * 2000) + 1440);//500
PWM_SetCompare2(2.88(Angle2 / 180 * 2000) + 1440);//500
servo1_duty = ((Angle1+90)/18010+2.5);
servo2_duty = ((Angle2+90)/18010+2.5);
// printf("%.3f\r\n",servo1_duty);
// printf("%.3f\r\n",servo2_duty);
}
float S1_PID(float erro)
{
static float S1_PD_Kp = 0.55506 ,
S1_PD_Ki = 0.000038 ,
S1_PD_Kd = 0.22096 ;
now_error = erro ; //误差
now_error_LeiJi = now_error + now_error_LeiJi;//累计误差_求和
P1 = S1_PD_Kp * now_error;
I1 = S1_PD_Ki * now_error_LeiJi;
D1 = S1_PD_Kd * (now_error - last_error);
last_error = now_error;
Out_posPID = P1 + I1 + D1;
OUT_PWM1 = Out_posPID; //输出
OUT_PWM1 = OUT_PWM1 ;
return OUT_PWM1 ;
}
float S2_PID(float erro)
{
static float S2_PD_Kp = 0.73900 ,
S2_PD_Ki = 0.00009 ,
S2_PD_Kd = 0.16880 ;
now_error = erro ; //误差
now_error_LeiJi = now_error + now_error_LeiJi;//累计误差_求和
P2 = S2_PD_Kp * now_error;
I2 = S2_PD_Ki * now_error_LeiJi;
D2 = S2_PD_Kd * ( now_error - last_error);
Out_posPID = P2 + I2 + D2;
last_error = now_error;
OUT_PWM2 = Out_posPID;
OUT_PWM2 = OUT_PWM2 ;
return OUT_PWM2 ;
}
float PWM1_Limt(float Angle)
{
if (Angle > 90)
Angle = 90;
else if (Angle < -90)
Angle = -90;
Angle=Angle+90;
return Angle;
}
float PWM2_Limt(float Angle)
{
if (Angle > 90)
Angle = 90;
else if (Angle < -90)
Angle = -90;
Angle=Angle+90;
return Angle;
}
STM32不进入蓝牙串口接收中断函数可能是由于多种原因导致的。以下是一些可能的原因和相应的解决方法:
我只使用了一个串口中断优先级还需要小心设置吗