麦克娜姆轮车包括蓝牙手机控制、手柄控制、上位机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)(2,2)(2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2)(2,2)(2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2,2)(2)(2,2)(2,2)(2,2)(2,2)(2,2)(2)(2,2)(2)(2,2)(2,2)(2)(2)(2)(2,2)(2,2,2)(2,2)(2)(2,2)(2,2,2)(2,2)(2)(2,2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2,2,2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(2)(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(); // PID_Init(); Waveform_Config() Bluetooth_Config()//串口4 Wifi_Config()//串口5 RF2G4_Init();//使用SPI1 USART1_Config(); //串口1 OLED_Init(); //I2C //--------------------蜂鸣器\ 串口1 3 \射频通信检测---------------------------------------------- // 上电蜂鸣器鸣响 BEEP_Sound(); // 成功判断串口通信 printf("串口3成功测试通信\n\n\n\n"); //测试串口3PID波形输出 Usart1_SendString( USART1, "串口1成功测试通信\n\n\n\n");///测试串口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->LOAD24位计数器) // 当计数器递减到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-&t;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)!='\0');
/* 等待发送完成 */
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
{}
}
/***************** 发送一个16位数 **********************/
void Usart1_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{
uint8_t temp_h, temp_l;
/* 取出高八位 */
temp_h = (ch&0XFF00)>>8;
/* 取出低八位 */
temp_l = ch&0XFF;
/* 发送高八位 */
USART_SendData(pUSARTx,temp_h);
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
/* 发送低八位 */
USART_SendData(pUSARTx,temp_l);
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/重定向c库函数printf到串口,重定向后可使用printf函数
//int fputc(int ch, FILE *f)
//{
// /* 发送一个字节数据到串口 */
// USART_SendData(DEBUG_USARTx, (uint8_t) ch);
//
// /* 等待发送完毕 */
// while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
//
// return (ch);
//}
/重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
//int fgetc(FILE *f)
//{
// /* 等待串口输入数据 */
// while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);
// return (int)USART_ReceiveData(DEBUG_USARTx);
//}
// 串口中断接收上位机PID参数
void DEBUG_USART_IRQHandler(void)
{
if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)
{
u8 data=USART_ReceiveData(DEBUG_USARTx);//获取数据
USART_SendData(DEBUG_USARTx, data);
}
USART_ClearITPendingBit(DEBUG_USARTx, USART_IT_RXNE);
}
#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h"
#include <stdio.h>
// 串口1-USART1
#define DEBUG_USARTx USART1
#define DEBUG_USART_CLK RCC_APB2Periph_USART1
#define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200
// USART GPIO 引脚宏定义
#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
#define DEBUG_USART_IRQ USART1_IRQn
#define DEBUG_USART_IRQHandler USART1_IRQHandler
void USART1_Config(void);
void Usart1_SendByte( USART_TypeDef * pUSARTx, uint8_t ch);
void Usart1_SendString( USART_TypeDef * pUSARTx, char *str);
void Usart1_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch);
void Usart1_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num);
#endif /* __USART_H */
#include "key.h"
void KEY_Init_JX(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
#ifndef __KEY_H
#define __KEY_H
#include "stm32f10x.h"
#include "bit_band.h"
#define KEY1 PC_in(15)
#define KEY2 PC_in(14)
void KEY_Init_JX(void) ;
#endif /* __KEY_H */
//****************************************************************************************************
// 在"stm32f10x.h"中:
//
// #define FLASH_BASE ((uint32_t)0x08000000) // FLASH基地址
// #define SRAM_BASE ((uint32_t)0x20000000) // SRAM基地址(位带区)
// #define PERIPH_BASE ((uint32_t)0x40000000) // 外设(寄存器)基地址(位带区)
//
// #define SRAM_BB_BASE ((uint32_t)0x22000000) // SRAM的别名区的基地址
// #define PERIPH_BB_BASE ((uint32_t)0x42000000) // 外设的别名区的基地址
//
// #define FSMC_R_BASE ((uint32_t)0xA0000000) // FSMC寄存器基地址
//
//
// bit_word_addr = bit_band_base + (byte_offset * 32) + (bit_number * 4)
//
// bit_word_addr:别名区中,对应的'字'的地址,它和位带区的某个位是映射关系
// bit_band_base:别名区的起始地址,SRAM_BB_BASE 或 PERIPH_BB_BASE。
// byte_offset:包含目标位的字节所在位带区的地址
// bit_number:目标在字节中的序号(由低到高)
//
//****************************************************************************************************
#ifndef __BIT_BAND_H
#define __BIT_BAND_H
#include "stm32f10x.h"
// 注:参数:Pin_x不应该超过15
//****************************************************************************************************
#define PA_out(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X1080C * 32) + (Pin_x * 4)))
#define PB_out(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X10C0C * 32) + (Pin_x * 4)))
#define PC_out(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X1100C * 32) + (Pin_x * 4)))
#define PD_out(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X1140C * 32) + (Pin_x * 4)))
#define PE_out(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X1180C * 32) + (Pin_x * 4)))
#define PF_out(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X11C0C * 32) + (Pin_x * 4)))
#define PG_out(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X1200C * 32) + (Pin_x * 4)))
#define PA_in(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X10808 * 32) + (Pin_x * 4)))
#define PB_in(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X10C08 * 32) + (Pin_x * 4)))
#define PC_in(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X11008 * 32) + (Pin_x * 4)))
#define PD_in(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X11408 * 32) + (Pin_x * 4)))
#define PE_in(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X11808 * 32) + (Pin_x * 4)))
#define PF_in(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X11C08 * 32) + (Pin_x * 4)))
#define PG_in(Pin_x) * ((volatile unsigned long *)(0x42000000 + (0X12008 * 32) + (Pin_x * 4)))
//****************************************************************************************************
#endif /* __BIT_BAND_H */
#include "rf2G4.h"
#include "MotorDrive.h"
#include "waveform.h"
// 2G4通信地址
//------------------------------------------------------------------------------------------
const u8 RF2G4_ADDR_TX[5] = {0x34,0x43,0x10,0x10,0x01};
const u8 RF2G4_ADDR_RX[5] = {0x34,0x43,0x10,0x10,0x01}; // 或者可用ASCII:jixin
//------------------------------------------------------------------------------------------
u8 RF2G4_Send_Data[14] = { 0 }; // 2.4G发射数据缓存数组
u8 RF2G4_Receive_Data[14] = { 0 }; // 2.4G接收数据缓存数组
// 无线发射(RF2G4_Send_Data[14]):共输出14个数据,分别为
//--------------------------------------------------------------
// 0 == KEY1
// 1 == KEY2
// 2 == KEY3
// 3 == KEY4
// 4 == 0
// 5 == 0
// 6 == 0
// 7 == 0
// 8 == 0
// 9 == 0
//ADC数据:
// 10 == 左转,右转
// 11 == 油门
// 12 == 左右运行
// 13 == 前后运行
//--------------------------------------------------------------
// RF2G4初始化
//------------------------------------------------------------------------------------------
void RF2G4_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //CSN片选引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //CE模式引脚,未使用
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //中断引脚未使用
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
SPI2_Init(); // 初始化SPI
RF2G4_CE=0; // 使能SI24R1
RF2G4_CSN=1; // SPI片选取消
}
//------------------------------------------------------------------------------------------
// 2G4的SPI读写
//==========================================================================================
// SPI对SI24R1寄存器的写操作
// Reg = 寄存器
// Write_Value = 写入的值
// return = 状态值
//--------------------------------------------------------
u8 RF2G4_Write_Reg(u8 Reg,u8 Write_Value)
{
u8 V_Reg;
RF2G4_CSN = 0; // 片选使能
V_Reg =SPI2_ReadWriteByte(Reg); // 发送寄存器号 ,返回状态值
SPI2_ReadWriteByte(Write_Value); // 写入寄存器的值
RF2G4_CSN = 1; // 禁止SPI传输
return(V_Reg); // 返回状态值
}
//--------------------------------------------------------
// 向寄存器中写入指定长度的数据
// Reg = 寄存器
// P_Data = 数据指针
// N_Data = 数据个数
// return = 此次读到的状态寄存器值
//--------------------------------------------------------
u8 RF2G4_Write_Cont(u8 Reg, u8* P_Data, u8 N_Data)//P_Data是地址指针变量
{
u8 V_Reg = 0;
u8 C_Write = 0;
RF2G4_CSN = 0;
V_Reg = SPI2_ReadWriteByte(Reg); // 选定寄存器,并读取状态值
for(; C_Write<N_Data; C_Write++)
{
SPI2_ReadWriteByte(*P_Data++); // 写入数据,*P_Data++是数据
}
RF2G4_CSN = 1;
return V_Reg; // 返回读到的状态值
}
//--------------------------------------------------------
// SPI对SI24R1寄存器的读操作
// Reg = 寄存器
// return = 写入的值
//--------------------------------------------------------
u8 RF2G4_Read_Reg(u8 Reg)
{
u8 V_Reg;
RF2G4_CSN = 0;
SPI2_ReadWriteByte(Reg); // 发送寄存器号(包含命令+寄存器地址)
V_Reg=SPI2_ReadWriteByte(0xFF); // 读取寄存器内容
RF2G4_CSN = 1;
return(V_Reg); // 返回寄存器的值
}
//--------------------------------------------------------
// 从寄存器中读出指定长度的数据
// Reg = 寄存器(位置)
// P_Data = 数据指针
// N_Data = 数据个数
// return = 此次读到的状态寄存器值
//----------------------------------------------------------------------------
u8 RF2G4_Read_Cont(u8 Reg, u8* P_Data, u8 N_Data)
{
u8 V_Reg;
u8 C_Read = 0;
RF2G4_CSN = 0; // 使能SPI传输
V_Reg=SPI2_ReadWriteByte(Reg); // 发送寄存器值(位置),并读取状态值
for(; C_Read<N_Data;C_Read++)
P_Data[C_Read] = SPI2_ReadWriteByte(0xFF); // 读出数据
RF2G4_CSN = 1; // 关闭SPI传输
return V_Reg; // 返回读到的状态值
}
//----------------------------------------------------------------------------
//==========================================================================================
// 检测SI24R1是否正常
// return = 0:成功, 1:失败
//---------------------------------------------------------------------------------------------------
u8 RF2G4_Check(void)
{
u8 Array_Test[5]={0X66,0X66,0X66,0X66,0X66};
u8 C_Test = 0;
SPI2_SetSpeed(SPI_BaudRatePrescaler_4); // SPI速度为9Mhz(SI24R1的最大SPI时钟为10Mhz)
RF2G4_Write_Cont(W_REGISTER+TX_ADDR,Array_Test,5); // 写入5个字节的地址.
RF2G4_Read_Cont(TX_ADDR,Array_Test,5); // 读出写入的地址
for(; C_Test<5; C_Test++)
if(Array_Test[C_Test]!=0X66)
break;
if(C_Test!=5)return 1; // SI24R1错误
return 0; // SI24R1正确
}
//---------------------------------------------------------------------------------------------------
// 初始化SI24R1为接收模式
//-----------------------------------------------------------------------------------------------------------
void RF2G4_RX_Mode(void)
{
RF2G4_CE = 0; //待机模式,无数据传输
RF2G4_Write_Cont(W_REGISTER+RX_ADDR_P0, (u8*)RF2G4_ADDR_RX, RX_ADR_WIDTH); // 设置RX节点地址,(u8*)RF2G4_ADDR_RX,数组转化为指针变量
RF2G4_Write_Reg(W_REGISTER+EN_AA,0x01); // 使能通道0的自动应答
RF2G4_Write_Reg(W_REGISTER+EN_RXADDR,0x01); // 使能通道0的接收地址
RF2G4_Write_Reg(W_REGISTER+RF_CH,40); // 设置RF通信频率2440MHz
RF2G4_Write_Reg(W_REGISTER+RX_PW_P0,14); // 设置通道0的有效数据宽度(14位)
RF2G4_Write_Reg(W_REGISTER+RF_SETUP,0x0F); // 设置:发射功率0dBm,电流消耗11.3mA、射频数据率2Mbps
RF2G4_Write_Reg(W_REGISTER+CONFIG, 0x0F); // 配置参数;接收模式、开机模式、CRC=2Byte、开启CRC、。。。
RF2G4_CE = 1; // CE为高,进入接收模式
}
//-----------------------------------------------------------------------------------------------------------
// 初始化SI24R1为发射模式
//-------------------------------------------------------------------------------------------------------------------
void RF2G4_TX_Mode(void)
{
RF2G4_CE = 0; //待机模式
//比起接收模式多的选项1
RF2G4_Write_Cont(W_REGISTER+TX_ADDR,(u8*)RF2G4_ADDR_TX,TX_ADR_WIDTH); // 设置TX节点地址
RF2G4_Write_Cont(W_REGISTER+RX_ADDR_P0,(u8*)RF2G4_ADDR_RX,RX_ADR_WIDTH); // 设置RX节点地址(ACK)
RF2G4_Write_Reg(W_REGISTER+EN_AA,0x01); // 使能通道0的自动应答,即设置为增强模式
RF2G4_Write_Reg(W_REGISTER+EN_RXADDR,0x01); // 使能通道0的接收地址
//比起接收模式多的选项 2
RF2G4_Write_Reg(W_REGISTER+SETUP_RETR,0x1A); // 设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
RF2G4_Write_Reg(W_REGISTER+RF_CH,40); // 设置RF通信频率
RF2G4_Write_Reg(W_REGISTER+RF_SETUP,0x0F); // 设置:发射功率0dBm、射频数据率2Mbps
RF2G4_Write_Reg(W_REGISTER+CONFIG,0x0E); // 配置参数;接收模式、开机模式、CRC=2Byte、开启CRC、。。。
RF2G4_CE = 1; //进入发送模式
}
//-------------------------------------------------------------------------------------------------------------------
// SI24R1发送一帧数据
// P_Data = 待发送数据首地址
// N_Data = 待发送数据的个数
// return = 发送完成状况
//-------------------------------------------------------------------------------------------
u8 RF2G4_Tx_Packet(u8* P_Data,u8 N_Data)
{
u8 V_Reg;
SPI2_SetSpeed(SPI_BaudRatePrescaler_4); // SPI速度为9Mhz(24L01的最大SPI时钟为10Mhz)
RF2G4_CE = 0;//待机模式,无数据传输,其实可以让其一直为1就行,不需要等0,发送到缓存器后再发送出去。
RF2G4_Write_Cont(W_TX_PAYLOAD,P_Data,N_Data); // 将要发送的数据写入发送缓存器,P_Data上面已经定义是个指针地址,这直接使用这个变量就代表指针
RF2G4_CE = 1; // 进入发送模式,CE为高,>10us发送完成
while(RF2G4_IRQ != 0); // 等待发送完成置1
V_Reg = RF2G4_Read_Reg(STATUS); // 读取状态寄存器的值
RF2G4_Write_Reg(W_REGISTER+STATUS,V_Reg); // 清除TX_DS/MAX_RT中断标志,写1清除中断
if(V_Reg & TX_MAX) // 判断是否达到最大重发次数
{
RF2G4_Write_Reg(FLUSH_TX,0xFF); // 清除TX_FIFO
return TX_FAIL_MAX; // 返回发送失败(达到最大重发次数)
}
if(V_Reg & TX_OK)
{
return TX_SUCCESS; // 返回发送成功
}
return TX_FAIL; // 返回发送失败
}
//-------------------------------------------------------------------------------------------
// SI24R1接收一帧数据
// P_Data = 缓存接收数据的首地址
// N_Data = 待缓存数据的个数
// return = 数据接收情况
//-------------------------------------------------------------------------------------------
u8 RF2G4_Rx_Packet(u8* P_Data,u8 N_Data)
{
u8 V_Reg;
SPI2_SetSpeed(SPI_BaudRatePrescaler_4); // SPI速度为9Mhz(SI24R1的最大SPI时钟为10Mhz)
V_Reg=RF2G4_Read_Reg(STATUS); // 读取状态寄存器的值
RF2G4_Write_Reg(W_REGISTER+STATUS,V_Reg); // 清除RX_DS/MAX_RT中断标志
if(V_Reg & RX_OK) // 判断是否接收到数据
{
RF2G4_Read_Cont(R_RX_PAYLOAD,P_Data,N_Data); // 读取数据
RF2G4_Write_Reg(FLUSH_RX,0xFF); // 清除RX_FIFO
return RX_SUCCESS; // 返回接收成功
}
return RX_FAIL; // 返回接收失败
}
//-------------------2G4手柄控制小车---------------------------------------------------
extern char MODE;
extern u16 C_stop;
extern u8 F_stop;
void RF24L01_control(void)
{
if(MODE==0)
{
if(RF2G4_Rx_Packet(RF2G4_Receive_Data,14)== RX_SUCCESS) // 判断是否接收到数据
{
//测试接收的数据发送到到串口3
Usart3_SendArray(USART3, RF2G4_Receive_Data, 14);
F_stop = 0 ; //停车标志位清零
C_stop = 0 ; // 停车计数清零,重新计数
// 根据接收到的指令执行相应动作
//-------------------------------------------------------------------------------------------------
if(RF2G4_Receive_Data[10]<177&&RF2G4_Receive_Data[10]>77)
{
if( RF2G4_Receive_Data[13]>177)
{
if(RF2G4_Receive_Data[12]<177&&RF2G4_Receive_Data[12]>77) Car_forward(RF2G4_Receive_Data[11]/2.55);
else if(RF2G4_Receive_Data[12]>177) Car_rightup(RF2G4_Receive_Data[11]/2.55);
else if(RF2G4_Receive_Data[12]<77) Car_leftup(RF2G4_Receive_Data[11]/2.55);
else Car_stop(0);
}
else if( RF2G4_Receive_Data[13]<77)
{
if(RF2G4_Receive_Data[12]<177&&RF2G4_Receive_Data[12]>77) Car_backward(RF2G4_Receive_Data[11]/2.55);
else if(RF2G4_Receive_Data[12]>177) Car_rightdown(RF2G4_Receive_Data[11]/2.55);
else if(RF2G4_Receive_Data[12]<77) Car_leftdown(RF2G4_Receive_Data[11]/2.55);
else Car_stop(0);
}
else if( RF2G4_Receive_Data[13]<177&&RF2G4_Receive_Data[13]>77)
{
if( RF2G4_Receive_Data[12]>177) Car_right(RF2G4_Receive_Data[11]/2.55);
else if( RF2G4_Receive_Data[12]<77) Car_left(RF2G4_Receive_Data[11]/2.55);
else Car_stop(0);
}
}
else if( RF2G4_Receive_Data[10]>177) Car_turnright(RF2G4_Receive_Data[11]/2.55);
else if( RF2G4_Receive_Data[10]<77) Car_turnleft(RF2G4_Receive_Data[11]/2.55);
else Car_stop(0);
}
if( F_stop == 1) Car_stop(0); // 命令失效,小车熄火
}
}
#ifndef __RF2G4_H
#define __RF2G4_H
#include "stm32f10x.h"
#include "bit_band.h"
#include "spi.h"
//--------------------------------
// 2G4通信地址
//--------------------------------
extern const u8 RF2G4_ADDR_TX[5];
extern const u8 RF2G4_ADDR_RX[5];
//地址宽度
#define TX_ADR_WIDTH 5 // 发射地址宽度(5字节)
#define RX_ADR_WIDTH 5 // 接收地址宽度(5字节)
//--------------------------------
// 2.4G发射数据缓存数组
extern u8 RF2G4_Send_Data[14];
// 2.4G接收数据缓存数组
extern u8 RF2G4_Receive_Data[14];
//--------------------------------------
//---------------------------------------------------------------
//SI24R1连接
#define RF2G4_CE PB_out(0) // SI24R1选信号
#define RF2G4_CSN PC_out(2) // SPI片选信号
#define RF2G4_IRQ PB_in(1) // IRQ主机数据输入
//---------------------------------------------------------------
//SI24R1寄存器操作命令
//-----------------------------------------------------------------------------------
#define R_REGISTER 0x00 // 读寄存器,低5位为寄存器地址
#define W_REGISTER 0x20 // 写寄存器,低5位为寄存器地址
#define R_RX_PAYLOAD 0x61 // 读RX有效数据,1~32字节
#define W_TX_PAYLOAD 0xA0 // 写TX有效数据,1~32字节
#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器.接收模式下用
#define NOP 0xFF // 空操作,可以用来读状态寄存器
//-----------------------------------------------------------------------------------
//SPI(SI24R1)寄存器地址
//----------------------------------------------------------------------------------------------------------------------
#define CONFIG 0x00 // 配置寄存器地址;bit0:1接收模式,0发射模式;bit1:1上电,0掉电选择;bit2:CRC模式:0,8位模式;
//bit3:1,CRC使能,bit4:中断MAX_RT(达到最大重发次数中断)使能;bit5:中断TX_DS使能;bit6:中断RX_DR使能
#define EN_AA 0x01 // 使能自动应答功能 bit0~5,对应通道0~5
#define EN_RXADDR 0x02 // 接收数据通道允许,bit0~5,对应通道0~5
#define RF_CH 0x05 // 射频通道,bit6:0,工作通道频率设置;
#define RF_SETUP 0x06 // RF寄存器;bit3:传输速率(0:1Mbps,1:2Mbps);bit2:1,发射功率;bit0:低噪声放大器增益
#define RX_PW_P0 0x11 // 通道0接收数据宽度(1~32字节),设置为0则非法
#define RX_ADDR_P0 0x0A // 数据通道0设置地址,最大长度5个字节,低字节在前
#define TX_ADDR 0x10 // 发送地址(低字节在前),ShockBurstTM模式下,RX_ADDR_P0与此地址相等
#define SETUP_RETR 0x04 // 建立自动重发;bit3:0,自动重发计数器;bit7:4,自动重发延时 250*x+86us
#define STATUS 0x07 // 状态寄存器;bit0:TX FIFO满标志;bit3:1,接收数据通道号(最大:6);bit4,达到最多次重发
// bit5:数据发送完成中断;bit6:接收数据中断;
#define TX_MAX 0x10 // 达到最大发送次数中断
#define TX_OK 0x20 // TX发送完成中断
#define RX_OK 0x40 // 接收到数据中断
#define TX_FAIL_MAX 2 // 发送失败
#define TX_SUCCESS 0 // 发送成功
#define TX_FAIL 1 // 发送失败
#define RX_SUCCESS 0 // 接收成功
#define RX_FAIL 1 // 接收失败
//未使用寄存器
#define SETUP_AW 0x03 // 设置地址宽度(所有数据通道):bit1,0:00,3字节;01,4字节;02,5字节;默认11是5个字节,所以程序中未进行设置
#define OBSERVE_TX 0x08 // 发送检测寄存器,bit7:4,数据包丢失计数器;bit3:0,重发计数器
#define RSSI 0x09 // 载波检测寄存器,bit0,载波检测;
#define FIFO_STATUS 0x17 // FIFO状态寄存器;bit0,RX FIFO寄存器空标志;bit1,RX FIFO满标志;bit2,3,保留
// bit4,TX FIFO空标志;bit5,TX FIFO满标志;bit6,1,循环发送上一数据包.0,不循环;
//----------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
void RF2G4_Init(void);
u8 RF2G4_Write_Reg(u8 Reg,u8 Write_Value);
u8 RF2G4_Write_Cont(u8 Reg, u8* P_Data, u8 N_Data);
u8 RF2G4_Read_Reg(u8 Reg);
u8 RF2G4_Read_Cont(u8 Reg, u8* P_Data, u8 N_Data);
u8 RF2G4_Check(void);
void RF2G4_RX_Mode(void);
void RF2G4_TX_Mode(void);
u8 RF2G4_Tx_Packet(u8* P_Data,u8 N_Data);
u8 RF2G4_Rx_Packet(u8* P_Data,u8 N_Data);
//-------------------------------------------------------------------------------------
void RF24L01_control(void);
#endif /* __RF2G4_H */
#include "beep.h"
#include "delay.h"
void BEEP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_8);
}
void BEEP_Sound(void)
{
BEEP=1;
delay_ms(100);
BEEP=0;
}
#ifndef __BEEP_H
#define __BEEP_H
#include "stm32f10x.h"
#include "bit_band.h"
#define BEEP PA_out(8)
void BEEP_Init(void);
void BEEP_Sound(void);
#endif