电话跳线架打法图解:S3C2440之IIC

来源:百度文库 编辑:中财网 时间:2024/04/28 04:26:52

                                                    S3C2440之IIC

 

IIC(Inter-Integrated Circuit,I2C)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微处理器及其外围设备。在iic总线上,只需要两条线:串行数据线SDA和串行时钟线SCL,便可完成通信。如图:

IIC启动和停止信号的定义


s3c2440内部有一个IIC总线接口,通过对其寄存器的配置和时序的操作即可完成IIC通信,其编程流程如下:

一,在主设备发送模式下,它的工作流程为:

1,首先配置IIC模式(包括配置GPE15,GPE14为第二功能 时钟线和数据线,iic中断使能,发送时钟频率等)

view plaincopy to clipboardprint?
  1. rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL,GPE15,GPE14为第二功能 时钟线和数据线  
  2. pISR_IIC = (unsigned)IicInt;//中断注册  
  3. rINTMSK &= ~(BIT_IIC);//iic中断使能        
  4. rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);//(1<<7)Enable ACK,(0<<6) Prescaler IICCLK=PCLK/16,(1<<5) Enable interrupt,  
  5.                         // (0xf)Transmit clock value Tx clock=IICCLK/(15+1)  
  6.                         // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz  
  7. rIICADD  = 0x10;                    //2440 slave address = [7:1]=0x10;  
  8. rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)  
  9. rIICLC = (1<<2)|(1);          // Filter enable, 5 clocks SDA output delay       added by lj  

2,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xF0写入控制状态寄存器IICSTAT中,这时等待从设备发送应答信号

view plaincopy to clipboardprint?
  1. rIICSTAT   = 0xf0;              //MasTx,Start  
  2. rIICCON    = 0xaf;              //Resumes IIC operation.             
  3. while(_iicStatus==0x100);       //Wait until IICSTAT change  

3,如果想要继续发送数据,那么在接收到应答信号后,再把待发送的数据写入寄存器IICDS中,清除中断标志后,再次等待应答信号;如果不想再发送数据了,那么把0x90写入寄存器IICSTAT中,清除中断标志并等待停止条件后,即完成了一次主设备的发送。

view plaincopy to clipboardprint?
  1. rIICSTAT = 0xd0;                    //1101_,11~MasRx,0~stop,1~RxTx enable //Stop MasTx condition   
  2. rIICCON  = 0xaf;                    //Resumes IIC operation.   
  3. Delay(1);                           //Wait until stop condtion is in effect.  
  4.    //Write is completed.  

二,在主设备接收模式下,它的工作流程为:

1,首先配置IIC模式,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xB0写入控制状态寄存器IICSTAT中

view plaincopy to clipboardprint?
  1. rIICDS        = slvAddr;            //slvAddr=0xa0    
  2. rIICSTAT      = 0xb0;               //1011,10~MasRx,1~Start,1~RxTx enable  
  3. rIICCON       = 0xaf;               //Resumes IIC operation.     
  4. while(_iicDataCount!=-1);//等待主接收模式停止,在中断函数里进行的  

2,这时等待从设备发送应答信号,如果想要接收数据,那么在应答信号后,读取寄存器IICDS,清除中断标志;如果不想接收数据了,那么就向寄存器IICSTAT写入0x90,清除中断标志并等待停止条件后,即完成了一次主设备的接收。

view plaincopy to clipboardprint?
  1. _iicData[_iicPt++] = rIICDS;              
  2. rIICSTAT = 0x90;                 //1001Stop MasRx condition   
  3. rIICCON  = 0xaf;                 //Resumes IIC operation.  
  4. Delay(1);                        //Wait until stop condtion is in effect  

其程序流程图如下:



下面的例程将向AT24C02写入若干字节,并读出来显示在超级终端:

IIC.c

view plaincopy to clipboardprint?
  1. //===================================================================  
  2. //       SMDK2440 IIC configuration  
  3. //  GPE15=IICSDA, GPE14=IICSCL  
  4. //  "Interrupt mode" for IIC block中断模式下的IIC操作  
  5. //===================================================================   
  6.   
  7. //******************[ Test_Iic ]**************************************  
  8. void Test_Iic(void)  
  9. {  
  10.     unsigned int i,j,save_E,save_PE;  
  11.     static U8 data[256];  
  12.   
  13.     Uart_Printf("\nIIC Test(Interrupt) using AT24C02\n");  
  14.   
  15.     save_E   = rGPECON;//保护现场  
  16.     save_PE  = rGPEUP;  
  17.     rGPEUP  |= 0xc000;                  //Pull-up disable ,1_disable,0_enable  
  18.     rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL,GPE15,GPE14为第二功能 时钟线和数据线  
  19.   
  20.     pISR_IIC = (unsigned)IicInt;//中断注册  
  21.     rINTMSK &= ~(BIT_IIC);//iic中断使能  
  22.   
  23.         
  24.     rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);//(1<<7)Enable ACK,(0<<6) Prescaler IICCLK=PCLK/16,(1<<5) Enable interrupt,  
  25.                                                 // (0xf)Transmit clock value Tx clock=IICCLK/(15+1)  
  26.                                                 // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz  
  27.   
  28.     rIICADD  = 0x10;                    //2440 slave address = [7:1]=0x10;  
  29.     rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)  
  30.     rIICLC = (1<<2)|(1);                  // Filter enable, 5 clocks SDA output delay       added by lj  
  31.       
  32.     Uart_Printf("Write test data into AT24C02\n");  
  33.   
  34.     for(i=0;i<256;i++)  
  35.         Wr24C080(0xa0,(U8)i,i);//写入0~255主设备地址0~255?从设备地址0xa0?  
  36.              
  37.     for(i=0;i<256;i++)//data[]清零  
  38.         data[i] = 0;  
  39.   
  40.     Uart_Printf("Read test data from AT24C02\n");  
  41.       
  42.     for(i=0;i<256;i++)  
  43.         Rd24C080(0xa0,(U8)i,&(data[i])); //从同一个地址读入256个字节  
  44.   
  45.         //Line changed 0 ~ f  
  46.     for(i=0;i<16;i++)  
  47.     {  
  48.         for(j=0;j<16;j++)  
  49.             Uart_Printf("%2x ",data[i*16+j]);  
  50.         Uart_Printf("\n");//每16字节换一行  
  51.     }  
  52.     rINTMSK |= BIT_IIC; //iic操作结束,禁止iic中断     
  53.     rGPEUP  = save_PE;  //恢复现场  
  54.     rGPECON = save_E;  
  55. }  
  56.   
  57.   
  58. //*************************[ Wr24C080 ]****************************  
  59. void Wr24C080(U32 slvAddr,U32 addr,U8 data)  
  60. {  
  61.     _iicMode      = WRDATA;//写数据模式  
  62.     _iicPt        = 0;  
  63.     _iicData[0]   = (U8)addr;  
  64.     _iicData[1]   = data;  
  65.     _iicDataCount = 2;//中断里写两个数据(地址)  
  66.       
  67.     rIICDS   = slvAddr;                 //slvAddr=0xa0  
  68.     rIICSTAT = 0xf0;                    //11MasTx,1Start,1enable rx/tx(使能中断)首先发送从设备地址,在中断函数里发送数据  
  69.       //Clearing the pending bit isn't needed because the pending bit has been cleared.  
  70.       
  71.     while(_iicDataCount!=-1);//等待主发送模式停止,在中断函数里进行的  
  72.   
  73.     _iicMode = POLLACK;//MasTx condition  has Stoped,等待ACK应答模式,有应答表示从设备已经收到  
  74.   
  75.     while(1)  
  76.     {  
  77.         rIICDS     = slvAddr;           //slvAddr=0xa0  
  78.         _iicStatus = 0x100;             //IICSTAT clear?  
  79.         rIICSTAT   = 0xf0;              //MasTx,Start  
  80.         rIICCON    = 0xaf;              //Resumes IIC operation.   
  81.              
  82.         while(_iicStatus==0x100);       //Wait until IICSTAT change   
  83.              
  84.         if(!(_iicStatus&0x1))  
  85.             break;                      //When ACK is received  
  86.     }  
  87.     rIICSTAT = 0xd0;                    //1101_,11~MasRx,0~stop,1~RxTx enable //Stop MasTx condition   
  88.     rIICCON  = 0xaf;                    //Resumes IIC operation.   
  89.     Delay(1);                           //Wait until stop condtion is in effect.  
  90.        //Write is completed.  
  91. }  
  92.           
  93. //**********************[ Rd24C080 ] ***********************************  
  94. void Rd24C080(U32 slvAddr,U32 addr,U8 *data)  
  95. {  
  96.     _iicMode      = SETRDADDR;//写地址模式  
  97.     _iicPt        = 0;  
  98.     _iicData[0]   = (U8)addr;  
  99.     _iicDataCount = 1;//写一个数据(地址)  
  100.   
  101.     rIICDS   = slvAddr;                 //slvAddr=0xa0首先写入从设备地址  
  102.     rIICSTAT = 0xf0;                    //MasTx,Start发送从设备地址    
  103.       //Clearing the pending bit isn't needed because the pending bit has been cleared.  
  104.     while(_iicDataCount!=-1);//等待主发送模式停止,在中断函数里进行的  
  105.   
  106.     _iicMode      = RDDATA;//读数据模式  
  107.     _iicPt        = 0;  
  108.     _iicDataCount = 1;//读一个数据(地址)  
  109.       
  110.     rIICDS        = slvAddr;            //slvAddr=0xa0    
  111.     rIICSTAT      = 0xb0;               //1011,10~MasRx,1~Start,1~RxTx enable  
  112.     rIICCON       = 0xaf;               //Resumes IIC operation.     
  113.     while(_iicDataCount!=-1);//等待主接收模式停止,在中断函数里进行的  
  114.   
  115.     *data = _iicData[1];//iic发送过来的数据将被放入_iicData[1]中,然后被传递到data[]数组中  
  116. }  
  117.   
  118.   
  119. //-------------------------------------------------------------------------  
  120. void __irq IicInt(void)         //iic中断函数  
  121. {  
  122.     U32 iicSt,i;  
  123.       
  124.     rSRCPND = BIT_IIC;          //Clear pending bit  
  125.     rINTPND = BIT_IIC;          //Clear pending bit  
  126.     iicSt   = rIICSTAT;         //读取状态寄存器的值  
  127.       
  128.     if(iicSt & 0x8){}           //When bus arbitration is failed.  
  129.     if(iicSt & 0x4){}           //When a slave address is matched with IICADD  
  130.     if(iicSt & 0x2){}           //When a slave address is 0000000b  
  131.     if(iicSt & 0x1){}           //When ACK isn't received用户自己添加?  
  132.   
  133.     switch(_iicMode)            //根据不同的模式作出相应的动作  
  134.     {  
  135.        case POLLACK:  
  136.            _iicStatus = iicSt;//等待  
  137.            break;  
  138.   
  139.        case RDDATA:  
  140.            if((_iicDataCount--)==0)  
  141.            {  
  142.                _iicData[_iicPt++] = rIICDS;  
  143.               
  144.                rIICSTAT = 0x90;                 //1001Stop MasRx condition   
  145.                rIICCON  = 0xaf;                 //Resumes IIC operation.  
  146.                Delay(1);                        //Wait until stop condtion is in effect.  
  147.                                                 //Too long time...   
  148.                                                 //The pending bit will not be set after issuing stop condition.  
  149.                break;                           //在停止状态下,中断挂起位将不会被置位  
  150.            }        
  151.            _iicData[_iicPt++] = rIICDS;         //将rIICDS中的数据,即接收到的数据存入_iicData[1];The last data has to be read with no ack.  
  152.   
  153.            if((_iicDataCount)==0)  
  154.                rIICCON = 0x2f;                  //Resumes IIC operation with NOACK.    
  155.            else   
  156.                rIICCON = 0xaf;                  //Resumes IIC operation with ACK  
  157.                break;  
  158.   
  159.         case WRDATA:  
  160.             if((_iicDataCount--)==0)            //_iicDataCount=2,当第三次进入中断时进入此{},停止主发送模式  
  161.             {  
  162.                 rIICSTAT = 0xd0;                //1101Stop MasTx condition   
  163.                 rIICCON  = 0xaf;                //Resumes IIC operation.  
  164.                 Delay(1);                       //Wait until stop condtion is in effect.  
  165.                                                 //The pending bit will not be set after issuing stop condition.  
  166.                                                 //在停止状态下,中断挂起位将不会被置位  
  167.                 break;      
  168.             }  
  169.             rIICDS = _iicData[_iicPt++];        //_iicData[0] has dummy.可以发送两个数据,第一个发送的是_iicData[0]=addr即主设备地址,  
  170.                                                 //第二个发送的是_iicData[1]=data即要发送的数据,  
  171.             for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL等待时钟上升沿  
  172.                 
  173.             rIICCON = 0xaf;                     //resumes IIC operation.  
  174.             break;  
  175.   
  176.         case SETRDADDR:  
  177. //          Uart_Printf("[ S%d ]",_iicDataCount);  
  178.             if((_iicDataCount--)==0)  
  179.                 break;                          //IIC operation is stopped because of IICCON[4]      
  180.             rIICDS = _iicData[_iicPt++];        //只发送一个数据_iicData[0]=addr,即主设备地址  
  181.             for(i=0;i<10;i++);                  //For setup time until rising edge of IICSCL等待时钟上升沿  
  182.             rIICCON = 0xaf;                     //Resumes IIC operation.重复iic操作  
  183.             break;  
  184.   
  185.         default:  
  186.             break;        
  187.     }  
  188. }  

效果图:


完整工程文件可在这里下载。