概述
麦克娜姆轮小车包含蓝牙手机控制,手柄控制,上位机PID调节程序;其它配件程序见原理图;
WIF控制(暂未添加)MPU6050(暂未添加)。
注释部分调试时未做修改,不做参照,直接解读程序:
#include "stm32f10x.h"
#include "bit_band.h"
#include "delay.h"
#include "timer.h"//置位标志位
#include "led.h"
#include "key.h"
#include "beep.h"
#include "MotorDrive.h"
#include "encoder.h"
#include "pid.h"
#include "waveform.h"//串口3与上位机通讯传输PID数据
#include "rf2G4.h"
#include "bluetooth.h"
#include "wifi.h"
#include "usart.h"//留作后期LINUX上位机
#include "oled.h"
u8 MODE=0;//模式选择:0,PS2控制;1,蓝牙控制 ;2,PID控制 ;3,WiFi控制
int Motspeed=60;//转/s
extern u8 F_pid_functiion;
extern u8 F_pid_waveform;
extern u8 F_mileage;
extern u8 F_oled_usart3;
int main(void)
{
u8 L_CNT = 0 ; // 循环计数,LED闪烁
// 注:程序中使用中断时,NVIC分组设置应尽量位于程序起始处,并且在设置后尽量不要再更改NVIC分组
// 定时器6,中断分组0.0;
// 定时器3,中断分组0,1;
// 串口1,中断分组1.1;波形显示串口3,中断分组1.2;蓝牙串口4,中断分组1.3;WIFI串口5,中断分组1.4;
// 外部编码器,中断分组(2,0)(2,1)(2,2)(2,3)
//------------------------------------------------------------------------------------------
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_Init();
TIM3_Time_Init();
LED_Init_JX();
KEY_Init_JX();
BEEP_Init();
Car_Init();
EncoderInit();
TIM6_Time_Init(); //用于编码器T法测速计时
PID_Init();
Waveform_Config();//配置串口3
Bluetooth_Config();//串口4
Wifi_Config();//串口5
RF2G4_Init();//使用SPI1
USART1_Config(); //串口1
OLED_Init(); //I2C
//--------------------蜂鸣器 串口1 3 射频通讯检测----------------------------------------------
// 上电蜂鸣器鸣响
BEEP_Sound();
// 判断串口通讯成功
printf("串口3测试通讯成功nnnn"); //测试串口3PID波形输出
Usart1_SendString( USART1, "串口1测试通讯成功nnnn");//测试串口1上位机通讯
// 判断SI24R1是否正常
if(!RF2G4_Check())
{
for( L_CNT=0; L_CNT<10; L_CNT++ ) // 如果2.4G模块连接正常,则LED_Green上电后闪烁几次
{
LED = !LED ;
delay_ms(50);
}
LED = 1;
}
RF2G4_RX_Mode(); // 将SI24R1设置为接收模式
while(1)
{
//------------------------Pid调试小车---------------------------------------------------
//5ms执行一次PID计算
if(F_pid_functiion==1)
{
F_pid_functiion=0;
PIDSPD_SinglePulse();
}
if( F_pid_waveform==1 )//100ms发送波形,太快上位机不能下发数据
{
F_pid_waveform=0;
// osci_sendA();
// osci_sendB();
// osci_sendC();
// osci_sendD();
}
//--------------------PS2,蓝牙、WIFI小车控制---------------------------------------------------
// RF24L01_control();
//------------------------计算里程--------------------------------------------------
// if( F_mileage==1 ) //50ms计算里程
// {
// F_mileage=0;
// GetMileage();
// }
//-------------------OLED、串口显示数据---------------------------------------------------
if( F_oled_usart3==1 )//200ms显示数据
{
F_oled_usart3=0;
OLED_display();
// Usart3_display();
}
}
}
#include "delay.h"
static u16 SysTick_each_us_CNT ; // SysTick计时1us所需的计数次数
static u16 SysTick_each_ms_CNT ; // SysTick计时1ms所需的计数次数
// 初始化SysTick定时器
void delay_Init(void)
{
// RCC通过AHB时钟(HCLK)8分频后作为Cortex系统定时器(SysTick)的可选外部时钟
// 默认:SystemCoreClock = SYSCLK_FREQ_72MHz ;
//**********************************************************************************************************
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); // SysTick的时钟选为外部时钟的8分频(HCLK/8)
SysTick_each_us_CNT = SystemCoreClock / 8 / 1000000; // 得到1us的计数次数
SysTick_each_ms_CNT = SysTick_each_us_CNT * 1000; // 得到1ms的计数次数
}
// 延时delay_us_Num微秒
// 参数delay_us_Num的值应 < 1,864,135(十进制)
//*********************************************
u8 delay_us(u32 delay_us_Num)
{
u8 NOP_CNT = 4 ;
u32 T_SysTick_CTR ;
// 如果没有此判断,当参数为0时,会陷入死循环
//********************************************
if( delay_us_Num == 0 ) // 参数不允许为0
{ return 0 ; } // 跳出函数
// 当参数是1us时,不使用SysTick定时器,直接使用几个NOP实现1us延时
//****************************************************************
if( delay_us_Num == 1 )
{
while( --NOP_CNT ) // NOP_CNT = 4 ;
{
__NOP(); // NOP:一个指令周期的空操作
}
return 0 ; // 跳出函数
}
// SysTick定时器真正计时前,程序多耗时1us左右,在此负补偿SysTick计数器
//*****************************************************************
if( delay_us_Num>1 && delay_us_Num<1000 )
{ delay_us_Num -- ; }
// SysTick->LOAD:SysTick重装载寄存器(SysTick->LOAD为24位计数器)
// 当计数器递减到0时(或强制清0时),将SysTick->LOAD中的值重新载入计数器
//**********************************************************************************************************
SysTick->LOAD = (u32)SysTick_each_us_CNT * delay_us_Num ; // 将此次函数的计数次数写入重装载寄存器中
// SysTick->VAL:SysTick的递减计数器
// 向SysTick->VAL中写入数据,其就会被清0。
// 当其递减到0时,COUNTFLAG位置1。
//**********************************************************************************************************
SysTick->VAL = 0x00; // 将SysTick->VAL清0,从而使得SysTick->LOAD中的值装入SysTick->VAL
// SysTick->CTRL的最低位为SysTick定时器的使能位:1使能 0失能
//*****************************************************************************************
SysTick->CTRL |= (u32)0x01 ; // 使能SysTick定时器,计数器开始递减
// 一直等待计数器递减至0
//**********************************************************************************************************************
do{
T_SysTick_CTR = SysTick->CTRL ; // 将SysTick->CTRL中的值缓存到T_SysTick_CTR变量中
}while( (T_SysTick_CTR & 0x01) && !(T_SysTick_CTR & (1<<16) ) ); // 当SysTick->CTRL的最低位为1,且第16位为0时,继续循环
SysTick->CTRL &= ~ ( (u32)0x01 ) ; // 失能SysTick定时器
SysTick->VAL = 0X00; // 清0计数器
return 0 ; // 跳出函数
}
// 延时delay_ms_Num毫秒
// 参数delay_ms_Num的值应 < 1,864(十进制)
//****************************************
u8 delay_ms(u16 delay_ms_Num)
{
u32 T_SysTick_CTR ;
// 如果没有此判断,当参数为0时,会陷入死循环
//********************************************
if( delay_ms_Num == 0 ) // 参数不允许为0
{ return 0 ; } // 跳出函数
// SysTick->LOAD:SysTick重装载寄存器(SysTick->LOAD为24位计数器)
// 当计数器递减到0时(或强制清0时),将SysTick->LOAD中的值重新载入计数器
//**********************************************************************************************************
SysTick->LOAD = (u32)SysTick_each_ms_CNT * delay_ms_Num ; // 将此次函数的计数次数写入重装载寄存器中
// SysTick->VAL:SysTick的递减计数器
// 向SysTick->VAL中写入数据,其就会被清0。
// 当其递减到0时,COUNTFLAG位置1。
//**********************************************************************************************************
SysTick->VAL = 0x00; // 将SysTick->VAL清0,从而使得SysTick->LOAD中的值装入SysTick->VAL
// SysTick->CTRL的最低位为SysTick定时器的使能位:1使能 0失能
//*****************************************************************************************
SysTick->CTRL |= (u32)0x01 ; // 使能SysTick定时器,计数器开始递减
// 一直等待计数器递减至0
//**********************************************************************************************************************
do{
T_SysTick_CTR = SysTick->CTRL ; // 将SysTick->CTRL中的值缓存到T_SysTick_CTR变量中
}while( (T_SysTick_CTR & 0x01) && !(T_SysTick_CTR & (1<<16) ) ); // 当SysTick->CTRL的最低位为1,且第16位为0时,继续循环
SysTick->CTRL &= ~ ( (u32)0x01 ) ; // 失能SysTick定时器
SysTick->VAL = 0X00; // 清空计数器
return 0 ; // 跳出函数
}
#ifndef __DELAY_H
#define __DELAY_H
#include "stm32f10x.h"
// 注:调用延时函数之前,必须先调用delay_Init()将SysTick初始化
//**************************************************************
// 将SysTick定时器的时钟设为:9M=72M/8(HCLK的8分频,HCLK默认为72M)
//**************************************************************
void delay_Init(void) ; // 初始化SysTick定时器
//**************************************************************
// SysTick时钟:9M(计数9次=1us),计数器最大值:2^24-1=16777215
// SysTick定时器延时时长应 <= 1,864,135 us
//**************************************************************
// 参数delay_us_Num的值应 < 1,864,135(十进制)
//**************************************************************
u8 delay_us(u32 delay_us_Num) ; // 延时delay_us_Num微秒
// 参数delay_ms_Num的值应 < 1,864(十进制)
//**************************************************************
u8 delay_ms(u16 delay_ms_Num) ; // 延时delay_ms_Num毫秒
#endif /* __DELAY_H */
#include "MotorDrive.h"
#include "PID.h"
//驱动器使能
void MotEN_Init_JX(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//开启重映射时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);//开启重映射
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_ResetBits(GPIOC,GPIO_Pin_0);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_15);
}
// TIM2_PWM输出初始化
// TIM2_CH1 = PA0
// TIM2_CH2 = PA1
// TIM2_CH3 = PA2
// TIM2_CH4 = PA3
void TIM2_PWM_Init_JX(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = TIM2_Reload_Num;
TIM_TimeBaseStructure.TIM_Prescaler =TIM2_Frequency_Divide;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
// TIM_OCInitStructure.TIM_Pulse = 0; // 占空比配置CCR
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
// TIM_ARRPreloadConfig(TIM2,ENABLE); // 使能TIM2的自动预重装载寄存器,使能影子寄存器
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); // 使能TIM2在OC1上的预装载寄存器
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_Cmd(TIM2, ENABLE);
}
//-----------------------------------------------------------------------------------------------------------------
// TIM4_PWM输出初始化
// TIM4_CH1 = PB6
// TIM4_CH2 = PB7
// TIM4_CH3 = PB8
// TIM4_CH4 = PB9
//-----------------------------------------------------------------------------------------------------------------
void TIM4_PWM_Init_JX(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = TIM4_Reload_Num;
TIM_TimeBaseStructure.TIM_Prescaler =TIM4_Frequency_Divide;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
//初始化TIM4_CH1-4的PWM
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
TIM_OC3Init(TIM4, &TIM_OCInitStructure);
TIM_OC4Init(TIM4, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_Cmd(TIM4, ENABLE);
}
//-----------------------------------------------------------------------------------------------------------------
void Car_Init(void)
{
MotEN_Init_JX();
TIM2_PWM_Init_JX();
TIM4_PWM_Init_JX();
//驱动器置1使能
GPIO_SetBits(GPIOA,GPIO_Pin_15);
GPIO_SetBits(GPIOC,GPIO_Pin_0);
}
void MotA(int val)
{
if(val>200)
{
TIM2->CCR1=val; TIM2->CCR2=0;
}
else if(val<-200)
{
val=-val;
TIM2->CCR1=0; TIM2->CCR2=val; //50%的启动值
}
else
{
TIM2->CCR1=0; TIM2->CCR2=0;
}
}
void MotB(int val)
{
if(val>200)
{
TIM2->CCR3=val; TIM2->CCR4=0;
}
else if(val<-200)
{
val=-val;
TIM2->CCR3=0; TIM2->CCR4=val;
}
else
{
TIM2->CCR3=0; TIM2->CCR4=0;
}
}
void MotC(int val)
{
if(val>200)
{
TIM4->CCR1=0; TIM4->CCR2=val;
}
else if(val<-200)
{
val=-val;
TIM4->CCR1=val; TIM4->CCR2=0;
}
else
{
TIM4->CCR1=0; TIM4->CCR2=0;
}
}
void MotD(int val)
{
if(val>200)
{
TIM4->CCR3=0; TIM4->CCR4=val;
}
else if(val<-200)
{
val=-val;
TIM4->CCR3=val; TIM4->CCR4=0;
}
else
{
TIM4->CCR3=0; TIM4->CCR4=0;
}
}
void Car_forward(int value)
{
Mot_speedset(value,value,value,value);
}
void Car_backward(int value)
{
Mot_speedset(-value,-value,-value,-value);
}
void Car_left(int value)
{
Mot_speedset(-value,value,value,-value);
}
void Car_right(int value)
{
Mot_speedset(value,-value,-value,value);
}
void Car_turnleft(int value)
{
Mot_speedset(value,value,-value,-value);
}
void Car_turnright(int value)
{
Mot_speedset(-value,-value,value,value);
}
void Car_leftup(int value)
{
Mot_speedset(0,value,value,0);
}
void Car_rightup(int value)
{
Mot_speedset(value,0,0,value);
}
void Car_leftdown(int value)
{
Mot_speedset(-value,0,0,-value);
}
void Car_rightdown(int value)
{
Mot_speedset(0,-value,-value,0);
}
void Car_stop(int value)
{
Mot_speedset(0,0,0,0);
}
/*使用速度 mm/s 作为目标值*/
//空载时转速300RMP,即5转每秒,减速比20,则减速前速度是100转每秒,PWM设置最大值是100,720分频,1ms周期;
//带负载转速是240RMP,即4转每秒,减速比20,则减速前速度是80转每秒;
//电机周长是308mm,减速比是20,则减速前是15mm每转,空载转速是1.5m/s,带负载速度是1200mm/s=1.2m/s;
//void Mot_speedset(int Speed1, int Speed2,int Speed3, int Speed4)//转/s
//{
// int SPD1=0;
// int SPD2=0;
// int SPD3=0;
// int SPD4=0;
速度是每秒n转,车轮周长乘以1/20=电机本身每转多少毫米,乘以n转每秒,就是每秒多少毫米=速度
// SPD1=(s32)Speed1*(MotorWheelPerimeter/MotorRedRatio);//需要调用#include "encoder.h"
// SPD2=(s32)Speed2*(MotorWheelPerimeter/MotorRedRatio);
// SPD3=(s32)Speed3*(MotorWheelPerimeter/MotorRedRatio);
// SPD4=(s32)Speed4*(MotorWheelPerimeter/MotorRedRatio);
//
// PIDSpeed_SetGoal_A(SPD1);
// PIDSpeed_SetGoal_B(SPD2);
// PIDSpeed_SetGoal_C(SPD3);
// PIDSpeed_SetGoal_D(SPD4);
//}
/*使用速度 转/s 作为目标值*/
void Mot_speedset(int Speed1, int Speed2,int Speed3, int Speed4)//转/s
{
PIDSpeed_SetGoal_A(Speed1);
PIDSpeed_SetGoal_B(Speed2);
PIDSpeed_SetGoal_C(Speed3);
PIDSpeed_SetGoal_D(Speed4);
}
#ifndef __MOTORDRIVE_H
#define __MOTORDRIVE_H
#include "stm32f10x.h"
//--------------------------------
// 分频系数:720(分频值+1)
// 计数频率:100kHz
// 计数周期:10us
// 重装载值:99
// 溢出周期:1ms
// 溢出频率:1kHz
//--------------------------------------------------------------
#define TIM2_Frequency_Divide (72-1) // TIM2时钟预分频值
#define TIM2_Reload_Num (1000-1) // 自动重装载寄存器的值
#define TIM4_Frequency_Divide (72-1) // TIM1时钟预分频值
#define TIM4_Reload_Num (1000-1) // 自动重装载寄存器的值
//--------------------------------------------------------------
void MotEN_Init_JX(void);
void TIM2_PWM_Init_JX(void);
void TIM4_PWM_Init_JX(void);
void Car_Init(void);
void MotA(int val);
void MotB(int val);
void MotC(int val);
void MotD(int val);
void Car_forward(int value);
void Car_backward(int value);
void Car_left(int value);
void Car_right(int value);
void Car_turnleft(int value);
void Car_turnright(int value);
void Car_leftup(int value);
void Car_rightup(int value);
void Car_leftdown(int value);
void Car_rightdown(int value);
void Car_stop(int value);
void Mot_speedset(int Speed1, int Speed2,int Speed3, int Speed4);
//----------------------------------------------------------------------------
#endif /* __PWM_H */
#include "led.h"
void LED_Init_JX(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_ResetBits(GPIOC,GPIO_Pin_3);
}
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
#define LED PC_out(3)
void LED_Init_JX(void);
#endif
#include "timer.h"
#include "PID.h"
void TIM3_Time_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = TIM3_Reload_Num ;
TIM_TimeBaseStructure.TIM_Prescaler = TIM3_Frequency_Divide;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM3, ENABLE);
}
u8 F_pid_functiion=0;//PID计算,5ms
u8 F_pid_waveform=0;//上位机波形显示,100ms
u8 F_oled_usart3=0;//OLED显示和串口输出标志位,200ms
u8 F_mileage=0;//里程计算标志位,50ms
u16 C_stop=0;//小车失联计数位
u8 F_stop=0;//小车失联停止标志位,1s
void TIM3_IRQHandler(void)
{
if( TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET )
{
static u16 C_pid_function=0;//5ms
static u16 C_pid_waveform=0;//100ms
static u16 C_oled_usart3=0;//200ms
static u16 C_mileage=0; //50ms
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
C_pid_function++;
if(C_pid_function >= 5)
{
C_pid_function = 0;
F_pid_functiion = 1; //5ms 执行PID功能函数
}
C_pid_waveform++;
if(C_pid_waveform >= 100)
{
C_pid_waveform = 0;
F_pid_waveform = 1 ; //100ms pid发送上位机波形,调试用
}
C_oled_usart3++;
if(C_oled_usart3 >= 200) //200MS
{
C_oled_usart3 = 0;
F_oled_usart3 = 1 ; //200ms执行OLED和串口输出显示
}
C_mileage++;
if(C_mileage >= 50)
{
C_mileage=0;
F_mileage=1; //50ms 里程表调用一次计数
}
C_stop ++;
if(C_stop >= 1000)
{
C_stop = 0;
F_stop = 1; // 1s小车接收不到信号停车
}
}
}
//------------------------------------------------------------------------------------
#ifndef __TIMER_H
#define __TIMER_H
#include "stm32f10x.h"
//--------------------------------
// 分频系数:72(分频值+1)
// 计数频率:1MHz
// 计数周期:1us
// 重装载值:4999
// 溢出周期:5ms
//--------------------------------------------------------------
#define TIM3_Frequency_Divide 72-1
#define TIM3_Reload_Num 1000-1
//--------------------------------------------------------------
void TIM3_Time_Init(void) ;
#endif /* __TIMER_H */
#include "usart.h"
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置USART为中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
/* 抢断优先级*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子优先级 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
/* 使能中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置NVIC */
NVIC_Init(&NVIC_InitStructure);
}
void USART1_Config(void)//串口1通讯
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 打开串口GPIO的时钟
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
// 打开串口外设的时钟
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
// 将USART Tx的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
// 将USART Rx的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
// 配置串口的工作参数
// 配置波特率
USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
// 配置 针数据字长
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校验位
USART_InitStructure.USART_Parity = USART_Parity_No ;
// 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;
// 配置工作模式,收发一起
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 完成串口的初始化配置
USART_Init(DEBUG_USARTx, &USART_InitStructure);
// 串口中断优先级配置
NVIC_Configuration();
// 使能串口接收中断
USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);
// 使能串口
USART_Cmd(DEBUG_USARTx, ENABLE);
}
/***************** 发送一个字节 **********************/
void Usart1_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
/* 发送一个字节数据到USART */
USART_SendData(pUSARTx,ch);
/* 等待发送数据寄存器为空 */
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/****************** 发送8位的数组 ************************/
void Usart1_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num)
{
uint8_t i;
for(i=0; i<num; i++)
{
/* 发送一个字节数据到USART */
Usart1_SendByte(pUSARTx,array[i]);
}
/* 等待发送完成 */
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
}
/***************** 发送字符串 **********************/
void Usart1_SendString( USART_TypeDef * pUSARTx, char *str)
{
unsigned int k=0;
do
{
Usart1_SendByte( pUSARTx, *(str + k) );
k++;
} while(*(str + k)!='