📄 iic.c
字号:
/****************************************************************************/
/* */
/* FILE NAME VERSION */
/* */
/* IIC.C 1.0 */
/* */
/* DESCRIPTION */
/* */
/* JX44B0(S3C44B0X)IIC驱动实验 */
/* */
/* */
/* DATA STRUCTURES */
/* */
/* FUNCTIONS : */
/* 在JX44B0教学实验箱进行IIC实验 */
/* */
/* DEPENDENCIES */
/* JX44B0-1 */
/* JX44B0-2 */
/* JX44B0-3 */
/* */
/* */
/* NAME: */
/* REMARKS: */
/* */
/* Copyright (C) 2003 Wuhan CVTECH CO.,LTD */
/****************************************************************************/
/****************************************************************************/
/* 学习JX44B0中IIC总线编程方法: */
/****************************************************************************/
/* 包含文件 */
#include "44b.h"
#include "44blib.h"
#include "rtc.h"
#define U8 unsigned char
#define U32 unsigned long
#define WRDATA (1)
#define POLLACK (2)
#define RDDATA (3)
#define SETRDADDR (4)
#define IICBUFSIZE 0x20
typedef (*ISR_ROUTINE_ENTRY)(void);
/* functions */
void Test_Iic(void);
void IicInt(void);
void IicInt(void);
void iic_write_24C08(U32 slvAddr,U32 addr,U8 data);
void iic_read_24C08(U32 slvAddr,U32 addr,U8 *data);
void write_24C08(unsigned char slvAddr,unsigned char addr,unsigned char data);
void iic_isr(void);
void IsrIRQ() __attribute__ ((interrupt("IRQ")));
int iic_data_tx_size;
int iic_data_rx_size;
int iic_data_tx_index;
int iic_data_rx_index;
unsigned char iic_buffer[256];
unsigned char iic_command;
unsigned int iic_status;
/*****************************************************************************
// Function name : IsrIRQ
// Description : 非矢量方式下中断的查表处理
// 中断地址表位于0x0c7fff00开始的256字节
// Return type : void
// Argument : void
*****************************************************************************/
void IsrIRQ()
{
int count = 0;
unsigned int isr_pending;
unsigned int isr_mask = 0x00000001;
unsigned int isr_mask_set = rINTMSK;
ISR_ROUTINE_ENTRY isr_routine_entry = (ISR_ROUTINE_ENTRY)0x0;
isr_pending = (rINTPND & ~isr_mask_set);
while(isr_mask)
{
if((isr_pending&isr_mask) == 0)
{
count+=4;
isr_mask <<= 1;
continue;
}
isr_routine_entry = (ISR_ROUTINE_ENTRY)(*(int*)(HandleADC+count));
break;
}
if(isr_routine_entry) (*isr_routine_entry)();
}
/*****************************************************************************
// Function name : init_interrupt_handler
// Description : 非矢量方式下中断向量表初始化处理
// Return type : void
// Argument : irq_handler
// 中断处理函数入口
*****************************************************************************/
void init_interrupt_handler(unsigned int irq_handler)
{
int i;
rINTPND = 0x00000000; /* 清除所有未决的中断 */
rI_ISPC = 0x03FFFFFF;
for( i = 0; i < 256; i+=4) /* 清除中断表 */
*(unsigned int*)(_ISR_STARTADDRESS+i) = 0;
*(unsigned int*)(HandleIRQ) = irq_handler; /* 设置IRQ模式处理函数 */
}
/*****************************************************************************
// Function name : install_isr_handler
// Description : 非矢量方式下中断向量的安装
// Return type : void
// Argument : irq_no, 中断号
// irq_routine, 中断处理函数地址
*****************************************************************************/
void install_isr_handler(int irq_no, void* irq_routine)
{
*(unsigned int*)(irq_no) = (unsigned int)irq_routine;
}
/*****************************************************************************
// Function name : Main
// Description : IIC测试程序主函数
// IIC总线实现对JX44B0教学系统上的EEPROM芯片24C08进行读写操作
// Return type : int
// Argument : void
*****************************************************************************/
int Main(void)
{
int old_index ;
rINTCON = 0x7; /* Non-vectored,IRQ/FIQ disable */
init_interrupt_handler((unsigned int)IsrIRQ);
install_isr_handler(HandleIIC, (void*)IicInt);
rINTMOD=0x0; /*设置所有中断为IRQ模式 */
rINTMSK=(0x07ffffff&~(BIT_GLOBAL|BIT_IIC)); /* 使能TICK中断 */
rINTCON=0x5; /* IRQ enable,FIQ disable */
Test_Iic();
while(1);
}
/*****************************************************************************
// Function name : iic_init
// Description : IIC初始化
// Return type : void
// Argument : void
*****************************************************************************/
void iic_init(void)
{
rPCONF = (rPCONF&0xFFFFFF0) | 0xa; /*PF0:IICSCL, PF1:IICSDA */
rPUPF |=0x3; /*pull-up disable */
Delay(100);
rIICCON=(1<<7)|(0<<6)|(1<<5)|(0xf); /*Enable interrupt, IICCLK=MCLK/16 */
rIICADD=0x10; /* S3C44B0X address */
rIICSTAT=0x10;
}
/*****************************************************************************
// Function name : Test_Iic
// Description : test iic
// Return type : void
// Argument : void
*****************************************************************************/
void Test_Iic(void)
{
unsigned int i,j;
static unsigned char data[128];
Uart_Printf("[IIC Test using KS24C08]\n");
iic_init();
Uart_Printf("Write test data into KS24C08\n");
for(i=0;i<128;i++)
{
Uart_Printf("\rWrite 0x%02x", i);
iic_write_24C08(0xa0,(U8)i,i+0x18); /*IIC写操作,写128个字节 0-255*/
}
Uart_Printf("\n");
for(i=0;i<128;i++) data[i]=0;
Uart_Printf("Read test data from KS24C08\n");
for(i=0;i<128;i++)
{
Uart_Printf("\rRead 0x%02x", i);
iic_read_24C08(0xa0,(U8)i,&(data[i])); /*IIC读操作,读取一个字节*/
}
Uart_Printf("\n");
for(i=0;i<16;i++)
{
for(j=0;j<16;j++) Uart_Printf("%2x ",data[i*16+j]);
Uart_Printf("\n");
}
}
/*****************************************************************************
// Function name : iic_write_24C08
// Description : write data to 24c08
// Return type : void
// Argument : U32 slvAddr : Slave addressdata
// Argument : U32 addr : address into chip
// Argument : U8 data : data by writen
*****************************************************************************/
void iic_write_24C08(U32 slvAddr,U32 addr,U8 data)
{
int index;
iic_command=WRDATA;
iic_data_tx_index=0;
iic_buffer[0]=(U8)addr;
iic_buffer[1]=data;
iic_data_tx_size=2;
rIICDS = slvAddr;
rIICSTAT= 0xf0; /*MasTx,Start */
/* Clearing the pending bit isn't needed because the pending bit has */
/* been cleared. */
while(iic_data_tx_size!=-1);
rIICSTAT=0xd0; /*top MasTx condition */
rIICCON=0xaf; /*resumes IIC operation. */
Delay(1); /*until stop condtion is in effect. */
iic_command=POLLACK;
while(1)
{
rIICDS=slvAddr;
iic_status=0x100;
rIICSTAT=0xf0; /*MasTx,Start */
rIICCON=0xaf; /*resumes IIC operation. */
while(iic_status==0x100);
if(!(iic_status&0x1))
break; /*when ACK is received */
}
rIICSTAT=0xd0; /*stop MasTx condition */
rIICCON=0xaf; /*resumes IIC operation. */
Delay(1); /*until stop condition is in effect.*/
/*write is completed.*/
}
/****************************************************************************
// Function name : iic_read_24C08
// Description : read data from 24c08
// Return type : void
// Argument : U32 slvAddr : Slave address
// Argument : U32 addr : address into chip
// Argument : U8 *data : data buffer
*****************************************************************************/
void iic_read_24C08(U32 slvAddr,U32 addr,U8 *data)
{
iic_command=SETRDADDR;
iic_data_tx_index=0;
iic_buffer[0]=(U8)addr;
iic_data_tx_size=1;
rIICDS=slvAddr;
rIICSTAT=0xf0; /* MasTx,Start */
/* Clearing the pending bit isn't needed because the pending bit has */
/* been cleared. */
while(iic_data_tx_size!=-1);
iic_command=RDDATA;
iic_data_rx_index=0;
iic_data_rx_size=1;
rIICDS=slvAddr;
rIICSTAT=0xb0; /*MasRx,Start */
rIICCON=0xaf; /*resumes IIC operation. */
while(iic_data_rx_size!=-1);
rIICSTAT=0x90; /*stop MasRx condition */
rIICCON=0xaf; /*resumes IIC operation. */
Delay(1); /*until stop condition is in effect.*/
/*too long time... */
*data=iic_buffer[1];
}
/****************************************************************************
// Function name : IicInt
// Description : iic中断处理函数
// Return type : void
// Argument : void
*****************************************************************************/
void IicInt(void)
{
unsigned char data;
U32 iicSt,i;
rI_ISPC=BIT_IIC;
iicSt=rIICSTAT;
switch(iic_command)
{
case POLLACK:
iic_status=iicSt;
break;
case RDDATA:
iic_data_rx_size--;
iic_buffer[iic_data_rx_index++]=rIICDS;
if( iic_data_rx_size == -1 ) break;
/* The last data has to be read with no ack. */
if((iic_data_rx_size)==0)
{
rIICCON=0x2f; /* resumes IIC operation with NOACK.*/
}
else
{
rIICCON=0xaf; /* resumes IIC operation with ACK */
}
break;
case WRDATA:
case SETRDADDR:
iic_data_tx_size--;
if(iic_data_tx_size==-1) break;
rIICDS = iic_buffer[iic_data_tx_index++]; /*iic_buffer[0] has dummy*/
for(i=0;i<10;i++); /*until rising edge of IICSCL */
rIICCON=0xaf; /* resumes IIC operation. */
break;
default:
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -