IIC

1.rIICCON &= ~0x10; 清中断必须要在rIICDS = slvAddr; 和rIICSTAT = 0xf0;  // 主设备,启动  之后

2.延时对于写外部的低速设备来说非常重要,比如while(flag)之后一定要加延时,还有在写数据时发现只能写入基数地址的数据,这也是由于延时导致的

3.开始调试的时候系统总是死在read的函数中,后来发现在数据手册的note中说当读取最后一个数据的时候一定不能返回ACK信号,而我却在程序中使用while(flag)来等待ACK引发中断,这不死才怪呢。。。。所以数据手册中的NOTE部分也是特别重要的

4.在真正对AT24C02A进行读取数据时,在发送带有读命令的从设备地址后,AT24C02A会再返回一个从设备地址信息或从设备内存地址信息作为应答,所以一定要把该字节读取后抛弃,因为它不是我们所要读取的信息。

5.下面是核心代码:

  1. #include "def.h"  
  2. #include "2440addr.h"  
  3. #include "I2C.h"  
  4. #include "uart.h"   
  5. extern void Delay(int time);   
  6. int flag;   //用于标识是否收到应答信号,改标识在终端处理程序中被清0   
  7. void Test_Iic(void)   
  8. {   
  9.     unsigned int i,j,save_E,save_PE;   
  10.     static U8 data[256];   
  11.     uart_printf("\nIIC Test(Interrupt) using AT24C02\n");   
  12.     save_E   = rGPECON;   
  13.     save_PE  = rGPEUP;   
  14.     rGPEUP  |= 0xc000;                  //Pull-up disable   
  15.     rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL    
  16.     pISR_IIC = (unsigned)IicInt;   
  17.     rINTMSK &= ~(BIT_IIC);   
  18.       //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16   
  19.       // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz   
  20.     rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);   
  21.     rIICADD  = 0x10;                    //2440 slave address = [7:1]   
  22.     rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)   
  23.     rIICLC = (1<<2)|(1);                  // Filter enable, 15 clocks SDA output delay       added by junon   
  24.        
  25.     uart_printf("Write test data into AT24C02\n");   
  26.     for(i=0;i<256;i++)   
  27.        { Wr24C080(0xa0,(U8)i,i);   
  28.         Delay(1);   //注意这个延时不能少,否则出现有些数据无法写入的问题   
  29.        }       
  30.     for(i=0;i<256;i++)   
  31.         data[0] = 0;   
  32.     uart_printf("Read test data from AT24C02\n");   
  33.        
  34.      for(i=0;i<256;i++)   
  35.          Rd24C080(0xa0,(U8)i,&(data[i]));    
  36.     for(i=0;i<16;i++)   
  37.     {   
  38.         for(j=0;j<16;j++)   
  39.             uart_printf("%2x ",data[i*16+j]);   
  40.         uart_printf("\n");   
  41.     }   
  42.     rINTMSK |= BIT_IIC;       
  43.     rGPEUP  = save_PE;   
  44.     rGPECON = save_E;   
  45. }   
  46. void Wr24C080(U32 slvAddr, U32 addr, U8 data)   
  47. {   
  48.     flag=1;  //应答标志   
  49.     rIICDS = slvAddr;    
  50.     rIICSTAT = 0xf0;  // 主设备,启动   
  51.         rIICCON &= ~0x10;            //清中断标志 ,特别注意这条语句的位置,不能放到上条的前面     
  52.     while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
  53.      Delay(1);   
  54.         
  55.        
  56.      flag =1 ; //readly to translate addr   
  57.      rIICDS = addr;    
  58.      rIICCON &= ~0x10;            //清中断标志   
  59.      while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
  60.      Delay(1);   
  61.         
  62.      flag =1 ; //readly to translate data   
  63.      rIICDS = data;    
  64.      rIICCON &= ~0x10;            //清中断标志   
  65.      while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
  66.      Delay(1);   
  67.         
  68.     rIICSTAT = 0xd0;                    //Stop MasTx condition    
  69.     rIICCON  = 0xaf;                    //Resumes IIC operation.    
  70.     Delay(1);   
  71.        
  72. }   
  73.   
  74. void Rd24C080(U32 slvAddr, U32 addr, U8 *data)   
  75. {   
  76.     unsigned char temp;   
  77.     flag=1;  //应答标志   
  78.     rIICDS = slvAddr;    
  79.     rIICSTAT = 0xf0;  // 主设备发送模式用来发送slvAddr和addr,,启动   
  80.     rIICCON &= ~0x10;            //清中断标志   
  81.     while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
  82.      Delay(1);   
  83.         
  84.     flag =1 ; //readly to translate addr   
  85.      rIICDS = addr;    
  86.      rIICCON &= ~0x10;            //清中断标志   
  87.      while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
  88.      Delay(1);   
  89.            
  90.     flag=1;   
  91.     rIICDS = slvAddr;    
  92.     rIICSTAT = 0xb0;  // 主设备接收模式用来接收数据,启动   
  93.         rIICCON &= ~0x10;            //清中断标志   
  94.     while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
  95.      Delay(1);   
  96.        
  97.     //注意:读取下面这个字节必须进行,因为在发送带有读命令的从设备地址后,   
  98.     //AT24C02A会再返回一个从设备地址信息或从设备内存地址信息作为应答,所以一定要把该字节读取后抛弃,因为它不是我们所要读取的信息;   
  99.     flag =1 ; //readly to translate addr   
  100.     temp = rIICDS;   // 抛弃第一自己   
  101.     rIICCON &= ~0x10;            //清中断标志   
  102.     while(flag)   
  103.      Delay(1);   
  104.         
  105.     rIICCON = 0x2f;                  //Resumes IIC operation with NOACK.    
  106.     *data = rIICDS;    
  107.     Delay(1);   
  108.      rIICSTAT = 0x90;                    //Stop MasTx condition    
  109.      rIICCON  = 0xaf;                    //Resumes IIC operation.   
  110.            
  111.      Delay(1);   
  112.        
  113. }   
  114.   
  115. //-------------------------------------------------------------------------   
  116. void __irq IicInt(void)   
  117. {   
  118.     
  119.     rSRCPND = BIT_IIC;          //Clear pending bit   
  120.     rINTPND = BIT_IIC;   
  121.     flag = 0;   
  122.       
  123. }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值