ok6410裸机实验-i2c实验

本文介绍了OK6410进行I2C实验的详细过程,包括I2C总线的硬件特性、传输时序和信号状态。由于开发板缺少内置EEPROM,实验通过示波器检测外接IO的SCL和SDA信号。实验思路涉及初始化设置、中断函数和读写数据操作,参考了三星官方的6410_Test项目。

实验工具:rvds2.2

实验系统:windows 7

1      硬件特性

1.1 概述

I2C总线是由Philips公司开发的两线式串行总线,这两根线为时钟线(SCL)和双向数据线(SDA)。由于I2C总线仅需要两根线,因此在电路板上占用的空间更少,带来的问题是带宽较窄。I2C在标准模式下传输速率最高100Kb/s,在快速模式下最高可达400kb/s。属于半双工。

在嵌入式系统中,I2C应用非常广泛,大多数微控制器中集成了I2C总线,一般用于和RTC,EEPROM,智能电池电路,传感器,LCD以及其他类似设备之间的通信。

1.2 I2C总线传输时序

1.3 I2C总线的信号状态

1、  空闲状态:SDA和SCL都是高电平;

2、  开始条件(S):SCL为高电平时,SDA由高电平向低电平跳变,开始传输数据;

3、  结束条件(P):SCL为高电平时,SDA由低电平向高电平跳变,结束传输数据;

4、  数据有效:在SCL的高电平期间,SDA保持稳定,数据有效。SDA的改变只能发生在SCL的低电平期间;

5、  ACK信号:数据传输的过程中,接收器件每接收一个字节数据要产生一个ACK信号,向发送器件发出特定的低电平脉冲,表示已经收到数据。

2 ok6410 i2c实验

首先我们在这里不得不说一下飞凌的ok6410实在是不怎么样,竟然没有i2c-eepROM,所以我们只能通过示波器检测外接的user IO中i2c的SCL和SDA的信号来达到实验的目的。

下面是三星官方的IIC0 Interface原理图,在此贴出来给大家一个参考。

2.1 实验的具体思路,完成向eeprom写入数据,读出数据。

思路如下:

2.2试验中相关函数分析:

a、首先是i2c_init()完成gpio,i2c频率和slaveaddr的初始化。

void i2c_init()
{
  	u32	uSelClkSrc;
	u32	uClkValue;
	u32 ufreq=400000;
//UART_Printf("\n*** IIC0 Setting Frequency: %d Hz\n",ufreq);

	INTC_SetVectAddr(NUM_IIC,Isr_myIIC);
	INTC_Enable(NUM_IIC);

	GPIO_SetFunctionEach(eGPIO_B,eGPIO_5,2);
	GPIO_SetFunctionEach(eGPIO_B,eGPIO_6,2);	
	GPIO_SetPullUpDownEach(eGPIO_B,eGPIO_5,2);
	GPIO_SetPullUpDownEach(eGPIO_B,eGPIO_6,2);

	if ((((g_PCLK>>4)/ufreq)-1)>0xf) 
	{
		uSelClkSrc	=	1;
		uClkValue	=	((g_PCLK>>9)/ufreq) -1;		//	PCLK/512/freq
		UART_Printf("*** PCLK= %.2fMHz,  SelClkSrc= %d (IICCLK=PCLK/512)   ,ClkDivideValue= %d\n",(float)g_PCLK/1.0e6,uSelClkSrc,uClkValue);		
		UART_Printf("*** IICCLK= %d Hz,  IICSCL (Tx clock)=  %d Hz\n",(g_PCLK/512),((g_PCLK/512)/(uClkValue+1)));			
	} 
	else 
	{
		uSelClkSrc	=	0;
		uClkValue	=	((g_PCLK>>4)/ufreq) -1;		//	PCLK/16/freq
		UART_Printf("*** PCLK= %.2fMHz,  SelClkSrc= %d (IICCLK=PCLK/16)   ,ClkDivideValue= %d\n",(float)g_PCLK/1.0e6,uSelClkSrc,uClkValue);
		UART_Printf("*** IICCLK= %d Hz,  IICSCL (Tx clock)=  %d Hz\n",(g_PCLK/16),((g_PCLK/16)/(uClkValue+1)));		
	}

	//Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
	Outp32(rIICCON0,(uSelClkSrc<<6) | (1<<5) | (uClkValue&0xf));
	Outp32(rIICADD0,0xc0);		//	Slave address = [7:1]

	Outp32(rIICSTAT0,0x10);		//	IIC bus data output enable(Rx/Tx)
	Outp32(rIICLC0,0x4);			//	SDA Filter Enable,delayed 0clks
	
}

b、我们在这里使用中断来完成i2c数据的传输工作,所以下面我们要看看中断函数。

void __irq Isr_myIIC( void)
{
    unsigned int iicSt,i;

   	u32 uTemp0 = 0;
	u8 cCnt;
	
	g_cIIC_STAT0 = Inp32(rIICSTAT0);
	UART_Printf("\r\n##### i2c_int #####\r\n");
    switch (mask)
    {    
        case MasterRX:
        
           	if (g_uIIC_PT>0)
			g_PcIIC_BUFFER[g_uIIC_PT-1] = Inp32(rIICDS0);
           	
           	UART_Printf("***  MasterRX is %x\n",	g_PcIIC_BUFFER[g_uIIC_PT-1]);

			g_uIIC_PT++;

			if (g_uIIC_PT==g_uIIC_DATALEN)
			{
				uTemp0 = Inp32(rIICCON0);
				uTemp0 |= (1<<7);			// Enable Ack generation				
				Outp32(rIICCON0,uTemp0);	//
			}
			else if (g_uIIC_PT > g_uIIC_DATALEN)
			{
				// Added by SOP on 04/11/2008 -----
				uTemp0 = Inp32(rIICCON0);
				uTemp0 &= ~(1<<7);			// Disable Ack generation
				Outp32(rIICCON0,uTemp0);	// 
				//----------------------------------				

				Outp32(rIICSTAT0,0x90);		//	Stop Master Rx condition
			}

			uTemp0 = Inp32(rIICCON0);
			uTemp0 &= ~(1<<4);			//	Clear pending bit to resume
			Outp32(rIICCON0,uTemp0);
			
			Delay(100);
			break;


		case MasterTX:
			if (g_uIIC_PT<g_uIIC_DATALEN)
			{
				Outp32(rIICDS0,g_PcIIC_BUFFER[g_uIIC_PT]);
					UART_Printf("***  MasterTX is %x\n",	g_PcIIC_BUFFER[g_uIIC_PT]);
			}				
			else	
			{
				// Added by SOP on 04/11/2008 -----
				uTemp0 = Inp32(rIICCON0);
				uTemp0 &= ~(1<<7);
				uTemp0 &= ~(1<<4);			// Disable Ack generation
				Outp32(rIICCON0,uTemp0);	// 
				//----------------------------------

				Outp32(rIICSTAT0,0xd0);	// Stop Master Tx condition, ACK flag clear
				g_uIIC_PT++;			// Added For Test by SOP on 2008/05/27	
			 	Delay(1000);
			 	break;			
			}

			g_uIIC_PT++;
			uTemp0 = Inp32(rIICCON0);
			uTemp0 &= ~(1<<4);			//	Clear pending bit to resume
			Outp32(rIICCON0,uTemp0);
			
			Delay(100);	// wait until Stop Condition is in effect, Need to here Delay(1)	
			//UART_Printf("*** Ended IIC ISR MasterTX (rIICCON0 =>0x28 or a8): 0x%02x\n", uTemp0);		// For Debugging			

		//	Outp32(rIICSTAT0,0xf0);				// Master Tx Start.				
			break;
        default:
            break;    
     
    }
    g_cIIC_STAT0	&=0xf;
	INTC_ClearVectAddr();
    
}

c、接下来便是读写数据

/*
 * 主机发送
 * slvAddr : 从机地址,buf : 数据存放的缓冲区,len : 数据长度 
 */
void i2c_write(volatile unsigned int slvAddr, unsigned char *buf,volatile int len)
{ 
	u32 uTmp1;
 	g_uIIC_PT=0;
	g_uIIC_DATALEN=len;
	g_PcIIC_BUFFER=buf;
	mask=MasterTX;
	uTmp1 = Inp32(rIICSTAT0);


	while((uTmp1&(1<<5)) || (uTmp1&(1<<3)))	//	Wait until IIC bus is free or Arbitration successful.
	{
		uTmp1 = Inp32(rIICSTAT0);
	}
    /* 等待直至数据传输完毕 */    
    uTmp1 = Inp32(rIICCON0);
	uTmp1 |= (1<<7);						// ACK Enable
	Outp32(rIICCON0,uTmp1);				// Ack generation Enable
	Outp32(rIICDS0,slvAddr);
	Outp32(rIICSTAT0,0xf0);
   // while (g_tS3C24xx_I2C.DataCount != -1); 
   while(g_uIIC_PT<=g_uIIC_DATALEN);
   
}

到此I2c功能基本实现。

参考代码:三星官方提供的6410_Test裸机工程项目。












                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值