本帖最后由 芯圣电子官方QQ 于 2023-7-19 16:45 编辑
今天搞了一下硬件I2C读写AT24C04.
SCL接P01,SDA接P00.
代码:
#define ALLOCATE_EXTERN
#include "HC89S105AC8.h"
#define DEVICEADD 0xA0 //24C02器件地址
#define SCL P0_1 //I2C时钟控制位
#define SDA P0_0 //I2C数据传送位
unsigned char temp1,temp2,temp3; //用于存放读写数据
void Delay_ms(unsigned int fui_i); //延时函数
void IIC_Send_Byte(unsigned char fuc_Add, unsigned char fuc_Dat); //IIC发送一个字节的数据
unsigned char IIC_Read_Byte(unsigned char fuc_Add); //IIC读取一个字节的数据
/***************************************************************************************
* @实现效果 对24C02进行读写操作
***************************************************************************************/
void main()
{
/************************************系统初始化****************************************/
CLKCON = 0x02; //选择内部高频RC为系统时钟,内部高频RC Fosc=32MHz
CLKDIV = 0x02; //Fosc 2分频得到Fcpu,Fcpu=16MHz
/**********************************IIC配置初始化***************************************/
P0M0 = P0M0 & 0xF0 | 0x0A; //P00带上拉开漏输出
P0M0 = P0M0 & 0x0F | 0x80; //P01推挽输出
SCL_MAP = 0x01; //SCL映射P01口
SDA_MAP = 0x00; //SDA映射P00口
IICCON = 0x40; //启动IIC模块
IIC_Send_Byte(0x00, 0x26); //将fuc_Buf的数据写入地址0x00
Delay_ms(20);
IIC_Send_Byte(0x01, 0x69); //将fuc_Buf的数据写入地址0x00
Delay_ms(20);
IIC_Send_Byte(0x02, 0x90); //将fuc_Buf的数据写入地址0x00
Delay_ms(20);
temp1= IIC_Read_Byte(0x01);
temp2= IIC_Read_Byte(0x02);
temp3= IIC_Read_Byte(0x00);
while (1)
{
}
}
/***************************************************************************************
* @说明 IIC发送一个字节的数据
* @参数 fuc_Add:存储的地址
* fuc_Dat:存储的数据
* @返回值 无
* @注 无
***************************************************************************************/
void IIC_Send_Byte(unsigned char fuc_Add, unsigned char fuc_Dat)
{
IICCON &= ~0x08; //清除中断标志位
IICCON |= 0x20; //起始位发送起始信号
while ((!(IICCON & 0x08)) && (IICSTA != 0x08));
IICCON &= ~0x20; //起始位停止起始信号
IICCON &= ~0x08; //清除中断标志位
IICDAT = DEVICEADD; //写入器件地址
while (IICSTA != 0x18);
IICCON &= ~0x08; //清除中断标志位
IICDAT = fuc_Add; //写入地址
while (IICSTA != 0x28);
IICCON &= ~0x08; //清除中断标志位
IICDAT = fuc_Dat; //写入数据
while (IICSTA != 0x28);
IICCON &= ~0x08; //清除中断标志位
IICCON |= 0x10; //停止位发送停止信号
}
/***************************************************************************************
* @说明 IIC读取一个字节的数据
* @参数 fuc_Add:存储的地址
* @返回值 存储地址里面的数据
* @注 无
***************************************************************************************/
unsigned char IIC_Read_Byte(unsigned char fuc_Add)
{
unsigned char fuc_Dat;
IICCON &= ~0x08; //清除中断标志位
IICCON |= 0x20; //起始位发送起始信号
while ((!(IICCON & 0x08)) && (IICSTA != 0x08));
IICCON &= ~0x20; //起始位停止起始信号
IICCON &= ~0x08; //清除中断标志位
IICDAT = DEVICEADD; //写入器件地址
while (IICSTA != 0x18);
IICCON &= ~0x08; //清除中断标志位
IICDAT = fuc_Add; //写入读地址
while (IICSTA != 0x28);
IICCON &= ~0x08; //清除中断标志位
IICCON |= 0x20; //起始位发送起始信号
while ((!(IICCON & 0x08)) && (IICSTA != 0x08));
IICCON &= ~0x20; //起始位停止起始信号
IICCON &= ~0x08; //清除中断标志位
IICDAT = DEVICEADD | 0x01; //写入读指令
while (IICSTA != 0x40);
IICCON &= ~0x08; //清除中断标志位
while (IICSTA != 0x58);
fuc_Dat = IICDAT; //读入数据
IICCON &= ~0x08; //清除中断标志位
IICCON |= 0x10; //停止位发送停止信号
return fuc_Dat;
}
/***************************************************************************************
* @说明 延时函数
* @参数 fui_i : 延时时间
* @返回值 无
* @注 Fcpu = 16MHz,fui_i = 1时,延时时间约为1ms
***************************************************************************************/
void Delay_ms(unsigned int fui_i)
{
unsigned int fui_j;
for (; fui_i > 0; fui_i--)
for (fui_j = 1596; fui_j > 0; fui_j--);
}
效果图:
|