这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 学习AI8051开发板例程:18AI8051使用硬件IIC读取从机数据

共1条 1/1 1 跳转至

学习AI8051开发板例程:18AI8051使用硬件IIC读取从机数据

高工
2025-12-18 19:56:28     打赏

    Ai8051U 系列的单片机内部集成了一个IIC 串行总线控制器。IIC 是一种高速同步通讯总线,通讯使用 SCL(时钟线)和 SDA(数据线)两线进行同步通讯。对于 SCL和 SDA 的端口分配,Ai8051U 系列的单片机提供了切换模式,可将 SCL 和 SDA 切换到不同的 IO 口上,以方便用户将一组C 总线当作多组进行分时复用。

与标准 IC 协议相比较,忽略了如下两种机制:

●发送起始信号(START)后不进行仲裁

●时钟信号(SCL)停留在低电平时不进行超时检测

Ai8051U 系列的正C 总线提供了两种操作模式:主机模式(SCL 为输出口,发送同步时钟信号)和从机模式(SCL 为输入口,接收同步时钟信号)

一:IIC的引脚切换

3.118-1.png

可以看到AI8051硬件层:支持3组不同IO口配置,这里我们可以分时复用,从而可以外扩三组IIC从机设备。

二:底层函数如下所示:

void Wait()
{
    while (!(I2CMSST & 0x40));
    I2CMSST &= ~0x40;
}

void Start()
{
    I2CMSCR = 0x01;                         //发送START命令
    Wait();
}

void SendData(char dat)
{
    I2CTXD = dat;                           //写数据到数据缓冲区
    I2CMSCR = 0x02;                         //发送SEND命令
    Wait();
}

void RecvACK()
{
    I2CMSCR = 0x03;                         //发送读ACK命令
    Wait();
}

char RecvData()
{
    I2CMSCR = 0x04;                         //发送RECV命令
    Wait();
    return I2CRXD;
}

void SendACK()
{
    I2CMSST = 0x00;                         //设置ACK信号
    I2CMSCR = 0x05;                         //发送ACK命令
    Wait();
}

void SendNAK()
{
    I2CMSST = 0x01;                         //设置NAK信号
    I2CMSCR = 0x05;                         //发送ACK命令
    Wait();
}

void Stop()
{
    I2CMSCR = 0x06;                         //发送STOP命令
    Wait();
}

主要是操作AI8051的寄存器,从而实现数据的读取。

三:读取和写入函数如下所示::

3.1 写入函数如下所示:

void WriteNbyte(u8 addr, u8 *p, u8 number)  /*  WordAddress,First Data Address,Byte lenth   */
{
    Start();                                //发送起始命令
    SendData(SLAW);                         //发送设备地址+写命令
    RecvACK();
    SendData(addr);                         //发送存储地址
    RecvACK();
    do
    {
        SendData(*p++);
        RecvACK();
    }
    while(--number);
    Stop();                                 //发送停止命令
}

3.2 读取函数如下所示

void ReadNbyte(u8 addr, u8 *p, u8 number)   /*  WordAddress,First Data Address,Byte lenth   */
{
    Start();                                //发送起始命令
    SendData(SLAW);                         //发送设备地址+写命令
    RecvACK();
    SendData(addr);                         //发送存储地址
    RecvACK();
    Start();                                //发送起始命令
    SendData(SLAR);                         //发送设备地址+读命令
    RecvACK();
    do
    {
        *p = RecvData();
        p++;
        if(number != 1) SendACK();          //send ACK
    }
    while(--number);
    SendNAK();                              //send no ACK	
    Stop();                                 //发送停止命令
}

四:测试函数如下所示:

    ReadNbyte(0, tmp, 8);
    printf("Read1 = ");     //打印第一次读取内容
    for(i=0; i<8; i++)
    {
        printf("%02x ",tmp[i]);
        tmp[i]++;
    }
    printf("\r\n");

    WriteNbyte(0, tmp, 8);  //写入新的内容
    delay_ms(250);
    delay_ms(250);

    ReadNbyte(0, tmp, 8);
    printf("Read2 = ");     //打印第二次读取内容
    for(i=0; i<8; i++)
    {
        printf("%02x ",tmp[i]);
    }
    printf("\r\n");

可以看出,在操作IIC设备,24cxx时候,每次读取和写入的时候,需要注意在软件方面,增加一定的延时。


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]