S3C2440之IIC裸机驱动

发布者:SereneNature最新更新时间:2024-07-18 来源: cnblogs关键字:S3C2440  IIC  裸机驱动 手机看文章 扫描二维码
随时随地手机看文章

花了两天的时间终于把这个搞定了,其实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 AT24C02n');   
    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 AT24C02n');   
    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 AT24C02n');   
       
     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;   
      


关键字:S3C2440  IIC  裸机驱动 引用地址:S3C2440之IIC裸机驱动

上一篇:Uboot S3C2440 BL1 的流程
下一篇:S3C2440 gpio

推荐阅读最新更新时间:2024-11-09 10:27

s3c2440裸机-异常中断(四. irq之外部中断)
中断前: 中断产生后: 问题案例: 我们想实现一个按键点灯程序,我们知道有以下两种方案: 1.轮询方案:轮询检测按键的电平状态,当检测到被按下后,对应的gpio会拉低,点亮对应的led;(略) 2.中断方案:将按键配置成外部中断源,当有按键按下,触发中断,在中断服务程序(isr)中去完成点灯。 下面开始写代码: 一.中断初始化 1)中断源设置 我们用按键作为外部中断源,我们把按键对应的gpio配置成中断引脚,当按键按下,相应的gpio产生了电平跳变,就会触发外部中断。 我们想达到按下按键灯亮,松开按键灯灭这种效果(配成双边沿触发,按下的时候产生下降沿中断,进行点亮,松开产生上升沿中断,进行熄灭)。当然也可做成按一下
[单片机]
<font color='red'>s3c2440</font><font color='red'>裸机</font>-异常中断(四. irq之外部中断)
GPIO-点亮一个LED(JZ2440-S3C2440)
1、看电气原理图 GPF4--------(GPFCON =01; GPFDAT =1) GPF4引脚输出1(高电平):LED1灯灭。 GPF4引脚输出0(低电平):LED1电亮。 2、如何让引脚输出高/低电平 (1)配置引脚功能(2)输出引脚:写值到某个寄存器;输入引脚:读寄存器的值。 3、看芯片手册 GPIO包括A----J组。 这里要用到GPF组的寄存器: GPFCON寄存器:用来配置引脚的功能; GPFDAT:引脚的值。 GPFCON寄存器的可以设置引脚的功能为:输入、输出、中断和保留功能。 GPFDAT寄存器: 4、编写程序:GPFCON的地址为0x56000050。G
[单片机]
GPIO-点亮一个LED(JZ2440-S3C2440)
s3c2440裸机-spi编程-3-gpio模拟spi驱动OLED
操作OLED,通过三条线(SCK、DO、CS)与OLED相连,这里没有DI是因为2440只会向OLED传数据而不用接收数据。 gpio_spi.c来实现gpio模拟spi,负责spi通讯。对于OLED,有专门的指令和数据格式,要传输的数据内容,在oled.c这一层来实现,负责组织数据。 因此,我们需要实现以上两个文件。 1.SPI初始化 新建一个gpio_spi.c文件,实现SPI初始化SPIInt() 1.1 GPIO init(pinmux管脚等配置) 上图J3为板子pin2pin到OLED的底座。 GPF1作为OLED片选引脚,设置为输出; GPG4作为OLED的数据(Data)/命令(Command)选择引脚,
[单片机]
基于OHCI协议的S3C2440 USB Host Driver之协议介绍(四)
HCCA HCCA是256字节的内存结构,系统软件用来与HC发送或接受特殊控制和状态信息。256字节对齐。HC寄存器中的HcHCCA指向HCCA。 HccaInterruptTable为32个周期表的头指针数组。每帧HC仅访问该表一次。当前帧号的低5位用来索引。 HccaFramNumber HC每帧会更新该16位的值。在新帧,HC发SOF后,HC读一个ED开始处理之前,该值写为HcFmNumber的StartingFrame域。在SOF和更新该值之间,HC不在USB上传输任何数据。 HccaDoneHead周期性地,HC将HcDoneHead的值写到HccaDoneHead中,那么主机软件就可以处理完成的TD了。
[单片机]
基于OHCI协议的<font color='red'>S3C2440</font> USB Host <font color='red'>Driver</font>之协议介绍(四)
linux之I2C裸机驱动解析
1 硬件特性 1.1 概述 I2C总线是由Philips公司开发的两线式串行总线,这两根线为时钟线(SCL)和双向数据线(SDA)。由于I2C总线仅需要两根线,因此在电路板上占用的空间更少,带来的问题是带宽较窄。I2C在标准模式下传输速率最高100Kb/s,在快速模式下最高可达400kb/s。属于半双工。 在嵌入式系统中,I2C应用非常广泛,大多数微控制器中集成了I2C总线,一般用于和RTC,EEPROM,智能电池电路,传感器,LCD以及其他类似设备之间的通信。 1.2 I2C总线传输时序 1.3 I2C总线的信号状态 1、空闲状态:SDA和SCL都是高电平; 2、开始条件(S):
[单片机]
s3c2440 移值u-boot-2016.03 第1篇 新建单板
目前除RC版外,最新的就是 u-boot-2016.03.tar.bz2 ,大概看了几个年份的u-boot 发现,现在 更像是 linux kernel 。有 menuconfig 。 对比2012年的版本,发现 原来在 start.S 中做的一些事情,被拆分了。 board 分的更加详细。 之前没有 J-LINK 根本无法烧写 NOR FLASH ,导致 u-boot 只能在 NAND FLASH 上,但是卡在 重定向这一处。用了点灯大法,串口调试,都不是很理想。 买了个J-LINKV9 ,一试,原来烧写,NOR FLASH 这么简单。 因为 u-boot 自带的 只有 2410 的 单板,而且是不支持 NAND FLASH 的
[单片机]
<font color='red'>s3c2440</font> 移值u-boot-2016.03 第1篇 新建单板
S3C2440——键盘中断服务程序
S3C2440键盘模块电路 一共有S1、S2、S3、S4个按键,分别对应EINT19、EINT2、EINT0、EINT11这四个中断源。中断框架及服务程序如下: 中断响应,取出触发中断的键盘编号(1-4)放到R5中 ;文件ASM_Interrupt.s ;(1)设置中断向量表 Mode_USR EQU 0x50 ;IRQ中断开放,FIQ中断关闭 Mode_FIQ EQU 0xD1 ;关闭IRQ、FIQ中断 Mode_IRQ EQU 0xD2 ;关闭IRQ、FIQ中断 Mode_SVC EQU 0xD3 ;关闭IRQ、FIQ中断 GET 2440Reg_addr.
[单片机]
<font color='red'>S3C2440</font>——键盘中断服务程序
U-Boot补丁 S3C2440
# tar xvf u-boot-1.1.6.tar.bz2 //解压 # cd u-boot-1.1.6/ 制作补丁文件 # diff -urN u-boot-1.1.6 u-boot-1.1.6.new u-boot-1.1.6_jz2440.patch 打补丁 # patch -p1 u-boot-1.1.6_jz2440.patch p1:忽略补丁文件第一个”/”之前的内容(也就是如下:u-boot-1.1.6) # head u-boot-1.1.6_jz2440.patch diff -urN u-boot-1.1.6/board/100ask24x0/100ask24x0.c u-boo
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved