实验4 IIC通讯与EEPROM接口

简介:

1.       C语言编程,利用定时器产生一个0~99秒变化的秒表,并且显示在数码管上,每过一秒将这个变化写入实验板上AT24C02,当关闭实验板电源,并再次打开实验板电源时,单片机从AT24C02中将原来写入的数据读出来,接着继续变化在数码管上。

 

#include<reg51.h>

#define uchar unsigned char

#define uint unsigned int

 

//=========全局变量区============================================

bit  write=0;           //24C02的标志;

sbit sda=P2^0;                        

sbit scl=P2^1;

sbit high=P2^4;

sbit mid=P2^3;

sbit low=P2^2;

uint code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

 

uchar sec,tcnt;

uchar code table[]={

    0x3f,0x06,0x5b,0x4f,

    0x66,0x6d,0x7d,0x07,

    0x7f,0x6f,0x77,0x7c,

    0x39,0x5e,0x79,0x71

    };

//=========全局变量区结束============================================

/**

步骤

接线方式:

1P0接数码管J12,实现段选

2、译码器和数码管位选输入短接,J15+J16

3、本实验使用的晶振是12.000

**/

 

//========函数区============================================

void delay()

{;;}

void delay1ms(uint z)

{

    uint x,y;

    for(x=z;x>0;x--)

       for(y=110;y>0;y--);

}

/**

    延时

**/

void delay_1ms(uint x){

    uint i=x;

    uint j;

    for(;i>0;--i){

       for(j=110;j>0;--j);

    }

}

/**

    在数码管上显示对应的值

**/

void display(uchar Num)

{

    P0=NumTable[Num];

    delay_1ms(1);

    P0=0;      //送完段选信号后,进行消影的处理

}

 

/**

    控制数码管显示后3位,并分解计数值

**/

void DisplayNumByOrder(uint Value){

       low=0; mid=0; high=0;  display(0);        

        low=1; mid=0; high=0;  display(0);               

        low=0; mid=1; high=0;  display(0);

       low=1; mid=1; high=0;  display(0);

       low=0; mid=0; high=1;  display(0);

       low=1; mid=0; high=1;  display(Value%1000/100);

       low=0; mid=1; high=1;  display(Value%100/10);

       low=1; mid=1; high=1;  display(Value%10);

}

 

 

void start()  //开始信号

{  

    sda=1;

    delay();

    scl=1;

    delay();

    sda=0;

    delay();

}

void stop()   //停止

{

    sda=0;

    delay();

    scl=1;

    delay();

    sda=1;

    delay();

}

void respons()  //应答

{

    uchar i;

    scl=1;

    delay();

    while((sda==1)&&(i<250))i++;

    scl=0;

    delay();

}

 

void write_byte(uchar date)

{

    uchar i,temp;

    temp=date;

    for(i=0;i<8;i++)

    {

       temp=temp<<1;

       scl=0;

        delay();

       sda=CY;

       delay();

       scl=1;

       delay();

    }

    scl=0;

    delay();

    sda=1;

    delay();

}

uchar read_byte()

{

    uchar i,k;

    scl=0;

    delay();

    sda=1;

    delay();

    for(i=0;i<8;i++)

    {

       scl=1;

       delay();  

       k=(k<<1)|sda;

       scl=0;

       delay();  

    }

    return k;

}

void write_address(uchar address,uchar date)

{

    start();

    write_byte(0xa0);

    respons();

    write_byte(address);

    respons();

    write_byte(date);

    respons();

    stop();

}

uchar read_address(uchar address)

{

    uchar date;

    start();

    write_byte(0xa0);

    respons();

    write_byte(address);

    respons();

    start();

    write_byte(0xa1);

    respons();

    date=read_byte();

    stop();

    return date;

}

void init()

{

    sda=1;

    delay();

    scl=1;

    delay();

   

    sec=read_address(2);    //读出保存的数据赋于sec

    if(sec>100)        //防止首次读取出错误数据

       sec=0;

    TMOD=0x01;            //定时器工作在方式1

    ET0=1;

    EA=1;

    TH0=(65536-50000)/256;//TH0 TL0赋值

    TL0=(65536-50000)%256;//使定时器0.05秒中断一次

    TR0=1;                 //开始计时

}

void main()

{

    init();//初始化

 

    while(1)

    {

       DisplayNumByOrder(sec);

       if(write==1)            //判断计时器是否计时一秒

       {

           write=0;              //清零

           write_address(2,sec);      //24c02的地址2中写入数据sec

       }

    }

}

//========函数区结束============================================

 

 

//========中断函数区============================================

void t0() interrupt 1//定时中断服务函数

{

    TH0=(65536-50000)/256;//TH0 TL0赋值

    TL0=(65536-50000)%256;//重装计数初值

    tcnt++;        //每过50ms tcnt加一

    if(tcnt==20)  //计满20次(1秒)时

    {

        tcnt=0;   //重新再计

        sec++;

        write=1;  //1秒写一次24C02

        if(sec==100)//定时100秒,再从零开始计时

        sec=0;

    }

}

//========中断函数区结束============================================

 本文转自陈哈哈博客园博客,原文链接http://www.cnblogs.com/kissazi2/p/3174434.html如需转载请自行联系原作者


kissazi2

相关文章
|
人工智能 开发框架 算法
Qwen-Agent:阿里通义开源 AI Agent 应用开发框架,支持构建多智能体,具备自动记忆上下文等能力
Qwen-Agent 是阿里通义开源的一个基于 Qwen 模型的 Agent 应用开发框架,支持指令遵循、工具使用、规划和记忆能力,适用于构建复杂的智能代理应用。
10494 13
Qwen-Agent:阿里通义开源 AI Agent 应用开发框架,支持构建多智能体,具备自动记忆上下文等能力
|
BI 网络安全 数据安全/隐私保护
无线电HAM:业余无线电入门【无线电操作人员考证】【干货收藏】【网络安全进阶】
无线电HAM:业余无线电入门【无线电操作人员考证】【干货收藏】【网络安全进阶】
2101 0
无线电HAM:业余无线电入门【无线电操作人员考证】【干货收藏】【网络安全进阶】
|
10天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
11231 110
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
10天前
|
人工智能 IDE API
2026年国内 Codex 安装教程和使用教程:GPT-5.4 完整指南
Codex已进化为AI编程智能体,不仅能补全代码,更能理解项目、自动重构、执行任务。本文详解国内安装、GPT-5.4接入、cc-switch中转配置及实战开发流程,助你从零掌握“描述需求→AI实现”的新一代工程范式。(239字)
6073 136
|
1天前
|
人工智能 安全 API
|
8天前
|
人工智能 并行计算 Linux
本地私有化AI助手搭建指南:Ollama+Qwen3.5-27B+OpenClaw阿里云/本地部署流程
本文提供的全流程方案,从Ollama安装、Qwen3.5-27B部署,到OpenClaw全平台安装与模型对接,再到RTX 4090专属优化,覆盖了搭建过程的每一个关键环节,所有代码命令可直接复制执行。使用过程中,建议优先使用本地模型保障隐私,按需切换云端模型补充功能,同时注重显卡温度与显存占用监控,确保系统稳定运行。
2138 6
|
7天前
|
人工智能 Linux API
离线AI部署终极手册:OpenClaw+Ollama本地模型匹配、全环境搭建与问题一站式解决
在本地私有化部署AI智能体,已成为隐私敏感、低成本、稳定运行的主流方案。OpenClaw作为轻量化可扩展Agent框架,搭配Ollama本地大模型运行工具,可实现完全离线、无API依赖、无流量费用的个人数字助理。但很多用户在实践中面临三大难题:**不知道自己硬件能跑什么模型、显存/内存频繁爆仓、Skills功能因模型不支持工具调用而失效**。
3583 7