基于stm8s103f3p单片机的I2C接口驱动程序源码

void Driver_I2CON(void)

        //开I2C时钟
        CLK_PCKENR1 |= SETBIT0;
        //I2C模式选择 标准模式
        I2C_CCRH &= CLRBIT7;
        //设置输入时钟fck 标准模式>1M(配置2M) 
        I2C_FREQR = 0x02;
        //则标准(fsc为通信速率):
        //tck=1/fck=0.5us
        //CCR=1/(2fsc*tck) = 1000000/2fsc*0.5 = 1000000/fsc
      //按速率设置宏定义 配置通信速率 10Kbps 
        I2C_CCRH = 0;
        I2C_CCRL = 100;
        //配置上升时间寄存器
        I2C_TRISER = 3;
        //开启I2C模块
        I2C_CR1 |= SETBIT0;
}

/********************************************************************************************************
*  Function: Driver_I2CSend                                                                                   
*  Object: 硬件I2C发送
*  输入: 从设备地址; 待发送数据的头指针; 待发数据的长; 
*  输出: 无                                           
*  备注:  通信中如果出现超时故障 则直接返回 避免长等待
********************************************************************************************************/
void Driver_I2CSend(u8 Address,u8 *DataBuff,u16 DataLen)
{      
        u8 temp;
        u16 time;
        //等待总线空闲
        time = 500;
        while(I2C_SR3&CHSBIT1)    
            if(!--time) 
                return;
                
        //发起始条件
        I2C_CR2 |= SETBIT0;
        //等待发送完毕
        time = 500;
        while((I2C_SR1&CHSBIT0)==0)
            if(!--time) 
                return;
        //短暂延时
        _asm("nop");
        _asm("nop");
        _asm("nop");
        temp = I2C_SR1;
        
        //发从地址
        I2C_DR = Address;
        //等待ACK应答
        time = 500;
        while((I2C_SR1&CHSBIT1)==0)
            if(!--time) 
            {
                    //超时无应答 失败
                    //发停止 退出
                    I2C_CR2 |= SETBIT1;
                    return;
            }
        //短暂延时
        _asm("nop");
        _asm("nop");
        _asm("nop");
        temp = I2C_SR1;
        //清ADDR标志
        temp = I2C_SR3;
    
        //发送数据
        for(;DataLen>0;DataLen--,DataBuff++)
        {
                //等待寄存器为空
                time = 500;
                while(!(I2C_SR1&CHSBIT7))
                    if(!--time) 
                        return;
                I2C_DR = *DataBuff;
                //等待发送完毕
                time = 500;
                while(!(I2C_SR1&CHSBIT2))
                    if(!--time) 
                        return;
                _asm("nop");
                _asm("nop");
                _asm("nop");
        }
    
        //发停止条件,关闭通信
        //清BTF位
        temp = I2C_SR1;
        temp = I2C_DR;
        //发停止
        I2C_CR2 |= SETBIT1;
}

/********************************************************************************************************
*  Function: Driver_I2CRecv                                                                                   
*  Object: 硬件I2C接收 
*  输入: 从设备地址;待接收数据的头指针;待接收数据的长;
*  输出: 无                                          
*  备注:  通信中如果出现超时故障 则直接返回 避免长等待
********************************************************************************************************/
void Driver_I2CRecv(u8 Address,u8 *DataBuff,u16 DataLen)
{      
        u8 temp;
        u16 time;
        //等待总线空闲
        time = 500;
        while(I2C_SR3&CHSBIT1)
            if(!--time)
                return;
        
        //发起始条件
        I2C_CR2 |= SETBIT0;
        //等待发送完毕
        time = 500;
        while(!(I2C_SR1&CHSBIT0))
            if(!--time)
                return;
        _asm("nop");
        _asm("nop");
        _asm("nop");
        temp = I2C_SR1;
    
        //发从地址
        I2C_DR = Address;
        //等待ACK应答
        time = 500;
        while(!(I2C_SR1&CHSBIT1))
            if(!--time)
            {
                    //超时无应答 失败
                    //发停止 退出
                    I2C_CR2 |= SETBIT1;
                    return;
            }
        _asm("nop");
        _asm("nop");
        _asm("nop");
        temp = I2C_SR1;
        //清ADDR标志
        temp = I2C_SR3;
        
        //接收数据,读DataLen-1个数
        //使能ACK应答
        I2C_CR2    |= SETBIT2;
        for(;DataLen>1;DataLen--,DataBuff++)
        {
            //等待寄存器为满
            time = 500;
            while(!(I2C_SR1&CHSBIT6))
                if(!--time)
                    return;
            *DataBuff = I2C_DR;
        }
        //关闭ACK应答
        I2C_CR2 &= CLRBIT2;
    
        //发停止条件,关闭通信
        //清BTF位
        temp = I2C_SR1;
        temp = I2C_DR;
        //发停止
        I2C_CR2 |= SETBIT1;
        _asm("nop");
        _asm("nop");
        _asm("nop");
    
        //读最后一个数
        time = 500;
        while(!(I2C_SR1&CHSBIT6))
            if(!--time)
                return;
        *DataBuff = I2C_DR;          
}

//程序从这里开始运行
main()
{
        //初始化I2C接口
        Driver_I2CON();
        //可以开始进行I2C通信编程 
        //发送
        //Driver_I2CSend...
        //接收
        //Driver_I2CRecv...
        //OK
        while (1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GJZGRB

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值