s3c2440内部有一个IIC总线接口,因而为咱们衔接带有IIC通讯模块的外围设备供给了便当。它具有四种操作形式:主设备发送形式、主设备接纳形式、从设备发送形式和从设备接纳形式。
在这里只把s3c2440作为IIC总线的主设备来运用,因而只介绍前两种操作形式。在主设备发送形式下,它的作业流程为:首要装备IIC形式,然后把从设备地址写入接纳发送数据移位寄存器IICDS中,再把0xF0写入操控状况寄存器IICSTAT中,这时等候从设备发送应对信号,假如想要持续发送数据,那么在接纳到应对信号后,再把待发送的数据写入寄存器IICDS中,铲除中止标志后,再次等候应对信号;假如不想再发送数据了,那么把0x90写入寄存器IICSTAT中,铲除中止标志并等候中止条件后,即完结了一次主设备的发送。在主设备接纳形式下,它的作业流程为:首要装备IIC形式,然后把从设备地址写入接纳发送数据移位寄存器IICDS中,再把0xB0写入操控状况寄存器IICSTAT中,这时等候从设备发送应对信号,假如想要接纳数据,那么在应对信号后,读取寄存器IICDS,铲除中止标志;假如不想接纳数据了,那么就向寄存器IICSTAT写入0x90,铲除中止标志并等候中止条件后,即完结了一次主设备的接纳。在完结上述两个形式时,首要用到了操控寄存器IICCON、操控状况寄存器IICSTAT和发送接纳数据移位寄存器IICDS。由于咱们只把s3c2440作为主设备来用,而且体系的IIC总线上只需这么一个主设备,因而用来设置从设备地址的地址寄存器IICADD,和用于裁定总线的多主设备线路操控寄存器IICLC都无需装备。寄存器IICCON的第6位和低4位用于设置IIC的时钟频率,由于IIC的时钟线SCL都是由主设备供给的。s3c2440的IIC时钟源为PCLK,当体系的PCLK为50MHz,而从设备最高需求100kHz时,能够将IICCON的第6方位1,IICCON的低4位全为0即可。寄存器IICCON的第7位用于设置是否宣布应对信号,第5位用于是否使能发送和接纳中止,第4位用于中止的标志,当接纳或发送数据后必定要对该位进行清零,以铲除中止标志。寄存器IICSTAT的高2位用于设置是哪种操作形式,当向第5位写0或写1时,则表明完毕IIC或开端IIC通讯,第4位用于是否使能接纳/发送数据。
上面的一段是摘取网上或人的,写的很好。
AT24C02A(时序图具体见数据手册)
写操作有两种形式:字节写和页写。
在字节写形式下,主器材发送开端指令和从器材地址信息(R/W方位零)给从器材。在从器材发生应对信号后,主器材发送AT24C02的字节地址,主器材在收到从器材的另一个应对信号后,再发送数据到被寻址的存储单元。AT24C02再次应对并在主器材发生中止信号后开端内部数据的擦写,在内部擦写过程中,AT24C02不再应对主器材的任何恳求。
页写操作的发动字节,地址字节和第一个数据字节都跟字节写的方法相同,不同在于传送了一字节数据后并不发生中止信号。主器材被答应发送8个字节,每发送一个字节数据后AT24C02发生一个应对位并将字节地址低位加1,高位坚持不变。假如在发送中止信号之前主器材发送超越8个字节,地址计数器将主动翻转,从前写入的数据将被掩盖。只需接纳到主器材发送的中止信号,AT24C02发动内部写周期,将数据在一个写周期内写到数据区
读操作有三种形式:当即地址读、选择性读和连续读。
当即地址读
AT24C02包括一个地址计数器,内容为最终操作字节的地址加1。因而,假如前次读或写的操作地址为N,则当即读的地址从地址N+1开端。AT24C02接纳到器材地址信号和R/W方位1后,它首要发送一个应对信号,然后发送一个8位字节数据。主器材不需发送一个应对信号,但要发生一个中止信号,这时AT24C02中止传输。
选择性读
选择性读操作答应主器材对寄存器的恣意字节进行读操作。为进行这种操作,首要应该设定字节地址。主器材向AT24C02发送开端信号和从器材地址,从器材呼应之后发送主器材想读取的字节数据的地址。AT24C02应对之后,主器材从头发送开端信号和从器材地址,此刻R/W位才置1。AT24C02呼应并发送应对信号,然后输出所要求的一个8位字节数据,主器材不发送应对信号但发生一个中止信号,此刻AT24C02中止传输。
连续读
连续读操作的发动跟选择性读操作相同,除了在AT24C02发送完一个8位字节数据后,主器材发生一个应对信号而不是中止信号,这个应对信号奉告AT24C02要求更多的数据。对应每个应对信号,AT24C02将发送下一个地址的8位数据字节。为供给连续读操作,AT24C02内部地址计数器在每次读操作完结之后递加。这样整个寄存器区域在可在一个读操作内悉数读出。
贴出一个三星官方IIC测验程序,运用的是中止查询发式
上面的一段是摘取网上或人的,写的很好。
AT24C02A(时序图具体见数据手册)
写操作有两种形式:字节写和页写。
在字节写形式下,主器材发送开端指令和从器材地址信息(R/W方位零)给从器材。在从器材发生应对信号后,主器材发送AT24C02的字节地址,主器材在收到从器材的另一个应对信号后,再发送数据到被寻址的存储单元。AT24C02再次应对并在主器材发生中止信号后开端内部数据的擦写,在内部擦写过程中,AT24C02不再应对主器材的任何恳求。
页写操作的发动字节,地址字节和第一个数据字节都跟字节写的方法相同,不同在于传送了一字节数据后并不发生中止信号。主器材被答应发送8个字节,每发送一个字节数据后AT24C02发生一个应对位并将字节地址低位加1,高位坚持不变。假如在发送中止信号之前主器材发送超越8个字节,地址计数器将主动翻转,从前写入的数据将被掩盖。只需接纳到主器材发送的中止信号,AT24C02发动内部写周期,将数据在一个写周期内写到数据区
读操作有三种形式:当即地址读、选择性读和连续读。
当即地址读
AT24C02包括一个地址计数器,内容为最终操作字节的地址加1。因而,假如前次读或写的操作地址为N,则当即读的地址从地址N+1开端。AT24C02接纳到器材地址信号和R/W方位1后,它首要发送一个应对信号,然后发送一个8位字节数据。主器材不需发送一个应对信号,但要发生一个中止信号,这时AT24C02中止传输。
选择性读
选择性读操作答应主器材对寄存器的恣意字节进行读操作。为进行这种操作,首要应该设定字节地址。主器材向AT24C02发送开端信号和从器材地址,从器材呼应之后发送主器材想读取的字节数据的地址。AT24C02应对之后,主器材从头发送开端信号和从器材地址,此刻R/W位才置1。AT24C02呼应并发送应对信号,然后输出所要求的一个8位字节数据,主器材不发送应对信号但发生一个中止信号,此刻AT24C02中止传输。
连续读
连续读操作的发动跟选择性读操作相同,除了在AT24C02发送完一个8位字节数据后,主器材发生一个应对信号而不是中止信号,这个应对信号奉告AT24C02要求更多的数据。对应每个应对信号,AT24C02将发送下一个地址的8位数据字节。为供给连续读操作,AT24C02内部地址计数器在每次读操作完结之后递加。这样整个寄存器区域在可在一个读操作内悉数读出。
贴出一个三星官方IIC测验程序,运用的是中止查询发式
- #include
- #include”2440addr.h”
- #include”2440lib.h”
- #include”def.h”
- #defineWRDATA(1)
- #definePOLLACK(2)
- #defineRDDATA(3)
- #defineSETRDADDR(4)
- #defineIICBUFSIZE0x20
- staticU8iicData[IICBUFSIZE];
- staticvolatileintiicDataCount;
- staticvolatileintiicStatus;
- staticvolatileintiicMode;
- staticintiicPt;
- voidWr24C02(U32slvAddr,U32addr,U8data);
- voidRd24C02(U32slvAddr,U32addr,U8*data);
- voidIicPoll(void);
- voidRun_IicPoll(void);
- voidMain(void)
- {
- unsignedinti,j;
- staticU8data[256];//用于存储AT24C02读出的数据
- SelectFclk(2);//设置体系时钟400M
- ChangeClockDivider(2,1);//设置分频1:4:8
- CalcBusClk();//核算总线频率
- rGPHCON&=~((3<<4)|(3<<6));
- rGPHCON|=(2<<4)|(2<<6);//GPH2--TXD[0];GPH3--RXD[0]
- rGPHUP=0x00;//使能上拉功用
- Uart_Init(0,115200);
- Uart_Select(0);
- Uart_Printf(“[IICTest(Polling)usingAT24C020]\n”);
- rGPEUP|=0xc000;//关上拉
- rGPECON&=~0xf0000000;
- rGPECON|=0xa0000000;//GPE15:IICSDA,GPE14:IICSCL
- //使能应对,IIC总线时钟IICCLK=PCLK/16,使能中止,发送时钟IICCLK/16
- rIICCON=(1<<7)|(0<<6)|(1<<5)|(0xf);
- rIICADD=0x10;//2440从机地址=[7:1]
- rIICSTAT=0x10;//IIC总线数据输出使能(Rx/Tx)
- Uart_Printf(“WritetestdataintoAT24C02\n”);
- for(i=0;i<256;i++)
- Wr24C02(0xa0,(U8)i,i);//写入数据到AT24C02
- for(i=0;i<256;i++)//数组数据清零
- data[i]=0;
- Uart_Printf(“ReadtestdatafromAT24C02\n”);
- for(i=0;i<256;i++)
- Rd24C02(0xa0,(U8)i,&(data[i]));//读取AT24C02的数据放入data数组中
- for(i=0;i<16;i++)
- {
- for(j=0;j<16;j++)
- Uart_Printf(“%2x”,data[i*16+j]);//打印从AT24C02读出的数据
- Uart_Printf(“\n”);
- }
- }
- voidWr24C02(U32slvAddr,U32addr,U8data)//slvAddr为从地址
- {//addr为字节地址,data为写入的数据
- iicMode=WRDATA;//写数据形式
- iicPt=0;
- iicData[0]=(U8)addr;
- iicData[1]=data;
- iicDataCount=2;//依据AT24C02字节写的发式,要写从地址和字节地址
- rIICDS=slvAddr;//把0xa0地址写入到数据移位寄存器IICDS
- //MasterTxmode,Start(Write),IIC-busdataoutputenable
- //Busarbitrationsucessful,AddressasslavestatusflagCleared,
- //Addresszerostatusflagcleared,Lastreceivedbitis0
- rIICSTAT=0xf0;//
- //Clearingthependingbitisntneededbecausethependingbithasbeencleared.
- while(iicDataCount!=-1)
- Run_IicPoll();
- iicMode=POLLACK;
- while(1)
- {
- rIICDS=slvAddr;
- iicStatus=0x100;//Tocheckif_iicStatusischanged
- rIICSTAT=0xf0;//MasterTx,Start,OutputEnable,Sucessful,Cleared,Cleared,0
- rIICCON=0xaf;//ResumesIICoperation.
- while(iicStatus==0x100)
- Run_IicPoll();
- if(!(iicStatus&0x1))
- break;//WhenACKisreceived
- }
- rIICSTAT=0xd0;//MasterTxcondition,Stop(Write),OutputEnable
- rIICCON=0xaf;//ResumesIICoperation.
- Delay(1);//Waituntilstopcondtionisineffect.
- //Writeiscompleted.
- }
- //************************[_Rd24C02]********************************
- voidRd24C02(U32slvAddr,U32addr,U8*data)
- {
- iicMode=SETRDADDR;//设置要从从机读取数据的从地址
- iicPt=0;
- iicData[0]=(U8)addr;
- iicDataCount=1;//写从地址
- rIICDS=slvAddr;
- rIICSTAT=0xf0;//MasTx,Start
- //Clearingthependingbitisntneededbecausethependingbithasbeencleared.
- while(iicDataCount!=-1)
- Run_IicPoll();
- iicMode=RDDATA;//读数据形式
- iicPt=0;
- iicDataCount=1;//
- rIICDS=slvAddr;
- rIICSTAT=0xb0;//MasterRx,Start
- rIICCON=0xaf;//ResumesIICoperation.
- while(iicDataCount!=-1)
- Run_IicPoll();
- *data=iicData[1];
- }
- voidRun_IicPoll(void)
- {
- if(rIICCON&0x10)//Tx/Rx中止使能
- IicPoll();
- }
- voidIicPoll(void)
- {
- U32iicSt,i;
- iicSt=rIICSTAT;//ICC状况寄存器
- if(iicSt&0x8){}//总线裁定失利
- if(iicSt&0x4){}//从地址与ICCADD地址匹配
- if(iicSt&0x2){}//从地址为00000000b
- if(iicSt&0x1){}//未收到ACK
- switch(iicMode)
- {
- casePOLLACK:
- iicStatus=iicSt;
- break;
- caseRDDATA://从从机中读取数据
- if((iicDataCount–)==0)
- {
- iicData[iicPt++]=rIICDS;
- rIICSTAT=0x90;//StopMasRxcondition
- rIICCON=0xaf;//ResumesIICoperation.
- Delay(1);//Waituntilstopcondtionisineffect.
- //Toolongtime…
- //Thependingbitwillnotbesetafterissuingstopcondition.
- break;
- }
- iicData[iicPt++]=rIICDS;
- //Thelastdatahastobereadwithnoack.
- if((iicDataCount)==0)
- rIICCON=0x2f;//ResumesIICoperationwithNOACK.
- else
- rIICCON=0xaf;//ResumesIICoperationwithACK
- break;
- caseWRDATA://写数据到从机
- if((iicDataCount–)==0)
- {
- rIICSTAT=0xd0;//stopMasTxcondition
- rIICCON=0xaf;//resumesIICoperation.
- Delay(1);//waituntilstopcondtionisineffect.
- //Thependingbitwillnotbesetafterissuingstopcondition.
- break;
- }
- rIICDS=iicData[iicPt++];//iicData[0]hasdummy.
- for(i=0;i<10;i++);//forsetuptimeuntilrisingedgeofIICSCL
- rIICCON=0xaf;//resumesIICoperation.
- break;
- caseSETRDADDR://设置要从从机机读取数据的从机地址
- if((iicDataCount–)==0)
- {
- break;//IICoperationisstoppedbecauseofIICCON[4]
- }
- rIICDS=iicData[iicPt++];
- for(i=0;i<10;i++);//forsetuptimeuntilrisingedgeofIICSCL
- rIICCON=0xaf;//resumesIICoperation.
- break;
- default:
- break;
- }
- }