linux_I2C学习二(裸机)

来源:互联网 发布:ubuntu安装所有依赖包 编辑:程序博客网 时间:2024/06/10 01:40

一、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 0xa1void 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 0
原创粉丝点击