我是靠谱客的博主 冷傲诺言,最近开发中收集的这篇文章主要介绍麦克纳姆轮小车程序(标准库版本),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

麦克娜姆轮小车包含蓝牙手机控制,手柄控制,上位机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)!='');
  
  /* 等待发送完成 */
  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

最后

以上就是冷傲诺言为你收集整理的麦克纳姆轮小车程序(标准库版本)的全部内容,希望文章能够帮你解决麦克纳姆轮小车程序(标准库版本)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部