基于Xilinx N4板和MicroBlaze核的手机控制板载LED

基于蓝牙SPP指令的手机控制LED

错误1:通信一直失败

能解决的办法:由于SPP通信指令格式为“APT+指令”,且结尾必须是”\r\n”,所以一直没有成功的建立和手机的通信。

错误2:可以接收到蓝牙的数据,但是接收不到手机发送的,只能接收到O和换行符

能解决的办法:把清除FIFOS那段代码删除,清除FIFOS会使得接收到的数据也被清除。同时也要把接收数据的函数写在main函数里而不是中断里。

硬件连接

硬件框图

UCF使用了串口和GPIO部分。同实验二。

软件编写

ASCII码表中: 0X30~0X39:阿拉伯数字0~9

                   0X41~0X5A:大写字母A~Z

                   0X61~0X7A小写字母a~z

由于蓝牙上电会发送“II”,连接到手机上回发送“IA”,发送数据成功会发送“OK”,接收到数据格式为APR+XXXX,故不适合用大写字母,而阿拉伯数字只有10个,LED有16个,也不适合用阿拉伯数字。

由于蓝牙接收到SPP密码“APT+SPP8888\r\n”之后,才能进行SPP通信,所以在程序初始化的时候,就发送SPP密码解锁蓝牙的SPP功能。AT指令还有很多,但是在这里用不到那些查询蓝牙连接状态,播放音乐,挂断来电,音量加减的指令。

16个灯就是:a b c d e f g h i j k l m n o p

手机发送字符过去,蓝牙接收到之后,发给FPGA。如果在0X60~0X71也就是a~p之间,减去0X60提取到灯的位数,然后0X0001左移位数写给LED就可以控制相应的LED。

软件流程图

实验结果和心得体会

用USB转TTL在电脑的串口助手上面调试的时候,数据收发完全没问题,但是一旦用手机来控制,就出现接收不到数据也发送不出来数据的问题。经过排查,首先是那个数据格式“APT+\r\n”,如果不是这个格式手机就收不到数据。第二个大坑是UART的clear fifos,刚开始写在中断里,就会导致收到的数据不完整。查了一个中午,终于,在把它写到主函数里之后,通信成功了!通过手机可以控制相应的LED亮。

代码:

#include "platform.h"

#include "xintc.h"

#include "xintc_i.h"

#include "xil_exception.h"//(硬件异常和软件异常处理)

#include "stdio.h"

#include "xuartlite.h"

#include "xuartlite_l.h"

#include "xparameters.h"

#include "xil_io.h"

#include "xgpio.h"

void print(char *str);

void Initialize(void);

void Uart_Handler(void);

XIntc IntCtrl;

XUartLite UART;

short flag_RX=0x00;

unsigned char RX_data=0x00;

u8 buf[32]="APT+SPP8888\r\n";

u8 buf_test[32]="APT+OK\r\n";

u8 buf1[32]="APT+";

u8 buf2[32]="\r\n";

u8 buf3[32]="LED NUM is";

XGpio LED;

int k=0 , j=0;

u16 LED_OUT=1;

int main()

{

    print("programstart\r\n");

   Initialize();

   XGpio_DiscreteWrite(&LED,1,0xffff);

while(1)

{

////UART/////////////////////////////////////////////////////////////

    //0X49:I  0XA:换行    0X4F:O   0X4B:K  0XD:回车

       if(flag_RX)

       {

           flag_RX=0;

           RX_data =Xil_In32(XPAR_UART_BASEADDR+0X00);//数据寄存器的偏移地址是0X00

           xil_printf("UART received data  0x%X\r\n",RX_data);

           XUartLite_Send(&UART,buf_test,13);

           if(0x60<RX_data&&RX_data<0x71)//a~p

           {

           u8 temp=0;

           temp=RX_data-0X61;

           LED_OUT=0x0001<<temp;

           XGpio_DiscreteWrite(&LED,1,LED_OUT);

           }

           if(RX_data==0x7A)//z

           {

              Xil_Out16(XPAR_LEDS_BASEADDR,0x0000);

           }

           if(RX_data==0x41)//A

           {

              for( k=0;k<2;k++){

               for( j=0;j<15;j++){  XUartLite_SendByte(XPAR_UART_BASEADDR,buf[j]);}  }

           }

     }//if (flag)

       }

    return 0;

}

void Initialize(void)

{

   init_platform();

   XIntc_Initialize(&IntCtrl , XPAR_INTC_DEVICE_ID);

////UART/////////////////////////////////////////////////////////////   XUartLite_Initialize(&UART,XPAR_UART_DEVICE_ID);

   XUartLite_ResetFifos(&UART);

   while(XUartLite_IsTransmitFull(XPAR_UART_DEVICE_ID));

   XUartLite_Send(&UART,buf,15);

   XUartLite_EnableInterrupt(&UART);

   XIntc_Connect(&IntCtrl,XPAR_INTC_0_UARTLITE_2_VEC_ID,(XInterruptHandler)Uart_Handler,(void*)&UART);

////LED//////////////////////////////////////////////////////////////       XGpio_Initialize(&LED,  XPAR_LEDS_DEVICE_ID);

   XGpio_SetDataDirection(&LED,1,0x0000);//通道

    XIntc_Enable(&IntCtrl,2);//UART

    microblaze_enable_interrupts();

  microblaze_register_handler((XInterruptHandler)XIntc_InterruptHandler,(void*)&IntCtrl);

    XIntc_Start(&IntCtrl,XIN_REAL_MODE);

    for( k=0;k<4;k++)

           {

           for( j=0;j<15;j++)

            {

              XUartLite_SendByte(XPAR_UART_BASEADDR,buf[j]);

            }

           }

}

void Uart_Handler(void)

{

    int flag_UART;

    //print("inthe intr\r\n");

    flag_UART=Xil_In32(XPAR_UART_BASEADDR+0X08);//状态寄存器的偏移地址是0X08第8位是奇偶校验,错就返回1

    if(flag_UART&0X01)

    {

       flag_RX = 1;

    }

}

猜你喜欢

转载自blog.csdn.net/weixin_42413559/article/details/80720598