花了两天的时间终于把这个搞定了,其实I2C的原理还是比较简单的,只是几个细节性的东西还是需要特别的注意,主要是需要注意一下几点:
1.rIICCON &= ~0x10; 清中断必须要在rIICDS = slvAddr; 和rIICSTAT = 0xf0;  // 主设备,启动  之后

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

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

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

5.下面是核心代码:

#include "def.h"  
#include "2440addr.h"  
#include "I2C.h"  
#include "uart.h"   
extern void Delay(int time);   
int flag;   //用于标识是否收到应答信号,改标识在终端处理程序中被清0   
void Test_Iic(void)   
{   
    unsigned int i,j,save_E,save_PE;   
    static U8 data[256];   
    uart_printf("\nIIC Test(Interrupt) using AT24C02\n");   
    save_E   = rGPECON;   
    save_PE  = rGPEUP;   
    rGPEUP  |= 0xc000;                  //Pull-up disable   
    rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL    
    pISR_IIC = (unsigned)IicInt;   
    rINTMSK &= ~(BIT_IIC);   
      //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16   
      // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz   
    rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);   
    rIICADD  = 0x10;                    //2440 slave address = [7:1]   
    rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)   
    rIICLC = (1<<2)|(1);                  // Filter enable, 15 clocks SDA output delay       added by junon   
       
    uart_printf("Write test data into AT24C02\n");   
    for(i=0;i<256;i++)   
       { Wr24C080(0xa0,(U8)i,i);   
        Delay(1);   //注意这个延时不能少,否则出现有些数据无法写入的问题   
       }       
    for(i=0;i<256;i++)   
        data[0] = 0;   
    uart_printf("Read test data from AT24C02\n");   
       
     for(i=0;i<256;i++)   
         Rd24C080(0xa0,(U8)i,&(data[i]));    
    for(i=0;i<16;i++)   
    {   
        for(j=0;j<16;j++)   
            uart_printf("%2x ",data[i*16+j]);   
        uart_printf("\n");   
    }   
    rINTMSK |= BIT_IIC;       
    rGPEUP  = save_PE;   
    rGPECON = save_E;   
}   
void Wr24C080(U32 slvAddr, U32 addr, U8 data)   
{   
    flag=1;  //应答标志   
    rIICDS = slvAddr;    
    rIICSTAT = 0xf0;  // 主设备,启动   
        rIICCON &= ~0x10;            //清中断标志 ,特别注意这条语句的位置,不能放到上条的前面     
    while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
     Delay(1);   
        
       
     flag =1 ; //readly to translate addr   
     rIICDS = addr;    
     rIICCON &= ~0x10;            //清中断标志   
     while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
     Delay(1);   
        
     flag =1 ; //readly to translate data   
     rIICDS = data;    
     rIICCON &= ~0x10;            //清中断标志   
     while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
     Delay(1);   
        
    rIICSTAT = 0xd0;                    //Stop MasTx condition    
    rIICCON  = 0xaf;                    //Resumes IIC operation.    
    Delay(1);   
       
}   
  
void Rd24C080(U32 slvAddr, U32 addr, U8 *data)   
{   
    unsigned char temp;   
    flag=1;  //应答标志   
    rIICDS = slvAddr;    
    rIICSTAT = 0xf0;  // 主设备发送模式用来发送slvAddr和addr,,启动   
    rIICCON &= ~0x10;            //清中断标志   
    while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
     Delay(1);   
        
    flag =1 ; //readly to translate addr   
     rIICDS = addr;    
     rIICCON &= ~0x10;            //清中断标志   
     while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
     Delay(1);   
           
    flag=1;   
    rIICDS = slvAddr;    
    rIICSTAT = 0xb0;  // 主设备接收模式用来接收数据,启动   
        rIICCON &= ~0x10;            //清中断标志   
    while(flag == 1)   //当发送从地址完成之后会收到ACK信号,在中断处理函数中将该标志置为0   
     Delay(1);   
       
    //注意:读取下面这个字节必须进行,因为在发送带有读命令的从设备地址后,   
    //AT24C02A会再返回一个从设备地址信息或从设备内存地址信息作为应答,所以一定要把该字节读取后抛弃,因为它不是我们所要读取的信息;   
    flag =1 ; //readly to translate addr   
    temp = rIICDS;   // 抛弃第一自己   
    rIICCON &= ~0x10;            //清中断标志   
    while(flag)   
     Delay(1);   
        
    rIICCON = 0x2f;                  //Resumes IIC operation with NOACK.    
    *data = rIICDS;    
    Delay(1);   
     rIICSTAT = 0x90;                    //Stop MasTx condition    
     rIICCON  = 0xaf;                    //Resumes IIC operation.   
           
     Delay(1);   
       
}   
  
//-------------------------------------------------------------------------   
void __irq IicInt(void)   
{   
    
    rSRCPND = BIT_IIC;          //Clear pending bit   
    rINTPND = BIT_IIC;   
    flag = 0;   
      
}

原文链接:http://www.linuxidc.com/Linux/2011-06/37583p4.htm

S3C2440之IIC裸机驱动的更多相关文章

  1. Exynos4412 IIC总线驱动开发(一)—— IIC 基础概念及驱动架构分析

    关于Exynos4412 IIC 裸机开发请看 :Exynos4412 裸机开发 —— IIC总线 ,下面回顾下 IIC 基础概念 一.IIC 基础概念 IIC(Inter-Integrated Ci ...

  2. JZ2440 裸机驱动 第12章 I2C接口

    本章目标: 了解I2C总线协议: 掌握S3C2410/S3C2440中I2C接口的使用方法: 12.1 I2C总线协议及硬件介绍 12.1.1 I2C总线协议 1 I2C总线的概念 2 I2C总线的信 ...

  3. Tiny6410之按键裸机驱动

    操作步骤: 第一步:查看开发板电路原理图 找到LED 和按键的管脚所对应的寄存器 LED:(见Tiny6410之LED裸机驱动) nLED_1 - GPK4 nLED_2 - GPK5 nLED_3 ...

  4. 基于S3C2440的嵌入式Linux驱动——看门狗(watchdog)驱动解读

    本文将介绍看门狗驱动的实现. 目标平台:TQ2440 CPU:s3c2440 内核版本:2.6.30 1. 看门狗概述 看门狗其实就是一个定时器,当该定时器溢出前必须对看门狗进行"喂狗“,如 ...

  5. I2C裸机驱动程序设计

    ① I2C(Inter-Integrated Circuit)总线是由飞利浦公司开发的两线式串行总线,用于连接微控制器及其外围设备 ② I2C总线有两根双向信号线 (1)SDA:Serial Data ...

  6. s3c2440的IIC控制

    在tq2440和mini2440上都连接着EEPROM 它们作用也不过測试I2C总线能否用. 当中在mini2440上EEPROM型号是 AT24C08,在tq2440上这个型号是 AT24C02A. ...

  7. S3C2440—1.熟悉裸机开发板

    文章目录 一.板载资源介绍 二.安装驱动及上位机 1.USB的驱动及上位机 2.eop驱动安装 3.安装烧录软件oflash 三.烧写开发板 1.预备知识 2.烧写裸板 3.使用u-boot烧写程序 ...

  8. S3C2440上RTC时钟驱动开发实例讲解(转载)

    嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 共享资源,欢迎转载:http:/ ...

  9. 基于KEIL4开发ARM9(S3C2440)的裸机程序

    本文主要介绍如何使用Keil4开发ARM9(S3C2440)裸机程序. 说明: 一.平台: 操作系统:Windows XP系统 KEIL版本:4.73 开发板:ARM9(S3C2440) 二.建立工程 ...

随机推荐

  1. [ACM] hdu 1671 Phone List (特里)

    Phone List Problem Description Given a list of phone numbers, determine if it is consistent in the s ...

  2. 关于s2sh框架关于hibernate懒加载问题的说明和解决方案

    首先我们来看下面这个图,解释了一个web程序的一次请求流程! 懒加载异常的说明: 懒加载就是我们在查询一个对象时,它所有的属性是否要被查出来! 如果懒加载开启的话,session在service层就被 ...

  3. 关于Android开发中导出jar包后的资源使用问题解决

    我们经常遇到一个需求,就是给别人使用我们工程的时候,为了能够屏蔽代码,把代码封装成jar包提供给第三方使用,但是这样我们的资源文件怎么给对方用呢? 其实并不用这么的复杂,下面就介绍一下具体的方法 一, ...

  4. 微信应用号开发知识贮备之Webpack实战

    天地会珠海分舵注:随着微信应用号的呼之欲出,相信新一轮的APP变革即将发生.作为行业内人士,我们很应该去拥抱这个趋势.这段时间在忙完工作之余准备储备一下这方面的知识点,以免将来被微信应用号的浪潮所淹没 ...

  5. java ResultSet 结果集处理 createStatement() 里参数的意义(第一弹)

    createStatement(int   resultSetType,int  resultSetConcurrency)参数一:结果集类型可取值:  1.ResultSet.TYPE_FORWOR ...

  6. TML5安全:CORS(跨域资源共享)简介

    来源:http://blog.csdn.net/hfahe/article/details/7730944 前言:像CORS对于现代前端这么重要的技术在国内基本上居然很少有人使用和提及,在百度或者Go ...

  7. node.js + mongodb

    node.js + mongodb 这次内容是结合bootstrap把登陆注册做好,还有就是express的中间件等问题. 看这篇博客之前建议先看我上篇写的那篇博客http://www.cnblogs ...

  8. servlet请求转发与重定向的差别------用生活实例来形象说明两者的差别

    1,请求重定向:client行为,response.sendRedirect(),从本质上讲等同于两次请求,前一次的请求对象不会保留,地址栏的URL地址会改变. 2,请求转发:server行为,req ...

  9. avalonjs 1.3.7发布

    avalonjs 1.3.7发布 又到每个月的15号了,现在avalon已经固定在每个月的15号发布新版本.这次发布又带来许多新特性,让大家写码更加轻松,借助于“操作数据即操作DOM”的核心理念与双向 ...

  10. sql语句 面试题

    ql语句 面试题   自动编号   学号   姓名 课程编号 课程名称 分数 1        2005001  张三  0001      数学    69 2        2005002  李四 ...