linux_I2C学习二(裸机)

一、EEPROM简介:

EEPROM (Electrically Erasable Programmable Read-Only Memory),电可擦可编程只 读存储器,是一种类似于flash的固态存储器, 但是与 flash相比又存在一些区别:
1.EEPROM 可以按位擦写, 而FLASH只能大片 擦除
2.EEPROM 一般容量都不大, 一般都在64Kbit以下

二、I2C初始化:

使用IIC必须要做的工作及步骤
(1)如果此设备作为从机就需要先设置IIC地址,使用IICADD寄存器(作为主机就不需要)
(2)设置IICCON寄存器:
2.2、打开相应中断
2.3、设置SCL时钟
(3)设置IICSTAT寄存器,打开Serial功能
(4)设置相应IO为IIC功能
(5)设置IICCON寄存器运行产生ACK

三、I2C主设备写功能设计


1. 设置处理器为主设备+发送模式
2. 将从设备的地址写入到IICDS寄存器
3. 写入0xF0写入IICSTAT--发送从设备地址到IIC总线上
4. 主机等待ACK的产生,如果产生ACK响应就会产生中断,说明从设备存在
5. 将要传输的字节数据写入IICDS寄存器
6. 清除中断
7. 等待ACk的产生,继续产生中断
写完一个字节后:
8. 主机写入0xD0到IICSTAT
9. 清除中断
完成一次数据的传输

三、I2C主设备读功能设计

1. 设置为主设备接收模式
2. 写入从设备地址到IICDS
3. 写入0XB0到IICSTAT开始接收
循环
{
4. 等待中断
5.1. 从IICDS里取出数据
5.2. 清除中断
}
写入0X90到IICSTAT结束接收
清除中断

24C02:写数据格式:

24C02:读数据格式:

24C02示例代码:
#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]);	
    }	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值