iic.c

来自「博创2410的实验代码」· C语言 代码 · 共 249 行

C
249
字号
/***************************************************************************\
	Copyright (c) 2004-2007 threewater@up-tech.com, All rights reserved.
	by threewter	2005.2.26
\***************************************************************************/
/***************************************************************************\
    #说明: iic接口驱动程序
	----------------------------------  Bug  --------------------------------------

	----------------------------------  TODO list  --------------------------------------

	----------------------------------修正--------------------------------------

	2005-2-26	创建

\***************************************************************************/

#include "../inc/macro.h"
#include "../inc/reg2410.h"
#include "../inc/iic.h"
#include "../inc/lib.h"
#include "../inc/isr.h"
#define GPIO_IIC_SCL			(GPIO_MODE_ALT0 | GPIO_PULLUP_DIS | GPIO_E14)
#define GPIO_IIC_SDA		(GPIO_MODE_ALT0 | GPIO_PULLUP_DIS | GPIO_E15)

#define IIC_READ				1
/*等待ACK应答,如果超过时间限制,打印超时信息*/
#define WAIT_IICACK()	do{int i=0; \
			while(!(rIICCON&IICCON_INTPEND)){ i++; hudelay(1);\
			 if(i>1000){ printk("iic ack time out!\n"); break;} }\
			}while(0)
//设置IIC,参见IIC控制寄存器
void Set_IIC_mode(int nIICCON, int *poldIICCON)
{	
	if(poldIICCON){
		*poldIICCON=rIICCON;
	}
	rIICCON=nIICCON;
}
/*IIC初始化设置,主要设置相关的GPIO为IIC功能和设置相关的IIC寄存器*/
void IIC_init(void)
{
	static int time=0;

	if(time!=0)
		return;

	time++;
	
	set_gpio_ctrl (GPIO_IIC_SCL);//设置GPE14功能为IICSCL
	set_gpio_ctrl (GPIO_IIC_SDA);//设置GPE14功能为IICSDA

	//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/4
	// If PCLK 50.7MHz, IICCLK = 99KHz, Tx Clock = 25KHz
	rIICCON = IICCON_ACKEN |IICCON_CLK512 | IICCON_INTR | IICCON_CLKPRE(0x3);//IIC参数设置,参看手册

	rIICADD  = 0x10;                    //2410 slave address = [7:1],IIC总线地址设置
	rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)
}
/*IIC重新设置,主要是设置2410为IIC主发送模式,发送键盘映射值给ZLG7290,驱动LED显示*/
void Led_IIC_init(void)
{	//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/4
	// If PCLK 50.7MHz, IICCLK = 99KHz, Tx Clock = 25KHz
	rIICCON = IICCON_ACKEN |IICCON_CLK512 | IICCON_INTR | IICCON_CLKPRE(0x3);//IIC控制寄存器设置

	rIICADD  = 0x10;                    //2410 slave address = [7:1]
	//rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)
	rIICSTAT = 0xd0;        //设置2410为IIC主发送模式
}
/*设置为II2C主发送模式 启动IIC数据传送*/
void IIC_MasterTxStart(char data)
{
	int i;

	Disable_Irq(IRQ_IIC);//关闭IIC中断
	
	rIICDS   = data;   //往IIC数据寄存器写入数据
	for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL
	rIICSTAT = IICSTAT_MODE_MT|IICSTAT_START|IICSTAT_OUTEN;	//MasTx,Start 0xf0,总线控制,详细参看手册
//	while(!(IICCON&IICCON_INTPEND));
	WAIT_IICACK();//等待ACK应答
}
/*IIC数据传送*/
void IIC_MasterTx(char data)
{
	U32 temp;
	int i;

	temp=rIICCON;
	temp  &= (~IICCON_INTPEND);	//清除中断标志并重新启动写操作
	temp |= IICCON_ACKEN;      //应答使能

	rIICDS   = data;                 //写入数据
	for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL
	rIICCON  = temp;	//Resumes IIC operation.数据传输开始
//	while(!(IICCON&IICCON_INTPEND));
	WAIT_IICACK();      //等待数据传输结束
}
/*IIC数据接收*/
char IIC_MasterRx(int isACK)
{
	char data;
	U32 temp;

	temp=rIICCON;
	if(isACK){//Resumes IIC operation with ACK
		temp  &= (~IICCON_INTPEND);	
		temp |= IICCON_ACKEN;
	}
	else{	//Resumes IIC operation with NOACK
		temp  &= ~(IICCON_INTPEND|IICCON_ACKEN);
	}

	rIICCON = temp;
//	while(!(IICCON&IICCON_INTPEND));
	WAIT_IICACK();
	data = rIICDS ;


	return data;
}
/*IIC数据接收开始*/
void IIC_MasterRxStart(char address)
{
	U32 temp;

	//Disable_Irq(IRQ_IIC);

	temp=rIICCON;
	temp  &= (~IICCON_INTPEND);	//清除IIC中断
	temp |= IICCON_ACKEN;    //ACK应答使能

	rIICDS   = address;   //数据寄存器写入地址
	rIICSTAT = IICSTAT_MODE_MR|IICSTAT_START|IICSTAT_OUTEN; //MasRx,Start, 0xb0,接收开始
	rIICCON = temp;
//	while(!(IICCON&IICCON_INTPEND));
	WAIT_IICACK();  //等待接收完成
}
/*IIC数据发送停止*/
void IIC_MasterTxStop(void)
{
	U32 temp;

	temp=rIICCON;
	temp  &= (~IICCON_INTPEND);	//清除中断标志并重新启动写操作
	temp |= IICCON_ACKEN;           //应答使能

	rIICSTAT = IICSTAT_MODE_MT|IICSTAT_OUTEN;                //Stop MasTx condition 0xd0
	rIICCON = temp;
	hudelay(1);                       //Wait until stop condtion is in effect.

	rIICSTAT = IICSTAT_MODE_SR|IICSTAT_OUTEN;                //slaveRx condition从接收模式
	Enable_Irq(IRQ_IIC);   //IIC中断使能
}
/*IIC数据接收停止*/
void IIC_MasterRxStop(void)
{
	U32 temp;

	temp=rIICCON;
	temp  &= (~IICCON_INTPEND);	
	temp |= IICCON_ACKEN;

	rIICSTAT = IICSTAT_MODE_MR|IICSTAT_OUTEN;                //Stop MasRx condition 0x90
	rIICCON = temp;
	hudelay(1);                       //Wait until stop condtion is in effect.

	rIICSTAT = IICSTAT_MODE_SR|IICSTAT_OUTEN;                //slaveRx condition
	Enable_Irq(IRQ_IIC);
}
/*发IIC读请求*/

U8 IIC_Read(char devaddr, char address)
{
	U8 data;

	IIC_MasterTxStart(devaddr);//发送从设备地址
	IIC_MasterTx(address);        //发送寄存器地址
	IIC_MasterRxStart(devaddr|IIC_READ);//发IIC读命令

	data=IIC_MasterRx(FALSE);

	IIC_MasterRxStop();

	return data;
}
/*发IIC写请求*/
void IIC_Write(char devaddr, char address, unsigned char data)
{
	IIC_MasterTxStart(devaddr);  //发送IIC从设备地址
	IIC_MasterTx(address);  //发送寄存器地址
	IIC_MasterTx(data);   //发送数据
	IIC_MasterTxStop();  //数据接收停止
}
/*IIC读取n个数据*/
void IIC_ReadSerial(char devaddr, char address, unsigned char* pdata, int n)
{
	if (n <=0 )
		return;
	n--;

	IIC_MasterTxStart(devaddr);//发送IIC从设备地址
	IIC_MasterTx(address);   //发送寄存器地址
	IIC_MasterRxStart(devaddr|IIC_READ); //发送读命令

	for(;n>0;n--){
		*pdata=IIC_MasterRx(TRUE);//接收数据,等待ACK
		pdata++;
	}

	*pdata=IIC_MasterRx(FALSE);//接收数据,不等待ACK

	IIC_MasterRxStop();//数据接收停止
}
/*IIC写N个数据*/
void IIC_WriteSerial(char devaddr, char address, unsigned char* pdata, int n)
{
	if (n <=0 )
		return;

	IIC_MasterTxStart(devaddr);//发送IIC从设备地址
	IIC_MasterTx(address); //发送寄存器地址

	for(;n>0;n--){
		IIC_MasterTx(*pdata); //发送数据
		pdata++;
	}

//	*pdata=IIC_MasterRx(FALSE);

	IIC_MasterTxStop();//停止数据发送
}
/*IIC发送数据*/
void IIC_Send(char devaddr, const char* pdata, int n)
{
	if (n <=0 )
		return;
                                  //BIT7-BIT1   BIT0
	IIC_MasterTxStart(devaddr<<1);//从设备地址  0表示写操作
	
	for(;n>0;n--){                              //传输数据
		IIC_MasterTx(*pdata);
		pdata++;
	}

	IIC_MasterTxStop();   //IIC传输停止
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?