打印
[PIC®/AVR®/dsPIC®产品]

pic单片机与陀螺仪串口编程问题,请大虾们指错

[复制链接]
1656|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
断断续续弄了好多天,陀螺仪是串口输出,程序改来改去,一直出不了数据。程序如下(感觉没接受到数据传感器发来的数据,或者counter始终没有达到11位字节的数据),麻烦朋友们指明错误,谢谢。

#include <p18f2525.h>#include <math.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int

//^^^^^^^^^^^^^^^^^^^^^配置位的软件设置^^^^^^^^^^^^^^^^^^^^^^//
#pragma config WDT = OFF     //看门狗禁止
#pragma config OSC = HS      //晶振
#pragma config LVP = OFF     //低电压编程禁止


float Acc[3],Gyr[3],Mag[3],rpy[3];
float ROLL,PITCH,YAW;
unsigned char Re_buf[11];
unsigned char sign;
unsigned char counter=0;


//********串口函数声明*******//
void USART_Init(void);
void UartData(char dat);
void UartSend(uchar *ptr,unsigned char length);
void USART_init(void);
//void UartReceive();
void interrupt_ISR(void);

void delayms(unsigned char time)   //延时函数
{
        unsigned char i;
        unsigned char s;
        for(s=time;s<0;s--)
        for(i=192;i;i--);
}

//^^^^^^^^^^^^^^^^^^^^^单片机串口初始化^^^^^^^^^^^^^^^^^^^^^^//
void USART_init(void)                  
{
        TRISCbits.TRISC7=1;                        //IO方向初始化RC7、RC6口设置为输入
        TRISCbits.TRISC6=1;       
        PIE1bits.RCIE=0;                   //关闭接收使能RCIE
        RCSTA=0x00;                                   //关闭串行端口
        PIE1bits.RCIE=1;                   //串口接收中断
        PIE1bits.TXIE=1;                   //串口发送中断       
        RCSTA=0x90;                                   //使能串行端口,使能连续接收
        TXSTA=0x24;                                   //使能发送,高速波特率       
        SPBRG=51;                                   //设置波特率寄存器X=51,波特率为9600;波特率=Fosc/[16(X+1)]
        INTCON=0xC0;                           //全局中断GIE打开;使能外部中断PEIE
}
//^^^^^^^^^^^字节发送函数^^^^^^^^^^^^^^^^^^^//
void UartData(char dat)
{
        TXREG=dat;
        while(TXSTAbits.TRMT==0);
}
//^^^^^^^^^^^字符串发送函数^^^^^^^^^^^^^^^^^^^//
void UartSend(unsigned char *ptr,unsigned char length)    //*s^^^^ptr
{
        int i=0;
        while(i<length)
        {
                UartData(*(ptr+i));
                i++;
        }
}




/*

void send_Instruction(void)
{
        unsigned char send_data[3]={0};
        send_data[0]=0xa5;
        send_data[1]=0x15;//加计功能字节
        send_data[2]=(unsigned char)(send_data[0]+send_data[1]);//指令校验和
        UartSend(send_data,3);//发送加速度输出指令
        delayms(1);
        send_data[0]=0xa5;
        send_data[1]=0x25;
        send_data[2]=(unsigned char)(send_data[0]+send_data[1]);
        UartSend(send_data,3);//发送陀螺仪数据输出指令
        delayms(1);
        send_data[0]=0xa5;
        send_data[1]=0x35;
        send_data[2]=(unsigned char)(send_data[0]+send_data[1]);
        UartSend(send_data,3);//发送磁场数据输出指令
        delayms(1);
        send_data[0]=0xa5;
        send_data[1]=0x45;
        send_data[2]=(unsigned char)(send_data[0]+send_data[1]);
    UartSend(send_data,3);//发送欧拉角数据输出指令
        delayms(1);
        send_data[0]=0xa5;
        send_data[1]=0x65;
        send_data[2]=(unsigned char)(send_data[0]+send_data[1]);
        UartSend(send_data,3);//发送四元数数据输出指令
}




*/
//*******************串口中断********************//
void interrupt_ISR(void)
{
        if(PIR1bits.RCIF&&PIE1bits.RCIE)

{
        PIR1bits.RCIF=0;
                 Re_buf[counter]=RCREG;
            if(counter==0&&Re_buf[0]!=0x5A&&counter==1&&Re_buf[1]!=0x5A) return;      //第0号和1号数据不是帧头
             
              counter++;                                                                //如果是帧头则开始计数
             
              if(counter==11)             //接收到11个数据
              {   
                 counter=0;               //重新赋值,准备下一帧数据的接收
                
                 sign=1;
          
              }
             
          }
          
}          

void main(void)
{
        delayms(500);
               TRISBbits.TRISB3=0;
                PORTBbits.RB3=1;
                TRISBbits.TRISB4=0;
                PORTBbits.RB4=1;
                //delayms(50);
        USART_init();
        UartData(0XA5);    //欧拉角发送指令,暂时只接受欧拉角数据(这种向模块发送指令的程序书写有没有问题???)
        UartData(0X45);
        UartData(0XEA);

   while(1)
   {     
         
        if(sign)
            {
                sign=0;
                interrupt_ISR();
        if(Re_buf[0]==0x5A&&Re_buf[1]==0x5A)      //检查帧头
              {  
                        switch(Re_buf[2])
                        {
                        case 0x15:          //三轴加速度
                        {
                        Acc[0]=((short)(Re_buf[4]<<8|Re_buf[5]))/16383.0;
                    Acc[1]=((short)(Re_buf[4]<<8|Re_buf[5]))/16383.0;
                        Acc[2]=((short)(Re_buf[4]<<8|Re_buf[5]))/16383.0;
               
                        }
                        break;

                        case 0x25:         //陀螺仪数据
                        {
                        Gyr[0]=((short)(Re_buf[4]<<8|Re_buf[5]))/16383.0;
                        Gyr[1]=((short)(Re_buf[6]<<8|Re_buf[7]))/16383.0;
                        Gyr[2]=((short)(Re_buf[8]<<8|Re_buf[9]))/16383.0;
       
                        }
                        break;

                //        case 0x35:         //磁力计数据
                        //{
                //        Mag[0]=((short)(Re_buf[4]<<8|Re_buf[5]))/16383.0;
                //        Mag[1]=((short)(Re_buf[6]<<8|Re_buf[7]))/16383.0;
                //        Mag[2]=((short)(Re_buf[8]<<8|Re_buf[9]))/16383.0;
       
                //        }
                        break;
                       
                        case 0x45:          //欧拉角数据
                        {
                        ROLL=((short)(Re_buf[4]<<8|Re_buf[5]))/16383.0*100;
                        PITCH=((short)(Re_buf[6]<<8|Re_buf[7]))/16383.0*100;
                        YAW=((short)(Re_buf[8]<<8|Re_buf[9]))/16383.0*100;
                        rpy[0]=ROLL;
                        rpy[1]=PITCH;
                        rpy[2]=YAW;
       
                        }
                        break;
                       
                       
                       
                       
               
                        /*
                       
                        case 0x65:            //四元数数据
                        {
                        Q[0]=((short)(Re_buf[0]<<8|Re_buf[1]))/16383.0*10000;
                        Q[1]=((short)(Re_buf[2]<<8|Re_buf[3]))/16383.0*10000;
                        Q[2]=((short)(Re_buf[4]<<8|Re_buf[5]))/16383.0*10000;
                        Q[3]=((short)(Re_buf[6]<<8|Re_buf[7]))/16383.0*10000;
                        }
                        break;       
                       
                        */       
                  }               
               }
      }
   }
}
在烧录程序后,单片机在主程序中一直在这两处循环,没有进入下面的函数(图1),也没有进入中断或者在在主函数循环中加入中断后单步运行如(图2)



111.png (35.19 KB )

图1

图1

222.png (28.23 KB )

图2

图2
沙发
JY-DX-JY| | 2016-8-9 18:05 | 只看该作者
串口调通了吗?或者先用串口助手调调。

使用特权

评论回复
板凳
老麻烦了|  楼主 | 2016-8-9 18:46 | 只看该作者
JY-DX-JY 发表于 2016-8-9 18:05
串口调通了吗?或者先用串口助手调调。

中断程序只走了一次,数据应该没有出来

使用特权

评论回复
地板
老麻烦了|  楼主 | 2016-8-10 22:09 | 只看该作者
顶起来

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

54

帖子

1

粉丝