📄 i2c_lpc23xx_v1_00.c
字号:
#include "app_config.h"
#define I2C0_BASE_ADDR 0xE001C000
#define I2C1_BASE_ADDR 0xE005C000
#define I2C2_BASE_ADDR 0xE0080000
#define I2C_CONSET 0x00
#define I2C_STAT 0x04
#define I2C_DAT 0x08
#define I2C_ADR 0x0C
#define I2C_SCLH 0x10
#define I2C_SCLL 0x14
#define I2C_CONCLR 0x18
const unsigned long i2c_base[MAX_I2C] = {I2C0_BASE_ADDR,I2C1_BASE_ADDR,I2C2_BASE_ADDR};
unsigned int i2c_cnt[MAX_I2C];
unsigned int i2c_len[MAX_I2C];
unsigned char i2c_stop_flag[MAX_I2C];
unsigned char i2c_nack[MAX_I2C];
void I2CMasterInit(unsigned char dev, unsigned short cll_val, unsigned short clh_val)
{
(*(volatile unsigned long *)(i2c_base[dev] + I2C_ADR)) = 0x00; //not used in master mode
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONCLR)) = 0x6C; //clear all flag
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONSET)) = 0x40; //enable i2c
(*(volatile unsigned long *)(i2c_base[dev] + I2C_SCLL)) = cll_val;
(*(volatile unsigned long *)(i2c_base[dev] + I2C_SCLH)) = clh_val;
}
void i2c_master_send_cont(unsigned char dev, unsigned char *dat)
{
if (i2c_cnt[dev] == 0)
{
(*(volatile unsigned long *)(i2c_base[dev] + I2C_DAT)) = dat[i2c_cnt[dev]++];
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONCLR)) = 0x28; //clear STA and SI flag
}
else
if (i2c_cnt[dev] == i2c_len[dev])
{
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONSET)) = 0x10; //stop
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONCLR)) = 0x08; //clear SI flag
i2c_stop_flag[dev] = 1;
}
else
{
(*(volatile unsigned long *)(i2c_base[dev] + I2C_DAT)) = dat[i2c_cnt[dev]++];
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONCLR)) = 0x08; //clear SI flag
}
}
void i2c_master_send_stop(unsigned char dev, unsigned char *dat)
{
i2c_nack[dev] = 1;
i2c_stop_flag[dev] = 1;
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONSET)) = 0x10; //stop
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONCLR)) = 0x08; //clear SI flag
}
unsigned char I2CMasterSend(unsigned char dev, unsigned int len, unsigned char *dat)
{
unsigned char stat;
i2c_stop_flag[dev] = 0;
i2c_cnt[dev] = 0;
i2c_nack[dev] = 0;
i2c_len[dev] = len;
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONSET)) = 0x20; //start
while (!i2c_stop_flag[dev])
{
while (!((*(volatile unsigned long *)(i2c_base[dev] + I2C_CONSET)) | 0x08)); //wait for SI set
stat = (*(volatile unsigned long *)(i2c_base[dev] + I2C_STAT));
switch (stat)
{
case 0x08 :
i2c_master_send_cont(dev, dat);
break;
case 0x10 :
i2c_master_send_cont(dev, dat);
break;
case 0x18 :
i2c_master_send_cont(dev, dat);
break;
case 0x28 :
i2c_master_send_cont(dev, dat);
break;
case 0x00 :
i2c_master_send_stop(dev, dat);
break;
case 0x20 :
i2c_master_send_stop(dev, dat);
break;
case 0x30 :
i2c_master_send_stop(dev, dat);
break;
default :
break;
}
}
return (!i2c_nack[dev]);
}
void i2c_master_recv_cont(unsigned char dev, unsigned char *dat)
{
if (i2c_cnt[dev] == i2c_len[dev] - 1)
{
dat[i2c_cnt[dev]++] = (*(volatile unsigned long *)(i2c_base[dev] + I2C_DAT));
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONCLR)) = 0x0C; //clear SI and ACK flag
}
else
if (i2c_cnt[dev] == 0)
{
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONSET)) = 0x04; //set ACK flag
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONCLR)) = 0x08; //clear SI flag
i2c_cnt[dev]++;
}
else
{
dat[i2c_cnt[dev]++] = (*(volatile unsigned long *)(i2c_base[dev] + I2C_DAT));
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONSET)) = 0x04; //set ACK flag
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONCLR)) = 0x08; //clear SI flag
}
}
void i2c_master_recv_stop(unsigned char dev, unsigned char *dat)
{
dat[i2c_cnt[dev]] = (*(volatile unsigned long *)(i2c_base[dev] + I2C_DAT));
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONSET)) = 0x14; //set stop and ACK
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONCLR)) = 0x08; //clear SI flag
i2c_stop_flag[dev] = 1;
}
unsigned char I2CMasterRecv(unsigned char dev, unsigned int len, unsigned char *dat)
{
unsigned char stat;
i2c_stop_flag[dev] = 0;
i2c_cnt[dev] = 0;
i2c_nack[dev] = 0;
i2c_len[dev] = len;
(*(volatile unsigned long *)(i2c_base[dev] + I2C_CONSET)) = 0x20; //start
while (!i2c_stop_flag[dev])
{
while (!((*(volatile unsigned long *)(i2c_base[dev] + I2C_CONSET)) | 0x08)); //wait for SI set
stat = (*(volatile unsigned long *)(i2c_base[dev] + I2C_STAT));
switch (stat)
{
case 0x08 :
i2c_master_send_cont(dev, dat);
i2c_cnt[dev]--;
break;
case 0x10 :
i2c_master_send_cont(dev, dat);
i2c_cnt[dev]--;
break;
case 0x40 :
i2c_master_recv_cont(dev, dat);
break;
case 0x50 :
i2c_master_recv_cont(dev, dat);
break;
case 0x58 :
i2c_master_recv_stop(dev, dat);
break;
default :
break;
}
}
return (1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -