TQ2440 IIC基础

对于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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值