c语言(IIC)对AT24c02进行读写

#include "myiic.h"
#include "gpio.h"
#include "tim.h"
#include <stdio.h>
#include <string.h>
enum MODE{
    INPUT = 0,
    OUTPUT,
};

void my_delay_us(uint32_t us){
    __HAL_TIM_SET_COUNTER(&htim6, 0);
    while(__HAL_TIM_GET_COUNTER(&htim6) < us);
}
void myiic_set_sda_mode(uint8_t mode){
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if(mode == INPUT){
        /*Configure GPIO pin : PtPin */
        GPIO_InitStruct.Pin = IIC_SDA_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        HAL_GPIO_Init(IIC_SDA_GPIO_Port, &GPIO_InitStruct);
    }
    if(mode == OUTPUT){
        /*Configure GPIO pin : PtPin */
        GPIO_InitStruct.Pin = IIC_SDA_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
        HAL_GPIO_Init(IIC_SDA_GPIO_Port, &GPIO_InitStruct);
    }
}
void set_sda_high(){
    HAL_GPIO_WritePin(IIC_SDA_GPIO_Port, IIC_SDA_Pin, GPIO_PIN_SET);
}
void set_sda_low(){
    HAL_GPIO_WritePin(IIC_SDA_GPIO_Port, IIC_SDA_Pin, GPIO_PIN_RESET);
}
void set_scl_high(){
    HAL_GPIO_WritePin(IIC_SCL_GPIO_Port, IIC_SCL_Pin, GPIO_PIN_SET);
}
void set_scl_low(){
    HAL_GPIO_WritePin(IIC_SCL_GPIO_Port, IIC_SCL_Pin, GPIO_PIN_RESET);
}
uint8_t read_sda(){
    return HAL_GPIO_ReadPin(IIC_SDA_GPIO_Port, IIC_SDA_Pin);
}
uint8_t read_scl(){
    return HAL_GPIO_ReadPin(IIC_SCL_GPIO_Port, IIC_SCL_Pin);
}
//起始信号,SCL为高电平时候,SDA下降沿为开始
void myiic_start(){
    myiic_set_sda_mode(OUTPUT);//设置SCL为输出
    set_sda_high();
    set_scl_high();
    my_delay_us(5);
    set_sda_low();
    my_delay_us(5);
}

//终止信号,SCL为高电平时候,SDA上升沿为结束
void myiic_stop(){
    myiic_set_sda_mode(OUTPUT);//设置SCL为输出
    set_sda_low();
    set_scl_high();
    my_delay_us(5);
    set_sda_high();
    my_delay_us(5);
}

//读应答 要求
uint8_t myiic_read_ack(){
    set_scl_low();//读应答之前将scl拉低,使得sda线可以改变
    myiic_set_sda_mode(INPUT);//设置sda为输
    set_scl_high();
    my_delay_us(5);
    if(read_sda()){
        set_scl_low();
        return 1;
    }else{
        set_scl_low();
        return 0;
    }
}

//发送应答
void myiic_send_ack(uint8_t i){
    set_scl_low();//将scl拉低sda才能变化
    myiic_set_sda_mode(OUTPUT);//设置SCL为输出
    if(i){
        set_sda_high();
    }else{
        set_sda_low();
    }
    set_scl_high();
    my_delay_us(5);
//    set_scl_low();
//    set_sda_high();
}
uint8_t send_byte(uint8_t data){
    myiic_set_sda_mode(OUTPUT);//设置SCL为输出
    uint8_t i = 0;
    uint8_t temp = 0x80;
    for(i = 0; i < 8; i++){
        set_scl_low();
        /*在这段时间里面改变数据*/
        if((data & temp) == 0){
            set_sda_low();
        }else{
            set_sda_high();
        }
        temp >>= 1;
        set_scl_high();
//        my_delay_us(5);
    }
    set_scl_low();
}

uint8_t read_byte(){
    //将sda设置为输入模式
    myiic_set_sda_mode(INPUT);
    uint8_t data = 0;
    uint8_t i = 0;
    uint8_t temp = 0x80;
    for(i = 0; i < 8; i++){
        set_scl_low();
        /*在这段时间里面改变数据*/
//        my_delay_us(5);
        set_scl_high();
//        my_delay_us(5);
        data <<= 1;
        data |= read_sda();
        set_scl_low();
    }
    return data;
}

void At24c02Write(unsigned char addr,unsigned char dat){
    myiic_start();
    send_byte(0xa0);//发送写器件地址
    if(myiic_read_ack()){
        printf("slave not response1\r\n");
    }
    send_byte(addr);//发送要写入内存地址
    if(myiic_read_ack()){
        printf("slave not response2\r\n");
    }
    send_byte(dat);    //发送数据
    if(myiic_read_ack()){
        printf("slave not response3\r\n");
    }
    myiic_stop();
}

unsigned char At24c02Read(unsigned char addr)
{
    uint8_t num;
    myiic_start();
    send_byte(0xa0); //发送写器件地址
    if(myiic_read_ack()){
        printf("slave not response4\r\n");
    }
    send_byte(addr); //发送要读取的地址
    if(myiic_read_ack()){
        printf("slave not response5\r\n");
    }
    myiic_start();
    send_byte(0xa1); //发送读器件地址
    if(myiic_read_ack()){
        printf("slave not response6\r\n");
    }
    num = read_byte(); //读取数据
    myiic_send_ack(1);
    myiic_stop();
    return num;    
}

void at24c02_write_string(unsigned char addr, uint8_t* data){
    uint8_t i = 0;
    for(i = 0; i < strlen(data); i++){
        At24c02Write(addr, data[i]);
        addr++;
        HAL_Delay(1);
    }
}

void at24c02_read_string(unsigned char addr, uint8_t* data, uint8_t len){
    uint8_t i = 0;
    for(i = 0; i < len; i++){
        data[i] = At24c02Read(addr);
        addr++;
        HAL_Delay(1);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值