原创 Part 2. Using LEDs via GPIO and input from UART

2010-8-13 20:37 1704 8 8 分类: FPGA/CPLD

Step A. Use GPIO to control the LED

? The microblaze processor is configured in part 1 ti connect to the LED via GPIO. You can read from the GPIO and write to the GPIO. In this case, only writing is necessary. 
? Include header file "xgpio_1.h" to use the GPIO functions. 
? When using the GPIO, first you have to specify whether a bit is for input or output. Use the following to set it:

XGpio_Initialize(BASEADDR, DEVICE_ID);
XGpio_mSetDataDirection(BASEADDR, 1, 0x00000000);


? The first parameter is the address mapped to the GPIO. The second parameter is the GPIO channel, which is 1 in this case. The third parameter is for setting the read/write mode of individual bit, 1 means for read and 0 means for write. 
? You can then write to the GPIO using the following function: 
XGpio_mSetDataReg(BASEADDR, 1, data);

? Write an application that turn on the LED lights one at a time from left to right (or any pattern of your choice). The lights should change every half a second. You can use a busy waiting loop here to wait for time.

Step B.Use Timer and Interrupt Handler

? Timer can be used to generate interrupt in regular intervals. A timer is setup in part 1 with interrupt enabled. When the timeout expired, a interrupt will be generated to your microblaze processor. To setup a interrupt handler, use the following function:

#include "xtmrctr_1.h"
#include "xintc_1.h"

/* Enable MicroBlaze interrupts */
microblaze_enable_interrupts();
/* Register the interrupt handler in the vector table */ 
XIntc_RegisterHandler(INTC_BASEADDR, INTR, (XInterruptHandler)handler, (void*)BASEADDR); 
/* Start the interrupt controller */
XIntc_mMasterEnable(INTC_BASEADDR);


? to set the timer: 
/* Set the number of cycles the timer counts before interrupting */
XTmrCtr_mSetLoadReg(BASEADDR, 0, time_tick);
/* Reset the timers, and clear interrupts */
XTmrCtr_mSetControlStatusReg(TIMER_BASEADDR, 0,
XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK );
/* Enable interrupt requests in the interrupt controller */
XIntc_mEnableIntr(INTC_BASEADDR,
                              TIMER_INTERRUPT_MASK);
/* Start the timers */
XTmrCtr_mSetControlStatusReg(TIMER_BASEADDR, 0,
XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK |
XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK);

? interruptHander is a function with the following function declaration: 
void handler(void * baseaddr_p);

? and for timer interrupt, you can use the following template:
void timer_int_handler(void * baseaddr_p) {
     unsigned int csr;
     /* Read timer 0 CSR to see if it requested the interrupt */
     csr = XTmrCtr_mGetControlStatusReg(BASEADDR, 0);
     if (csr & INT_OCCURED_MASK) {
          /* handler interrupt here*/
     }
     /* Clear the timer interrupt */
     XTmrCtr_mSetControlStatusReg(BASEADDR, 0, csr);
}

? Copy your code from step A and modify it to use the timer instead of busy-waiting loop. 

Step C.Use UART to read character from serial port

? The microblaze processor is configured in part 1 to connect to the serial port via UART and use interrupt. When a character is entered into hyperterminal, the character is sent to the UART and an interrupt is generated. You can setup a interrupt handler for UART interrupt just like you did for timer interrupt, and read the characters one by one from the UART using the following function:

#include "xuartlite_1.h"

XUartLite_mIsReceiveEmpty(BASEADDR) is false when there is data waiting to be read
XUartLite_RecvByte(BASEADDR) return one character (char)


? enable UART interrupt

/* Enable interrupt requests in the interrupt controller */
XIntc_mEnableIntr(INTC_BASEADDR,
TIMER_INTERRUPT_MASK | UART_INTERRUPT_MASK);
/* Enable UART interrupts */
XUartLite_mEnableIntr(BASEADDR);

? Copy your code from step B and modify it to decrease the time between LED changes by half if a '[' is received and increase the time two times if a ']' is received.


PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /3 下一条