×
单片机 > 单片机程序设计 > 详情

S3C2440 IIC总线接口

发布时间:2020-08-27 发布时间:
|
    s3c2440内部有一个IIC总线接口,因此为我们连接带有IIC通信模块的外围设备提供了便利。它具有四种操作模式:主设备发送模式、主设备接收模式、从设备发送模式和从设备接收模式。
     在这里只把s3c2440当做IIC总线的主设备来使用,因此只介绍前两种操作模式。在主设备发送模式下,它的工作流程为:首先配置IIC模式,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xF0写入控制状态寄存器IICSTAT中,这时等待从设备发送应答信号,如果想要继续发送数据,那么在接收到应答信号后,再把待发送的数据写入寄存器IICDS中,清除中断标志后,再次等待应答信号;如果不想再发送数据了,那么把0x90写入寄存器IICSTAT中,清除中断标志并等待停止条件后,即完成了一次主设备的发送。在主设备接收模式下,它的工作流程为:首先配置IIC模式,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xB0写入控制状态寄存器IICSTAT中,这时等待从设备发送应答信号,如果想要接收数据,那么在应答信号后,读取寄存器IICDS,清除中断标志;如果不想接收数据了,那么就向寄存器IICSTAT写入0x90,清除中断标志并等待停止条件后,即完成了一次主设备的接收。在完成上述两个模式时,主要用到了控制寄存器IICCON、控制状态寄存器IICSTAT和发送接收数据移位寄存器IICDS。由于我们只把s3c2440当做主设备来用,并且系统的IIC总线上只有这么一个主设备,因此用来设置从设备地址的地址寄存器IICADD,和用于仲裁总线的多主设备线路控制寄存器IICLC都无需配置。寄存器IICCON的第6位和低4位用于设置IIC的时钟频率,因为IIC的时钟线SCL都是由主设备提供的。s3c2440的IIC时钟源为PCLK,当系统的PCLK为50MHz,而从设备最高需要100kHz时,可以将IICCON的第6位置1,IICCON的低4位全为0即可。寄存器IICCON的第7位用于设置是否发出应答信号,第5位用于是否使能发送和接收中断,第4位用于中断的标志,当接收或发送数据后一定要对该位进行清零,以清除中断标志。寄存器IICSTAT的高2位用于设置是哪种操作模式,当向第5位写0或写1时,则表示结束IIC或开始IIC通讯,第4位用于是否使能接收/发送数据。
上面的一段是摘取网上某人的,写的很好。
AT24C02A(时序图详细见数据手册)
写操作有两种模式:字节写和页写。
在字节写模式下,主器件发送起始命令和从器件地址信息(R/W位置零)给从器件。在从器件产生应答信号后,主器件发送AT24C02的字节地址,主器件在收到从器件的另一个应答信号后,再发送数据到被寻址的存储单元。AT24C02再次应答并在主器件产生停止信号后开始内部数据的擦写,在内部擦写过程中,AT24C02不再应答主器件的任何请求。
页写操作的启动字节,地址字节和第一个数据字节都跟字节写的方式一样,不同在于传送了一字节数据后并不产生停止信号。主器件被允许发送8个字节,每发送一个字节数据后AT24C02产生一个应答位并将字节地址低位加1,高位保持不变。如果在发送停止信号之前主器件发送超过8个字节,地址计数器将自动翻转,先前写入的数据将被覆盖。只要接收到主器件发送的停止信号,AT24C02启动内部写周期,将数据在一个写周期内写到数据区
读操作有三种模式:立即地址读、选择性读和连续读。
立即地址读
   AT24C02包含一个地址计数器,内容为最后操作字节的地址加1。因此,如果上次读或写的操作地址为N,则立即读的地址从地址N+1开始。AT24C02接收到器件地址信号和R/W位置1后,它首先发送一个应答信号,然后发送一个8位字节数据。主器件不需发送一个应答信号,但要产生一个停止信号,这时AT24C02停止传输。
选择性读
选择性读操作允许主器件对寄存器的任意字节进行读操作。为进行这种操作,首先应该设定字节地址。主器件向AT24C02发送起始信号和从器件地址,从器件响应之后发送主器件想读取的字节数据的地址。AT24C02应答之后,主器件重新发送起始信号和从器件地址,此时R/W位才置1。AT24C02响应并发送应答信号,然后输出所要求的一个8位字节数据,主器件不发送应答信号但产生一个停止信号,此时AT24C02停止传输。
连续读
连续读操作的启动跟选择性读操作一样,除了在AT24C02发送完一个8位字节数据后,主器件产生一个应答信号而不是停止信号,这个应答信号告知AT24C02要求更多的数据。对应每个应答信号,AT24C02将发送下一个地址的8位数据字节。为提供连续读操作,AT24C02内部地址计数器在每次读操作完成之后递增。这样整个寄存器区域在可在一个读操作内全部读出。
贴出一个三星官方IIC测试程序,使用的是中断查询发式
 
  1. #include   
  2. #include "2440addr.h"  
  3. #include "2440lib.h"  
  4. #include "def.h"  
  5.   
  6. #define WRDATA      (1)  
  7. #define POLLACK     (2)  
  8. #define RDDATA      (3)  
  9. #define SETRDADDR   (4)  
  10.   
  11. #define IICBUFSIZE 0x20  
  12. static U8 iicData[IICBUFSIZE];  
  13. static volatile int iicDataCount;  
  14. static volatile int iicStatus;  
  15. static volatile int iicMode;  
  16. static int iicPt;  
  17.      
  18. void Wr24C02(U32 slvAddr,U32 addr,U8 data);     
  19. void Rd24C02(U32 slvAddr,U32 addr,U8 *data);    
  20.   
  21. void IicPoll(void);  
  22. void Run_IicPoll(void);  
  23.   
  24.   
  25. void Main(void)  
  26. {  
  27.     unsigned int i,j;  
  28.     static U8 data[256];    //用于存储AT24C02读出的数据  
  29.       
  30.     SelectFclk(2);  //设置系统时钟 400M       
  31.     ChangeClockDivider(2, 1);      //设置分频 1:4:8  
  32.     CalcBusClk();           //计算总线频率  
  33.       
  34.     rGPHCON &=~((3<<4)|(3<<6));     
  35.     rGPHCON |=(2<<4)|(2<<6);    //GPH2--TXD[0];GPH3--RXD[0]     
  36.         
  37.     rGPHUP=0x00;        //使能上拉功能  
  38.           
  39.     Uart_Init(0,115200);  
  40.     Uart_Select(0);  
  41.       
  42.     Uart_Printf("[ IIC Test(Polling) using AT24C020 ]\n");  
  43.   
  44.     rGPEUP  |= 0xc000;                 //关上拉  
  45.       
  46.     rGPECON &= ~0xf0000000;  
  47.     rGPECON |= 0xa0000000;       //GPE15:IICSDA , GPE14:IICSCL      
  48.   
  49.     //使能应答, IIC总线时钟IICCLK=PCLK/16, 使能中断, 发送时钟IICCLK/16  
  50.     rIICCON  = (1<<7) | (0<<6) | (1<<5) | (0xf);  
  51.   
  52.     rIICADD  = 0x10;            //2440 从机地址 = [7:1]  
  53.     rIICSTAT = 0x10;            //IIC总线数据输出使能(Rx/Tx)  
  54.       
  55.     Uart_Printf("Write test data into AT24C02\n");  
  56.   
  57.     for(i=0;i<256;i++)  
  58.         Wr24C02(0xa0,(U8)i,i);//写入数据到AT24C02  
  59.           
  60.     for(i=0;i<256;i++)   //数组数据清零  
  61.         data[i] = 0;  
  62.   
  63.     Uart_Printf("Read test data from AT24C02\n");  
  64.     for(i=0;i<256;i++)  
  65.         Rd24C02(0xa0,(U8)i,&(data[i]));//读取AT24C02的数据放入data数组中  
  66.   
  67.     for(i=0;i<16;i++)  
  68.     {  
  69.         for(j=0;j<16;j++)  
  70.             Uart_Printf("%2x ",data[i*16+j]); //打印从AT24C02读出的数据  
  71.         Uart_Printf("\n");  
  72.     }     
  73. }  
  74.   
  75. void Wr24C02(U32 slvAddr,U32 addr,U8 data) // slvAddr 为从地址  
  76. {                                          //addr为字节地址,data为写入的数据  
  77.     iicMode      = WRDATA;  //写数据模式   
  78.     iicPt        = 0;  
  79.     iicData[0]   = (U8)addr;  
  80.     iicData[1]   = data;  
  81.     iicDataCount = 2; //根据AT24C02字节写的发式,要写从地址和字节地址  
  82.       
  83.     rIICDS = slvAddr;    //把0xa0地址写入到数据移位寄存器IICDS  
  84.     //Master Tx mode, Start(Write), IIC-bus data output enable  
  85.     //Bus arbitration sucessful, Address as slave status flag Cleared,  
  86.     //Address zero status flag cleared, Last received bit is 0  
  87.     rIICSTAT      = 0xf0; //       
  88.     //Clearing the pending bit isn't needed because the pending bit has been cleared.  
  89.     while(iicDataCount!=-1)  
  90.         Run_IicPoll();  
  91.   
  92.     iicMode = POLLACK;  
  93.   
  94.     while(1)  
  95.     {  
  96.         rIICDS     = slvAddr;  
  97.         iicStatus = 0x100;             //To check if _iicStatus is changed   
  98.         rIICSTAT   = 0xf0;              //Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0  
  99.         rIICCON    = 0xaf;              //Resumes IIC operation.   
  100.         while(iicStatus==0x100)    
  101.             Run_IicPoll();  
  102.                 
  103.         if(!(iicStatus & 0x1))  
  104.             break;                      //When ACK is received  
  105.     }  
  106.     rIICSTAT = 0xd0;                    //Master Tx condition, Stop(Write), Output Enable  
  107.     rIICCON  = 0xaf;                    //Resumes IIC operation.   
  108.     Delay(1);                           //Wait until stop condtion is in effect.  
  109.     //Write is completed.  
  110. }  
  111.           
  112. //************************[ _Rd24C02 ]********************************  
  113. void Rd24C02(U32 slvAddr,U32 addr,U8 *data)  
  114. {  
  115.     iicMode      = SETRDADDR; //设置要从从机读取数据的从地址  
  116.     iicPt        = 0;  
  117.     iicData[0]   = (U8)addr;  
  118.     iicDataCount = 1;       //写从地址  
  119.   
  120.     rIICDS   = slvAddr;  
  121.     rIICSTAT = 0xf0;                    //MasTx,Start    
  122.     //Clearing the pending bit isn't needed because the pending bit has been cleared.  
  123.     while(iicDataCount!=-1)  
  124.         Run_IicPoll();  
  125.   
  126.     iicMode      = RDDATA;  //读数据模式  
  127.     iicPt        = 0;  
  128.     iicDataCount = 1;   //  
  129.       
  130.     rIICDS   = slvAddr;  
  131.     rIICSTAT = 0xb0;                    //Master Rx,Start  
  132.     rIICCON  = 0xaf;                    //Resumes IIC operation.     
  133.     while(iicDataCount!=-1)  
  134.         Run_IicPoll();  
  135.   
  136.     *data = iicData[1];  
  137. }  
  138.   
  139. void Run_IicPoll(void)  
  140. {  
  141.     if(rIICCON & 0x10)     // Tx/Rx 中断使能  
  142.         IicPoll();  
  143. }         
  144.      
  145. void IicPoll(void)  
  146. {  
  147.     U32 iicSt,i;  
  148.       
  149.     iicSt = rIICSTAT;   //ICC状态寄存器  
  150.     if(iicSt & 0x8){}   //总线仲裁失败    
  151.     if(iicSt & 0x4){}   //从地址与ICCADD地址匹配  
  152.     if(iicSt & 0x2){}   //从地址为00000000b                
  153.     if(iicSt & 0x1){}   //未收到ACK                  
  154.   
  155.     switch(iicMode)  
  156.     {  
  157.         case POLLACK:  
  158.             iicStatus = iicSt;  
  159.             break;  
  160.   
  161.         case RDDATA:    //从从机中读取数据  
  162.             if((iicDataCount--)==0)  
  163.             {  
  164.                 iicData[iicPt++] = rIICDS;  
  165.               
  166.                 rIICSTAT = 0x90;                //Stop MasRx condition   
  167.                 rIICCON  = 0xaf;                //Resumes IIC operation.  
  168.                 Delay(1);                       //Wait until stop condtion is in effect.  
  169.                                                 //Too long time...   
  170.                                                 //The pending bit will not be set after issuing stop condition.  
  171.                 break;      
  172.             }        
  173.             iicData[iicPt++] = rIICDS;  
  174.                             //The last data has to be read with no ack.  
  175.             if((iicDataCount)==0)  
  176.                 rIICCON = 0x2f;                 //Resumes IIC operation with NOACK.    
  177.             else   
  178.                 rIICCON = 0xaf;                 //Resumes IIC operation with ACK  
  179.             break;  
  180.   
  181.         case WRDATA:    //写数据到从机  
  182.             if((iicDataCount--)==0)  
  183.             {  
  184.                 rIICSTAT = 0xd0;                //stop MasTx condition   
  185.                 rIICCON  = 0xaf;                //resumes IIC operation.  
  186.                 Delay(1);                       //wait until stop condtion is in effect.  
  187.                 //The pending bit will not be set after issuing stop condition.  
  188.                 break;      
  189.             }  
  190.             rIICDS = iicData[iicPt++];        //iicData[0] has dummy.  
  191.             for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL  
  192.             rIICCON = 0xaf;                     //resumes IIC operation.  
  193.             break;  
  194.   
  195.         case SETRDADDR: //设置要从从机机读取数据的从机地址  
  196.             if((iicDataCount--)==0)  
  197.             {  
  198.                 break;                  //IIC operation is stopped because of IICCON[4]      
  199.             }  
  200.             rIICDS = iicData[iicPt++];  
  201.             for(i=0;i<10;i++);          //for setup time until rising edge of IICSCL  
  202.             rIICCON = 0xaf;             //resumes IIC operation.  
  203.             break;  
  204.   
  205.         default:  
  206.             break;        
  207.     }  
  208. }  

 

 



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C51 特殊功能寄存器SFR的名称和地址