IIC设计

一.IIC初始化

1.IIC中断初始化

2.SCL时钟设置

3.设置IICSTAT

4.设置引脚功能

5.允许产生应答信号

二.IIC写一个字节

1.设置处理器主设备为发送模式

2.将从设备地址写入到IICDS寄存器

3.写入0xf0到IICSTAT

4.等待ack的产生

5.写入从设备要写入的地址到IICDS寄存器

6.等待ack产生

7.将要传输的数据写入IICDS寄存器

8.等待ack的产生

9.写入0xd0到IICSTAT

10.清除中断

三.IIC写一个字节

1.设置处理器主设备为发送模式

2.将主设备地址写入到IICDS寄存器

3.写入0xf0到IICSTAT

4.等待ack的产生

5.写入从设备要写入的地址到IICDS寄存器

6.等待ack产生

7.设置处理器为接收模式

7.1取出数据

7.2清除中断

7.3等待中断

8.写入0x90到IICSTAT

9清除中断

代码

#define INTPND (*(volatile unsigned long*)0x4a000010)
#define SRCPND (*(volatile unsigned long*)0x4a000000)
#define INTMSK (*(volatile unsigned long*)0x4a000008)
#define GPECON (*(volatile unsigned long*)0x56000040)
#define GPEUP  (*(volatile unsigned long*)0x56000048)

#define IICCON    (*(volatile unsigned char*)0x54000000)
#define IICSTAT   (*(volatile unsigned char*)0x54000004)
#define IICDS     (*(volatile unsigned char*)0x5400000C)

#define SLAVE_WRITE_ADD 0xa0
#define SLAVE_READ_ADD 0xa1


void delay(int i)
{
   int j = 0;
   while (i--)    
   {
       for (j=0;j<100;j++)
       {    
           ;
       }  
   }    
}


void i2c_init()
{
    //1.a 初始化中断
    INTPND |= (1<<27);
    SRCPND |= (1<<27);  
    INTMSK &= ~(1<<27);
     
    IICCON |= (1<<5); 
    
    //1.b 设置scl时钟
    IICCON &= ~(1<<6);
    IICCON &= ~(0xf<<0);
    IICCON |= (0x5<<0);
    
    //2. 设置IICSTAT    
    IICCON |= (1<<4);
    
    //3.设置引脚功能
    GPECON |= (0x2<<28)|(0x2<<30);
    GPEUP |= (0x3<<14);
    
    //4.允许产生ACK
    IICCON |= (1<<7);
}


void write_byte(unsigned char xchar, unsigned char daddr)
{
    
    //1. 设置处理器为主设备+发送模式
    IICSTAT |= (3<<6);
    
    //2. 将从设备的地址写入到IICDS寄存器
    IICDS = SLAVE_WRITE_ADD;
    IICCON &= ~(1<<4);
    
    //3. 写入0xF0写入IICSTAT
    IICSTAT = 0xF0;
    
    //4. 等待ACK的产生
    while ((IICCON & (1<<4)) == 0 )
        delay(100);
    
    //5.1写入字节的地址到IICDS寄存器
    IICDS = daddr;
    IICCON &= ~(1<<4);
    
    //5.2等待ACK的产生
    while ((IICCON & (1<<4)) == 0 )
        delay(100);
    
    //6. 将要传输的字节数据写入IICDS寄存器
    IICDS = xchar;
    IICCON &= ~(1<<4);   
    
    //8. 等待ACk的产生
    while ((IICCON & (1<<4)) == 0 )
        delay(100);
    
    //9. 写入0xD0到IICSTAT
    IICSTAT = 0xD0;
    
    //10. 清除中断    
    IICCON &= ~(1<<4);    
    
    delay(100);
}

void read_data(unsigned char *buf, unsigned char daddr, int length)
{
    int j =0;
    unsigned char unusedata;
    
    //1. 设置为主设备发送模式
    IICSTAT |= (3<<6);
    
    //写入从设备地址
    IICDS = SLAVE_WRITE_ADD;
    IICCON &= ~(1<<4);
    
    //写入0xF0到IICSTAT
    IICSTAT = 0xF0;
    
    //等待ACK
    while ((IICCON & (1<<4)) == 0 )
        delay(100);
    
    //写入eeprom内部地址
    IICDS = daddr;
    IICCON &= ~(1<<4);
    
    //等待ACK
    while ((IICCON & (1<<4)) == 0 )
        delay(100);
            
    
    //设置为主设备接收模式
    IICSTAT &= ~(3<<6);
    IICSTAT |= (2<<6);
    
    
    //2.写入从设备地址到IICDS
    IICDS = SLAVE_READ_ADD;
    IICCON &= ~(1<<4);
    
    
    //3.写入0xB0到IICSTAT开始接收
    IICSTAT = 0xb0;
    while ((IICCON & (1<<4)) == 0 )
        delay(100);
        
    
        /*写入设备内部地址*/
    IICDS = daddr;
    IICCON &= ~(1 << 4);
    while((IICCON & (1 << 4)) == 0)
    {
        delay(100);
    }    
         
    
    //丢掉收到的第1个字节
    unusedata = IICDS;
    IICCON &= ~(1<<4);
    while ((IICCON & (1<<4)) == 0 )
            delay(100);
    
    for(j=0;j<length;j++)
    {
        if(j == (length -1))
        {
           IICCON &= ~(1<<7);         
        }
   
    //5.1 从IICDS里取出数据
        buf[j]=IICDS;
    
    //5.2 清除中断
        IICCON &= ~(1<<4);
    
    //4.等待中断
        while ((IICCON & (1<<4)) == 0 )
            delay(100);
    }
        
        
    //写入0x90到IICSTAT
    IICSTAT = 0x90;
    
 
    // 清除中断
    IICCON &= ~(1<<4);
}

void i2c_test()
{
    int i=0;
    unsigned char sbuf[256]={0};
    unsigned char dbuf[256]={0};    
    
    i2c_init();
    
    for(i=0;i<256;i++)
    {
        sbuf[i] = i+1;
        dbuf[i] = 0;
    }
    
    printf("dbuf befor I2C read:\r\n");
    
    for(i =0; i<256;i++)
    {
       if(i%8==0)
           printf("\r\n");
           
       printf("%d\t",dbuf[i]);    
    }    
    
    for(i=0;i<256;i++)
        write_byte(sbuf[i],i);
        
    printf("i2c reading, plese wait!\n\r");
    
    read_data(dbuf,0,256);
    
    printf("dbuf after I2C read:\r\n");
    
    for(i =0; i<256;i++)
    {
       if(i%8==0)
           printf("\r\n");
           
       printf("%d\t",dbuf[i]);    
    }    
}
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值