10. ARM9(2440) IIC-theoretical knowledge and program examples

Publisher:sky0001Latest update time:2015-09-23 Source: eefocusKeywords:ARM9  IIC Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
Overview

The S3C2440A RISC microprocessor can support a multi-master IIC bus serial interface. A dedicated serial data line (SDA) and a dedicated
serial clock line (SCL) pass information between the bus master and the peripherals connected to the IIC bus. Both the SDA and SCL lines are bidirectional.
In multi-master IIC bus mode, multiple S3C2440A RISC microprocessors can send or receive serial data from or to slave devices. The master
S3C2440A can start and end data transfers through the IIC bus. The IIC bus in the S3C2440A uses standard bus arbitration procedures.
To control the multi-master IIC bus operation, values ​​must be written to the following registers:
– Multi-master IIC bus control register, IICCON
– Multi-master IIC bus control/status register, IICSTAT
– Multi-master IIC bus Tx/Rx data shift register, IICDS
– Multi-master IIC bus address register, IICADD
When releasing the IIC bus, both the SDA and SCL lines should remain high. A high-to-low SDA transition initiates a start condition.
A low-to-high SDA transition while SCL remains stable at a high level initiates a stop condition.
The start and stop conditions are usually generated by the master device. The first data byte is the 7-bit address value, which is placed on the bus after the start condition is initiated to determine
the slave device that the master device wants to select. The 8th bit determines the direction of the transfer (read or write).
Each byte placed on the SDA line should have a total of 8 bits. Bytes can be sent or received without restriction during the bus transfer operation. Data is usually
sent most significant bit (MSB) first, and each byte should be immediately followed by an acknowledge (ACK) bit.

 

 

The I2C bus can form a multi-master and multi-slave system. In a multi-master system structure, the system obtains the right to control the bus through hardware or software arbitration. In the application system, the I2C bus mostly adopts a master-slave structure, that is, there is only one master node on the bus, and the other devices on the bus are slave devices. The device addressing on the I2C bus is determined by the device address wiring, and the read/write direction is controlled by accessing the lowest bit of the address.

At present, most general-purpose memory chips are EEPROM, and their commonly used protocols are mainly two-wire serial connection protocol (I2C) and

Three-wire serial connection protocol. There are many types of EEPROMs with I2C bus interface, among which AT24CXX series is very popular. Products include AT24C01, AT24C02, AT24C04, AT24C08, AT24C16, etc.

AT24 series memory chips are manufactured using CMOS technology and have a built-in boost circuit, which allows them to work under single voltage supply conditions. The standard package is an 8-pin DIP package.

The functions of each pin are described as follows:

SCL: Serial clock. Follows ISO/IEC7816 synchronization protocol, open drain, requires pull-up resistor. On the rising edge of this pin, the system inputs data to each EEPROM device and outputs it on the falling edge.

SDA: Serial data line. Open drain, need to connect pull-up resistor. Bidirectional serial data line, open drain, can be wired-OR with other open devices.

A0, A1, A2: Device/page address input terminals. In AT24C01 and AT24C02, the pins are hard-wired, and other AT24Cxx can be connected to the address lines.

WP: Read/write protection. When connected to a low level, the entire space can be read/written, and when connected to a high level, it cannot be read/written and is protected.

Vcc/GND: 5V operating voltage.

 

Device Address (DADDR)     The device address of AT24C04 is 1010.

AT24CXX data operation format

In the I2C bus, to read/write the internal storage unit of AT24C04, in addition to giving the device address (DADDR) of the device

In addition, the page address (PADDR) for reading/writing must be specified. The two together make up the operation address (OPADDR) as follows:

                1010 A2 A1 A0-R/W   , usually A2 A1 A0 is hard-connected, such as grounded, so the device address is 0xa0

 

The following is a description of IIC from someone else's article, which is very well written.

There is an IIC bus interface inside the s3c2440, so it is convenient for us to connect peripheral devices with IIC communication modules. It has four operating modes: master device sending mode, master device receiving mode, slave device sending mode and slave device receiving mode. Here we only use the s3c2440 as the master device of the IIC bus, so only the first two operating modes are introduced. In the master device sending mode, its workflow is: first configure the IIC mode, then write the slave device address into the receive and send data shift register IICDS, and then write 0xF0 into the control status register IICSTAT, then wait for the slave device to send a response signal. If you want to continue sending data, then after receiving the response signal, write the data to be sent into the register IICDS, clear the interrupt flag, and wait for the response signal again; if you don’t want to send data anymore, then write 0x90 into the register IICSTAT, clear the interrupt flag and wait for the stop condition, and the master device has completed the transmission. In the master device receiving mode, its workflow is: first configure the IIC mode, then write the slave device address into the receive and send data shift register IICDS, and then write 0xB0 into the control status register IICSTAT. At this time, wait for the slave device to send a response signal. If you want to receive data, then read the register IICDS after the response signal to clear the interrupt flag; if you don't want to receive data, then write 0x90 to the register IICSTAT, clear the interrupt flag and wait for the stop condition, and then the master device reception is completed. When completing the above two modes, the control register IICCON, the control status register IICSTAT and the send and receive data shift register IICDS are mainly used. Since we only use s3c2440 as a master device, and there is only one master device on the IIC bus of the system, the address register IICADD used to set the slave device address and the multi-master device line control register IICLC used for arbitration bus do not need to be configured. The 6th bit and the lower 4 bits of the register IICCON are used to set the clock frequency of IIC, because the clock line SCL of IIC is provided by the master device. The IIC clock source of s3c2440 is PCLK. When the system PCLK is 50MHz and the slave device requires a maximum of 100kHz, the 6th bit of IICCON can be set to 1, and the lower 4 bits of IICCON can be all 0. The 7th bit of register IICCON is used to set whether to send a response signal, the 5th bit is used to enable sending and receiving interrupts, and the 4th bit is used for the interrupt flag. After receiving or sending data, this bit must be cleared to clear the interrupt flag. The upper 2 bits of register IICSTAT are used to set which operation mode is used. When writing 0 or 1 to the 5th bit, it means ending IIC or starting IIC communication. The 4th bit is used to enable receiving/sending data.

 

       Since communication is a matter for both parties, after understanding the operation mode of the master device, it is also necessary to understand the operation mechanism of the slave device. The two must be perfectly combined to achieve mutual communication. Here, the slave device is EEPROM-AT24C02A. In order for S3C2440 to read and write AT24C02A correctly, the timing of S3C2440 must be completely in accordance with the timing of AT24C02A. There are two modes of AT24C02A write operation: byte write and page write. Byte write is to first receive the device address information with a write command, if it meets the requirements, then respond, and then receive the device memory address information. After issuing a response, it receives the data to be written, thus completing the byte write process. The difference between page write and byte write is that page write can write multiple data at a time, while byte write can only write one data at a time. However, since a page of AT24C02A is only 8 bytes, page write can only write 8 data at most, and can only be written within the page, and it will not happen that a page write writes two pages at the same time. There are three modes for the read operation of AT24C02A: current address read, random read and sequential read. Current address read can only read the data in the current address. Its timing is to first receive the device address information with the read command, respond if it matches, and then send the data in the current address. If the response signal sent from the master device is not received, the operation is terminated. The timing of random read is to continuously receive the device address information with the write command and the device memory address information, and then the master device restarts IIC communication. AT24C02A receives the device address information with the read command again, and after sending the response signal, it sends the data of the memory address, and ends the communication without receiving any response signal. Current address read and random read can only read one data at a time, while sequential read can read several data at a time. Its timing is that after the current address read or random read sends data, if the response signal is received, AT24C02A will send out the data in the next memory address. Unless AT24C02A does not receive any response signal, it will continue to send out the data in the next memory address. Sequential reads do not have the 8-byte page limit.

 

       After introducing the IIC communication method between s3c2440 and AT24C02A, we can write the program. Here, we use UART to realize the reading and writing of AT24C02A by PC. The communication protocol of UART is that PC sends the command byte first: 0xC0 means to write data to AT24C02A, 0xC1 means to read data from AT24C02A, and after the command byte, it is followed by the device memory address and the number of bytes to be written or read. If EEPROM data is to be written, the data content to be written is after these three bytes. After the UART communication is completed, s3c2440 will write or read AT24C02A according to the different commands. If it is to read EEPROM, s3c2440 will also use UART to upload the read data to PC. In this program, we only enable the receive interrupt of UART, but not the send interrupt, that is, let s3c2440 take the initiative to complete the sending task. And in the operation with AT24C02A, we use the page write and sequence read mode, so that we can complete a read or write operation to the greatest extent, and the page write and sequence read modes we have written can also realize the byte write and random read mode. Here we limit the amount of data read or written at most to 8 bytes.

The following is a program analysis using the FL2440 development board:


#include
#include "2440addr.h"
#include "def.h"
#include "IIC.h"

static U8 _iicData[IICBUFSIZE];
static volatile int _iicDataCount;//Send count flag
static volatile int _iicStatus;//IIC status flag
static volatile int _iicMode;//IIC mode flag
static int _iicPt;
extern void Uart_Printf(char *fmt,...);
extern void Uart_Init(int baud);
void Delay(int x);

//================================================ ===================
//        SMDK2440 IIC configuration
//   GPE15=IICSDA, GPE14=IICSCL
//   "Interrupt mode" for IIC block
//====== ================================================== ===========

//******************[Test_Iic]****************************** ***********
void Test_Iic(void)

 
    unsigned int i,j,save_E,save_PE;
    static U8 data[512];//256
    //Uart_Init(115200);

    Uart_Printf("nIIC Test(Interrupt) using AT24C02n");

    save_E    = rGPECON;
    save_PE   = rGPEUP;
    rGPEUP   |= 0xc000;                   //Pull-up disable
   
    rGPECON &=0xfffffff;
    rGPECON |= 0xa0000000;                 //GPE15:IICSDA , GPE14:IICSCL

    pISR_IIC = (unsigned)IicInt;
    rINTMSK &= ~(BIT_IIC);

      //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
      // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
    rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);
    rIICADD   = 0x10;                     //2440 slave address = [7:1] There is no effect when there is no such statement in the experiment, because the master mode is used
    rIICSTAT = 0x10;                     //IIC bus data output enable(Rx/Tx)
 rIICLC = (1<<2)|(1);       // Filter enable, 15 clocks SDA output delay        added by junon
    rIICDS = 0xDD;
    Uart_Printf("Write test data into AT24C02n");

    for(i=0;i<256;i++)//256
        Wr24C080(0xa0,(U8)i,i);//Write data 0--255 to address 0--255
          
    for(i=0;i<256;i++)//256
        data[i] = 0;//Clear array

    Uart_Printf("Read test data from AT24C02n");
   
    for(i=0;i<256;i++)
        Rd24C080(0xa0,(U8)i,&(data[i]));//Store the read data into the data array

        //Line changed 0 ~ f
    for(i=0;i<16;i++)//Print the read data   16
    {
        for(j=0;j<16;j++)
            Uart_Printf("%2x ",data[i*16+j]);
        Uart_Printf("n");
    }
    rINTMSK |= BIT_IIC;//Shield interrupt    
    rGPEUP   = save_PE;//Restore GPE port
    rGPECON = save_E;
    while(1);
}

[page]
//*************************[ Wr24C080 ]********************************
void Wr24C080(U32 slvAddr,U32 addr,U8 data)//First address    internal address    data
{
    _iicMode       = WRDATA;//Mode flag is recorded as WRDAT
    _iicPt         = 0;//Pointer is recorded as 0
    _iicData[0]    = (U8)addr;//Internal address
    _iicData[1]    = data;//Data to be written
    _iicDataCount = 2;
   
    rIICDS    = slvAddr;                  //0xa0 device address
    rIICSTAT = 0xf0;                     //MasTx,Start Start sending
      //Clearing the pending bit isn't needed because the pending bit has been cleared.
   
    while(_iicDataCount!=-1);//Not sent yet, wait here

    _iicMode = POLLACK; //After sending, wait for the response signal ACK

    while(1)
    {
        rIICDS      = slvAddr;
        _iicStatus = 0x100;
        rIICSTAT    = 0xf0;               //MasTx,Start
        rIICCON     = 0xaf;               //Resumes IIC operation. Restore IIC bus
          
        while(_iicStatus==0x100);//Not received ACK, wait here
          
        if(!(_iicStatus&0x1))
            break;                       //When ACK is received     , jump out of the loop
    }
    rIICSTAT = 0xd0;                     //Stop MasTx condition
    rIICCON   = 0xaf;                     //Resumes IIC operation.
    Delay(1);                            //Wait until stop condtion is in effect. Restore
       //Write is completed.
}
       
//**********************[ Rd24C080 ] ***************************************
void Rd24C080(U32 slvAddr,U32 addr, U8 *data) //The address where the data read from the first internal address is stored
{
    _iicMode       = SETRDADDR; //The mode is set to SETRDADDR
    _iicPt         = 0;
    _iicData[0]    = (U8)addr; //_iicData[0] stores the internal address
    _iicDataCount = 1; //Count value

    rIICDS    = slvAddr; //First address 0xa0
    rIICSTAT = 0xf0;                     //MasTx, Start   //
      Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicDataCount!=-1); //Reading not completed

    _iicMode       = RDDATA; //After completion, enter the data reading mode
    _iicPt         = 0;
    _iicDataCount = 1;
   
    rIICDS         = slvAddr;
    rIICSTAT       = 0xb0;                //MasRx, Start is set to the main receiving mode
    rIICCON        = 0xaf;                //Resumes IIC operation. Resume IIC bus operation   
    while (_iicDataCount! = -1); //Reading is not completed

    *data = _iicData[1]; //1
}


//-------------------------------------------------------------------------
void __irq IicInt(void)
{
    U32 iicSt,i;
   
    rSRCPND = BIT_IIC;           //Clear pending bit
    rINTPND = BIT_IIC;
    iicSt    = rIICSTAT;//Control status registerif
   
    (iicSt & 0x8){}            //When bus arbitration is failed.Bus arbitration failed to perform no operationif
    (iicSt & 0x4){}            //When a slave address is matched with IICADD from address match to perform no operationif
    (iicSt & 0x2){}            //When a slave address is 0000000b
    if(iicSt & 0x1){}            //When ACK isn't received   did not receive the response signal to perform no operation

    switch(_iicMode)
    {
       case POLLACK:
           _iicStatus = iicSt; // Assign the value of the control status register to _iicStatus
           break;

       case RDDATA:
           if((_iicDataCount--)==0)
           {
               _iicData[_iicPt++] = rIICDS;
           
               rIICSTAT = 0x90;                  //Stop MasRx condition
               rIICCON   = 0xaf;                  //Resumes IIC operation.
               Delay(1);                         //Wait until stop condtion is in effect.
                                                //Too long time...
                                                //The pending bit will not be set after issuing stop condition.
               break;    
           }      
           _iicData[_iicPt++] = rIICDS;          //The last data has to be read with no ack .

           if((_iicDataCount)==0)
               rIICCON = 0x2f;                   //Resumes IIC operation with NOACK.  No acknowledge signal is generated for the first time, and the second reading is performed and the
                                                 ///////////////// data read for the second time is stored in the array (the data read for the first and second times are actually the same)
           else
               rIICCON = 0xaf;                   //Resumes IIC operation with ACK
               break;

        case WRDATA:
            if((_iicDataCount--)==0)//After the first address, internal address and data are sent
            {
                rIICSTAT = 0xd0;                 //Stop MasTx condition generates a stop signal
                rIICCON   = 0xaf;                 //Resumes IIC operation. Restores IIC bus
                Delay(1);                        //Wait until stop condtion is in effect.
                       //The pending bit will not be set after issuing stop condition.
                break;    
            }
            rIICDS = _iicData[_iicPt++];         //_iicData[0] has dummy. After the first interrupt, store the value of internal address addr into IICDS   and store the data to be written for the second time
            for(i=0;i<10;i++);                   //for setup time until rising edge of IICSCL//Delay
             
            rIICCON = 0xaf;                      //resumes IIC operation. Restores IIC bus
            break;

        case SETRDADDR:
//           Uart_Printf("[ S%d ]",_iicDataCount);
            if((_iicDataCount--)==0)
                break;//Second interrupt jumps out                           //IIC operation is stopped because of IICCON[4]    
            rIICDS = _iicData[_iicPt++];//The first interrupt stores the internal address addr into the shift register
            for(i=0;i<10;i++);                   //For setup time until rising edge of IICSCL
            rIICCON = 0xaf;                      //Resumes IIC operation.
            break;

        default:
            break;      
    }
}
void Delay(int x) 
{
  int k, j;
  while(x)
  {
   for (k=0;k<=0xff;k++)
    for(j=0;j<=0xff;j++);
    
   x--;
  }
}

Keywords:ARM9  IIC Reference address:10. ARM9(2440) IIC-theoretical knowledge and program examples

Previous article:STM32 general-purpose timer (TIM2-5) PWM output
Next article:11 ARM9 (2440) network card interface expansion

Recommended ReadingLatest update time:2024-11-16 10:51

mini2440 entry-level block device driver (using RAM cache to simulate a disk) code record (the kernel uses 2.6.32.2)
#include linux/module.h #include linux/errno.h #include linux/interrupt.h #include linux/mm.h #include linux/fs.h #include linux/kernel.h #include linux/timer.h #include linux/genhd.h #include linux/hdreg.h #include linux/ioport.h #include linux/init.h #include linux/wait.h #include linux/blkdev.h #includ
[Microcontroller]
Linux 2.6.32 ported to MINI 2440 (4) Porting + analyzing the DM9000 network card driver
Development Environment:     Host: fedora 14     Virtual machine: vmware workstation 10     Cross-compilation tool: arm-linux-gcc 4.3.2     Development board: mini2440 (2m nor, 64m sdram, 256m nand)     Kernel version: linux2.6.32.2 The uImage in the previous post can start the yaffs2 file system, but not
[Microcontroller]
Linux 2.6.32 ported to MINI 2440 (4) Porting + analyzing the DM9000 network card driver
JZ2440 programming method notes
1. The steps for burning ordinary programs with dnw on jz2440 are: ①Choose to burn uboot into nor flash or nand flash ②Open dnw and select the program to be burned. Note that it is not uboot, but the program you want to burn. It regards all programs as uboot. 2. Method using tftp: Preliminary preparation After ente
[Microcontroller]
Timing reboot of Embedded Linux in Micro2440
Because the ARM server I worked on at my internship company required scheduled restarts, I looked up some relevant information today. I found that there was no specific method for my current development platform, so I developed a set of methods for everyone to learn from. Embedded Linux under FriendlyArm Micro2
[Microcontroller]
U-Boot patch for S3C2440
# tar xvf u-boot-1.1.6.tar.bz2 //Decompression # cd u-boot-1.1.6/ Creating a patch file # diff -urN u-boot-1.1.6 u-boot-1.1.6.new u-boot-1.1.6_jz2440.patch Patch # patch -p1 u-boot-1.1.6_jz2440.patch p1: Ignore the content before the first "/" in the patch file (that is, as follows: u-boot-1.1.6) # head
[Microcontroller]
Location of mini2440 one-line touch driver code
The location of the first-line touch screen driver code of the mini2440 development board in the Linux kernel code provided by Friendly Arm is as follows: linux-2.6.32.2driversinputtouchscreenmini2440_1wire_host.c /*  * mini2440_1wire_host.c  *  * This program is free software; you can redistribute it and/or modif
[Microcontroller]
ARM9 mini2451 bare metal learning - NAND flash driver learning 2
In the previous article, we mainly learned the basic knowledge of NAND Falsh. Today, we will summarize the initialization of NAND Flash, as well as block erase, page read and write operations, and the acquisition of chip ID number. 6. NAND FLASH operation interface We know that functions need to use a stack when t
[Microcontroller]
ARM9 mini2451 bare metal learning - NAND flash driver learning 2
S3C2440 burns program directly into SDRAM via J-Link
       Since the S3C2440 core board and the main board are made in the laboratory, the H-Jtag of the friendly arm cannot be used, so J-Link is used to test whether the soldered core board works normally . Steps: 1. Connect the core board and turn on the power . 2. Use the J-Link commander that comes with J-Link (it
[Microcontroller]
S3C2440 burns program directly into SDRAM via J-Link
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号