⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic.c

📁 《嵌入式系统-使用HCS12微控制器的设计与应用》在CodeWarrior开发环境下的源程序。
💻 C
字号:
//[IIC.c]IIC总线通信-------------------------------------------------------*
//外部函数:                                                                *
//    (1)IICinit:IIC模块初始化                                             *
//    (2)IICread1:MCU从从机读1个字节                                       *
//    (3)IICwrite1:MCU向从机写1个字节                                      *
//    (4)IICreadN:MCU从从机读N个字节                                       *
//    (5)IICwriteN:MCU向从机写N个字节                                      *
//内部函数:                                                                *
//    (1) SendSignal:在IIC总线上发送起停信号                               *
//    (2) Wait:等待应答或一个字节数据的传送完成                            *
//硬件连接:                                                                *
//    MCU的IIC接口与从机的IIC接口相连,DG128的IIC模块的引脚SDA和SCL分别与   *
//    PTC2和PTC3引脚复用,这两个引脚应分别与从机的IIC模块的SDA和SCL相连     *
//说明:本文件与具体的芯片型号有关                                          *
//-------------------------------------------------------------------------*

//头文件                       
#include "IIC.h"    //IIC通信头文件

//IICinit:IIC模块初始化----------------------------------------------------*
//功   能:对IIC模块进行初始化,默认为允许IIC,IIC总线频率:62.5KHz,禁止IIC中  *
//        断,从机接收模式,不发送应答信号                                   *
//参   数:无                                                               *
//返   回:无                                                               *
//-------------------------------------------------------------------------*
void IICInit(void)
{
    IBFD = 0x60;//总线频率:20MHz,IIC总线频率:62.5KHz,SDA保持时间:2.45us
         
    IBAD = 0xF0;      //D7-D0位是MCU作为从机时的地址,最低位不使用
	//不发送应答信号
           //接收模式
           //从机模式
           //禁止IIC中断
           //使能IIC模块
    IBCR = 0x88;     
}

//SendSignal:在IIC总线上发送起停信号---------------------------------------*
//功 能:根据需要产生开始或停止信号                                         *
//参 数:Signal = 'S'(Start),产生开始信号;Signal = 'O'(Over),产生停止信号   *
//返 回:无                                                                 *
//-------------------------------------------------------------------------*
void SendSignal(INT8U Signal)
{
    if (Signal == 'S')    
        IBCR |= 0x20;     //主机模式选择位MST由0变为1,可以产生开始信号
    else if (Signal == 'O')
        IBCR &= ~0x20;    //主机模式选择位MST由1变为0,可以产生停止信号
}

//Wait:等待应答或一个字节数据的传送完成------------------------------------*
//功能:在时限内,循环检测接收应答标志位,或传送完成标志位,判断MCU是否接收到应*
//     答信号或一个字节是否已在总线上传送完毕                              *
//参数:x = 'A'(Ack),等待应答;x = 'T'(Transmission),等待一个字节数据传输完成*
//返回:0:收到应答信号或一个字节传送完毕;1:未收到应答信号或一个字节没传送完 *
//-------------------------------------------------------------------------*
INT8U Wait(INT8U x)
{
    INT8U ErrTime, i;
    ErrTime = 255;    //定义查询超时时限
    for (i = 0;i < ErrTime;i++)
    {
        if (x == 'A')          //等待应答信号
        {
            if ((IBSR & 0x01) == 0)
            SCISend1('c');    
                return 0;    //传送完一个字节后,收到了从机的应答信号
        }
        else if (x == 'T')     //等待传送完成一个字节信号
        {
            if ((IBSR & 0x02) != 0)    
            {
                IBSR |= 0x02;    //清IICIF标志位
                SCISend1('d'); 
                return 0;        //成功发送完一个字节
            }       
        }
    }
    if (i >= ErrTime)
        SCISend1('f'); 
        return 1;     //超时,没有收到应答信号或发送完一个字节
}

//IICread1:从从机读1个字节数据---------------------------------------------*
//功    能:从从机读1个字节数据                                             *
//参    数:                                                                *
//    (1) DeviceAddr:设备地址                                              *
//    (2) AccessAddr:访问地址                                              *
//    (3) Data:带回收到的一个字节数据                                      *
//返    回:为0,成功读一个字节;为1,读一个字节失败                           *
//内部调用:SendSignal,Wait                                                 *
//-------------------------------------------------------------------------*
INT8U IICread1(INT8U DeviceAddr, INT8U AccessAddr, INT8U *Data)
{      
    IBCR |= 0x10;                //TX = 1,MCU设置为发送模式
    SendSignal('S');             //发送开始信号    
    IBDR = DeviceAddr & 0xfe;    //发送设备地址,并通知从机接收数据    
    if (Wait('T'))               //等待一个字节数据传送完成        
        return 1;                //没有传送成功,读一个字节失败    
    if (Wait('A'))               //等待从机应答信号        
        return 1;                //没有等到应答信号,读一个字节失败    
    IBDR = AccessAddr;           //发送访问地址    
   if (Wait('T'))               //等待一个字节数据传送完成    
        return 1;                //没有传送成功,读一个字节失败
    if (Wait('A'))               //等待从机应答信号    
        return 1;                //没有等到应答信号,读一个字节失败       
    IBCR |= 0x04;                //主机模式下,RSTA位置1,产生重复开始信号    
    IBDR = DeviceAddr | 0x01;    //通知从机改为发送数据    
    if (Wait('T'))               //等待一个字节数据传送完成    
        return 1;                //没有传送成功,读一个字节失败    
    if (Wait('A'))               //等待从机应答信号   
        return 1;                //没有等到应答信号,读一个字节失败
    IBCR &= 0xef;                //TX = 0,MCU设置为接收模式    
    *Data = IBDR;                //读出IBDR,准备接收数据 
       
       if (Wait('T'))               //等待从机应答信号   
        return 1;                //没有等到应答信号,读一个字节失败   
    SendSignal('O');             //发送停止信号    
    *Data = IBDR;                //读出接收到的一个数据
    return 0;                    //正确接收到一个字节数据
}

//IICwrite1:向从机写1个字节数据--------------------------------------------*
//功     能:向从机写1个字节数据                                            *
//参     数:                                                               *
//    (1) DeviceAddr:设备地址                                              *
//    (2) AccessAddr:访问地址                                              *
//    (3) Data:要发给从机的1个字节数据                                     *
//返     回:为0,成功写一个字节;为1,写一个字节失败                          *
//内部调用 :Start, SendByte, WaitAck, Stop                                 *
//-------------------------------------------------------------------------*
INT8U IICwrite1(INT8U DeviceAddr, INT8U AccessAddr, INT8U Data)
{
    IBCR |= 0x10;                //TX = 1,MCU设置为发送模式
    SendSignal('S');             //发送开始信号
    IBDR = DeviceAddr & 0xfe;    //发送设备地址,并通知从机接收数据
    if (Wait('T'))               //等待一个字节数据传送完成
        return 1;                //没有传送成功,写一个字节失败
    if (Wait('A'))               //等待从机应答信号
        return 1;                //没有等到应答信号,写一个字节失败   
    IBDR = AccessAddr;           //发送访问地址
    if (Wait('T'))               //等待一个字节数据传送完成
        return 1;                //没有传送成功,写一个字节失败
    if (Wait('A'))               //等待从机应答信号
        return 1;                //没有等到应答信号,写一个字节失败   
    IBDR = Data;                 //写数据
    if (Wait('T'))               //等待一个字节数据传送完成
        return 1;                //没有传送成功,写一个字节失败
    if (Wait('A'))               //等待从机应答信号
        return 1;                //没有等到应答信号,写一个字节失败   
    SendSignal('O');             //发送停止信号
    return 0;
}

//IICreadN:从从机读N个字节数据---------------------------------------------*
//功    能:从从机读N个字节数据                                             *
//参    数:                                                                *
//    (1) DeviceAddr:设备地址                                              *
//    (2) AccessAddr:访问地址                                              *
//    (3) Data:读出数据的缓冲区                                            *
//    (4) N:从从机读的字节个数                                             *
//返    回:为0,成功读N个字节;为1,读N个字节失败                             *
//内部调用:IICread1                                                        *
//-------------------------------------------------------------------------*
INT8U IICreadN(INT8U DeviceAddr, INT8U AccessAddr, INT8U Data[], INT8U N)
{
    INT8U i, j;
    for (i = 0;i < N;i++)
    {
        for(j = 0;j < 15;j++);    //最小延时(发送的每个字节之间要有时间间隔)
        if (IICread1(DeviceAddr, AccessAddr + i, &Data[i]))  
            return 1;    //其中一个字节没有接收到,返回失败标志:1
    }
    if (i >= N)
        return 0;        //成功接收N个数据,返回成功标志:0
}

//IICwriteN:向从机写N个字节数据--------------------------------------------*
//功     能:向从机写N个字节数据                                            *
//参    数:                                                                *
//    (1) DeviceAddr:设备地址                                              *
//    (2) AccessAddr:访问地址                                              *
//    (3) Data:要写入的数据                                                *
//    (4) N:写入数据个数                                                   *
//返    回:为0,成功写N个字节;为1,写N个字节失败                             *
//内部调用:IICwrite1                                                       *
//-------------------------------------------------------------------------*
INT8U IICwriteN(INT8U DeviceAddr, INT8U AccessAddr, INT8U Data[], INT8U N)
{
    INT8U i, j;
    for (i = 0;i < N;i++)
    {
        for(j = 0;j < 15;j++);    //最小延时(发送的每个字节之间要有时间间隔)
        if (IICwrite1(DeviceAddr, AccessAddr + i, Data[i]))
            return 1;    //其中一个字节没有发送出去,返回失败标志:1
    }
    if (i >= N)
        return 0;        //成功发送N个数据,返回成功标志:0
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -