TQ2440 IIC基础

来源:互联网 发布:mac 杀毒 编辑:程序博客网 时间:2024/04/30 14:47

对于S3C2440 IIC的主发送/接收模式来说,主要涉及三个寄存器 IICCON,IICSTAT,IICDS。



从上图可以看出,IIC的时钟来源是 PCLK,数据从SDA线移入然后保存在IICDS寄存器中。


在S3C2440中,当数据发送完或者接收完数据后会产生中断。


IIC 主发送模式流程图:



IIC 主接收模式流程图:





在文档中的比较需要注意的是,对于EEProm来说,读取数据时最后一个一定不要发送ACK


此程序是参照赵春江的程序来写的,他的博客:

赵春江博客

示例代码:

#ifndef IIC_H#define IIC_H#include "2440addr.h"#include "config.h"void IIC_Init(void);void wr2402(unsigned char devAddr,unsigned char addr,unsigned char *data, int len);void rd2402(unsigned char devAddr,unsigned char addr,unsigned char *data, int len);__irq void IIC_ISR(void);void delay(int time);#endif

#include "IIC.h"void IIC_Init(void){/*将IO口配置为SDA和SCL*/rGPECON &= ~(0xf<<28);rGPECON |= (2<<28) | (2<<30);/*禁止上拉*/rGPEUP |= (1<<14) | (1<<13);/*使能应答信号,设置IIC时钟为fPCLK的512分频,使能中断*/rIICCON = (1<<7) | (1<<6) | (1<<5);pISR_IIC = (unsigned int)IIC_ISR;/*使能串行输出*/rIICSTAT |= (1<<4);/*使能中断*/rINTMSK &= ~(1<<27);rSRCPND = (1<<27);rINTPND = (1<<27);}volatile int flag;void wr2402(unsigned char devAddr,unsigned char addr, unsigned char *data, int len){int i;/*发送从设备地址(寻址)*/flag = 1;rIICDS = devAddr;rIICCON &= ~(1<<4);//清除中断,注意,这句话要放在写IICDS后面rIICSTAT = 0xf0;//设置为主发送模式while(flag==1)//等待从设备应答delay(100);/*发送所写的内存地址*/flag = 1;rIICDS = addr;rIICCON &= ~(1<<4);while(flag == 1)delay(100);/*发送所需要写入的数据*/for(i=0; i<len; i++){flag = 1;rIICDS = data[i];rIICCON &= ~(1<<4);while(flag == 1)delay(100);}/*发送停止信号*/rIICSTAT = 0xd0;/*恢复操作*/rIICCON = 0xe0;delay(100);}void rd2402(unsigned char devAddr,unsigned char addr,unsigned char *data, int len){int i;/*发送从设备地址*/flag = 1;rIICDS = devAddr;rIICCON &= ~(1<<4);rIICSTAT = 0xf0;while(flag == 1)delay(100);/*发送所需要读的内存地址*/flag = 1;rIICDS = addr;rIICCON &= ~(1<<4);while(flag == 1)delay(100);/*设置主设备接收模式*/flag = 1;rIICDS = devAddr;rIICCON &= ~(1<<4);rIICSTAT = 0xB0;while(flag == 1)delay(100);/*读取的是设备地址*/flag = 1;i = rIICDS;rIICCON &= ~(1<<4);while(flag==1)delay(100);/*读数据*/for(i=0; i<len; i++){flag = 1;/*最后一个数据不发送ACK*/if (i==len-1){rIICCON &= ~(1<<7);}data[i] = rIICDS;rIICCON &= ~(1<<4);while(flag==1)delay(100);}rIICSTAT = 0x90; rIICCON = 0xe0; delay(100);}__irq void IIC_ISR(void){flag = 0;rSRCPND = (1<<27);rINTPND = (1<<27);}void delay(int time){int i,j;for(i=0; i<time;i++)for(j=0;j<1000;j++);}


#include "2440addr.h"#include "config.h"#include "IIC.h"unsigned char data[16];void Main(void){int i;IIC_Init();for(i=0; i<16; i++)data[i] = i;wr2402(0xa0,0,data,8);wr2402(0xa0,8,data+8,8);//这里使用的是AT24C02,每页只有8B,所以每次最多只能写8B,多了会回滚for(i=0; i<16; i++)data[i] = 0;rd2402(0xa0,0,data,16);//读可以不受页大小的影响while(1);}


0 0
原创粉丝点击