现在已经实现了蓝牙控制小车部分 和 自动循迹部分 ,但是把俩个部分合在一起,使用蓝牙让小车进入到循迹,就不管用了,编译也没有问题,求助大神看看是哪里的问题。
#include "UPLib\UP_System.h"
u32 data;
#define BaseSpeed 800 //小车基础速度
s16 Speed1,Speed2,Speed3,Speed4; //四个舵机的速度
u8 CDS_LEN; //解析循迹板回传数据的有效数据长度
u8 CDS_DATA[5]; //循迹板返回数据的缓存
u8 track_sign; //循迹板7个点的状态
u32 rec_num;
/*函数说明:串口3开启中断,用于控制器与寻线板之间的中断接收与定时发送*/
void USART3_NVIC(void) //开启串口3中断
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemp
tionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*函数说明:解析循迹板传回的数据,按照寻线板说明文档的具体协议解析寻线板返回的信息,并将寻线板状态赋值给track_sign*/
void CDS_UARTHadler(u8 Data) //用于解析收到的循迹板传回的数据
{//返回数据示例FF FF 00 03 00 03 FB--字头1 字头2 ID 长度 错误信息 数据 校验
u8 temp; //收到的数据
static u8 sum = 0; //校验
static u8 count = 0;
static u8 data_count = 0;
temp = Data;
switch(count)
{
case 0:
{
if(temp == 0xFF) //判断字头1
count = 1;
else
sum = 0;
}
break;
case 1:
{
if(temp != 0xFF) //判断字头2
{
count = 0;
sum = 0;
}
else
{
count = 2;
}
}
break;
case 2:
{
if(temp != 0x00) //循迹板ID,固定为0x00
{
count = 0;
sum = 0;
}
else
{
sum = 0x00;
count = 3;
}
}
break;
case 3:
{
if(temp != 0x03) //有效数据长度
{
count = 0;
sum = 0;
}
else
{
CDS_LEN = 0x03;
sum += CDS_LEN;
count = 4;
data_count = 0x00;
}
}
break;
case 4:
{
if(data_count < (CDS_LEN-1))//回传数据的有效数据存入缓存
{
CDS_DATA[data_count] = temp;
sum += temp;
data_count += 1;
}
else if(data_count == ((CDS_LEN-1)))
{
sum = ~sum;
if(sum == temp) //判断校验位是否正确
{
if(CDS_DATA[0] == 0x00) //判断状态位0x00为正常
{
track_sign = CDS_DATA[1] ;//循迹板状态存入标志变量中
rec_num++;
}
}
sum = 0;
data_count = 0;
count = 0;
}
}
break;
default:
break;
}
}
/*函数说明:串口3中断服务程序,调用CDS_UARTHadler(u 8 Data)*/
void USART3_IRQHandler(void)//串口3中断函数
{
//接收中断
if(USART_GetITStatus(USART3,USART_IT_RXNE)==SET)//判断是否为接收中断
{
USART_ClearITPendingBit(USART3,USART_IT_RXNE);//清中断标志
CDS_UARTHadler(USART_ReceiveData(USART3)); //解析收到的数据
}
//溢出-如果发生溢出需要先读SR,再读DR寄存器 则可清除不断入中断的问题
if(USART_GetFlagStatus(USART3,USART_FLAG_ORE)==SET)
{
USART_ClearFlag(USART3,USART_FLAG_ORE); //读SR
USART_ReceiveData(USART3); //读DR
}
}
/*函数说明:*/
void UP_UART3_Putc(unsigned char c)
{
USART_SendData(USART3, c);
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET );
}
/*函数说明:寻线板状态读取*/
void CDS_Read_Sign(void)//读取循迹板状态函数
{
UART3_RXDS; //关闭舵机总线的接收信号线
UART3_TXEN; //打开舵机总线的发送信号线
UP_UART3_Putc(0xff);//字头1
UP_UART3_Putc(0xff);//字头2
UP_UART3_Putc(0x00);//循迹板ID
UP_UART3_Putc(0x04);//数据长度
UP_UART3_Putc(0x02);//读指令
UP_UART3_Putc(0x32);//读取内存地址
UP_UART3_Putc(0x01);//读取数据长度
UP_UART3_Putc(0xc6);//校验
UP_delay_us(10); //延时10us等待数据被发送完毕
//循迹板通讯接口采用了CDS系列数字舵机的单总线接口,接收和发送数据是复用一根线
UART3_TXDS; //关闭舵机总线的发送信号线
UART3_RXEN; //打开舵机总线的接收信号线
}
/*函数说明:定时单位基于1ms,每3ms给舵机和寻线板发送指令,根据传感器的状态及时调整小车的方向,可以发送Speed1等值调节舵机速度*/
void Timer_Handler(u32 null)//1ms定时中断,定时给舵机和循迹板发送指令
{
static u32 Count;
//舵机每收到一次数据会立刻返回数据,而且舵机总线收发信号线是复用的
//所以每当给一个舵机发送指令后最好延时3ms等待该舵机返回数据完毕,再
//发送另外一条舵机指令,防止指令丢失
if(0 == Count)
{
CDS_Read_Sign();
}
else if(3 == Count)
{//因在Count为0时打开了舵机总线的接收,在发送新数据前要关闭
UART3_RXDS; //关闭舵机总线的接收信号线,舵机速度设置函数中包含了UART3_TXEN
UP_CDS_SetSpeed(0x01,Speed1);
}
else if(6 == Count)
UP_CDS_SetSpeed(0x02,Speed2);
else if(9 == Count)
UP_CDS_SetSpeed(0x03,Speed3);
else if(12 == Count)
UP_CDS_SetSpeed(0x04,Speed4);
if(12 == Count)
Count = 0;
else
Count += 1;
}
void move_forward(u8 sign);
void BluetoothHadler(u32 Bluetoothdata) /*蓝牙接收数据*/
{ data=Bluetoothdata;
}
void go() /*小车前进*/
{
UP_CDS_SetSpeed(1, 1000);
UP_CDS_SetSpeed(2, -1000);
UP_CDS_SetSpeed(3, 1000);
UP_CDS_SetSpeed(4, -1000);
}
void back() /*小车后退*/
{
UP_CDS_SetSpeed(1, -1000);
UP_CDS_SetSpeed(2, 1000);
UP_CDS_SetSpeed(3, -1000);
UP_CDS_SetSpeed(4, 1000);
}
void Right() /*小车右转*/
{
UP_CDS_SetSpeed(1, 1000);
UP_CDS_SetSpeed(2, -800);
UP_CDS_SetSpeed(3, 1000);
UP_CDS_SetSpeed(4, -800);
}
void Left() /*小车左转*/
{
UP_CDS_SetSpeed(1, 800);
UP_CDS_SetSpeed(2, -1000);
UP_CDS_SetSpeed(3, 800);
UP_CDS_SetSpeed(4, -1000);
}
void stop()/*小车停止*/
{
UP_CDS_SetSpeed(1, 0);
UP_CDS_SetSpeed(2, 0);
UP_CDS_SetSpeed(3, 0);
UP_CDS_SetSpeed(4, 0);
}
/*函数说明:速度值设定,用于定时发送的速度值*/
void SetSpeed(s16 left,s16 right)
{
Speed1 = left;//
Speed2 = 0-right;//
Speed3 = left;//
Speed4 = 0-right;//
}
/*函数说明:根据传感器的状态,调用SetSpeed(s16 left,s16 right)函数,设置相应Speed值*/
void move_forward(u8 sign)
{
static u8 turn_sign = 0;
switch(sign&0x7f) //track_sign最高位无效,低7位为红外状态,bit0~bit6对应从左到右7个红外
{
case 0x08://0001 000
SetSpeed(BaseSpeed,BaseSpeed); //前进
turn_sign = 0;//转弯标志:0前进,1左转,2右转
break;
case 0x0c://0011 000
SetSpeed(BaseSpeed-100,BaseSpeed+100); //左转
turn_sign = 1;
break;
case 0x04://0010 000 1
SetSpeed(BaseSpeed-200,BaseSpeed+200);//左转
turn_sign = 1;
break;
case 0x02://0100 000
SetSpeed(0-BaseSpeed,BaseSpeed); //左转
turn_sign = 1;
break;
case 0x01://1000 000
SetSpeed(0-BaseSpeed,BaseSpeed); //左转
turn_sign = 1;
break;
case 0x18://0001 100
SetSpeed(BaseSpeed+100,BaseSpeed-200); //右转
turn_sign = 2;
break;
case 0x10://0000 100
SetSpeed(BaseSpeed+200,BaseSpeed-200); //右转
turn_sign = 2;
break;
case 0x20://0000 010
SetSpeed(BaseSpeed,0-BaseSpeed); //右转
turn_sign = 2;
break;
case 0x40://0000 001
SetSpeed(BaseSpeed,0-BaseSpeed); //右转
turn_sign = 2;
break;
default:
if(0 == turn_sign)
SetSpeed(BaseSpeed,BaseSpeed);
else if(1 == turn_sign)
SetSpeed(0-BaseSpeed,BaseSpeed);
else if(2 == turn_sign)
SetSpeed(BaseSpeed,0-BaseSpeed);
break;
}
}
//主函数
int main(void)
{
u8 i;
UP_Bluetooth_Init(); /*蓝牙初始化*/
UP_Bluetooth_EnableIT(); /*使能蓝牙数据接收中断*/
UP_Bluetooth_SetHadler(BluetoothHadler); /*定义蓝牙数据接收中断入口函数*/
/*初始化系统*/
UP_System_Init();
UP_CDS_SetMode(1, CDS_MOTOMODE); /*小车设置为电机模式*/
UP_CDS_SetMode(2, CDS_MOTOMODE);
UP_CDS_SetMode(3, CDS_MOTOMODE);
UP_CDS_SetMode(4, CDS_MOTOMODE);
UP_LCD_ShowString(2,0,"-=Demo_VGA=-");
UP_LCD_ShowString(0,1,"Rec_Num:");
/*进入While(1)死循环*/
while(1)
{ if(data== 1) /*如果收到蓝牙数据为“1”,就前进*/
{ go();
}
if(data == 2) /*如果收到蓝牙数据为“2”,就后退*/
{ back();
}
if(data == 3)
{ Right();
}
if(data == 4)
{ Left ();
}
if(data == 5)
{ stop ();
}
if(data==23)
{
UP_Timer_EnableIT(TIMER_CHANNEL0,1000);//使能定时中断
UP_Timer_SetHadler(Timer_Handler);//设置定时中断的入口函数
USART3_NVIC();
USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//串口3接收中断使能
UP_LCD_ShowInt(8,1,rec_num); //显示收到的循迹板返回数据帧数
for(i=0;i<7;i++) //显示循迹板的7个点的状态
{
if((track_sign & (1<
UP_LCD_ShowInt(2*i,2,1);
else
UP_LCD_ShowInt(2*i,2,0);
}
move_forward(track_sign); //巡线
UP_delay_ms(100);
}
}
}
蓝牙循迹.rar (3.31 MB )