S3c2440 IIC
IIC(Inter-Integrated Circuit,I2C)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微处理器及其外围设备。在iic总线上,只需要两条线:串行数据线SDA和串行时钟线SCL,便可完成通信。如图:
IIC启动和停止信号的定义
s3c2440内部有一个IIC总线接口,通过对其寄存器的配置和时序的操作即可完成IIC通信,其编程流程如下:
一,在主设备发送模式下,它的工作流程为:
1,首先配置IIC模式(包括配置GPE15,GPE14为第二功能 时钟线和数据线,iic中断使能,发送时钟频率等)
- rGPECON |= 0xa00000; //GPE15:IICSDA , GPE14:IICSCL,GPE15,GPE14为第二功能 时钟线和数据线
- pISR_IIC = (unsigned)IicInt;//中断注册
- rINTMSK &= ~(BIT_IIC);//iic中断使能
- rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);//(1<<7)Enable ACK,(0<<6) Prescaler IICCLK=PCLK/16,(1<<5) Enable interrupt,
- // (0xf)Transmit clock value Tx clock=IICCLK/(15+1)
- // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
- rIICADD = 0x10; //2440 slave address = [7:1]=0x10;
- rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
- rIICLC = (1<<2)|(1); // Filter enable, 5 clocks SDA output delay added by lj
2,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xF0写入控制状态寄存器IICSTAT中,这时等待从设备发送应答信号
- rIICSTAT = 0xf0; //MasTx,Start
- rIICCON = 0xaf; //Resumes IIC operation.
- while(_iicStatus==0x100); //Wait until IICSTAT change
3,如果想要继续发送数据,那么在接收到应答信号后,再把待发送的数据写入寄存器IICDS中,清除中断标志后,再次等待应答信号;如果不想再发送数据了,那么把0x90写入寄存器IICSTAT中,清除中断标志并等待停止条件后,即完成了一次主设备的发送。
- rIICSTAT = 0xd0; //1101_,11~MasRx,0~stop,1~RxTx enable //Stop MasTx condition
- rIICCON = 0xaf; //Resumes IIC operation.
- Delay(1); //Wait until stop condtion is in effect.
- //Write is completed.
二,在主设备接收模式下,它的工作流程为:
1,首先配置IIC模式,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xB0写入控制状态寄存器IICSTAT中
- rIICDS = slvAddr; //slvAddr=0xa0
- rIICSTAT = 0xb0; //1011,10~MasRx,1~Start,1~RxTx enable
- rIICCON = 0xaf; //Resumes IIC operation.
- while(_iicDataCount!=-1);//等待主接收模式停止,在中断函数里进行的
2,这时等待从设备发送应答信号,如果想要接收数据,那么在应答信号后,读取寄存器IICDS,清除中断标志;如果不想接收数据了,那么就向寄存器IICSTAT写入0x90,清除中断标志并等待停止条件后,即完成了一次主设备的接收。
- _iicData[_iicPt++] = rIICDS;
- rIICSTAT = 0x90; //1001Stop MasRx condition
- rIICCON = 0xaf; //Resumes IIC operation.
- Delay(1); //Wait until stop condtion is in effect
其程序流程图如下:
下面的例程将向AT24C02写入若干字节,并读出来显示在超级终端:
IIC.c
- //===================================================================
- // SMDK2440 IIC configuration
- // GPE15=IICSDA, GPE14=IICSCL
- // "Interrupt mode" for IIC block中断模式下的IIC操作
- //===================================================================
- //******************[ Test_Iic ]**************************************
- 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 ,1_disable,0_enable
- rGPECON |= 0xa00000; //GPE15:IICSDA , GPE14:IICSCL,GPE15,GPE14为第二功能 时钟线和数据线
- pISR_IIC = (unsigned)IicInt;//中断注册
- rINTMSK &= ~(BIT_IIC);//iic中断使能
- rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);//(1<<7)Enable ACK,(0<<6) Prescaler IICCLK=PCLK/16,(1<<5) Enable interrupt,
- // (0xf)Transmit clock value Tx clock=IICCLK/(15+1)
- // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
- rIICADD = 0x10; //2440 slave address = [7:1]=0x10;
- rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
- rIICLC = (1<<2)|(1); // Filter enable, 5 clocks SDA output delay added by lj
- Uart_Printf("Write test data into AT24C02\n");
- for(i=0;i<256;i++)
- Wr24C080(0xa0,(U8)i,i);//写入0~255主设备地址0~255?从设备地址0xa0?
- for(i=0;i<256;i++)//data[]清零
- data[i] = 0;
- Uart_Printf("Read test data from AT24C02\n");
- for(i=0;i<256;i++)
- Rd24C080(0xa0,(U8)i,&(data[i])); //从同一个地址读入256个字节
- //Line changed 0 ~ f
- for(i=0;i<16;i++)
- {
- for(j=0;j<16;j++)
- Uart_Printf("%2x ",data[i*16+j]);
- Uart_Printf("\n");//每16字节换一行
- }
- rINTMSK |= BIT_IIC; //iic操作结束,禁止iic中断
- rGPEUP = save_PE; //恢复现场
- rGPECON = save_E;
- }
- //*************************[ Wr24C080 ]****************************
- void Wr24C080(U32 slvAddr,U32 addr,U8 data)
- {
- _iicMode = WRDATA;//写数据模式
- _iicPt = 0;
- _iicData[0] = (U8)addr;
- _iicData[1] = data;
- _iicDataCount = 2;//中断里写两个数据(地址)
- rIICDS = slvAddr; //slvAddr=0xa0
- rIICSTAT = 0xf0; //11MasTx,1Start,1enable rx/tx(使能中断)首先发送从设备地址,在中断函数里发送数据
- //Clearing the pending bit isn't needed because the pending bit has been cleared.
- while(_iicDataCount!=-1);//等待主发送模式停止,在中断函数里进行的
- _iicMode = POLLACK;//MasTx condition has Stoped,等待ACK应答模式,有应答表示从设备已经收到
- while(1)
- {
- rIICDS = slvAddr; //slvAddr=0xa0
- _iicStatus = 0x100; //IICSTAT clear?
- rIICSTAT = 0xf0; //MasTx,Start
- rIICCON = 0xaf; //Resumes IIC operation.
- while(_iicStatus==0x100); //Wait until IICSTAT change
- if(!(_iicStatus&0x1))
- break; //When ACK is received
- }
- rIICSTAT = 0xd0; //1101_,11~MasRx,0~stop,1~RxTx enable //Stop MasTx condition
- rIICCON = 0xaf; //Resumes IIC operation.
- Delay(1); //Wait until stop condtion is in effect.
- //Write is completed.
- }
- //**********************[ Rd24C080 ] ***********************************
- void Rd24C080(U32 slvAddr,U32 addr,U8 *data)
- {
- _iicMode = SETRDADDR;//写地址模式
- _iicPt = 0;
- _iicData[0] = (U8)addr;
- _iicDataCount = 1;//写一个数据(地址)
- rIICDS = slvAddr; //slvAddr=0xa0首先写入从设备地址
- rIICSTAT = 0xf0; //MasTx,Start发送从设备地址
- //Clearing the pending bit isn't needed because the pending bit has been cleared.
- while(_iicDataCount!=-1);//等待主发送模式停止,在中断函数里进行的
- _iicMode = RDDATA;//读数据模式
- _iicPt = 0;
- _iicDataCount = 1;//读一个数据(地址)
- rIICDS = slvAddr; //slvAddr=0xa0
- rIICSTAT = 0xb0; //1011,10~MasRx,1~Start,1~RxTx enable
- rIICCON = 0xaf; //Resumes IIC operation.
- while(_iicDataCount!=-1);//等待主接收模式停止,在中断函数里进行的
- *data = _iicData[1];//iic发送过来的数据将被放入_iicData[1]中,然后被传递到data[]数组中
- }
- //-------------------------------------------------------------------------
- void __irq IicInt(void) //iic中断函数
- {
- U32 iicSt,i;
- rSRCPND = BIT_IIC; //Clear pending bit
- rINTPND = BIT_IIC; //Clear pending bit
- iicSt = rIICSTAT; //读取状态寄存器的值
- if(iicSt & 0x8){} //When bus arbitration is failed.
- if(iicSt & 0x4){} //When a slave address is matched with IICADD
- if(iicSt & 0x2){} //When a slave address is 0000000b
- if(iicSt & 0x1){} //When ACK isn't received用户自己添加?
- switch(_iicMode) //根据不同的模式作出相应的动作
- {
- case POLLACK:
- _iicStatus = iicSt;//等待
- break;
- case RDDATA:
- if((_iicDataCount--)==0)
- {
- _iicData[_iicPt++] = rIICDS;
- rIICSTAT = 0x90; //1001Stop MasRx condition
- rIICCON = 0xaf; //Resumes IIC operation.
- Delay(1); //Wait until stop condtion is in effect.
- //Too long time...
- //The pending bit will not be set after issuing stop condition.
- break; //在停止状态下,中断挂起位将不会被置位
- }
- _iicData[_iicPt++] = rIICDS; //将rIICDS中的数据,即接收到的数据存入_iicData[1];The last data has to be read with no ack.
- if((_iicDataCount)==0)
- rIICCON = 0x2f; //Resumes IIC operation with NOACK.
- else
- rIICCON = 0xaf; //Resumes IIC operation with ACK
- break;
- case WRDATA:
- if((_iicDataCount--)==0) //_iicDataCount=2,当第三次进入中断时进入此{},停止主发送模式
- {
- rIICSTAT = 0xd0; //1101Stop MasTx condition
- rIICCON = 0xaf; //Resumes IIC operation.
- Delay(1); //Wait until stop condtion is in effect.
- //The pending bit will not be set after issuing stop condition.
- //在停止状态下,中断挂起位将不会被置位
- break;
- }
- rIICDS = _iicData[_iicPt++]; //_iicData[0] has dummy.可以发送两个数据,第一个发送的是_iicData[0]=addr即主设备地址,
- //第二个发送的是_iicData[1]=data即要发送的数据,
- for(i=0;i<10;i++); //for setup time until rising edge of IICSCL等待时钟上升沿
- rIICCON = 0xaf; //resumes IIC operation.
- break;
- case SETRDADDR:
- // Uart_Printf("[ S%d ]",_iicDataCount);
- if((_iicDataCount--)==0)
- break; //IIC operation is stopped because of IICCON[4]
- rIICDS = _iicData[_iicPt++]; //只发送一个数据_iicData[0]=addr,即主设备地址
- for(i=0;i<10;i++); //For setup time until rising edge of IICSCL等待时钟上升沿
- rIICCON = 0xaf; //Resumes IIC operation.重复iic操作
- break;
- default:
- break;
- }
- }
S3c2440 IIC相关推荐
- s3c2440 IIC AT24C08 (II)非中断模式
承接上一篇: http://blog.csdn.net/qq361294382/article/details/51589964 本次实验使用非中断方式实现S3C2440 对于AT24C08 实 ...
- S3C2440之IIC
http://blog.csdn.net/okliujieko/article/details/7039937 S3C2440之IICS3C2440之IIC IIC(Inter-Integrated ...
- S3C2440之IIC裸机驱动
花了两天的时间终于把这个搞定了,其实I2C的原理还是比较简单的,只是几个细节性的东西还是需要特别的注意,主要是需要注意一下几点: 1.rIICCON &= ~0x10; 清中断必须要在rIIC ...
- S3C2440 SDRAM内存驱动 .
SDRAM(Synchronous Dynamic Random Access Memory,同步动态随机存储器)也就是通常所说的内存.内存的工作原理.控制时序.及相关控制器的配置方法一直是嵌入式系统 ...
- S3C2440时钟系统详解
在讲述系统时钟之前,因为这些设备都是挂靠在系统时钟上的,所以必须先说系统时钟,S3C2440的时钟系统如下 外部时钟源分两种,晶振或者外部频率,由om3-2选择,时钟电路根据两种选择也有两种 我们来分 ...
- linux 扫描i2c端口,s3c2440用I2C接口访问EEPROM
在前面阅读理解了I2C的官方协议文档后,就拿s3c2440和EEPROM来验证一下. 本来是想用s3c2440的SDA和SCL管脚复用为GPIO来模拟的,但在没有示波器的情况下搞了一周,怎么都出不来, ...
- Exynos4412 IIC总线驱动开发(一)—— IIC 基础概念及驱动架构分析
关于Exynos4412 IIC 裸机开发请看 :Exynos4412 裸机开发 -- IIC总线 ,下面回顾下 IIC 基础概念 一.IIC 基础概念 IIC(Inter-Integrated Ci ...
- I2C总线学习—查缺补漏—S3C2440的I2C控制器
I2C总线学习-查缺补漏-S3C2440的I2C控制器 学习了IIC总线协议的理论部分,觉得应该学习具体操作2440的IIC控制器,毕竟最终都是为了学习S3C2440 ...
- Linux底层IIC 总线的理解、调用函数以及常见面试问题
对 IIC 总线的理解.调用函数以及常见面试问题 一.IIC 总线概述: IIC 即Inter-Integrated Circuit(集成电路总线) I2C总线是PHLIPS公司推出的一种串行总线, ...
最新文章
- Condition_number
- Spring Boot AOP记录用户操作日志
- mysql5.6 pt-query-digest,分析pt-query-digest输出信息
- 几何分布和超几何分布
- SQL语句:SQLwhile(0=0)与while @@fetch_status=0.
- 音视频技术开发周刊 56期
- count(id)count(1)count(*)count(字段)
- GBDT和随机森林的区别
- 截至频率_截至2013年核心Java帖子
- 咦,拆分个字符串都这么讲究?
- inux下切换到root权限有以下几种方式
- .NET Interop.SHDocVw和MSHTML引用如何操作
- SQL 数据库 学习 012 数据库关系图
- wds和extap作为cpe区别
- FAST-LIO论文阅读
- es linux下使用api进行es故障操作处理
- 我经历过的失败产品和项目(四):没有落单的多媒体彩铃媒体服务器
- c语言写照明系统的代码,无线LED照明系统设计(ZigBee)的设计与实现(C语言)
- STC15w4k32s4单片机 串口通信
- Ajax,Axios,Fetch的学习,对比和使用