• MicroBlaze核的串行接口实验:SPI UART


    reference :  https://blog.csdn.net/weixin_42413559/article/details/80720566

    串行接口:SPI UART

    XPS->SDK(Platform)->新建BSP->新建appproject

    问题1:在创建工程的时候没有像书上那样,添加了RS232接口,那么在prots中添加UART端口可以吗?

    经过试验,在创建工程的时候和在创建完成之后添加RS232都可以用来烧写程序的

    错误1:在导出到SDK的时候,导出失败

    不能解决的办法:新建一个BSB工程,在file->switch workspace里面把工作目录改为2的Export(改了之后SDK立即闪退重启)

    能解决的办法:重新在XPS里面导出到SDK,第二次还是没成功,SDK打开的还是上次走马管的内容,在file那里更改工作目录,软件再次闪退之后就好了。

    问题2:不小心把terminal给关了,怎么调出来?

    在左下角星号那里(showview as a fast view)

    错误2:<led> is already declared in thisregion.在生成网标的时候。

    能解决的办法:把实例LED改名字为LEDs,分析原因可能是系统默认里面还定义了LED,导致产生了冲突。

    错误3:LEDS没有声明,在生成比特流的时候。

    不能解决的办法:把LEDS改为LEDs,跟实例名字一样。

    能解决的办法:把LEDS改为LED,因为external端口的名字是LED而不是LEDs,LEDs是实例的端口。分析错误2应该是实例名和外部端口名不能一样。

    错误4:IO非用户可以使用/非IOSTANDARD

    不能解决的办法:把GPIO所有端口从UCF里面先删除,结果生成比特流时报错LED和SPI的连接。重新检查了UCF中发GPIO每一个引脚的连接发现没问题。重启软件。

    能解决的办法:在console里面看error情况。结果发现报错时SPI的引脚连接。我并没有为SPI分配引脚。

    错误5:缺少timer和spi相关的头文件

    不能解决的办法:删除一次BSP包,Refresh,重启SDK

    能解决的办法:删除两次BSP包,并refresh

    错误6: XUartLite_Send(&UART,buf,27);报warnning。

    不能解决的办法:原来这个函数传输进去的指针应该是*u8,但是buf是个char型变量

    错误7:把上个走马管的工程初始化代码赋值粘贴进去之后,不仅my_ISR报错,而且bsp的库文件的interrupt里面有个函数也报错:重复定义

    不能解决的办法:删除BSP重新添加(不报错),把上个走马管的.c文件打开复制过去(又报错)

    能解决的办法:每个函数都自己写一遍,直到把microblaze_register_handler添加进去的时候,my_ISR才会报错。应该是void My_ISR(void) __attribute__((interrupt_handler));的注册方式和microblaze_register_handler的注册方式是冲突的。将void My_ISR(void)去除,采用中断的API函数进行中断控制器和中断设备的连接。这个时候BSP错误再次出现,删除重新添加后即可。

    错误8:

    不能解决的办法:重启软件,重新打

    能解决的办法:虽然SpiIntrHandler声明过,但是还没有定义,定义了之后就不报错了。Undecleard和undefined是不一样的

    错误9:把程序烧写进去之后,初始化能过,但是10ms定时器中断进不去不能解决的办法:

    能解决的办法:从头到尾检查TIMER的初始化,发现10ms定时器进不去是因为没有开始定时器中断,即XTmrCtr_Start(&TimerCounterInst,0);。

    错误10:串口发不出来数据

    能解决的办法:串口中断函数没有注册

    错误11:串口接收不到数据

    能解决的办法:串口的初始化程序的设备ID有误,Device_0是DebugMode的,Device_1是RS232的,Device_2才是UART的,而我参考的代码只有一个串口,是Device_0所以一直是错的。并且没有使能UART的中断

    错误12:buf里面的27个char“UART Initialize Success ”总是只打印前16个,后面的打印不出来

    不能解决的办法:把数组容量改大

    能解决的办法:XUartLite_Send只能一次传输16个数据

    错误13:Btn_SW不能触发中断产生数据

    不能解决的办法:重启软件,把走马管的代码复制粘贴修改实例和地址名字,把按键的硬件由只有I功能改为IO功能,把LED的硬件由只有O功能改为IO功能,新建.c文件只写LED部分

    能解决的办法:把export删掉重新Export,然后就好了!没错,为了找这个问题我花了整整一晚上时间加上上午一个半小时!心态都快要崩了

    错误14:SW的值只能传输一半

    不能解决的办法:由于XUartLite_Send(&UART,&SW,1);//只能Send u8类型的,故不能把SW一次传输完,所以要把SW的值分两次传输完。但是如何区分两次信息的传输,以及分别接收SW的前一半和后一半解决不了。尝试了这个方法,发现还是不行。

    XUartLite_Send(&UART,&flag,1);

                  XUartLite_Send(&UART,&flag,1);

                  XUartLite_Send(&UART,&flag,1);//发送三次代表配对密码

    if(flag_in){flag_in=0;flag_out_first=1;}     

                  if(RX_data==0){flag_ok++;}

                  if(flag_ok==3)

                  {

                         flag_in=1;

                  }

                  if(flag_out_sec)

                  {

                         flag_out_sec=0;

                         Xil_Out8(XPAR_LEDS_BASEADDR+0xF,RX_data);

                  }

                  if(flag_out_first)

                  {

                         flag_out_first=0;

                         Xil_Out8(XPAR_LEDS_BASEADDR,RX_data);

                         flag_out_sec=1;

                  }

    能解决的办法:在验收的时候,见到有人做成功的。

    错误15:SPI没有时钟输出

    能解决的办法:检查SPI的初始化函数发现,connect和setstatus连接的不一样,connect连接的是库函数里面的XSpi_InterruptHandler,而setstatusHandler连接的是用户自定义的函数SpiIntrHandler

    错误16:DAC的锯齿波只有30HZ

    不能解决的办法:把其他函数都不运行,只运行锯齿波的,提高只有2HZ

    能解决的办法:把+1换成+更大的的数。经过测试T的初始值为0X24的时候频率为1KHZ,同时为了快速调节,当SW==0X4的时候,会加快T会倍增到5倍(每次加400HZ)。电压每次变化0.08V。

    错误17:ADC接收不到数据(一直是0X4CEC,重新烧写之后会变,但是保持恒定),但是示波器显示ADC转换数据正常

    不能解决的办法:单独把SPI写到While(1)里

    能解决的办法:请教同学发现print的时候,直接print ReadBuff的地址了,因为ReadBuff是个数组,代表地址,所以要先拼接之后再输出。

    硬件连接

    实验二硬件框图

    ① UART:PMODE,定义JA4(E17),JA10(E18)为RX和TX

    ② Swtiches&Btns(GPIO):8个按键

    ③ LED(GPIO):8个LED

    ④ SPI DA&AD:

    ⑤ timer(用来定时发送数据)

    ⑥ 中断控制器

     

    ⑦ UCF:

    NET "CLK" TNM_NET = sys_clk_pin;

    TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz;

    NET "CLK"      LOC= "E3"  | IOSTANDARD ="LVCMOS33";

    NET "REST"     LOC = "E16" | IOSTANDARD ="LVCMOS33";

    NET "RX_232"   LOC= "C4"  | IOSTANDARD ="LVCMOS33";

    NET "TX_232"   LOC= "D4"  | IOSTANDARD ="LVCMOS33";

    NET "RX"       LOC= "E17"  | IOSTANDARD ="LVCMOS33";

    NET "TX"       LOC= "E18"  | IOSTANDARD ="LVCMOS33";

    NET "Btn<0>" LOC = "T16" | IOSTANDARD= "LVCMOS33";#左

    NET "Btn<1>" LOC = "V10" | IOSTANDARD= "LVCMOS33";#下

    NET "Btn<2>" LOC = "R10" | IOSTANDARD= "LVCMOS33";#右

    NET "Btn<3>" LOC = "F15" | IOSTANDARD= "LVCMOS33";#上

    NET "SW<0>" LOC = "U9" | IOSTANDARD ="LVCMOS33";

    NET "SW<1>" LOC = "U8" | IOSTANDARD ="LVCMOS33";

    NET "SW<2>" LOC = "R7" | IOSTANDARD ="LVCMOS33";

    NET "SW<3>" LOC = "R6" | IOSTANDARD ="LVCMOS33";

    NET "SW<4>" LOC = "R5" | IOSTANDARD ="LVCMOS33";

    NET "SW<5>" LOC = "V7" | IOSTANDARD ="LVCMOS33";

    NET "SW<6>" LOC = "V6" | IOSTANDARD ="LVCMOS33";

    NET "SW<7>" LOC = "V5" | IOSTANDARD ="LVCMOS33";

    NET "SW<8>" LOC = "U4" | IOSTANDARD ="LVCMOS33";

    NET "SW<9>" LOC = "V2" | IOSTANDARD ="LVCMOS33";

    NET "SW<10>" LOC = "U2" | IOSTANDARD= "LVCMOS33";

    NET "SW<11>" LOC = "T3" | IOSTANDARD= "LVCMOS33";

    NET "SW<12>" LOC = "T1" | IOSTANDARD= "LVCMOS33";

    NET "SW<13>" LOC = "R3" | IOSTANDARD= "LVCMOS33";

    NET "SW<14>" LOC = "P3" | IOSTANDARD= "LVCMOS33";

    NET "SW<15>" LOC = "P4" | IOSTANDARD= "LVCMOS33";

    NET "LED<0>" LOC = "T8" | IOSTANDARD= "LVCMOS33";

    NET "LED<1>" LOC = "V9" | IOSTANDARD= "LVCMOS33";

    NET "LED<2>" LOC = "R8" | IOSTANDARD= "LVCMOS33";

    NET "LED<3>" LOC = "T6" | IOSTANDARD= "LVCMOS33";

    NET "LED<4>" LOC = "T5" | IOSTANDARD= "LVCMOS33";

    NET "LED<5>" LOC = "T4" | IOSTANDARD= "LVCMOS33";

    NET "LED<6>" LOC = "U7" | IOSTANDARD= "LVCMOS33";

    NET "LED<7>" LOC = "U6" | IOSTANDARD= "LVCMOS33";

    NET "LED<8>" LOC = "V4" | IOSTANDARD= "LVCMOS33";

    NET "LED<9>" LOC = "U3" | IOSTANDARD= "LVCMOS33";

    NET "LED<10>" LOC = "V1" | IOSTANDARD= "LVCMOS33";

    NET "LED<11>" LOC = "R1" | IOSTANDARD= "LVCMOS33";

    NET "LED<12>" LOC = "P5" | IOSTANDARD= "LVCMOS33";

    NET "LED<13>" LOC = "U1" | IOSTANDARD= "LVCMOS33";

    NET "LED<14>" LOC = "R2" | IOSTANDARD= "LVCMOS33";

    NET "LED<15>" LOC = "P2" | IOSTANDARD= "LVCMOS33";

    NET "SPI_MOSI" LOC = "B13" | IOSTANDARD ="LVCMOS33";

    NET "SPI_MISO" LOC = "G13" | IOSTANDARD ="LVCMOS33";

    NET "SPI_CLK" LOC = "F14" | IOSTANDARD = "LVCMOS33";

    NET "SPI_SS"  LOC = "C17" | IOSTANDARD = "LVCMOS33";

    软件编写

    软件流程图

    xil_printf("0x%X ",x) (只能打印整数)

    1).头文件:

    #include"xparameters.h"

    #include"platform.h"

    #include"xil_io.h"

    #include"xgpio.h"

    #include"xtmrctr.h"

    #include"xspi.h"

    #include"xintc.h"

    #include"xintc_i.h"

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

    #include"stdio.h"

    #include"xuartlite.h"

    #include"xuartlite_l.h"

    2).定义函数:

    voidprint(char *str);

    voidInitialize(void);

    voidUart_Handler(void);

    voidTimerCounterHandler(void* CallBackRef , u8 TmrCtrNumber);

    voidBtn_SWHandler(void*CallBackRef);

    void SpiIntrHandler(void *CallBackRef ,u32 StatusEvent ,u32ByteCount);

    //voidMy_ISR(void) __attribute__((interrupt_handler));

    voidJuChiBo(int T,int Amplitude);

    voidADC(void);

    3).声明实例,定义变量:

    XIntcInterruptController;

    XTmrCtrTimerCounterInst;

    XUartLiteUART;

    XSpiSPiInstance;

    volatile int TransferProgress;(volatile是代表被不同进程访问和修改的变量的修饰符)

    u8 ReadBuffer[2];

    u8 WriteBuffer[2];(存放SPI的数据)

    char buf[27]="UART Initialize Success ";

    short flag_RX=0x00;

    unsigned char RX_data=0x00;

    int count=0;

    XGpio Btn_SW,LED;

    int Btn=0 , SW_pre=0 , SW=0;//按键和开关的值

    int flag_SW=0 , flag_Btn=0;//按键和开关的触发标志位

    int time_10ms=0;//10ms计时

    4).初始化函数:

        a.初始化串口:

        XUartLite_Initialize(&UART,XPAR_UARTLITE_0_DEVICE_ID);

        XUartLite_ResetFifos(&UART);

        while(XUartLite_IsTransmitFull(XPAR_UARTLITE_0_BASEADDR));

        XUartLite_Send(&UART,buf,27);

    b.初始化SPI

    初始化:XSpi_Initialize(&SPiInstance,XPAR_SPI_0_DEVICE_ID);

    挂载到中断控制器上:XIntc_Connect()

    设置中断:XSpi_SetStatusHandler(&SpiInstance , &SPiInstance, (XSpi_StatusHandler) SpiIntrHandler);

    使能中断:XIntc_Enable(&IntCtrl,3);//SPI

    设置模式:

    XSpi_SetOptions(&SpiInstance ,XSP_MASTER_OPTION|XSP_CLK_PHASE_1_OPTION);

    设置从设备选择信号:XSpi_SetSlaveSelect(&SPiInstance,1);

    使能:XSpi_Start(&SPiInstance);

    c.初始化中断控制器:

    XIntc_Initialize(&IntCtrl, XPAR_INTC_DEVICE_ID);

    INTC中断源使能

    XIntc_Enable(&IntCtrl,0);//Timer

    XIntc_Enable(&IntCtrl,1);//Btn_SW

    XIntc_Enable(&IntCtrl,2);//UART

    XIntc_Enable(&IntCtrl,3);//SPI

    启动

    XIntc_Start(&IntCtrl,XIN_REAL_MODE);

    d.初始化定时器:

    XTmrCtr_Initialize(&TimerCounterInst,XPAR_TMRCTR_0_DEVICE_ID);//XPAR_TMRCTR_0_DEVICE_ID

    XTmrCtr_SetHandler(&TimerCounterInst,TimerCounterHandler , &TimerCounterInst);

    XTmrCtr_SetOptions(&TimerCounterInst,0,XTC_INT_MODE_OPTION|XTC_AUTO_RELOAD_OPTION| XTC_DOWN_COUNT_OPTION);

    XTmrCtr_SetResetValue(&TimerCounterInst, 0, 0x00f4240);//0xf4240是1000 000

    XIntc_Enable(&IntCtrl, XPAR_INTC_0_TMRCTR_0_VEC_ID);//TMRCTR_Interruppt_ID

    XIntc_Connect(&IntCtrl,XPAR_INTC_0_TMRCTR_0_VEC_ID,(XInterruptHandler)XTmrCtr_InterruptHandler,(void*)&TimerCounterInst);

    e.初始化GPIO:

        用API函数来初始化:

    XGpio_Initialize(&Btn, XPAR_BTN_SW_DEVICE_ID);

        XGpio_SetDataDirection(&Btn,1,0xff);(实例,通道,输入/出)

    GPIO中断使能:(两个Enable)

    XGpio_InterruptEnable(&Btn_SW,1);

    XGpio_InterruptEnable(&Btn_SW,2);

    XGpio_InterruptGlobalEnable(&Btn_SW);

    f.注册和使能microblaze的中断:

    microblaze_enable_interrupts();

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

    5).中断控制器处理函数

        void My_ISR(void)。

    判断中断源并进入相应的实例中断处理函数。

    清除中断标志位。

    SPI,UART,Btn_SW,Timer的中断优先级为3,4,5,6。

        6).各实例中断处理函数

           UART:判断状态寄存器第8位奇偶校验位,错就返回1(跳过读数据)。判断是否接收到有效数据,如果是就取出数据。

    最后在控制寄存器中清除(复位)FIFO,使能UART的硬件中断。

    SPI:修改传输标志位

    Btn_SW:

    voidBtn_SWHandler(void*CallBackRef)//chinnel1是SW。2是Btn

    {

        Btn=XGpio_DiscreteRead(&Btn_SW,2);

        flag_Btn=1;

        XGpio_InterruptDisable(&Btn_SW,2);

        if(time_10ms==5)//忽略按键弹起再次触发的中断

        {

           XGpio_InterruptClear(&Btn_SW,2);

           XGpio_InterruptEnable(&Btn_SW,2);

        }

        SW_pre=SW;

        SW=XGpio_DiscreteRead(&Btn_SW,1);

        if(SW_pre==SW){flag_SW=0;}//如果这次的开关值跟上次一样,就不立flag,防止因为Btn的触发导致SW的误触发

        else

        {

        flag_SW=1;

        XGpio_InterruptClear(&Btn_SW,1);

        XGpio_InterruptEnable(&Btn_SW,1);

        }

    }

    Timer:

    voidTimerCounterHandler(void* CallBackRef , u8 TmrCtrNumber)

    {

        time_10ms++;

        if(time_10ms>100)

        {

           time_10ms=0;

           print("1s");

        }

    }//10ms进一次中断,100次(1s)从terminal输出一次

        7).输出锯齿波的函数

           将count的低8位为buf[0],低9~12位通过平移、筛选之后送给buf[1]。

        8).采集电压的函数

           读取电压量存进ReadBuffer

    9).主函数:

        a.初始化

        b.判断UART是否接收到数据

        c.判断Btn是否接收到数据

        d.判断SW是否接收到数据

        e.输出锯齿波

        f.读取ADC的值

    #include "xparameters.h"
    #include "platform.h"
    #include "xil_io.h"
    #include "xgpio.h"
    #include "xtmrctr.h"
    #include "xspi.h"
    #include "xintc.h"
    #include "xintc_i.h"
    #include "xil_exception.h"//(硬件异常和软件异常处理)
    #include "stdio.h"
    #include "xuartlite.h"
    #include "xuartlite_l.h"
     
    void print(char *str);
    void Initialize(void);
    void Uart_Handler(void);
    void TimerCounterHandler(void* CallBackRef , u8 TmrCtrNumber);
    void Btn_SWHandler(void*CallBackRef);
    void SpiIntrHandler(void *CallBackRef ,u32 StatusEvent ,u32 ByteCount);
    //void My_ISR(void) __attribute__((interrupt_handler));
    void JuChiBo(int T,int Amplitude);
    void ADC(void);
    void delay_ms(u32 t);
     
    XIntc IntCtrl;
    XTmrCtr TimerCounterInst;
    XUartLite UART;
    XSpi SPiInstance;
    volatile int TransferProgress;
    u8 ReadBuffer[2]={0,0};
    u8 WriteBuffer[2];
    u8 buf[32]="UART Init Suc
    ";
    short flag_RX=0x00;
    unsigned char RX_data=0x00;
    int count=0;
    XGpio Btn_SW;
    XGpio LED;
    u8 Btn=0 , Btn_pre = 0 , SW8_1=0 , SW8_2=0;
    u16 SW_pre=0 , SW=0;
    int flag_SW=0 , flag_Btn=0;
    volatile int time_10ms1=0,time_10ms2=0,time_10ms3=0,time_10ms_ADC=0,time_10ms_DAC=0;
    u32 Amplitude = 4096;
    u8 T=0x24 ;
    char c;
    u16 temp=0;
    u16 Error=0;
    u16 Voltage=0;
     
    int main()
    {
         print("program start
    ");
         Initialize();
         XUartLite_Send(&UART,buf,32);//u8变为char,so warnning
         XGpio_DiscreteWrite(&LED,1,0xffff);
    while(1)
    {
        if(time_10ms1>1000){time_10ms1=0;print("10s
    ");}//10s
        if(time_10ms2>100)
        {time_10ms2=0;print("1s
    ");}//1s XUartLite_Send(&UART,buf,32);XUartLite_SendByte(XPAR_UARTLITE_2_BASEADDR,0);
    ////UART///////////////////////////////////////////////////////////////////////////////////////////////////////////
        if(flag_RX)
        {
     
            flag_RX=0;
            RX_data = Xil_In32(XPAR_UART_BASEADDR+0X00);//数据寄存器的偏移地址是0X00
            Xil_Out32(XPAR_UART_BASEADDR+0x0c,0X13);//clear fifo,0x0c是控制寄存器的偏移地址c=12,0x13=0001 0011
            xil_printf("UART received data  0x%X
    ",RX_data);
            //XUartLite_Send(&UART,&RX_data,1);
            Xil_Out8(XPAR_LEDS_BASEADDR,RX_data);
            //XGpio_DiscreteWrite(&LED,1,RX_data);
            //XUartLite_SendByte(XPAR_UARTLITE_2_BASEADDR,RX_data);
        }
    ////Btn////////////////////////////////////////////////////////////////////
        if(flag_Btn)
        {
            flag_Btn=0;
            xil_printf("Btn data is 0x%X
    ",Btn);
            //Btn=Btn+0x41;
            XUartLite_Send(&UART,&Btn,1);
            switch (Btn){
            case 0x01:{T=T-5;break;}
            case 0x02:{Amplitude=Amplitude-100;break;}
            case 0x04:{T=T+5;break;}
            case 0x08:{Amplitude=Amplitude+100;break;}
            }
            xil_printf("T is 0x%X
    ",T);
            xil_printf("Amplitude is 0x%X
    ",Amplitude);
     
        }
    ////SW////////////////////////////////////////////////////////////////////
        if(flag_SW)
        {
            flag_SW=0;
            xil_printf("SW data is 0x%X
    ",SW);
            SW8_1=(u8)SW;
            temp=SW;
            temp=temp>>8;
            SW8_2=(u8)(temp);
            //xil_printf("temp data is 0x%X
    ",temp);
            xil_printf("SW8_1 data is 0x%X
    ",SW8_1);
            xil_printf("SW8_2 data is 0x%X
    ",SW8_2);
            //SW8_1=SW8_1+0x41;
            //SW8_2=SW8_2+0x41;
     
            XUartLite_Send(&UART,&SW8_1,1);//只能Send u8类型的,故不能把SW一次传输完
            //XUartLite_Send(&UART,&SW8_2,1);
            //Xil_Out8(0X40040000+0X8,SW8_2);//LEDS  :  0X40040000~0x4004FFFF
        }
    ////DA///////////////////////////////////////////////////////////////////
        if(SW==0x1||SW==0x4) JuChiBo(T,Amplitude);
    ////AD///////////////////////////////////////////////////////////////////
         if(SW==0x2) ADC();
    }
     
        return 0;
    }
     
    void Initialize(void)
    {
        init_platform();
        XIntc_Initialize(&IntCtrl , XPAR_INTC_DEVICE_ID);
    ////TIMER////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        XTmrCtr_Initialize(&TimerCounterInst, XPAR_TMRCTR_0_DEVICE_ID);//XPAR_TMRCTR_0_DEVICE_ID
        XTmrCtr_SetHandler(&TimerCounterInst, TimerCounterHandler , &TimerCounterInst);
        XTmrCtr_SetOptions(&TimerCounterInst, 0,XTC_INT_MODE_OPTION|XTC_AUTO_RELOAD_OPTION| XTC_DOWN_COUNT_OPTION);
        XTmrCtr_SetResetValue(&TimerCounterInst , 0, 0x00f4240);//0xf4240是1000 000
        XIntc_Enable(&IntCtrl , XPAR_INTC_0_TMRCTR_0_VEC_ID);//TMRCTR_Interruppt_ID
        XIntc_Connect (&IntCtrl,XPAR_INTC_0_TMRCTR_0_VEC_ID,(XInterruptHandler)XTmrCtr_InterruptHandler ,(void*)&TimerCounterInst);
     
    ////UART////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        XUartLite_Initialize(&UART,XPAR_UART_DEVICE_ID);
        XUartLite_ResetFifos(&UART);
        while(XUartLite_IsTransmitFull(XPAR_UART_DEVICE_ID));
        XUartLite_Send(&UART,buf,27);
        XUartLite_EnableInterrupt(&UART);
        XIntc_Connect (&IntCtrl,XPAR_INTC_0_UARTLITE_2_VEC_ID,(XInterruptHandler)Uart_Handler,(void*)&UART);
     
    ////SPI/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        XSpi_Initialize(&SPiInstance,XPAR_SPI_0_DEVICE_ID);
        XIntc_Connect (&IntCtrl,XPAR_INTC_0_SPI_0_VEC_ID,(XInterruptHandler)XSpi_InterruptHandler,(void*)&SPiInstance);
        XSpi_SetStatusHandler(&SPiInstance,&SPiInstance,(XSpi_StatusHandler)SpiIntrHandler);
        XSpi_SetOptions(&SPiInstance,XSP_MASTER_OPTION|XSP_CLK_PHASE_1_OPTION);
        XSpi_SetSlaveSelect(&SPiInstance,1);
     
    ////Btn_SW////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        XGpio_Initialize(&Btn_SW , XPAR_BTN_SW_DEVICE_ID);
        XGpio_SetDataDirection(&Btn_SW,1,0xffff);//通道1
        XGpio_SetDataDirection(&Btn_SW,2,0xf);//通道2
        XGpio_InterruptEnable(&Btn_SW,1);
        XGpio_InterruptEnable(&Btn_SW,2);
        XGpio_InterruptGlobalEnable(&Btn_SW);
        XIntc_Connect (&IntCtrl,XPAR_INTC_0_GPIO_0_VEC_ID,(XInterruptHandler)Btn_SWHandler,(void*)&Btn_SW);
     
    ////LED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        XGpio_Initialize(&LED ,  XPAR_LEDS_DEVICE_ID);
        XGpio_SetDataDirection(&LED,1,0x0000);//通道
     
    ////INTC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        XIntc_Enable(&IntCtrl,0);//Timer
        XIntc_Enable(&IntCtrl,1);//Btn_SW
        XIntc_Enable(&IntCtrl,2);//UART
        XIntc_Enable(&IntCtrl,3);//SPI
        microblaze_enable_interrupts();
        microblaze_register_handler((XInterruptHandler)XIntc_InterruptHandler,(void*)&IntCtrl);
     
        XIntc_Start(&IntCtrl,XIN_REAL_MODE);
        XTmrCtr_Start(&TimerCounterInst,0);
        XSpi_Start(&SPiInstance);
    }
     
    //void My_ISR(void)
    //{
    //    int status;
    //    status = Xil_In32(XPAR_INTC_BASEADDR+0x00);//终端控制器中断状态寄存器偏移地址
    //    if(status&0x8)
    //    {
    //        Uart_Handler();
    //    }
    //    Xil_Out32(XPAR_INTC_BASEADDR+0X0C,status);//清除INTC中断
    //}
    void Uart_Handler(void)
    {
        int flag_UART;
        flag_UART=Xil_In32(XPAR_UART_BASEADDR+0X08);//状态寄存器的偏移地址是0X08第8位是奇偶校验,错就返回1
        if(flag_UART&0X01)
        {
            flag_RX = 1;
            //RX_data = Xil_In32(XPAR_UART_BASEADDR+0X00);//数据寄存器的偏移地址是0X00
            //print("in the intr
    ");
            //Xil_Out8(XPAR_GPIO_1_BASEADDR,RX_data);
        }
        //Xil_Out32(XPAR_UART_BASEADDR+0x0c,0X13);//clear fifo,0x0c是控制寄存器的偏移地址c=12,0x13=0001 0011
    }
     
    void SpiIntrHandler(void *CallBackRef ,u32 StatusEvent ,u32 ByteCount)
    {
        TransferProgress=FALSE;
        //print("in spi intr
    ");
        if(StatusEvent != XST_SPI_TRANSFER_DONE)
        Error++;
    }
     
    void JuChiBo(int T,int Amplitude)
    {
         WriteBuffer[0]=(u8)(count);
         WriteBuffer[1]=(u8)(count>>8)&0xf;
         if(SW==0X4)
         {
             count=count+T*3;
         }
         else count=count+T;
         if(count>Amplitude) count = 0;
         TransferProgress = TRUE;
         XSpi_Transfer(&SPiInstance , WriteBuffer,ReadBuffer , 2);
         Voltage=ReadBuffer[1];
         Voltage=Voltage<<8;
         Voltage=Voltage+ReadBuffer[0];
         Voltage=Voltage<<4;
         Voltage=Voltage>>4;
         while(TransferProgress);
         if(time_10ms_DAC>100){time_10ms_DAC=0; xil_printf("DAC
    ");xil_printf("ADC data is 0x%X
    ",Voltage);}
    }
    void ADC(void)
    {
         TransferProgress = TRUE;
         XSpi_Transfer(&SPiInstance , WriteBuffer , ReadBuffer , 2);
         while(TransferProgress);
         Voltage=ReadBuffer[1];
         Voltage=Voltage<<8;
         Voltage=Voltage+ReadBuffer[0];
         Voltage=Voltage<<4;
         Voltage=Voltage>>4;
         if(time_10ms_ADC>100){ time_10ms_ADC=0; xil_printf("ADC data is 0x%X
    ",Voltage);     xil_printf("ADC
    ");}
    }
    void Btn_SWHandler(void*CallBackRef)//chinnel1是SW。2是Btn
    {
    //////////////Btn//////////////////////////////////////////////////////////////////////
    ///
        Btn_pre=Btn;
        Btn=XGpio_DiscreteRead(&Btn_SW,2);
        if(Btn_pre==Btn){flag_Btn=0;}
        else{
        flag_Btn=1;
        XGpio_InterruptDisable(&Btn_SW,2);
        delay_ms(30);
        }
    //    xil_printf("In the INTC of GPIO
    ");
    /////////////SW////////////////////////////////////////////////////////////////////////////
    ////                                                                                //////
        SW_pre=SW;
        SW=XGpio_DiscreteRead(&Btn_SW,1);
        if(SW_pre==SW){flag_SW=0;}//如果这次的开关值跟上次一样,就不立flag,防止因为Btn的触发导致SW的误触发
        else
        {
        flag_SW=1;
        }
        XGpio_InterruptClear(&Btn_SW,2);
        XGpio_InterruptClear(&Btn_SW,1);
        XGpio_InterruptEnable(&Btn_SW,2);
     
    }
    void TimerCounterHandler(void* CallBackRef , u8 TmrCtrNumber)
    {
        time_10ms1++;
        time_10ms2++;
        time_10ms3++;
        time_10ms_ADC++;
        time_10ms_DAC++;
    }
    void delay_ms(u32 t)
    {
        int i;
        for(i=0;i<100000*t;i++);
    }
  • 相关阅读:
    运行jar包读取外部配置文件
    DES加密
    BlockingQueue
    文件锁
    Hive 的 排序
    linux下date命令实现时间戳与日期的转换
    bcov进行覆盖率统计
    对c++服务端进行覆盖率统计
    github基础命令
    gcc编译参数-fPIC问题 `a local symbol' can not be used when making a shared object;
  • 原文地址:https://www.cnblogs.com/limanjihe/p/9884966.html
Copyright © 2020-2023  润新知