112

 

 

 

 

 

 

 

/**
 * @Author: wangxy
 * @Date: 2024-03-16
 * @LastEditTime: 2024-03-19
 * @LastEditors: wangxy
 * @Description: proj_eeprom
 * @FilePath: proj_eeprom.c
 */
 
#include "proj_eeprom.h"
 
/**
 * @details: This function is IIC Init
 */
void IIC_Init(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();
    /* Enable GPIOC clock */
    CLK->AHBCLK0 |= CLK_AHBCLK0_GPCCKEN_Msk;
    /* Lock protected registers */
    SYS_LockReg();
    /* INIT SCL SDA OUTPUT */
    GPIO_SetMode(PC, BIT0, GPIO_MODE_OUTPUT);
    GPIO_SetMode(PC, BIT1, GPIO_MODE_OUTPUT);
    IIC_SCL_PIN = 1;
    IIC_SDA_PIN = 1;
}
 
/**
 * @details: This function is IIC Start
 */
void IIC_Start(void)
{
    IIC_SDA_OUT();
    SDA_HIGH();
    SCL_HIGH();
    delay_us(5);
    SDA_LOW();
    delay_us(4);
    SCL_LOW();  //钳住时钟,开始发送数据
}
 
/**
 * @details: This function is IIC Stop
 */
void IIC_Stop(void)
{
    SCL_LOW();  //保证SCL为低
    IIC_SDA_OUT();
    SDA_LOW();
    delay_us(5);
    SCL_HIGH();
    delay_us(4);
    SDA_HIGH();
    delay_us(4);
}
 
/**
 * @details: This function is IIC SendAck 
 */
void IIC_SendAck(void)
{
    SCL_LOW();  //保证SCL为低
    IIC_SDA_OUT();
    SDA_LOW();    //置低发送ACK数据
    delay_us(2);
    SCL_HIGH(); //告诉IIC从机,该读取ACK应答了
    delay_us(4);//留给从机读取ACK的时间
    SCL_LOW();  //钳住时钟,开始下一次发送数据
}
 
/**
 * @details: This function is IIC SendNoAck
 */
void IIC_SendNoAck(void)
{
    SCL_LOW();  //保证SCL为低
    IIC_SDA_OUT();
    SDA_HIGH(); //置高发送NACK数据
    delay_us(4);
    SCL_HIGH(); //告诉IIC从机,该读取NACK应答了
    delay_us(4);//留给从机读取NACK的时间
    SCL_LOW();  //钳住时钟,开始下一次发送数据
}
 
/**主机释放SDA总线,从机控制SDA总线
 * @details: This function is IIC WaitforAck
 */
int8_t IIC_WaitforAck(void)
{
    volatile uint8_t count =0;    //读取数据超时时间
    SCL_LOW();  //保证SCL为低
    IIC_SDA_IN();
    SDA_HIGH(); //确保:主设备发送完一个字节的数据后,必须释放SDA(释放之后为空闲高电平),让从机去控制SDA
    delay_us(3);//留给从机准备ACK/NACK信号的时间
    SCL_HIGH(); //主设备将时钟拉高-开始读取信号,从设备在这个时候将ACK信号发出
    delay_us(3);//总线电平稳定时间
    while(SDA_READ()){
        delay_us(1);
        if (count++ > 250){
            IIC_Stop();
            RS_LOGE("IIC_WaitforAck failed\n");
            return -1;
        }
    }
    SCL_LOW();  //钳住时钟,开始下一次发送数据
    return 0;
}
 
/**
 * @details: This function is IIC Send Byte Data
 */
int8_t IIC_SendByteData(uint8_t data)
{
    uint8_t i=0;
    SCL_LOW();  //保证SCL为低
    IIC_SDA_OUT();
    for(i=0; i<8; i++){
        delay_us(2);
        if(data&0x80){
            SDA_HIGH();
        }else{
            SDA_LOW();
        }
        data <<= 1;
        delay_us(2);
        SCL_HIGH();     //告诉IIC从机,该读取数据了
        delay_us(2); //留给从机读取数据的时间
        SCL_LOW();   //钳住时钟,开始下一次发送数据
    }
    //发送完成等待ACK
    retuen IIC_WaitforAck();
}
 
/**
 * @details: This function is IIC Rcv Byte Data
 */
uint8_t IIC_RcvByteData(uint8_t ackFlag)
{
    uint8_t i;
    uint8_t rcvData = 0;
    IIC_SDA_IN();
    for(i=0; i<8; i++){
        SCL_LOW();  //告诉IIC从机,该写入数据了
        delay_us(2);//留给从机发送数据的时间
        SCL_HIGH();
        rcvData <<= 1;
        if(SDA_READ())
            rcvData |= 0x01;
        delay_us(2);
    }
    if(!ackFlag){
        //发送NOACK
        IIC_SendNoAck();
    }else{
        //发送ACK
        IIC_SendAck();
    }
    SCL_LOW();   //钳住时钟,开始下一次发送数据
    return rcvData;
}
 
 

 

posted @ 2025-03-13 13:52  panda_w  阅读(31)  评论(0)    收藏  举报