microblaze例程 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki
#include "xil_io.h"
u8 Xil_In8(UINTPTR Addr)
u16 Xil_In16(UINTPTR Addr)
u32 Xil_In32(UINTPTR Addr)
u64 Xil_In64(UINTPTR Addr)
void Xil_Out8(UINTPTR Addr, u8 Value)
void Xil_Out16(UINTPTR Addr, u16 Value)
void Xil_Out32(UINTPTR Addr, u32 Value)
void Xil_Out64(UINTPTR Addr, u64 Value)
DDR访问,一般会关闭Dcache
#include "xil_cache.h"
Xil_ICacheDisable();
Xil_DCacheDisable();
Xil_DCacheFlush();
#define BRAM_BASE_ADDR 0xC0000000
#define LOCK_ADDR (BRAM_BASE_ADDR+0x0100)
// process-0
Xil_Out32(LOCK_ADDR, 1);
while(1){
u32 lock=Xil_In32(LOCK_ADDR);
if(lock==1){
Xil_Out32(LOCK_ADDR, 0);
do_something();
Xil_Out32(LOCK_ADDR, 1);
}
usleep(800*1000);
}
// process-1
while(1){
u32 lock=Xil_In32(LOCK_ADDR);
if(lock==1){
Xil_Out32(LOCK_ADDR, 0);
do_something();
Xil_Out32(LOCK_ADDR, 1);
}
usleep(500*1000);
}
#include <stdio.h>
#include "xparameters.h"
#include "xgpio.h"
#include "sleep.h"
#define GPIO_DEVICE_ID XPAR_AXI_GPIO_0_DEVICE_ID // 根据实际硬件配置修改
#define LED_CHANNEL 1
int main() {
XGpio gpio;
int Status;
xil_printf("Microblaze GPIO test!\r\n");
// 初始化GPIO
Status = XGpio_Initialize(&gpio, GPIO_DEVICE_ID);
if (Status != XST_SUCCESS) {
printf("GPIO Initialization failed\n");
return XST_FAILURE;
}
// 设置GPIO为输出
XGpio_SetDataDirection(&gpio, LED_CHANNEL, 0x00);
while (1) {
// 依次翻转四个GPIO引脚
XGpio_DiscreteWrite(&gpio, LED_CHANNEL, 0b0001);
usleep(500000); // 等待500毫秒
XGpio_DiscreteWrite(&gpio, LED_CHANNEL, 0b0010);
usleep(500000);
XGpio_DiscreteWrite(&gpio, LED_CHANNEL, 0b0100);
usleep(500000);
XGpio_DiscreteWrite(&gpio, LED_CHANNEL, 0b1000);
usleep(500000);
}
return 0;
}
#include "xparameters.h"
#include "xintc.h"
#include "xgpio.h"
#include "sleep.h"
#define KEY_DEV_ID XPAR_AXI_GPIO_1_DEVICE_ID //按键 AXI GPIO ID
#define LED_DEV_ID XPAR_AXI_GPIO_0_DEVICE_ID //LED AXI GPIO ID
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID //中断控制器ID
#define EXCEPTION_ID XIL_EXCEPTION_ID_INT //中断异常ID
#define AXI_GPIO_INTR_ID XPAR_INTC_0_GPIO_1_VEC_ID //AXI GPIO中断ID
static XIntc Intc; //中断控制器实例
static XGpio KEY_Gpio; //GPIO中断实例 按键
static XGpio LED_Gpio; //GPIO实例
int led_value; //LED值
int key_value; //按键值
int Intr_times = 0; //有效中断计数
int key_intr_flag = 0; //中断标志
void GpioHandler(void *CallbackRef);
int main(){
xil_printf("AXI GPIO INTERRUPT TEST!\r\n");
//AXI_GPIO器件初始化
XGpio_Initialize(&KEY_Gpio, KEY_DEV_ID);
XGpio_Initialize(&LED_Gpio, LED_DEV_ID);
//为指定的GPIO信道设置所有独立信号的输入/输出方向
XGpio_SetDataDirection(&LED_Gpio, 1, 0);
//设置LED初始值
XGpio_DiscreteWrite(&LED_Gpio, 1, 0x0f);
// sleep(2);
// XGpio_DiscreteWrite(&LED_Gpio, 1, 0x00);
XGpio_SetDataDirection(&KEY_Gpio, 1, 1);
// while(1){
// int v=XGpio_DiscreteRead(&KEY_Gpio, 1);
// xil_printf("%d\r\n",v);
// sleep(1);
// }
//初始化中断控制器
XIntc_Initialize(&Intc, INTC_DEVICE_ID);
//关联中断ID和中断服务函数
XIntc_Connect(&Intc,AXI_GPIO_INTR_ID,(Xil_ExceptionHandler)GpioHandler,&KEY_Gpio );
//使能中断
XGpio_InterruptEnable(&KEY_Gpio, 1);
//使能全局中断
XGpio_InterruptGlobalEnable(&KEY_Gpio);
//在中断控制器上启用中断向量
XIntc_Enable(&Intc,AXI_GPIO_INTR_ID);
//启动中断控制器
XIntc_Start(&Intc, XIN_REAL_MODE);
//设置并打开中断异常处理
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(EXCEPTION_ID,
(Xil_ExceptionHandler)XIntc_InterruptHandler,&Intc);
Xil_ExceptionEnable();
while(1){
if(key_intr_flag){ //检测中断标志信号有效
key_value = XGpio_DiscreteRead(&KEY_Gpio, 1); //读取按键值
if(key_value != 3){ //检测按键是否按下
if(Intr_times == 0) //根据有效中断数点亮LED
led_value = 0x01;
else if(Intr_times == 1)
led_value = 0x02;
else if(Intr_times == 2)
led_value = 0x04;
else
led_value = 0x08;
//按键按下后点亮对应LED灯
XGpio_DiscreteWrite(&LED_Gpio, 1, led_value);
xil_printf("i = %d\r\n",Intr_times); //打印当前的Intr_times
Intr_times = (Intr_times + 1)%4; //将计数值约束在0到3之间
//延迟1秒
sleep(1);
}
key_intr_flag = 0; //中断标志清零
}
}
return 0;
}
void GpioHandler(void *CallbackRef){
XGpio *GpioPtr = (XGpio *)CallbackRef;
key_intr_flag = 1; //接收到中断,标志信号拉高
XGpio_InterruptDisable(GpioPtr, 1); //关闭中断
XGpio_InterruptClear(GpioPtr, 1); //清除中断
XGpio_InterruptEnable(GpioPtr, 1); //使能中断
}
#include "xil_exception.h"
#include "xdebug.h"
#include "xparameters.h"
#include "xintc.h"
#include "xuartlite.h"
#include "xuartlite_l.h"
#define UART_DEVICE_ID XPAR_UARTLITE_0_DEVICE_ID //串口器件ID
#define UART_INTR_ID XPAR_INTC_0_UARTLITE_0_VEC_ID //串口中断ID
#define INTC_ID XPAR_INTC_0_DEVICE_ID //中断控制器ID
#define RX_NOEMPTY XUL_SR_RX_FIFO_VALID_DATA // 接收FIFO非空
static XIntc Intc; //中断控制器实例
static XUartLite Uart; //串口实例
void uart_handler(void *CallbackRef);
int main(void){
//初始化串口设备
XUartLite_Initialize(&Uart , UART_DEVICE_ID);
xil_printf("hello!\r\n");
//初始化中断控制器
XIntc_Initialize(&Intc, INTC_ID);
//关联处理函数
XIntc_Connect(&Intc, UART_INTR_ID,(XInterruptHandler)uart_handler,&Uart);
//使能串口
XUartLite_EnableInterrupt(&Uart);
//打开中断控制器
XIntc_Start(&Intc, XIN_REAL_MODE);
//使能中断控制器
XIntc_Enable(&Intc,UART_INTR_ID);
//设置并打开中断异常处理功能
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIntc_InterruptHandler , &Intc);
Xil_ExceptionEnable();
while(1);
}
void uart_handler(void *CallbackRef)//中断处理函数
{
u8 Read_data;
u32 isr_status;
XUartLite *InstancePtr= (XUartLite *)CallbackRef;
//读取状态寄存器
isr_status = XUartLite_ReadReg(InstancePtr->RegBaseAddress ,
XUL_STATUS_REG_OFFSET);
if(isr_status & RX_NOEMPTY){ //接收FIFO中有数据
//读取数据
Read_data=XUartLite_ReadReg(InstancePtr->RegBaseAddress ,
XUL_RX_FIFO_OFFSET);
//发送数据
XUartLite_WriteReg(InstancePtr->RegBaseAddress ,
XUL_TX_FIFO_OFFSET, Read_data);
}
}
#include "xil_exception.h"
#include "xdebug.h"
#include "xparameters.h"
#include "xintc.h"
#include "xuartlite.h"
#include "xuartlite_l.h"
#include "sleep.h"
#define UART_DEVICE_ID XPAR_UARTLITE_0_DEVICE_ID //串口器件ID
static XUartLite Uart; //串口实例
int main(void) {
//初始化串口设备
XUartLite_Initialize(&Uart, UART_DEVICE_ID);
//initial send
char str[] =
"hello world! i'm xujch! hello world! i'm xujch! hello world! i'm xujch!\r\n";
char *p = &str[0];
while (*p) {
XUartLite_SendByte(Uart.RegBaseAddress, *p);
p++;
}
//echo back
while (1){
char c=XUartLite_RecvByte(Uart.RegBaseAddress);
XUartLite_SendByte(Uart.RegBaseAddress, c);
}
}
以上程序,我们使用了XUartLite_RecvByte()和XUartLite_SendByte()这2个库函数,可以看看它是怎么写的:
void XUartLite_SendByte(UINTPTR BaseAddress, u8 Data)
{
while (XUartLite_IsTransmitFull(BaseAddress));
XUartLite_WriteReg(BaseAddress, XUL_TX_FIFO_OFFSET, Data);
}
u8 XUartLite_RecvByte(UINTPTR BaseAddress)
{
while (XUartLite_IsReceiveEmpty(BaseAddress));
return (u8)XUartLite_ReadReg(BaseAddress, XUL_RX_FIFO_OFFSET);
}
#include <stdio.h>
#include "xparameters.h"
#include "xintc.h"
#include "xtmrctr.h"
#include "xil_exception.h"
#include "xgpio.h"
#include "xil_printf.h"
#define LED_DEV_ID XPAR_GPIO_0_DEVICE_ID //LED ID
#define INTC_ID XPAR_INTC_0_DEVICE_ID //中断控制器ID
#define TMRCTR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID //定时器中断ID
#define TMRCTR_INTR_ID XPAR_INTC_0_TMRCTR_0_VEC_ID //定时中断ID
#define XIL_EXCEPTION_ID_INT 16U //中断异常ID
#define LED_Channel 1
XIntc Intc; //中断控制器实例
XGpio led_gpio; //LED实例
XTmrCtr Timer; //定时器实例
void timer_intr_hander(void *InstancePtr);
int main() {
print("timer interrupt test\n");
//初始化LED
XGpio_Initialize(&led_gpio, LED_DEV_ID);
//为指定的GPIO信道设置所有独立信号的输入/输出方向
XGpio_SetDataDirection(&led_gpio, 1, 0);
//设置LED初始值
XGpio_DiscreteWrite(&led_gpio, 1, 0x0f);
//定时器初始化
XTmrCtr_Initialize(&Timer, TMRCTR_DEVICE_ID);
//为指定的计时器启用指定的选项。
XTmrCtr_SetOptions(&Timer, 0, XTC_INT_MODE_OPTION | //中断操作
XTC_AUTO_RELOAD_OPTION | //自动加载
XTC_DOWN_COUNT_OPTION); //递减计数
//设置指定计时器的重置值
XTmrCtr_SetResetValue(&Timer, 0, 50000000);
//设置计时器回调函数,指定的计时器满一个周期时驱动程序将调用该回调函数
XTmrCtr_SetHandler(&Timer, timer_intr_hander, &Timer);
//开启定时器
XTmrCtr_Start(&Timer, 0);
//中断控制器初始化
XIntc_Initialize(&Intc, INTC_ID);
//关联中断源和中断处理函数
XIntc_Connect(&Intc, TMRCTR_INTR_ID,
(XInterruptHandler) XTmrCtr_InterruptHandler, &Timer);
//开启中断控制器
XIntc_Start(&Intc, XIN_REAL_MODE);
//使能中断控制器
XIntc_Enable(&Intc, TMRCTR_INTR_ID);
//设置并打开中断异常处理
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XIntc_InterruptHandler, &Intc);
Xil_ExceptionEnable();
while (1)
;
}
void timer_intr_hander(void *InstancePtr) //回调函数
{
static int led_state = 0x00;
//检测计数是否满一个周期
if (XTmrCtr_IsExpired(&Timer, 0)) {
led_state = ~led_state; //LED状态翻转
XGpio_DiscreteWrite(&led_gpio, 1, led_state); //输出LED值
}
}
#include "xtmrctr.h"
#include "xparameters.h"
#include "xil_exception.h"
#include "xintc.h"
#include <stdio.h>
#include "sleep.h"
#define TMRCTR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID
#define TMRCTR_INTERRUPT_ID XPAR_INTC_0_TMRCTR_0_VEC_ID
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#define INTC XIntc
#define INTC_HANDLER XIntc_InterruptHandler
#define PWM_PERIOD 50000000 /* PWM period in (50 ms) */
#define TMRCTR_0 0 /* Timer 0 ID */
#define TMRCTR_1 1 /* Timer 1 ID */
int TmrCtrPwmExample_my(INTC *IntcInstancePtr, XTmrCtr *InstancePtr, u16 DeviceId,
u16 IntrId);
INTC InterruptController; /* The instance of the Interrupt Controller */
XTmrCtr TimerCounterInst; /* The instance of the Timer Counter */
int main(void)
{
int Status;
/* Run the Timer Counter PWM example */
Status = TmrCtrPwmExample_my(&InterruptController, &TimerCounterInst,
TMRCTR_DEVICE_ID, TMRCTR_INTERRUPT_ID);
}
int TmrCtrPwmExample_my(INTC *IntcInstancePtr, XTmrCtr *TmrCtrInstancePtr,
u16 DeviceId, u16 IntrId)
{
u8 DutyCycle;
u32 Period;
u32 HighTime;
int Status;
Status = XTmrCtr_Initialize(TmrCtrInstancePtr, DeviceId);
Status = XTmrCtr_SelfTest(TmrCtrInstancePtr, TMRCTR_0);
Period = PWM_PERIOD;
HighTime = PWM_PERIOD;
do {
XTmrCtr_PwmDisable(TmrCtrInstancePtr);
DutyCycle = XTmrCtr_PwmConfigure(TmrCtrInstancePtr, Period, HighTime); /*Config PWM*/
XTmrCtr_PwmEnable(TmrCtrInstancePtr);
xil_printf("PWM Configured for Duty Cycle = %d\r\n", DutyCycle);
HighTime -= PWM_PERIOD / 20;
sleep(1);
} while (DutyCycle > 0);
return Status;
}