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 + -
显示快捷键?