IIC-EEPROM代码部分

简介: IIC-EEPROM代码部分

60dbb42ebb6b46758889d17791814d4c.png

理解:数码管开始显示0(假设为a,a=0);在按下K3时+1(a=0+1=1);如果想保存,则按下K1,掉电不丢失;开电后,按下K2,读取存储的数据;按K4清除a. 注:a 最大值为255.


在keil内创建文件不能用中文


多个项目,分开保存,App表示单片机控制外部设备(包括独立按键,数码管,iic,24c02),User表示主函数部分,Public表示所有函数都要有的部分(reg52.h 延时函数),Obj放置其他乱七八糟东西


.h文件放置定义,文件的包含等。固定格式 #ifndef _xxxx_H #define _xxxx_H #endif


Public.c部分:


#include "public.h"
void delay_10us(u16 ten_us)
{
    while(ten_us--);
}
void delay_ms(u16 ms)
{
    u16 i,j;
    for(i=ms;i>0;i--)
    {
        for(j==110;j>0;j--)
        {
            ;
        }
    }
}

Public.h部分:


#ifndef  _public_H
#define _public_H
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
void delay_10us(u16 ten_us);
void delay_ms(u16 ms);
#endif

smg.c部分(数码管)

#include "smg.h"
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void smg_display(u8 dat[],u8 pos)
{
    u8 i=0;
    u8 pos_temp=pos-1;
    for(i=pos_temp;i<8;i++)
    {
           switch(i)//位选
        {
            case 0: LSC=1;LSB=1;LSA=1;break;
            case 1: LSC=1;LSB=1;LSA=0;break;
            case 2: LSC=1;LSB=0;LSA=1;break;
            case 3: LSC=1;LSB=0;LSA=0;break;
            case 4: LSC=0;LSB=1;LSA=1;break;
            case 5: LSC=0;LSB=1;LSA=0;break;
            case 6: LSC=0;LSB=0;LSA=1;break;
            case 7: LSC=0;LSB=0;LSA=0;break;
        }
        SMG_A_DP_PORT=gsmg_code[dat[i-pos_temp]];//传送段选数据
        delay_10us(100);//延时一段时间,等待显示稳定
        SMG_A_DP_PORT=0x00;//消音
    }
}

smg.h部分


#ifndef _smg_H
#define _smg_H
#include "public.h"
#define SMG_A_DP_PORT    P0    //使用宏定义数码管段码口
//定义数码管位选信号控制脚
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
void smg_display(u8 dat[],u8 pos);
#endif

key.c(独立按键部分)

#include "key.h"
u8 key_scan(u8 mode)
{
    static u8 key=1;
    if(mode)key=1;
        if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))
        {
            delay_10us(1000);
            key=0;
            if(KEY1==0)
                return KEY1_PRESS;
            if(KEY2==0)
                return KEY2_PRESS;
            if(KEY3==0)
                return KEY3_PRESS;
            if(KEY4==0)
                return KEY4_PRESS;
        }
        else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)
        {
            key=1;
        }
            return KEY_UNPRESS;
    }

key.h部分


#ifndef _key_H
#define _key_H
#include "public.h"
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;
#define KEY1_PRESS  1
#define KEY2_PRESS  2
#define KEY3_PRESS  3
#define KEY4_PRESS  4
#define KEY_UNPRESS 0
u8 key_scan(u8 mode);
#endif

iic.c部分


#include "iic.h"

210d1c88845b45a281ddf94003113e88.png

// 产生IIC起始信号

void iic_start(void)
{
    IIC_SDA=1;//如果把该条语句放在SCL后面,第二次读写会出现问题
    delay_10us(1);
    IIC_SCL=1;
    delay_10us(1);
    IIC_SDA=0;    //当SCL为高电平时,SDA由高变为低
    delay_10us(1);
    IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
    delay_10us(1);
}

fca09cc6a8724f0f8b27f690ffb3cd90.png

//产生IIC停止信号


void iic_stop(void)
{    
    IIC_SDA=0;//如果把该条语句放在SCL后面,第二次读写会出现问题
    delay_10us(1);
    IIC_SCL=1;
    delay_10us(1);
    IIC_SDA=1;    //当SCL为高电平时,SDA由低变为高
    delay_10us(1);            
}

145fbf0ccbf6489f92e0568f0a52eb08.png

//产生ACK应答


void iic_ack(void)
{
    IIC_SCL=0;
    IIC_SDA=0;    //SDA为低电平
    delay_10us(1);
       IIC_SCL=1;
    delay_10us(1);
    IIC_SCL=0;
}


c11297421f3448679688f8092a4e87a0.png

//产生NACK非应答

void iic_nack(void)
{
    IIC_SCL=0;
    IIC_SDA=1;    //SDA为高电平
    delay_10us(1);
       IIC_SCL=1;
    delay_10us(1);
    IIC_SCL=0;    
}

8b11f55f0fd44235a491c65568d47d03.png

//等待应答信号到来,返回1成功,0失败

u8 iic_wait_ack(void)
{
    u8 time_temp=0;
    IIC_SCL=1;
    delay_10us(1);
    while(IIC_SDA)    //等待SDA为低电平
    {
        time_temp++;
        if(time_temp>100)//超时则强制结束IIC通信
        {    
            iic_stop();
            return 1;    
        }            
    }
    IIC_SCL=0;
    return 0;    
}

3e5abbb9ac814d43b7919de0b55a857b.png

//IIC发送一个字节


void iic_write_byte(u8 dat)
{                        
    u8 i=0; 
    IIC_SCL=0;
    for(i=0;i<8;i++)    //循环8次将一个字节传出,先传高再传低位
    {              
        if((dat&0x80)>0) 
            IIC_SDA=1;
        else
            IIC_SDA=0;
        dat<<=1;       
        delay_10us(1);  
        IIC_SCL=1;
        delay_10us(1); 
        IIC_SCL=0;    
        delay_10us(1);
    }     
}

//IIC读一个字节

u8 iic_read_byte(u8 ack)
{
    u8 i=0,receive=0;
    for(i=0;i<8;i++ )    //循环8次将一个字节读出,先读高再传低位
    {
        IIC_SCL=0; 
        delay_10us(1);
        IIC_SCL=1;
        receive<<=1;
        if(IIC_SDA)receive++;   
        delay_10us(1); 
    }                     
    if (!ack)
        iic_nack();
    else
        iic_ack();  
    return receive;
}

24c02.c部分:

#include "24c02.h"
#include "iic.h"
//在AT24CXX指定地址写入一个数据
//addr:写入数据的目的地址 dat:要写入的数据
void at24c02_write_one_byte(u8 addr,u8 dat)
{                                                                                                  
    iic_start();  
    iic_write_byte(0XA0);    //发送写命令              
    iic_wait_ack();       
    iic_write_byte(addr);    //发送写地址   
    iic_wait_ack();                                                           
    iic_write_byte(dat);    //发送字节                                   
    iic_wait_ack();                     
    iic_stop();                //产生一个停止条件
    delay_ms(10);     
}
//在AT24CXX指定地址读出一个数据
//输入addr:开始读数的地址 ,输出读到的数据
u8 at24c02_read_one_byte(u8 addr)
{                  
    u8 temp=0;                                                                                   
    iic_start();  
    iic_write_byte(0XA0);    //发送写命令       
    iic_wait_ack(); 
    iic_write_byte(addr);     //发送写地址  
    iic_wait_ack();        
    iic_start();              
    iic_write_byte(0XA1);     //进入接收模式                        
    iic_wait_ack();     
    temp=iic_read_byte(0);    //读取字节           
    iic_stop();                //产生一个停止条件    
    return temp;            //返回读取的数据
}

24c02.h部分:

#ifndef _24c02_H
#define _24c02_H
#include "public.h"
void at24c02_write_one_byte(u8 addr,u8 dat);//AT24C02指定地址写数据
u8 at24c02_read_one_byte(u8 addr);//AT24C02指定地址读数据
#endif


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
1月前
|
传感器 存储 缓存
STM32--MPU6050与I2C外设
STM32--MPU6050与I2C外设
|
1月前
|
存储 缓存 芯片
STM32--USART串口
STM32--USART串口
|
4月前
|
存储 芯片
STM32 cubemx配置USART DMA传输
STM32 cubemx配置USART DMA传输
62 0
|
9月前
|
C语言 C++
STM32F103C8 串口的使用
STM32F103C8 串口的使用
202 0
|
6月前
|
传感器 数据格式
STM32外设系列—DHT11
本文详细介绍了什么是DHT11,介绍了DHT11使用的单总线通信,并详细分析了与DHT11进行数据交互时的时序图。此外,给出了DHT11初始化,接收温湿度信息并校验的程序设计。
85 0
STM32外设系列—DHT11
|
9月前
|
存储 安全 定位技术
串口,IIC,SPI,USB等总线叙述
串口,IIC,SPI,USB等总线叙述
141 0
|
10月前
|
Linux 定位技术 芯片
|
10月前
|
移动开发
STM32F1案例 串口USART使用
STM32F1案例 串口USART使用
151 0
|
11月前
|
传感器
STM32通过IIC协议控制MPU6050
根据B站UP主“江科大自动化协”的教程总结
73 0
|
11月前
|
数据格式
【STM32】串口通讯USART串口中断配置
【STM32】串口通讯USART串口中断配置
380 0