// File Name : IIC.c
// Function : S3C2440 IIC-bus Master Tx/Rx mode Test Program
// (Interrupt / Non Interrupt (Polling))
// Program : Shin, On Pil (SOP)
// Date : May 21, 2002
// Version : 0.0
// History
// 0.0 : Programming start (March 11, 2002) -> SOP
//====================================================================
#include #include "2440addr.h" //register macro definition #include "2440lib.h" //Functions to be used, function declarations #include "def.h" //Macro definitions of several variable types #include "IIC.h" //volatile affects the compiler's compilation results, indicating that volatile variables may be //Do not compile and optimize operations related to volatile variables that have changed static U8 _iicData[IICBUFSIZE]; //Define an array with 256 data static volatile int _iicDataCount; //IIC data count static volatile int _iicStatus; //IIC status static volatile int _iicMode; //IIC mode static int _iicPt; //IIC pointer //=================================================================== // SMDK2440 IIC configuration // GPE15=IICSDA, GPE14=IICSCL // "Interrupt mode" for IIC block IIC operation in interrupt mode //=================================================================== //******************[ Test_Iic ]************************************** void Test_Iic(void) { unsigned int i,j,save_E,save_PE; static U8 data[256]; //define an array of 256 8-bit data Uart_Printf("nIIC Test(Interrupt) using AT24C02n"); save_E = rGPECON; //Save the scene save_PE = rGPEUP; rGPEUP |= 0xc000; //1100 0000 0000 0000 disable GPE14, GPE15 pull-up resistor rGPECON |= 0xa00000; //GPE15:IICSDA, GPE14:IICSCL (should be 0xa0000000)??? pISR_IIC = (unsigned)IicInt; //Function assigned to vector address rINTMSK &= ~(BIT_IIC); //Enable IIC interrupt //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16 // If PCLK 50.7MHz, IICCLK=PCLK/16=3.17MHz, Tx Clock(transmit clock)=IICCLK/16=0.198MHz rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf); rIICADD = 0x10; //2440 slave address=[7:1]=0x10 slave address rIICSTAT = 0x10; //IIC bus data output enable (Rx/Tx) IIC data output enable rIICLC = (1<<2)|(1); //Filter enable, 5 clocks SDA output delay added by junon (I feel it is useless) Uart_Printf("Write test data into AT24C02n"); for(i=0;i<256;i++) Wr24C080(0xa0,(U8)i,i); //The address of the slave device is 0xa0, starting from the internal address 0 of the slave device and ending at address 256, write 0~256 for(i=0;i<256;i++) data[i] = 0; //All elements of the data array are initialized to 0 Uart_Printf("Read test data from AT24C02n"); for(i=0;i<256;i++) Rd24C080(0xa0,(U8)i,&(data[i])); //Read the data from the device and store it in the data array //Line changed 0 ~ f for(i=0;i<16;i++) { for(j=0;j<16;j++) Uart_Printf("%2x",data[i*16+j]); //Print the data just read, that is, the value in the data array Uart_Printf("n"); //Change to a new line every 16 bytes } rINTMSK |= BIT_IIC; //IIC operation is completed, IIC interrupt is disabled rGPEUP = save_PE; //Restore the scene rGPECON = save_E; } //*************************[ Wr24C080 ]**************************** // Function name Slave address Data written to internal address //**************************************************************** void Wr24C080(U32 slvAddr,U32 addr,U8 data) { //The process is: S (start signal) --- send device address ---- device internal address ---- written data _iicMode = WRDATA; //Set to write data mode _iicPt = 0; //IIC pointer points to address 0 _iicData[0] = (U8)addr; //Assign a value to element 0 of the Data array, internal address _iicData[1] = data; //Assign a value to element 1 of the Data array, and write the data _iicDataCount = 2; //The initial value of the data count is 2 rIICDS = slvAddr; //0xa0 gives the slave device address to IICDS rIICSTAT = 0xf0; //MasTx, Start Set to master transmission mode, write IIC to generate start signal, enable RX/TX //Clearing the pending bit isn't needed because the pending bit has been cleared. //Start IIC writing. After sending the slave device address, an interrupt is generated and the interrupt function is entered. while(_iicDataCount!=-1 );//Because count is 2, the condition is not met and then wait!! After the first interrupt is processed, count=1, and then judge that the condition in while is not met, continue to wait, and after sending the internal address of the slave word device, an interrupt is generated and the interrupt function is entered //The following while statement is to determine whether the ACK signal is received _iicMode = POLLACK; //Wait for ACK response mode, a response means the slave device has received it while(1) { rIICDS = slvAddr; //slvAddr=0xa0 _iicStatus = 0x100; //IICSTAT clear?? rIICSTAT = 0xf0; //MasTx, Start, master transmission mode, generate start signal, enable serial output, start IIC rIICCON = 0xaf; //Resumes IIC operation. while(_iicStatus==0x100); //Wait until IICSTAT change if(!(_iicStatus&0x1)) // Check if the 0th bit of IICSTAT is 0. If it is 0, it means ACK is received. break; //When ACK is received } rIICSTAT=0xd0; //Generate a stop signal to stop IIC rIICCON=0xaf; //Reconfigure IICCON. Delay(1); //Wait until the stop signal of IICSTAT is valid //Write is completed. } //**********************[ Rd24C080 ] *********************************** //Read random address data read function //Process: S---Send device address---Device internal address---Send device address---Read data---NOACK---Abort void Rd24C080(U32 slvAddr,U32 addr,U8 *data) { _iicMode = SETRDADDR; //Set the read address _iicPt = 0; _iicData[0] = (U8)addr; _iicDataCount = 1; rIICDS = slvAddr; //slvAddr=0xa0 first write the slave device address rIICSTAT = 0xf0; //MasTx, Start start signal //Clearing the pending bit isn't needed because the pending bit has been cleared. while(_iicDataCount!=-1); //Because count is 1, the condition is not met and then wait!! After the first interrupt is processed, count=0, and then judge that the condition in while is not met, continue to wait, and after sending the internal address of the slave word device, an interrupt is generated and the interrupt function is entered. After the interrupt function is executed, count=-1, so this while loop is exited _iicMode = RDDATA; //Read data mode _iicPt = 0; _iicDataCount = 1; //Read a data (address) rIICDS = slvAddr; //slvAddr=0xa0, send the slave device address again rIICSTAT = 0xb0; //1011, 10~MasRx, 1~Start, 1~RxTx enable master receive mode rIICCON = 0xaf; //Resumes IIC operation. while(_iicDataCount!=-1); //Wait, after sending the device address, an interrupt is generated and the interrupt function is entered to execute the second interrupt processing. Count=-1, the condition is not met and exit while, and continue with the following statement *data = _iicData[1]; //Send the data received from IICDS to pointer data, } //------------------------------------------------------------------------- void __irq IicInt(void) //IIC interrupt initialization function { U32 iicSt,i; rSRCPND = BIT_IIC; //Clear pending bit so that the next interrupt can be executed rINTPND = BIT_IIC; //Clear pending bit so that the next interrupt can be executed iicSt = rIICSTAT; //Assign the value of the IICSTAT status register to iicSt if(iicSt & 0x8){} //When bus arbitration is failed. When bus arbitration fails, perform no operation if(iicSt & 0x4){} //When a slave address is matched with. When the received slave address matches the address in IICADD, perform no operation if(iicSt & 0x2){} //When a slave address is 0000000b. The slave address received is 0000000b if(iicSt & 0x1){} //When ACK isn't received, no operation is performed. switch(_iicMode) //Perform different operations according to different modes { case POLLACK: //ACK mode _iicStatus = iicSt; //Let _iicStatus equal the value of IICSTAT break; case RDDATA: //Read data mode if((_iicDataCount--)==0) //count is initially 1, so the if code segment is not executed. After the completion, count=0. When the second interrupt comes, the condition is met and the code inside the if is executed { _iicData[_iicPt++] = rIICDS; //Re-read the value in IICDS to _iicData[1] rIICSTAT = 0x90; //Stop MasRx condition 1001 0000 Generates a stop signal rIICCON = 0xaf; //Resumes IIC operation. Resume IIC operation Delay(1); //Wait until stop condtion is in effect. //Too long time... Wait until the stop signal takes effect //The pending bit will not be set after issuing stop condition. break; //jump back to the read function } //Cannot generate ACK if the last byte has not been read. Read data in IICDS _iicData[_iicPt++] = rIICDS; //The last data has to be read with no ack. if((_iicDataCount)==0) rIICCON = 0x2f; //Because the condition is met, execute rIICCON = 0x2f; the host generates NOACK and releases the IIC operation else rIICCON = 0xaf; //Generate ACK, release IIC operation break; case WRDATA: //write data mode if((_iicDataCount--)==0) //Judge whether it is 0 after self-decrement. (2 is 1 after self-decrement, not 0)
Previous article:mini2440 i2c device support
Next article:MINI2440i2c driver learning 2
Recommended ReadingLatest update time:2024-11-23 04:18
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- Why does the BLE Sensor APP require my location permission?
- Detailed explanation of the basic components and flight principles of quadcopters
- How is the software of CC2640 and CC2640R2F stored in the internal ROM and internal Flash?
- The role of electronic transformers in power supply technology
- Play with pyboardCN V2 -- pyboardCN LED driver expansion board (TM1628)
- KiCad related resource sharing
- L20G20IS data sheet, application notes, drivers, packaging
- The national programmer salary for April 2020 is released. Why are we always averaged? ? ?
- [Repost] What is the difference between an operational amplifier and a comparator?
- Problems encountered with diode step-down