S3C2440-IIC

哈尔滨理工大学软件工程专业08-7李万鹏原创作品,转载请标明出处

http://blog.csdn.net/woshixingaaa/archive/2011/01/19/6151797.aspx

IICInter-Integrated CircuitI2C)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微处理器及其外围设备,它的最主要优点是简单和有效。它只需要数据线SDA和时钟线SCL,就能够实现CPU与被控IC之间、ICIC之间进行双向传送。

下边是我的实验程序,具体IIC时序可以参考datasheet。

#include "2440addr.h" #define U32 unsigned int unsigned char iic_buffer[8]; U32 length; unsigned char add, word; int cmd, flag, count, command; void delay(int a) { int k; for(k=0;k<a;k++) ; } void __irq UART0_ISR(void){ char ch; rSRCPND |= (0x1<<28); rINTPND |= (0x1<<28); rSUBSRCPND |= 0x1<<0; if(rUTRSTAT0 & 0x1){ ch = rURXH0; while(!(rUTRSTAT0&0x4)); rUTXH0 = ch; if(count == 0) command = ch; if(command == 0xa1){ if(count == 1){ add = ch; } else if(count == 2){ word = ch; } else if(count == 3){ length = ch; } else if(count >= 4) { iic_buffer[count-4] = ch; if(count == length+3){ count = -1; cmd = 0x01; } } count++; } else if(command == 0xa2) { if(count == 1) add = ch; else if(count == 2) word = ch; else if(count == 3){ length = ch; count = -1; cmd = 0x02; } count++; } } } void __irq IIC_ISR(void){ rSRCPND |= 0x1<<27; rINTPND |= 0x1<<27; flag = 0; } void wrat24c02(unsigned char add,unsigned char word, U32 length){ int i; flag = 1; rIICDS = 0xa0; //dev add rIICCON &= ~(0x1<<4); //清中断 rIICSTAT = 0xf0; //主发送模式,写开始信号输出,IIC Rx/Tx使能 //等待ACK,接收器在接受到8位数据后,在第9个时钟周期,拉低SDA电平,然后会产生中断 while(flag == 1) delay(100); flag = 1; rIICDS = word; //word add 发送要写入的数据的内存其实地址 rIICCON &= ~(0x1<<4); while(flag) delay(100); //注意要有delay for(i = 0; i < length; i++){ flag = 1; rIICDS = iic_buffer[i]; rIICCON &= ~(0x1<<4); while(flag) delay(100); } rIICCON = 0xe0; //IIC应答有效,IICCLK=fpclk/512,IIC接受发送中断使能位 rIICSTAT = 0xd0; //主发送模式,rIICCON和rIICSTAT配置好,方便下次使用 } void rdat24c02(unsigned char add, unsigned char word, U32 length){ int i; char temp; flag = 1; rIICDS = add; //dev add rIICCON &= ~(0x1<<4); rIICSTAT = 0xf0; while(flag) delay(100); flag = 1; rIICDS = word; //word add rIICCON &= ~(0x1<<4); while(flag) delay(100); flag = 1; //这里的IIC的随机读操作,根据IIC的随机读时序,先发启动,要读取的设备地址和写的内存地址,方向是写,即0,重启IIC, //发要读取的设备地址,这次方向是读,然后接到ACK,从机向主机发data,主机相应ACK,直到最后一个data,主机不相应ACK, //发送停止信号 rIICDS = add; //dev add rIICSTAT = 0xb0; //改变方向为主接收 rIICCON &= ~(0x1<<4); while(flag) delay(100); flag = 1; temp = rIICDS; rIICCON &= ~(0x1<<4); while(flag) delay(100); for(i = 0; i < length; i++){ flag = 1; if(i == (length - 1)){ rIICCON &= ~(0x1<<7); } iic_buffer[i] = rIICDS; rIICCON &= ~(0x1<<4); while(flag) delay(100); } rIICCON = 0xd0; rIICSTAT = 0x90; delay(200); } int Main(){ int i; count= 0; length = 0; cmd = 0; command = 0; rGPECON = 0xa0000000; //GPE15~14 IICSDA,IICSCL rGPEUP = 0xc000; rIICCON = 0xe0; //IIC应答有效,IICCLK=fpclk/512,IIC接受发送中断使能位 rIICSTAT = 0x10; //IIC总线有效Rx/Tx rULCON0 = 0x3; rUCON0 = (1<<11)|(1<<2)|(1<<0); rUBRDIV0 = 26; rSRCPND = (0x1<<28)|(0x1<<27); rINTPND = (0x1<<28)|(0x1<<27); rSUBSRCPND = 0x1<<0; rINTMSK &= ~((0x1<<28)|(0x1<<27)); rINTSUBMSK &= ~(0x1<<0); pISR_UART0 = (U32)UART0_ISR; pISR_IIC = (U32)IIC_ISR; for(i = 0; i < 8; i++){ iic_buffer[i] = 0xee; } while(1){ switch(cmd){ case 0x01: cmd = 0; wrat24c02(add, word, length); break; case 0x02: cmd = 0; rdat24c02(add, word, length); for(i = 0; i < 8; i++){ while(!(rUTRSTAT0&0x4)); rUTXH0 = iic_buffer[i]; } break; } } return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值