51单片机学习第五课---B站UP主江协科技

news/2024/12/31 1:30:42/

1、I2C总线

 

注意:这里的SCL和SDA都是指总线,即主机来发送开始和停止信号。

 

 

 

 

2、AT24C02数据存储

main.c

#include <regx52.h>
#include"delay.h"
#include"LCD1602.h"
#include"key.h"
#include"at24c02.h"unsigned char keynum;
unsigned int num;void main ()
{LCD_Init();
LCD_ShowNum(1,1,num,5);
//  at24c02_writebyte(1,66) ;//写入一个字地址,子数据,写入的数据掉电不丢失
//  Delay(5);//写完不能马上读,at24c02芯片有要求写周期为5ms
//  Data=at24c02_readbyte(1);//把读到的子数据赋给Data
//  LCD_ShowNum(2,1,Data,3);//再LCD1602上把读到的数据显示出来
while(1)
{keynum=key();
if(keynum==1){num++;LCD_ShowNum(1,1,num,5);}  //按下按键1,num开始加1
if(keynum==2){num--;LCD_ShowNum(1,1,num,5);}  //按下按键2,num开始减1		
if(keynum==3)  //按下按键3,写入num的值,num的值从0~65535	{
at24c02_writebyte(0,num%256);//num是16位,把低八位写入,放在不同的地址
Delay(5);
at24c02_writebyte(1,num/256); //把高八位写入
Delay(5);
LCD_ShowString(2,1,"write ok");
Delay(1000);
LCD_ShowString(2,1,"         "); //清零}if(keynum==4)  //按下按键4,读出num的值{
num=at24c02_readbyte(0);//读取低八位
num=num|(at24c02_readbyte(1)<<8);//先读取高8位,再左移8位,与上低八位???这里at24c02_readbyte(1)是char类型,为8位,左移8位不会溢出吗?
//大整数移位操作都是算术移位(左移的话精度会增加,而不是把移出的位丢掉
LCD_ShowNum(1,1,num,5);
LCD_ShowString(2,1,"read ok");
Delay(1000);
LCD_ShowString(2,1,"         ");		}
}
}

I2C.C

#include <regx52.h>sbit I2C_scl=P2^1;	//定义端口
sbit I2C_sda=P2^0;void  I2C_start() //开始信号
{ I2C_sda=1;//确保sda是为高电平,虽然一上电sda是为高电平,但是在发送完一个字节且应答后,sda可能为低电平I2C_scl=1;//这里不能先把scl先拉高,因为如果sda为0,scl在高电平时sda里数据不能变化I2C_sda=0;I2C_scl=0; //这里拉低scl主要是开始信号后是发送字节,发送字节前,scl要在低电平下,主机才能把数据放到sda上
}
void  I2C_stop()//终止信号
{I2C_sda=0;I2C_scl=1;I2C_sda=1;}void  I2C_sendbyte(unsigned char byte)	//发送字节{unsigned char i;for(i=0;i<8;i++){I2C_sda=byte&(0x80>>i);//发送数据是从最高位开始,单独把最高位与1做与运算,当发送数据是1时还是1//是0就是0,再右移,直至最低位,8位数据都发送完,即完成一个字节的传输I2C_scl=1;	I2C_scl=0;//每完成一位数据的传输,scl要拉低,这样主机才能把下一位数据放到sda}}unsigned char I2C_receivebyte()//接收字节{unsigned char i,byte=0x00;I2C_sda=1;//接收字节前,主机要释放sda总线,接下来是从机向主机发送数据//scl低电平时,从机把数据放到sda,然后scl拉高,主机读取数据//为什么发送字节不用释放sda总线,因为发送字节时本来sda就是由总线控制,接收字节时,是从机要从//主机那里拿到控制权,然后把数据放到sda总线上,所以此时主机要释放总线for(i=0;i<8;i++){I2C_scl=1;//注意这里是拉高scl,因为此前肯定是低的,因为写字节后我们每次都拉低scl,这个期间内从机已经把数据放到sda里了if(I2C_sda){byte=byte|(0x80>>i);}I2C_scl=0;	//前面做了拉高,后面要拉低,拉低才能从机忘sda中写字节
}return byte;}void  I2C_send_ack(unsigned char Ackbit) //当主机发送字节,从机接收字节完后,主机发送应答
{I2C_sda=Ackbit;I2C_scl=1; //这里为什么不用先拉低,是因为发送字节后我们每次会拉低,此时scl已经是低的I2C_scl=0;}
unsigned char I2C_receive_ack()//当从机发送字节后,主机接收字节完,主机发接收应答
{
unsigned char Ackbit;I2C_sda=1;I2C_scl=1;Ackbit=I2C_sda;I2C_scl=0;
return Ackbit;
}

at24c02.c

#include<REGX52.h>
#include"I2C.h"
#define at24c02_address   0xA0   //0xA0从机写地址(主机向从机发送数据,从机写入数据),0xA1从机读地址(从机向主句发送数据,主机读数据)void at24c02_writebyte(unsigned char wordaddress,Data) //写入字节地址,字数据
{ unsigned char ack;I2C_start();//开始I2C_sendbyte(at24c02_address);//发送从机写地址I2C_receive_ack(); //接收应答I2C_sendbyte(wordaddress); //发送字地址I2C_receive_ack();I2C_sendbyte(Data);//发送数据I2C_receive_ack();I2C_stop(); //停止}unsigned char  at24c02_readbyte(unsigned char wordaddress)//读数据(随机读)
{unsigned char Data;I2C_start();I2C_sendbyte(at24c02_address);I2C_receive_ack();I2C_sendbyte(wordaddress);I2C_receive_ack();I2C_start();I2C_sendbyte(at24c02_address|0X01);I2C_receive_ack();Data=I2C_receivebyte();I2C_send_ack();I2C_stop();return  Data;}

 3、秒表(定时器扫描按键数码管)

功能:按下K1秒表开始计时,再按K1,暂停计时,按下K2计时清零,按下K3,AT24C02写入当下秒表的数据,按K4读出AT24C02写入的数据。但我的程序还有问题,就是我的秒写入后,只显示第一次写入的秒,后面再写入,minisec能正常写入和读出,但sec只会显示第一次写入的值,而且再按K3,min会加1,变成1.目前理解不了,后续再修改。

main.c

#include<regx52.h>
#include"Timer0.h"
#include"delay.h"
#include"LCD1602.h"
#include"key.h"
#include"nixie.h"
#include"at24c02.h"
#include"I2C.h"
unsigned char keynum,runflag;
unsigned char min,sec,minisec;
void main ()
{Timer0_Init();while(1){keynum=key();if(keynum==1){runflag=!runflag;}if(keynum==2){min=0;sec=0;minisec=0;}if(keynum==3){at24c02_writebyte(0,min);Delay(5);at24c02_writebyte(1,sec);Delay(5);at24c02_writebyte(2,minisec);Delay(5);}if(keynum==4){min=at24c02_readbyte(0);sec=at24c02_readbyte(1);minisec=at24c02_readbyte(2);}nixie_setbuff(0,min/10);nixie_setbuff(1,min%10);nixie_setbuff(2,11);nixie_setbuff(3,sec/10);nixie_setbuff(4,sec%10);nixie_setbuff(5,11);nixie_setbuff(6,minisec/10);nixie_setbuff(7,minisec%10);}
}
void sec_loop()
{ 
if(runflag){ minisec++;if (minisec>=100){minisec=0;sec++;}if (sec>=60){sec=0;min++;}if (min>=60){min=0;}}
}void Timer0_Routine()        interrupt 1
{static unsigned  int count1,count2,count3;	//TL0 = 0x18;				TH0 = 0xFC;count1++;
if(count1>=20)	
{count1=0;key_loop();}
count2++;
if(count2>=2)	
{count2=0;nixie_loop();
}
count3++;
if(count3>=10)	
{
count3=0;
sec_loop();
}
}

nixie.c

 #include <regx52.h>#include"delay.h"unsigned char nixie_buff[9]={0,10,10,10,10,10,10,10};	unsigned char nixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};void nixie_setbuff(unsigned char location,number){nixie_buff[location]= number;}
void nixie (unsigned char location,number)
{
P0=0x00;
switch(location){case 0:P2_2=1;P2_3=1;P2_4=1;break;case 1:P2_2=0;P2_3=1;P2_4=1;break;case 2:P2_2=1;P2_3=0;P2_4=1;break;case 3:P2_2=0;P2_3=0;P2_4=1;break;case 4:P2_2=1;P2_3=1;P2_4=0;break;case 5:P2_2=0;P2_3=1;P2_4=0;break;case 6:P2_2=1;P2_3=0;P2_4=0;break;case 7:P2_2=0;P2_3=0;P2_4=0;break;}P0=nixieTable[number];}
void nixie_loop()
{	static char i;nixie (i,nixie_buff[i]);i++;if(i>7){i=0;}}

 

注明出处链接:I2C讲解https://handsome-man.blog.csdn.net/article/details/123673285?fromshare=blogdetail&sharetype=blogdetail&sharerId=123673285&sharerefer=PC&sharesource=m0_51664996&sharefrom=from_link


http://www.ppmy.cn/news/1534214.html

相关文章

Ruby基础语法

Ruby 是一种动态、反射和面向对象的编程语言&#xff0c;它以其简洁的语法和强大的功能而受到许多开发者的喜爱。以下是 Ruby 语言的一些基本语法&#xff1a; 1. 打印输出 puts "Hello, Ruby!" 变量赋值 x 10 name "John" 2. 数据类型 Ruby 有多种…

mongodb光速上手

开始 mongodb是一种nosql数据库&#xff0c;即非关系型数据库。 安装好后将bin目录添加到环境变量。 安装studio-3t&#xff0c;这是可视化编辑器。 启动 mongo --host localhost --port 27017 指令 查看所有库 show dbs 使用或创建并使用库 use school use 数据库名 向…

滚雪球学Oracle[3.3讲]:数据定义语言(DDL)

全文目录&#xff1a; 前言一、约束的高级使用1.1 主键&#xff08;Primary Key&#xff09;案例演示&#xff1a;定义主键 1.2 唯一性约束&#xff08;Unique&#xff09;案例演示&#xff1a;定义唯一性约束 1.3 外键&#xff08;Foreign Key&#xff09;案例演示&#xff1a…

kafka下载配置

下载安装 参开kafka社区 zookeeperkafka消息队列群集部署https://apache.csdn.net/66c958fb10164416336632c3.html 下载 kafka_2.12-3.2.0安装包快速下载地址分享 官网下载链接地址&#xff1a; 官网下载地址&#xff1a;https://kafka.apache.org/downloads 官网呢下载慢…

简易CPU设计入门:取指令(三),ip_buf与rd_en的非阻塞赋值

在开篇&#xff0c;还是请大家首先准备好本项目所用的源代码。如果已经下载了&#xff0c;那就不用重复下载了。如果还没有下载&#xff0c;那么&#xff0c;请大家点击下方链接&#xff0c;来了解下载本项目的CPU源代码的方法。 下载本项目代码 准备好了项目源代码以后&…

网安学习(js漏洞挖掘)

内容来自bili白帽大法师白帽大法师的个人空间-白帽大法师个人主页-哔哩哔哩视频 (bilibili.com) 四种方式 目录 1、JS中存在插件名字&#xff0c;根据插件找到相应的漏洞直接利用 2、JS中存在一些URL链接&#xff0c;根据URL链接找到相应的页面进一步测试和利用 3、JS中存…

django的URL配置

1 django如何处理一个请求 首先Django要使用根URLconf模块&#xff0c;通过setting.py配置文件的ROOT_URLCONF来设置。 加载该模块后并查找变量 urlpatterns。这是一个Python的django.conf.urls.url()实例列表。 Django按顺序运行每个URL模式&#xff0c;并在匹配所请求的…

Ubuntu上安装Git:简单步骤指南

Git是目前世界上最流行的版本控制系统&#xff0c;广泛用于软件开发中。无论你是开发者还是版本控制的新手&#xff0c;Git都是你不可或缺的工具。本文将为你介绍如何在Ubuntu操作系统上安装Git。 什么是Git&#xff1f; Git是一个开源的分布式版本控制系统&#xff0c;由Lin…