OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4649|回复: 2

STM32蓝牙循迹程序 修改

[复制链接]

3

主题

4

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2016-4-24
在线时间
4 小时
发表于 2016-5-8 17:32:40 | 显示全部楼层 |阅读模式
5金钱
现在已经实现了蓝牙控制小车部分   和  自动循迹部分  ,但是把俩个部分合在一起,使用蓝牙让小车进入到循迹,就不管用了,编译也没有问题,求助大神看看是哪里的问题


#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_IRQChannelPreemptionPriority = 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 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;                               
        }
}

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);
          
         }
          
//主函数
int main(void)
{       
        u8 i;
       
      UP_Bluetooth_Init();                                  /*蓝牙初始化*/
      UP_Bluetooth_EnableIT();                           /*使能蓝牙数据接收中断*/
      UP_Bluetooth_SetHadler(BluetoothHadler); /*定义蓝牙数据接收中断入口函数*/
          UP_Timer_EnableIT(TIMER_CHANNEL0,1000);//使能定时中断
          UP_Timer_SetHadler(Timer_Handler);//设置定时中断的入口函数
          USART3_NVIC();
          USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//串口3接收中断使能
        /*初始化系统*/
        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_LCD_ShowInt(8,1,rec_num);      //显示收到的循迹板返回数据帧数
                for(i=0;i<7;i++)                                //显示循迹板的7个点的状态
                {
                        if((track_sign & (1<<i)))
                                UP_LCD_ShowInt(2*i,2,1);
                        else
                                UP_LCD_ShowInt(2*i,2,0);
                }               
                 move_forward(track_sign);                //巡线
                UP_delay_ms(100);
        }       
        }
        }
       






正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2016-5-11 21:43:13 | 显示全部楼层
回复

使用道具 举报

3

主题

21

帖子

0

精华

高级会员

Rank: 4

积分
537
金钱
537
注册时间
2014-10-6
在线时间
232 小时
发表于 2016-5-19 13:14:07 | 显示全部楼层
有分开的程序吗?可以帮你看一看
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 02:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表