[Serialization] [FPGA black gold Development Board] What about the niosii-iic bus Experiment (10)

Source: Internet
Author: User
Tags usleep
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 the iic bus experiment. In the hardware, we have applied 24lc04, a 512-byte EEPROM. The IIC interface is not integrated in the niosii. To implement this function, we have two ways: Write the IP core by yourself or port the IP core of another user, another method is to simulate the IIC bus protocol through the IO port. In this section, we use the latter to simulate the IIC bus protocol through the I/O port, in order to control the read/write of 24lc04.

First, let me briefly introduce the IIC bus principle. The IIC (Inter-Integrated Circuit) bus is a two-line serial bus developed by Philips to connect the microcontroller and its peripheral devices. It is a serial bus consisting of a data cable SDA and a clock SCL, which can send and receive data. Two-way transmission is performed between the CPU and the Controlled IC, and between the IC and IC. The maximum transmission rate is 100 kbps. It has three types of signals during data transmission: start signal, end signal, and response signal.

Start signal: in high-power mode, SDA switches from high level to low level to start transmitting data.

End signal: in high-power mode, SDA changes from low-level to high-level and ends data transmission.

Response signal: After receiving 8-bit data, the IC that receives the data sends a specific low-level pulse to the IC that sends the data, indicating that the data has been received. After the CPU sends a signal to the controlled unit, it waits for the controlled unit to send a response signal. After the CPU receives the response signal, it determines whether to continue to transmit the signal based on the actual situation. If no response signal is received, it is determined that the controlled unit has a fault.

Among these signals, the start signal is required. Either the end signal or the response signal can be used. It is the sequence diagram of the IIC bus.

After a brief introduction, let's start practicing it.

Hardware development

First, you need to add two I/O modules in the soft core, and name them As SCL and SDA. In this case, the check box creates ports only (output only) for output, and the SDA is Bidirection (tristate) port (bidirectional), as shown in

Next, we will automatically allocate the address and compile it.

After that, we return to the Quartus interface. Then assign the pins, as shown in

After the pins are allocated, run the Tcl script file and start compiling (CTRL + l )......

After the compilation is complete, our hardware is complete, and the next step is our software development section.

Software Development

First, we open the niosii 9.0 IDE and then compile (CTRL + B ).

After compilation, let's take a look at the system. h file to see if there are more of the SCL and SDA sections.Code. As we expected, the system. h file contains some code of the check box and SDA, as shown in the following table.

 
/** Cl configuration **/# define scl_name "/dev/SCL" # define scl_type "altera_avalon_pio" # define scl_base 0x00201060 ...... /** SDA configuration **/# define sda_name "/dev/SDA" # define sda_type "altera_avalon_pio" # define sda_base 0x00201070 ......

During the discussion with you, I have learned that many people want to know the usage of the built-in API of niosii. So today I will use this method to implement ourProgram. However, I recommend that you use my previous method to write programs. I have already said this and I will not repeat it here.

The following table describes how to create an IIC. h file in the INC directory.

# Ifndef iic_h _ # define out 1 # define in 0 typedef struct {void (* write_byte) (unsigned short ADDR, unsigned char dat); unsigned char (* read_byte) (unsigned short ADDR);} IIC; extern IIC; # endif/* iic_h _*/

Next, we need to create the IIC. c file under the driver, as shown in the following table.

 

# Include <stdio. h> # include <sys/unistd. h> # include <Io. h> # include "system. H "# include" altera_avalon_pio_regs.h "# include" alt_types.h "# include ".. /INC/IIC. H "static alt_u8 read_byte (alt_2010addr); static void write_byte (alt_2010addr, alt_u8 dat); IIC = {. write_byte = write_byte ,. read_byte = read_byte }; /** = function ================================================== =============================* Name: start * description: IIC start * =============================================== ====================== */static void start (void) {round (sda_base, out); iowr_altera_avalon_pio_data (sda_base, 1); Round (scl_base, 1); usleep (10); Round (sda_base, 0); usleep (5 );} /** = function ================================================== =============================* Name: uart_send_byte * DESC Ription: IIC stop * =============================================== =============================== */static void stop (void) {round (sda_base, out); iowr_altera_avalon_pio_data (sda_base, 0); Round (scl_base, 0); usleep (10); Round (scl_base, 1); usleep (5 ); iowr_altera_avalon_pio_data (sda_base, 1); usleep (10) ;}/ ** ==== function ============ ==================================== * Name: ACK * description: IIC response * ============================================ ====================== */static void ack (void) {alt_u8 TMP; values (scl_base, 0); values (sda_base, In); usleep (10); iowr_altera_avalon_pio_data (scl_base, 1); usleep (5 ); TMP = iord_altera_avalon_pio_data (sda_base); usleep (5); iowr_altera_avalo N_pio_data (scl_base, 0); usleep (10); While (TMP );} /** = function ================================================== =============================* Name: iic_write * description: IIC writes a byte * = =============================== */void iic_write (alt_u8 dat) {alt_u8 I, TMP; values (sda_base, out); for (I = 0; I <8; I ++) {iowr_altera_avalon_pio_data (scl_base, 0); usleep (5 ); TMP = (DAT & 0x80 )? 1: 0; dat <= 1; iowr_altera_avalon_pio_data (sda_base, TMP); usleep (5); iowr_altera_avalon_pio_data (scl_base, 1); usleep (10 );}} /** = function ================================================== =============================* Name: read * description: IIC reads a byte * = ================================= */static alt_u8 iic_read (void) {alt_u8 I, dat = 0; iowr_altera_avalon_pio_direction (sda_base, In); for (I = 0; I <8; I ++) {iowr_altera_avalon_pio_data (scl_base, 0 ); usleep (10); iowr_altera_avalon_pio_data (scl_base, 1); usleep (5); dat <= 1; dat | = iord_altera_avalon_pio_data (sda_base); usleep (5 );} usleep (5); Round (scl_base, 0); usleep (10); Round (scl_base, 1); usleep (10); iowr_altera_avalon_pio_data (scl_base, 0); Return dat ;} /** = function ================================================== =============================* Name: write_byte * description: write a byte * = =============================== */static void write_byte (alt_2010addr, alt_u8 dat) {alt_u8 cmd; cmd = (0xa0 | (ADDR> 7) & 0xfe; Start (); iic_write (CMD); ack (); iic_write (ADDR ); ack (); iic_write (DAT); ack (); stop ();} /** = function ================================================== =============================* Name: read_byte * description: read a byte from the eeprom * ====================================== =============================== */static alt_u8 read_byte (alt_2010addr) {alt_u8 cmd, dat; cmd = (0xa0 | (ADDR> 7) & 0xfe; Start (); iic_write (CMD); ack (); iic_write (ADDR ); ack (); Start (); cmd | = 0x01; Start (); iic_write (CMD); ack (); dat = iic_read (); stop (); return dat ;}

Finally, let's create the main. C function.

# Include <unistd. h> # include ".. /INC/IIC. H "# include <stdio. h> # include "alt_types.h" alt_u8 write_buffer [512], read_buffer [512]; int main () {alt_2010i, err; alt_u8 dat; printf ("\ nwriting data to EEPROM! \ N "); // write data of 512btye. The first 256 digits are 0 to 255, and the last 256 digits are 1 for (I = 0; I <512; I ++) {if (I <256) DAT = I; else dat = 1; IIC. write_byte (I, dat); write_buffer [I] = dat; printf ("0x % 02x", dat); usleep (10000);} printf ("\ nreading data from EEPROM! \ N "); // read the 512byte data and print for (I = 0; I <512; I ++) {read_buffer [I] = IIC. read_byte (I); printf ("0x % 02x", read_buffer [I]); usleep (1000) ;}err = 0; printf ("\ nverifing data! \ N "); // check whether the data is the same. If the data is different, it indicates that the read/write process is incorrect for (I = 0; I <512; I ++) {If (read_buffer [I]! = Write_buffer [I]) Err ++;} If (ERR = 0) printf ("\ ndata write and read successfully! \ N "); else printf (" \ ndata write and read failed! -- % D errors \ n ", err); Return 0 ;}

The program is very simple, as long as you have a certain understanding of the IIC bus will understand.

Okay. Let's talk about this section. Thank you for your support. If you have any questions, you can leave a message or directly join our advanced technology group: 107122106, or add my QQ: 984597569.

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.