打印
[通用8051核FLASH系列]

【芯圣SDK-HC89F0541测评】+24C02(硬件I2C)

[复制链接]
5927|39
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 芯圣电子官方QQ 于 2023-7-25 14:15 编辑

今天搞了一下AT24C02,硬件I2C
SCL:P0.1;
SDA:P0.0
代码:
#define        ALLOCATE_EXTERN
#include "HC89F0541.h"

#define        DEVICEADD        0xA0                                  //24C02器件地址
#define SCL        P0_1                                           //I2C时钟控制位
#define SDA P0_0                                    //I2C数据传送位

unsigned char guc_Buf = 0;                                //用于存放读写数据
unsigned char guc_Buf1 = 0;                                //用于存放读写数据
unsigned char guc_Buf2 = 0;                                //用于存放读写数据
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()
{
/************************************系统初始化****************************************/
        CLKSWR = 0x51;                                                //选择内部高频RC为系统时钟,内部高频RC 2分频,Fosc =16MHz
        CLKDIV = 0x01;                                                //Fosc 1分频得到Fcpu,Fcpu=16MHz
/**********************************IIC配置初始化***************************************/
        P0M1 = 0xC2;                                                //P01设置为推挽输出
  P0M0 = 0xE6;                                                //P03设置为带上拉开漏输出
        SCL_MAP = 0x01;                                                //SCL映射P01口
        SDA_MAP = 0x00;                                                //SDA映射P00口
        IICCON = 0x40;                                                 //启动IIC模块

        
        IIC_Send_Byte(0x00,0x66);        //将fuc_Buf的数据写入地址0x00
        Delay_ms(20);        
  IIC_Send_Byte(0x01,0x88);        //将fuc_Buf的数据写入地址0x00
        Delay_ms(20);
        IIC_Send_Byte(0x02,0x13);        //将fuc_Buf的数据写入地址0x00
        Delay_ms(20);        
        guc_Buf = IIC_Read_Byte(0x01);        //读取地址0x00的数据并写入fuc_Buf        
        guc_Buf1 = IIC_Read_Byte(0x02);        //读取地址0x00的数据并写入fuc_Buf        
        guc_Buf2 = IIC_Read_Byte(0x00);        //读取地址0x00的数据并写入fuc_Buf        
        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 --);
}
效果图:

工程:
IIC-读写24C02.rar (46.36 KB)

使用特权

评论回复
沙发
帅气的菜鸟| | 2020-7-15 11:40 | 只看该作者

使用特权

评论回复
板凳
wangshujun| | 2020-7-15 11:59 | 只看该作者
感觉硬件iic没有优势,也看不出来硬件iic的价值所在
1、软件模拟速度不是太大的问题,不会慢很多
2、使用硬件iic也需要等待每一个字节的状态信息,不会提速,字节的操作时间大约20us,也不适合切换到其他任务去执行,甚至开启中断服务都有点短
3、硬件iic的代码量似乎比软件模拟的还多
4、硬件iic的常用外设很难用dma驱动传输
唯一看上去有价值的是中断驱动模式进行读写,但是状态处理复杂度也有点高

使用特权

评论回复
地板
比神乐|  楼主 | 2020-7-15 14:22 | 只看该作者
wangshujun 发表于 2020-7-15 11:59
感觉硬件iic没有优势,也看不出来硬件iic的价值所在
1、软件模拟速度不是太大的问题,不会慢很多
2、使用硬 ...

我感觉硬件I2C还是要比模拟时序省不少代码的。

使用特权

评论回复
5
wangshujun| | 2020-7-15 15:04 | 只看该作者
比神乐 发表于 2020-7-15 14:22
我感觉硬件I2C还是要比模拟时序省不少代码的。

就少了模拟时钟和数据的移位收发,还多了中断标志的判断和处理
感觉更复杂了

使用特权

评论回复
6
比神乐|  楼主 | 2020-7-15 16:40 | 只看该作者
wangshujun 发表于 2020-7-15 15:04
就少了模拟时钟和数据的移位收发,还多了中断标志的判断和处理
感觉更复杂了 ...

有多也有少

使用特权

评论回复
7
wangshujun| | 2020-7-16 11:18 | 只看该作者

硬件外设还是要有dma或者使用中断才更有价值

对于1t51,16兆来说:
对于iic和spi来说中断方式也有点尴尬,iic用中断还凑合,但是对于51来说进出中断时间都算上,占比也极高了,大约会占用一半的cpu时间,有价值,但是不算很大
最高速状态的spi字节时间比中断进出时间还小,基本没使用中断的价值了,很可能比查询还慢

对于高主频的mcu,比如100兆的:
在高主频的mcu上iic的中断还是很方便的,节省的等待时间很可观
spi高速模式下,没有dma就很难发挥出价值了

使用特权

评论回复
8
51xlf| | 2020-8-3 16:18 | 只看该作者
硬件I2C就是一个坑   

使用特权

评论回复
9
i1mcu| | 2020-8-3 16:18 | 只看该作者
硬件II2C和软件I2C有什么区别

使用特权

评论回复
10
pmp| | 2020-8-3 16:19 | 只看该作者
芯片已经内置了I2C?  

使用特权

评论回复
11
mmbs| | 2020-8-3 16:19 | 只看该作者
还是模拟I2C时序           

使用特权

评论回复
12
1988020566| | 2020-8-3 16:20 | 只看该作者
硬件I2C 到底怎么样?  

使用特权

评论回复
13
lzbf| | 2020-8-3 16:20 | 只看该作者
哪些 口 可以用作I2C的连线口   

使用特权

评论回复
14
houjiakai| | 2020-8-3 16:20 | 只看该作者
              

使用特权

评论回复
15
youtome| | 2020-8-3 16:21 | 只看该作者
如何设置 硬件 i2c 外设的从设备

使用特权

评论回复
16
cemaj| | 2020-8-3 16:21 | 只看该作者
用起来比较复杂  

使用特权

评论回复
17
jimmhu| | 2020-8-3 16:21 | 只看该作者
硬件I2C 到底是不是个坑

使用特权

评论回复
18
1988020566| | 2020-8-3 16:21 | 只看该作者
硬件I2C稳定吗   

使用特权

评论回复
19
mmbs| | 2020-8-3 16:21 | 只看该作者
用普通的IO口模拟I2C功能

使用特权

评论回复
20
lzbf| | 2020-8-3 16:21 | 只看该作者
硬件IIC驱动有吗?   

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

467

主题

3517

帖子

7

粉丝