linux_I2C学习二(裸机)

原创 2015年07月09日 14:19:47

一、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]);	
    }	
}

MDK工程 mini2440 裸机程序 IIC i2c

  • 2012年06月20日 00:02
  • 161KB
  • 下载

GEC210(S5PV210)裸机驱动之I2C

主机平台:Linux CentOS 6.5 arm平台:粤嵌GEC210开发板(S5PV210) 这次写一下I2C的使用,I2C部分在S5PV210数据手册上写的很详细,很多问题在里面解决...

mini2440裸机之I2C

// File Name : IIC.c // Function  : S3C2440 IIC-bus Master Tx/Rx mode Test Program //             ...

ok6410裸机实验-i2c实验

实验工具:rvds2.2实验系统:windows 71      硬件特性1.1 概述I2C总线是由Philips公司开发的两线式串行总线,这两根线为时钟线(SCL)和双向数据线(SDA)。由于I2C...

I2C协议->裸机程序->adapter驱动程序分析

开发板:mini2440 内核  :linux2.6.32.2 参考  :韦东山毕业班I2C视频教程 1、i2c协议简要分析     i2c中线是一种由 PHILIPS 公司开发的串行总线,用于连...

S5PV210系列 (裸机十六) 之 I2C通信详解

什么是I2C通信物理接口:SCL + SDA(1)SCL(serial clock):时钟线,传输CLK信号,一般是I2C主设备向从设备提供时钟的通道。(2)SDA(serial data): 数据线...

linux内核I2C子系统学习(二)

下面具体分析如何写第一部分: 主控芯片的i2c驱动分为2个步骤: 写总线驱动: 选了个主控芯片,比如:S3C8900(自己瞎编的芯片) 在driver/i2c/busses/i2c-s3c24...

S3C2440裸机学习[2] - LCD驱动原理及代码分析[二]

下面看看2440test里面的lcd.c文件 static void PutPixel(U32 x,U32 y,U16 c) {     if(x         LCD_BU...

S5PV210使用I2C接口与AT24C08通信的裸机代码分析

S5PV210的I2C控制器有三个主要的寄存器,分别是I2CCON、I2CSTAT、I2CDS,以下为具体的控制位描述: #define I2CCON0 (*(volatile IN...

Linux I2C总线框架 学习笔记

【I2C框架结构】         Linux 内核中的 I2C 框架分为 3 部分,分别是 Core、Bus Driver、DeviceDriver 。其中 Core 部分是框架中的框架,会调用 B...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux_I2C学习二(裸机)
举报原因:
原因补充:

(最多只允许输入30个字)