串行接口: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\r\n”总是只打印前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\n\r",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\r\n";

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[]={,};
u8 WriteBuffer[];
u8 buf[]="UART Init Suc\r\n";
short flag_RX=0x00;
unsigned char RX_data=0x00;
int count=;
XGpio Btn_SW;
XGpio LED;
u8 Btn= , Btn_pre = , SW8_1= , SW8_2=;
u16 SW_pre= , SW=;
int flag_SW= , flag_Btn=;
volatile int time_10ms1=,time_10ms2=,time_10ms3=,time_10ms_ADC=,time_10ms_DAC=;
u32 Amplitude = ;
u8 T=0x24 ;
char c;
u16 temp=;
u16 Error=;
u16 Voltage=; int main()
{
print("program start\r\n");
Initialize();
XUartLite_Send(&UART,buf,);//u8变为char,so warnning
XGpio_DiscreteWrite(&LED,,0xffff);
while()
{
if(time_10ms1>){time_10ms1=;print("10s\r\n");}//10s
if(time_10ms2>)
{time_10ms2=;print("1s\r\n");}//1s XUartLite_Send(&UART,buf,32);XUartLite_SendByte(XPAR_UARTLITE_2_BASEADDR,0);
////UART///////////////////////////////////////////////////////////////////////////////////////////////////////////
if(flag_RX)
{ flag_RX=;
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\r\n",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=;
xil_printf("Btn data is 0x%X\r\n",Btn);
//Btn=Btn+0x41;
XUartLite_Send(&UART,&Btn,);
switch (Btn){
case 0x01:{T=T-;break;}
case 0x02:{Amplitude=Amplitude-;break;}
case 0x04:{T=T+;break;}
case 0x08:{Amplitude=Amplitude+;break;}
}
xil_printf("T is 0x%X\r\n",T);
xil_printf("Amplitude is 0x%X\r\n",Amplitude); }
////SW////////////////////////////////////////////////////////////////////
if(flag_SW)
{
flag_SW=;
xil_printf("SW data is 0x%X\r\n",SW);
SW8_1=(u8)SW;
temp=SW;
temp=temp>>;
SW8_2=(u8)(temp);
//xil_printf("temp data is 0x%X\r\n",temp);
xil_printf("SW8_1 data is 0x%X\r\n",SW8_1);
xil_printf("SW8_2 data is 0x%X\r\n",SW8_2);
//SW8_1=SW8_1+0x41;
//SW8_2=SW8_2+0x41; XUartLite_Send(&UART,&SW8_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 ;
} 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, ,XTC_INT_MODE_OPTION|XTC_AUTO_RELOAD_OPTION| XTC_DOWN_COUNT_OPTION);
XTmrCtr_SetResetValue(&TimerCounterInst , , 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,);
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,); ////Btn_SW////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
XGpio_Initialize(&Btn_SW , XPAR_BTN_SW_DEVICE_ID);
XGpio_SetDataDirection(&Btn_SW,,0xffff);//通道1
XGpio_SetDataDirection(&Btn_SW,,0xf);//通道2
XGpio_InterruptEnable(&Btn_SW,);
XGpio_InterruptEnable(&Btn_SW,);
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,,0x0000);//通道 ////INTC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
XIntc_Enable(&IntCtrl,);//Timer
XIntc_Enable(&IntCtrl,);//Btn_SW
XIntc_Enable(&IntCtrl,);//UART
XIntc_Enable(&IntCtrl,);//SPI
microblaze_enable_interrupts();
microblaze_register_handler((XInterruptHandler)XIntc_InterruptHandler,(void*)&IntCtrl); XIntc_Start(&IntCtrl,XIN_REAL_MODE);
XTmrCtr_Start(&TimerCounterInst,);
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 = ;
//RX_data = Xil_In32(XPAR_UART_BASEADDR+0X00);//数据寄存器的偏移地址是0X00
//print("in the intr\r\n");
//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\r\n");
if(StatusEvent != XST_SPI_TRANSFER_DONE)
Error++;
} void JuChiBo(int T,int Amplitude)
{
WriteBuffer[]=(u8)(count);
WriteBuffer[]=(u8)(count>>)&0xf;
if(SW==0X4)
{
count=count+T*;
}
else count=count+T;
if(count>Amplitude) count = ;
TransferProgress = TRUE;
XSpi_Transfer(&SPiInstance , WriteBuffer,ReadBuffer , );
Voltage=ReadBuffer[];
Voltage=Voltage<<;
Voltage=Voltage+ReadBuffer[];
Voltage=Voltage<<;
Voltage=Voltage>>;
while(TransferProgress);
if(time_10ms_DAC>){time_10ms_DAC=; xil_printf("DAC\r\n");xil_printf("ADC data is 0x%X\r\n",Voltage);}
}
void ADC(void)
{
TransferProgress = TRUE;
XSpi_Transfer(&SPiInstance , WriteBuffer , ReadBuffer , );
while(TransferProgress);
Voltage=ReadBuffer[];
Voltage=Voltage<<;
Voltage=Voltage+ReadBuffer[];
Voltage=Voltage<<;
Voltage=Voltage>>;
if(time_10ms_ADC>){ time_10ms_ADC=; xil_printf("ADC data is 0x%X\r\n",Voltage); xil_printf("ADC\r\n");}
}
void Btn_SWHandler(void*CallBackRef)//chinnel1是SW。2是Btn
{
//////////////Btn//////////////////////////////////////////////////////////////////////
///
Btn_pre=Btn;
Btn=XGpio_DiscreteRead(&Btn_SW,);
if(Btn_pre==Btn){flag_Btn=;}
else{
flag_Btn=;
XGpio_InterruptDisable(&Btn_SW,);
delay_ms();
}
// xil_printf("In the INTC of GPIO\r\n");
/////////////SW////////////////////////////////////////////////////////////////////////////
//// //////
SW_pre=SW;
SW=XGpio_DiscreteRead(&Btn_SW,);
if(SW_pre==SW){flag_SW=;}//如果这次的开关值跟上次一样,就不立flag,防止因为Btn的触发导致SW的误触发
else
{
flag_SW=;
}
XGpio_InterruptClear(&Btn_SW,);
XGpio_InterruptClear(&Btn_SW,);
XGpio_InterruptEnable(&Btn_SW,); }
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=;i<*t;i++);
}

MicroBlaze核的串行接口实验:SPI UART的更多相关文章

  1. I2S/PCM/IOM-2、I2C/SPI/UART/GPIO/slimbus

    概述 I2S,PCM,IOM-2都是数字音频接口,传数据的. I2C,SPI,UART,GPIO是控制接口,传控制信令的. I2S I2S(Inter-IC Sound Bus)是飞利浦公司为数字音频 ...

  2. SPI,UART,I2C都有什么区别,及其各自的特点

    区别: SPI:高速同步串行口.3-4线接口,收发独立.可同步进行 UART:通用异步串行口.按照标准波特率完成双向通讯,速度慢 I2C:一种串行传输方式,三线制,网上可找到其通信协议和用法的 3根线 ...

  3. 【转载】IIC SPI UART串行总线

    一.SPISPI(Serial Peripheral Interface,串行外设接口)是Motorola公司提出的一种同步串行数据传输标准,在很多器件中被广泛应用. 接口SPI接口经常被称为4线串行 ...

  4. 驱动之SPI,UART,I2C的介绍与应用20170118

    这篇文章主要介绍基本的驱动也是用的最多的协议类驱动中的SPI,I2C和UART.首先从最简单的UART也就是串口讲起: 1.UART UART由两根线也就是TX,RX以及波特率产生器组成,操作比较简单 ...

  5. 常用协议(SPI, UART, I2C)

    SPI: SPI是全双工的同步串行接口,数据速率可达几Mbps,在一般应用中有4根信号线:MOSI, MISO, SCK, SS. 根据时钟极性(CPOL)及相位(CPHA)不同可以组合成4种工作模式 ...

  6. 实验八--uart

    一.环境 系统:ubuntu12.04 开发板:jz2440 编译器:gcc 二.说明 有空补上 三.代码 head.S @************************************** ...

  7. Dubbo常用配置文件分析及核心源码阅读(SPI.Extension)

    1.多版本支持: 基于上篇博客的 快速启动 Dubbo 服务 的代码进行多版本支持的演示:基于原来的实现类GpHelloImpl ,我们需要新增一个新版本的实类:GpHelloImpl2 public ...

  8. [ZigBee] 7、ZigBee之UART剖析(ONLY串口发送)

    综述:USART0和USART1是串行通信接口,它们能够分别运行于异步UART模式或者同步SPI 模式.两个USART具有同样的功能,可以设置在单独的I/O 引脚. 1.UART 模式 UART 模式 ...

  9. [nRF51822] 7、基础实验代码解析大全(前十)

    实验01 - GPIO输出控制LED 引脚输出配置:nrf_gpio_cfg_output(LED_1); 引脚输出置高:nrf_gpio_pin_set(LED_1); 引脚电平转换:nrf_gpi ...

随机推荐

  1. ubuntu解压和压缩文件

    .tar 解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)———————————————.gz解压1:gun ...

  2. 判断一个点在多边形的内部C++

    /* 原理: 将测试点的Y坐标与多边形的每一个点进行比较, ** 会得到测试点所在的行与多边形边的所有交点. ** 如果测试点的两边点的个数都是奇数个, ** 则该测试点在多边形内,否则在多边形外. ...

  3. FreeBSD之基本配置

    1. 设置IP地址.网关ee /etc/rc.conf ifconfig_em0="inet 192.168.21.173 netmask 255.255.255.0"   #设置 ...

  4. 配置Tomcat配置路径

    <Host name="localhost" appBase="webapps" unpackWARs="true" autoDepl ...

  5. android-------- 常用且应该学习的框架

    今天来分享一下一些常用的库,在Github 上 star数也是很高的,开发中也是很常用的: 简单的分享一下,一起学习. http://www.xiufm.com/blog-1-944.html 框架名 ...

  6. 4.1.2 A Funny Game(POJ 2484)

    Problem description: n枚硬币排成一个圈,A和B轮流从中取一枚或两枚硬币,不过取两枚时,所取的两枚硬币必须是连续的.硬币取走之后留下空位,相隔空位的硬币视为不连续的.A开始先取,取 ...

  7. 精华 selenium_webdriver(python)调用js脚本

    #coding=utf-8 from selenium import webdriver import time driver = webdriver.Firefox() driver.get(&qu ...

  8. CF-339D-线段树

    http://codeforces.com/problemset/problem/339/D 给出一个序列.每次更改其中一个值然后询问序列的f(),序列的f()定义为: 每相邻两个元素按位或得到长度减 ...

  9. Oracle 常用sql整理

    1. 查看当前正在只用的undo段 select s.sid, s.serial#, s.username, r.name, t.STATUS, t.START_TIME, t.USED_UBLK, ...

  10. Hadoop--单点故障修复

    nameNode单点故障修复 1.启动虚拟机,启动集群  此时我们将主机hadoop1关机(断掉主机),开始抢救: 1.使用 秘书(secondaryNameNode),成功率不是100%  (这里我 ...