[Serialization] [FPGA black gold Development Board] niosii-serial port Experiment (6)

Source: Internet
Author: User
ArticleDirectory
    • Introduction
    • Hardware development
    • Software Development
Disclaimer: This article is an original work and copyright belongs to the author of this blog. All. If you need to repost, please indicate the source Http://www.cnblogs.com/kingst/

 

Introduction

In this section, we will talk about RS232, commonly known as serial port. Everyone should be familiar with this and have nothing to say. This section is more complex than the content we mentioned earlier. I will try my best to make it clear. In this section, I will not only explain how to implement the RS232 function, but also propose a programming idea.ProgramThe compilation is more rigorous and professional, and is more conducive to future maintenance and transplantation.

Hardware development

First, we need to build the RS232 module in the niosii soft core. Open the Quartus software, double-click it to go to the system builder, and click the Red Circle shown in the figure,

After clicking, as shown in, the Red Circle 1 is the baud rate, and we set it to 115200. The red circle 2 is to allow the software to change the baud rate. If we select it, we will allow it, in this way, we can use the software to change the baud rate at any time. If the software is not set, the default value is 115200 set above. In the red box 3, we set some parameters related to the serial port and check the method, data bit, stop bit, which is basically not used later. You can modify it based on your actual situation. After setting, click Next and finish to complete the build.

After the build, rename it RS232, and then automatically allocate the address and the interrupt number. Everything is ready. Click General to compile.

After compilation, exit and enter the Quartus interface and assign pins to it, as shown in

Run the Tcl script, compile, and wait ......

After compilation, you can download the program to FPGA in your own way, either as or JTAG.

Software Development

After opening the nioii 9.0 IDE, press the shortcut key Ctrl + B to compile the program and wait for compilation ......

After compilation, let's look at the system. h file. You can seeCodeAs shown in the following table, the red circle is the part we will use. You are familiar with it. One is the base address and the other is the interrupt number.

/** RS232 configuration **/# define rs232_name "/dev/RS232" # define rs232_type "serial" # define rs232_base 0x00201000 # define rs232_span 32 # define rs232_irq 2 # define rs232_baud 115200 # define rs232_data_bits 8 # define limit 0 # define rs232_parity 'n' # define rs232_stop_bits 1 # define limit 2 # define limit 0 # define limit 0 # define limit 0 # define limit "" # define rs232_freq 100000000 # define alt_module_class_rs232 altera_avalon_uart

Next, we start to write software programs. First, we need to modify the System File System (. h. See the following table.

Typedef struct {// receiving register Union {struct {volatile unsigned long int receive_data: 8; volatile unsigned long int NC: 24;} bits; volatile unsigned long int word;} rxdata; // sending register Union {struct {volatile unsigned long int transmit_data: 8; volatile unsigned long int NC: 24;} bits; volatile unsigned long int word;} txdata; // Status Register Union {struct {volatile unsigned long int PE: 1; volatile unsigned long int Fe: 1; volatile unsigned long int BRK: 1; volatile unsigned long int ROE: 1; volatile unsigned long int toe: 1; volatile unsigned long int TMT: 1; volatile unsigned long int trdy: 1; volatile unsigned long int rrdy: 1; volatile unsigned long int e: 1; volatile unsigned long int NC: 1; volatile unsigned long int dcts: 1; volatile unsigned long int CTS: 1; volatile unsigned long int EOP: 1; volatile unsigned long int NC1: 19;} bits; volatile unsigned long int word;} status; // control register Union {struct {volatile unsigned long int IPE: 1; volatile unsigned long int ife: 1; volatile unsigned long int ibrk: 1; volatile unsigned long int Iroe: 1; volatile unsigned long itoe: 1; volatile unsigned long int itmt: 1; volatile unsigned long int itrdy: 1; volatile unsigned long int irrdy: 1; volatile unsigned long int ie: 1; volatile unsigned long int trbk: 1; volatile unsigned long int idcts: 1; volatile unsigned long int RTS: 1; volatile unsigned long int ieop: 1; volatile unsigned long int NC: 19;} bits; volatile unsigned long int word;} control; // baud rate divider Union {struct {volatile unsigned long int baud_rate_divisor: 16; volatile unsigned long int NC: 16;} bits; volatile unsigned int word;} divisor;} uart_str;

This struct contains five sharing bodies, which correspond to five registers of RS232. Let's take a look at these five registers, as shown in, this figure is from page 6-11 of n2cpu_embedded peripherals.pdf.

(1) In this figure, the bits are changed according to the set data bit. We set the 8 bits, so the bits are of the same nature as the first 6 bits.

Similar to the PIO struct mentioned earlier, the content of this struct is defined in the register order (because endofpacket is not used, it is not defined in the structure) in this way, the corresponding offset can be implemented during the operation ).

In this struct, We nest five common bodies. In the shared bodies, we use struct and bit fields. The first glance must be dizzy. In fact, we want to control each bit of the register separately. At the same time, we can also implement the overall control of this register. The specific application will be applied in the following program.

With the struct above, we need to define a macro, which is similar to that of PIO.

 
# DEFINE _ UART # ifdef _ UART # define UART (uart_str *) rs232_base) # endif

I don't need to explain it. I have already explained it in the PIO section. It should be okay.

Next, create a UART. h file under Inc, as shown in

Write UART. h as shown in the following table.

/** =================================================== =========================================== * Filename: UART. H * Description: The head of UART device driver * version: * created: * revision: none * Compiler: NiO II ide ** Author: AVIC * company: golden Beach studio * ============================================ =========================*/# ifndef uart_h _ # define uart_h _ # include" .. /INC/systems. H "# define buffer_size 200/* optional * define * character */typedef struct {unsigned char mode_flag; // XMODEM 1; UART 0; unsigned int receive_flag; unsigned int receive_count; unsigned char receive_buffer [buffer_size]; int (* send_byte) (unsigned char data); void (* send_string) (unsigned int Len, unsigned char * Str); int (* init) (void); unsigned int (* baudrate) (unsigned int baudrate);} uart_t; extern uart_t UART; # endif/* uart_h _*/

In the above Code, the structure uart_t is very important. It is a programming idea simulating object-oriented, and also a very important programming method I mentioned earlier. We package all the functions and variables related to UART. For other functions, they can only see the UART struct, and the individual parts in it are invisible. I hope you can fully understand the ideas and enjoy great benefits for programming.

Next, we want to start writing the RS232 driver. First, we need to create a. c file named UART. C under the driver, as shown in

Compile the UART. c file, as shown in the following table.

/** =================================================== =========================================== * Filename: UART. c ** Description: RS232 device driver ** version: * created: * revision: none * Compiler: NiO II ide ** Author: AVIC * company: golden Beach studio * ============================================ =================================== * // * optional * include *------------------------------- ---------------------------- */# Include "sys/alt_irq.h" # include ".. /INC/systems. H "# include <stdlib. h> # include <stdio. h> # include ".. /INC/UART. H "/* required * function prototype * required */static int uart_send_byte (unsigned char data); static void uart_send_string (unsigned int Len, unsigned char * Str); static int uart_init (void); static void uart_isr (void); static int set_baudrate (unsigned int baudrate); // initialize the UART struct, note the struct initialization method uart_t UART = {. mode_flag = 0 ,. receive_flag = 0 ,. receive_count = 0 ,. send_byte = uart_send_byte ,. send_string = uart_send_string ,. init = uart_init ,. baudrate = set_baudrate }; /** = function ================================================== ====================== * Name: uart_send_byte * description: Send a byte data * ============================================= =========================== */static int uart_send_byte (unsigned char data) {// place the received data in the receiving data register. Wait for the Status Register trdy to set 1. If the trdy is set to 1, the receiving result is UART-> txdata. bits. transmit_data = data; while (! UART-> status. bits. trdy); Return 0 ;} /** = function ================================================== ==================== * Name: uart_send_string * description: send string data * ================================================= =========================*/static void uart_send_string (unsigned int Len, unsigned char * Str) {While (Len --) {uart_send_byte (* STR ++ );}} /** = function ================================================== ====================================== ============ * Name: uart_init * description: initialization program * ==================================================== ========================================= */static int uart_init (void) {// set the baud rate to 115200 set_baudrate (115200); // set the irrdy of the control register to 1, indicating that when the receiving is ready, the UART-> control will be interrupted. bits. irrdy = 1; // clear the Status Register, which is the way to process the entire register. WORD = 0; // register UART interrupt. ISR is uart_isr alt_irq_register (rs232_irq, null, uart_isr); Return 0;}/** === function ====== ========================================================== = * Name: uart_isr * description: serial Port interruption * ================================================= =========================================*/static void uart_isr (void) {// The receiving data status bit rrdy of the waiting Status Register. When the rrdy bit is 1, it indicates that the newly received value is transmitted to the receiving data register while (! (UART-> status. bits. rrdy); // reveive_buffer refers to the memory block opened in the memory through stack, and the data in the data register is sent to the UART in the memory block. receive_buffer [UART. receive_count ++] = UART-> rxdata. bits. receive_data; // when the last bit of the received data is \ n (carriage return), enter the if statement, that is, \ n serves as the end sign. After each data transmission, add a carriage return as the IF (UART. receive_buffer [UART. receive_count-1] = '\ n') {UART. receive_buffer [UART. receive_count] = '\ 0'; uart_send_string (UART. receive_count, UART. receive_buffer); UART. receive_count = 0; UART. receive_flag = 1 ;}} /** = function ================================================== ================ * Name: set_baudrate * description: set the baud rate * ========================================== =======================================*/static int set_baudrate (unsigned int baudrate) {// There is a formula for setting the baud rate. The baud rate is equal to the clock frequency/(divisor + 1). After the conversion, It is shown below. UART-> divisor. Word = (unsigned INT) (alt_cpu_freq/baudrate + 0.5); Return 0 ;}

After writing the above functions, we need to modify main. C, as shown in the following table.

 
# Include ".. /INC/systems. H "# include" system. H "# include" sys/alt_irq.h "# include <unistd. h> # include <stdio. h> # include ".. /INC/UART. H "int main () {unsigned char buffer [50] =" Hello FPGA! \ N "; // initialize the serial port. Pay attention to its usage.
 
UART. INIT (); // sends a string cyclically.
While (1) {UART. send_string (sizeof (buffer), buffer); usleep (500000);} return 0 ;}

I will talk about this today. I don't know whether the above explanation is suitable. If you have any questions, please leave a message for me.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.