当前位置:文档之家› 基于51单片机i2c多字节的读写

基于51单片机i2c多字节的读写

基于51单片机i2c多字节的读写

基于51单片机i2c多字节的读写

?使用Keil的编译环境下载,确实能够下载,但是入口的地址是如下黄色的那行显示所示,如果单步执行(F11)或全速运行(F5),程序始终在原位置不动(0x1FFF4252),如果强制的将PC指针的值和SP的值修改为

0x8000000与0x2000000,然后在点击运行,则能够跑到main()函数,再全速运行,能够看到客户板子上的LED灯的闪烁。

?

?

?但是如果不强制修改PC和SP指针的值,则程序不执行。

?

?所以问题就变成为什幺程序下载进去后的地址是

0x1FFF4252?0x1FFF4252又是什幺地址呢?查阅相应的手册,发现

0x1FFF4252是处在了Systemmemory区域。

?

?

?用万用表测量了客户板上的Boot0引脚的电平,发现电平不对,达到1.6V,这幺高的电平可以被视为高电平了。

?

?对照客户的原理图,原来Boot有上拉和下拉的电阻,焊接的时候将这两个电阻都焊接上去了,去掉上拉电阻,使的BOOT0的引脚接地为低电平,再编译下载进入Keil的环境,程序能够被正常执行了。问题找到了。

?

51单片机的模拟IIC总线程序

#include /*头文件的包含*/ #include #define uchar unsigned char /*宏定义*/ #define uint unsigned int #define _Nop() _nop_() /*定义空指令*/ /* 常,变量定义区 */ /*端口位定义*/ sbit SDA=P1^3; /*模拟I2C数据传送位*/ sbit SCL=P1^2; /*模拟I2C时钟控制位*/ /*状态标志*/ bit ack; /*应答标志位*/ void Start_I2c() { SDA=1; /*发送起始条件的数据信号*/ _Nop(); SCL=1; _Nop(); /*起始条件建立时间大于4.7us,延时*/ _Nop(); _Nop(); _Nop(); _Nop(); SDA=0; /*发送起始信号*/ _Nop(); /* 起始条件锁定时间大于4μs*/ _Nop(); _Nop(); _Nop(); _Nop(); SCL=0; /*钳住I2C总线,准备发送或接收数据 */ _Nop(); _Nop(); }

void Stop_I2c() { SDA=0; /*发送结束条件的数据信号*/ _Nop(); /*发送结束条件的时钟信号*/ SCL=1; /*结束条件建立时间大于4μs*/ _Nop(); _Nop(); _Nop(); _Nop(); _Nop(); SDA=1; /*发送I2C总线结束信号*/ _Nop(); _Nop(); _Nop(); _Nop(); } /******************************************************************* 字节数据传送函数 函数原型: void SendByte(uchar c); 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0 假) 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。 ********************************************************************/ void SendByte(uchar c) { uchar BitCnt; for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8位*/ { if((c<

51单片机教程

原作:平凡的单片机

1、何谓单片机一台能够工作的计算机要有这样几个部份构成:CPU(进行运算、控制)、RAM(数据存储)、ROM(程序存储)、输入/输出设备(例如:串行口、并行输出口等)。在个人计算机上这些部份被分成若干块芯片,安装一个称之为主板的印刷线路板上。而在单片机中,这些部份,全部被做到一块集成电路芯片中了,所以就称为单片(单芯片)机,而且有一些单片机中除了上述部份外,还集成了其它部份如A/D,D/A等。 天!PC中的CPU一块就要卖几千块钱,这么多东西做在一起,还不得买个天价!再说这块芯片也得非常大了。不,价格并不高,从几元人民币到几十元人民币,体积也不大,一般用40脚封装,当然功能多一些单片机也有引脚比较多的,如68引脚,功能少的只有10多个或20多个引脚,有的甚至只8只引脚。为什么会这样呢?功能有强弱,打个比方,市场上面有的组合音响一套才卖几百块钱,可是有的一台功放机就要卖好几千。另外这种芯片的生产量很大,技术也很成熟,51系列的单片机已经做了十几年,所以价格就低了。既然如此,单片机的功能肯定不强,干吗要学它呢?话不能这样说,实际工作中并不是任何需要计算机的场合都要求计算机有很高的性能,一个控制电冰箱温度的计算机难道要用PIII?应用的关键是看是否够用,是否有很好的性能价格比。所以8051出来十多年,依然没有被淘汰,还在不断的发展中。 2、MCS51单片机和8051、8031、89C51等的关系我们平常老是讲8051,又有什么8031,现在又有89C51,它们之间究竟是什么关系? MCS51是指由美国INTEL公司(对了,就是大名鼎鼎的INTEL)生产的一系列单片机的总称,这一系列单片机包括了好些品种,如8031,8051,8751,8032,8052,8752等,其中8051是最早最典型的产品,该系列其它单片机都是在8051的基础上进行功能的增、减、改变而来的,所以人们习惯于用8051来称呼MCS51系列单片机,而8031是前些年在我国最流行的单片机,所以很多场合会看到8031的名称。INTEL 公司将MCS51的核心技术授权给了很多其它公司,所以有很多公司在做以8051为核心的单片机,当然,功能或多或少有些改变,以满足不同的需求,其中89C51就是这几年在我国非常流行的单片机,它是由美国ATMEL 公司开发生产的。以后我们将用89C51来完成一系列的实验。 一、单片机的外部结构 拿到一块芯片,想要使用它,首先必须要知道怎样连线,我们用的一块称之为89C51的芯片,下面我们就看一下如何给它连线。1、电源:这当然是必不可少的了。单片机使用的是5V电源,其中正极接40引脚,负极(地)接20引脚。2、振蒎电路:单片机是一种时序电路,必须提供脉冲信号才能正常工作,在单片机内部已集成了振荡器,使用晶体振荡器,接18、19脚。只要买来晶振,电容,连上就可以了,按图1接上即可。3、复位引脚:按图1中画法连好,至于复位是何含义及为何需要复要复位,在单片机功能中介绍。4、EA引脚:EA引脚接到正电源端。至此,一个单片机就接好,通上电,单片机就开始工作了。 我们的第一个任务是要用单片机点亮一只发光二极管LED,显然,这个LED必须要和单片机的某个引脚相连,否则单片机就没法控制它了,那么和哪个引脚相连呢?单片机上除了刚才用掉的5个引脚,还有35个,我们将这个LED和1脚相连。(见图1,其中R1是限流电阻) 按照这个图的接法,当1脚是高电平时,LED不亮,只有1脚是低电平时,LED才发亮。因此要1脚我们要能够控制,也就是说,我们要能够让1引脚按要求变为高或低电平。即然我们要控制1脚,就得给它起个名字,总不能就叫它一脚吧?叫它什么名字呢?设计51芯片的INTEL公司已经起好了,就叫它P1.0,这是规定,不可以由我们来更改。

51单片机I2C接口实验报告

(预习报告) 一、实验目的 掌握基于MCS-51系统的总线扩展的方法 二、实验内容 1.利用MCS-51系统的P1口模拟总线接口,扩展串口存储器24C16,每次存入1个数据,并反复读回,用示波器测试读回的波形。(分别以数据AAH,55H测试) 2.将MCS-51系统片内存储器的10个数据存入串口存储器24C16并读回,分别设置存入的地址为页地址+00H和页地址+07H。读回为地址页地址+00H,将读回的数据存放在片内存储器,并与发送数据进行比较。 三、硬件原理图 只需将24C16的SCL与P1.1相连,SDA与P1.0相连即可。 24C16资料:

四、程序清单 8-4-1 ACK BIT 10H ;应答位判断标志 SDA BIT P1.0 ;数据线 SCL BIT P1.1 ;时钟线 ORG 0030H SEND: LCALL START ;启动 MOV A,#0A0H ;控制字节为#0A0H LCALL WRBYTE ;发送控制字节 LCALL CACK ;接收应答 JNB ACK,SEND ;收到无效应答,重新发送 MOV A,#30H ;写入的地址为#30H LCALL WRBYTE ;发送地址 LCALL CACK ;接收应答 JNB ACK,SEND ;收到无效应答,重新发送 MOV A,#0AAH ;写入的数据位#0AAH LCALL WRBYTE ;发送数据 LCALL CACK ;接收应答 JNB ACK,SEND ;收到无效应答,重新发送 LCALL STOP ;停止 LCALL DELAY ;发送与接收之间加入一段延时 READ: LCALL START ;启动 MOV A,#0A0H ;控制字节为#0A0H LCALL WRBYTE ;发送控制字节 LCALL CACK ;接收应答 JNB ACK,READ ;收到无效应答,重新启动

51单片机I2C总线驱动程序

51单片机I2C总线驱动程序 SI2I2C 总线是PHLIPS 公司推出的一种串行总线,是具备多主机系统所需 的包括总线裁决和高低速器件同步功能的高性能串行总线。I2C 总线只有两根 双向信号线。一根是数据线SDA,另一根是时钟线SCL。 一.I2C 系统结构每个接到I2C 总线上的器件都有唯一的地址。主机与其它器 件间的数据传送可以是由主机发送数据到其它器件,这时主机即为发送器。由 总线上接收数据的器件则为接收器。 二.数据位的有效性规定I2C 总线进行数据传送时,时钟信号为高电平期间, 数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线 上的高电平或低电平状态才允许变化。 三.字节传送与应答每一个字节必须保证是8 位长度。数据传送时,先传送最 高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有 9 位)。 四.驱动程序#define uchar unsigned char#define uint unsigned int#define somenop() _nop_(),_nop_(),_nop_(),_nop_(),_nop_(),_nop_()sbit SCL=P2;sb it SDA=P2;123451.起始信号和终止信号 SCL 线为高电平期间,SDA 线由高电平向低电平的变化表示起始信号;SCL 线为高电平期间,SDA 线由低电平向高电平的变化表示终止信号。 起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用 的状态;在终止信号产生后,总线就处于空闲状态 void I2C_Start() //起始{SCL=1;somenop();SDA=1;somenop(); SDA=0;somenop();SCL=0;somenop();}void I2C_Stop() //终止{ SDA=0;somenop();SCL=1;somenop();SDA=1;somenop();}12345678910111213141

I2C总线的单片机C语言实现及其应用

I2C总线的单片机C语言实现及其应用 本文介绍了I2C总线的概念、接口特性和传输时序,提出了一种用51系列单片机的C语言(C51)模拟I 2C总线数据传输的软件方法,并给出了在数字高清晰度电视地面接收机中的应用。 关键词:I2C总线;单片机;C语言;高清晰度电视 1I2C总线概述 I2C(Intel-Integrated Circuit)总线是荷兰的Philips公司于八十年代初推出的一种芯片间串行总线扩展技术。它用两根线(数据线SDA、时钟线SCL)可完成总线上主机与器件的全双工同步数据传送,可极方便地构成多主机系统和外围器件扩展系统。I2C总线支持所有NMOS、CMOS、TTL等工艺制造的器件,其上所有的节点都连到同名的SDA、SCL上。I2C总方法,数据传送都有相同的操作模式,接口电器特性相同且独立,可在系统供电情况下从系统中移去或增加IC芯片,有I2C接口的外围器件都有应答能力,读写片内单元时有地址自动加1功能,易实现多个字节的自动操作。近年来,国际上有关公司制造了多达几百种的I2C总线器件,如8051系列单片机8XC752、LCD驱动器、RAM、I/O接口等芯片都使用了I2C 总线接口。随着数字技术的发展,I2C总线控制系统已经应用于越来越多的电子产品。 2I2C总线的数据传输 2.1接口特性 I2C总线接口的数据线SDA和时钟线SCL必须经过上拉电阻接到正电源VDD上,各个I2C接口电路输出端必须是漏极开路或集电极开路,以便完成“线与”的功能。I2C的SDA和SCL都是双向传输线,当总线空闲时,此两线都是“1”(高电平)。由于不同的器件都会接到I2C总线,逻辑的“0”(低)及“1”(高)的信号电平取决于VDD的电压。总线上能连接的最大器件数取决于其电容容限400PF。 2.2I2C总线上的传输时序 I2C总线上每传输一位数据都有一个时钟脉冲相对应,在标准模式下可达100kbit/s,高速模式下可达400kbit/s,总线上依据器件功能不同可建立简单的主/从关系(master/slave),只有带CPU的器件才可成主控器。图1为I2C总线一次完整的数据传输。SCL为高期间,SDA状态必须稳定,SCL为低时才允许SDA状态变化。SCL保持高电平期间,SDA出现由高至低的转换将启动I2C总线,出现由低至高的转换将停止数据传输。起始和终止信号通常由主控器产生。I2C总线的信号时序有严格规定,本应用采用标准模式,SCL低电平周期≥4.7μs,SCL高电平周期≥4.0μs,START和STOP之间的总线空闲时间≥4.7 μs。 I2C总线上传送的每个字节必须为8位,启动和停止之间可传输的数据字节数不受限制。采用串行传送,首先传送最高位,每传送一个字节后必须跟一个应答位。主控器产生应答所需的时钟脉冲期间,发送器必须释放数据线(SDA为高),以便接收器输出应答位。低电平为应答信号,高电平为非应答信号。非应答信号是当主控器作为接收器时,收到最后一个字节数据后,必须发送一个非应答信号给被控发送器,使被控发送器释放数据线,以便主控器发停止信号,终止数据传送。当从器件不能再接收字节时也会出现 非应答 信号这种情况。 I2C总线上的器件一般有两个地址:受控地址和通用广播访问地址,每个器件有唯一的受控地址用于定点通信,而相同的通用广播访问地址则用于主控方同时对所有器件进行访问。如图1所示,起始信号后主控器发送的第一个字节就是被读器件的受控地址,称作寻址字节。寻址字节由高7位地址和最低1位方向位组成,方向位为“0”表明主控器对被控器的写操作(W),方向位为“1”表明对被控器的读操作(R)。总线上每个器件在起始信号后都把自己的地址与寻址字节的前7位相比较,如相同则器件被选中,产生应

51单片机的学习经验(附学习总结)

51单片机的学习经验(附学习总结) OFweek工控网讯:作为一名电子技术从业人员,你学过单片机吗?你会运用单片机吗?我想你一定学过,但不一定会运用。因为学习单片机比学习其他学科需要付出更多的努力和代价,不仅要学习理论知识还要练习实际操作,而且主要是在实际操作中才能真正学到单片机技术。此外,学习单片机还需要投入一定的学习成本,随着你学习知识的扩展成本还会增加。 单片机作为一种简单的控制器在生活中有这广泛的应用,当然在工业型单片机在生产中也扮演着很重要的角色,所以对于一个学习自动化的工控人来说,学习单片机是非常有必要的。 单片机的学习经验 1、学习电子技术基础知识,如电路、模拟电路和数字电路。这是学习电类相关专业的基础。 2、学习计算机硬件知识,如计算机的简单组成原理(只需要了解),当然要知道CPU是什么?总线是什么?一些相关概念。 3、程序编写的相关知识,主要是汇编语言和C语言。了解结构化语言的程序设计方法,也就是三种结构(顺序结构、分支结构(或称选择结构)、循环结构),会一些常用的算法。 4、以上是基础,有了这些基础,学习51单片机就只要花几周的时间就能上手。但学习单片机时,主要从单片机的存储器开始,其中特殊功能寄存器是重点,学会之后,就可以学习单片机的基础部分了,主要是四个部分:51单片机I/O口的使用、中断的使用、定时器的使用、外部器件的扩展。这些部分都可以用软件仿真(可以用proteus软件)。 5、可以买一两块廉价的单片机开发板,用廉价的方法(可以用热转印法做PCB板)仿制一些更简单的实验功能板,开始做板时千万不做得太复杂,我带过的很多学生中,有少部分人总是觉得太简单了,做个复杂的,结果做了个把星期,没有成功,最后只有放弃。还有一点很重要,就是用PROTEUS仿真时,最好只做单一功能的仿真,否则可能与实际在硬件上做的结果不一样。 6、从网上下载一些实例进行研究学习,不断提高。 学习单片机的步骤

51单片机I2C标准函数程序

51单片机I2C标准函数程序 #include #include #include typedef unsigned char uchar; typedef unsigned int uint; sbit SDA=P1^1; sbit SCL=P1^0; //===================================================== ========================= void Start()//开始信号 { SDA=1; SCL=1; _nop_(); _nop_(); SDA=0; _nop_(); _nop_(); SCL=0; } /************************************************************ ******************/ void Stop() //停止信号 { SDA=0; SCL=1; _nop_(); _nop_(); SDA=1; _nop_(); _nop_(); SDA=0; SCL=0; } /************************************************************ ******************/ void Ack()//应答信号

{ SDA=0; SCL=1; _nop_(); _nop_(); SCL=0; SDA=1; } /************************************************************ ******************/ void NoAck() //非应答信号 { SDA=1; SCL=1; _nop_(); _nop_(); SCL=0; SDA=0; } /************************************************************ ******************/ bit TestACk()//检查应答信号 { bit Cack=0; SDA=1; SCL=1; Cack=SDA; SCL=0; return(Cack); } /************************************************************ ******************/ void WriteByte(uchar input)//向I2C从设备中写入1字节 { uchar i; for(i=8;i!=0;i--) { SDA=(bit)(inupt&0x80); SCL=1; _nop_(); _nop_();

单片机模拟I2C总线及AT24C01应用实例(格式整理版)

单片机模拟I2C总线及AT24C01应用实例(格式整理版) I2C(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。I2C总线产生于在80年代,最初为音频和视频设备开发,如今主要在服务器管理中使用,其中包括单个组件状态的通信。例如管理员可对各个组件进行查询,以管理系统的配置或掌握组件的功能状态,如电源和系统风扇。可随时监控内存、硬盘、网络、系统温度等多个参数,增加了系统的安全性,方便了管理。 1.I2C总线特点 I2C总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。 2.I2C总线工作原理 2.1总线的构成及信号类型 I2C总线是一种串行数据总线,只有二根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。在CPU与被控IC之间、IC与IC之间进行双向传送,最高传送速率100kbps。各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址,在信息的传输过程中,I2C总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能。CPU发出的控制信号分为地址码和控制量两部分,地址码用来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对比度、亮度等)及需要调整的量。这样,各控制电路虽然挂在同一条总线上,却彼此独立,互不相关。 2.2位的传输 SDA线上的数据必须在时钟的高电平周期保持稳定数据线的高或低电平状态只有在SCL 线的时钟信号是低电平时才能改变,见图1:

51单片机学习心得

51单片机学习心得 51单片机的那些事儿(一) 记:笔者在大三下学期开始接触51系列单片机,历时120天的苦苦琢磨,方有小成,回首望去,颇有感慨。现将心得分享一下。希望对广大志同道合之士有所启发和帮助。 一,单片机到底是个什么东东 初学单片机,很容易被吓到,看着密密麻麻的管脚,还有一堆什么诸如MOV,DJNZ,AJMP,ORG,EQU等等让人头疼不已的东东,确实摸不着头脑。 不用怕,单片机就是一个数字集成电路,一个芯片,可以以一定的频率执行你规划好的一个过程,快速守时,节能高效,并且指令相对精简,过程明了,是一个很给力的助手。单片机具有其工控方面的独特优势,但是由于51系列是8位的,不适合处理多媒体,只可以做一些相对简单的流程控制。 说得再简单一些,单片机就是个什么也不知道的孩子,你教他做什么,怎么做,他就一遍遍不厌其烦的重复你教他的东西。 二,单片机的内部应用特点 单片机的应用很有特点。大体分为I/O,串行通信,PWM脉宽调制(属于I/O的一部分),定时/计数,中断这几类。至于I/O嘛,就是输入和输出,方式有并行,串行,I2C,PWM脉宽调制等等。以后会一一讲来。 (一),基础I/O应用 单片机最常见的就是I/O应用,一片51单片机,共40个引脚,有32个引脚是负责I/O的,可见单片机就是一个吞吐数据的黑盒子。

单片机首先要看的就是四个I/O端口,什么叫端口,就是负责I/O管脚与外部沟通的数据寄存器。51单片机有4个I/O端口,分别为P0,P1,P2,P3口。我们可以 直接对这四个寄存器写入数值,控制这32个管脚的电平高低,高就是1,低就是0。 这四个端口一共管辖32个管脚,单片机中的布尔操作(按位操作)是很人性化的,我们可以针对这32个管脚中的某一个管脚进行单独控制。例如,我们让P2.1管脚位高电平,那么我们就用汇编语句“SETB P2.1”或者C51语句,“SBIT P2_1=P2^1 P2_1=1”即可实现。 当然,你会发现,很多集成芯片都是用低电平来控制的,这是为什么呢。C51单片机复位之后,P0,P1,P2,P3四个端口的值均被设置为0FF,也就是说,那32个输入输出的管脚都被设置为高电平。如果那些外部芯片的使能信号是高电平有效,还没等我们操作,刚复位,那些外部芯片就开始该干嘛干嘛去了,整个系统岂不乱了套。所以,单片机无论是控制外部电路还是从外部读取数据,一般都是对低电平很敏感。例如,我们想通过P1.1管脚接一个开关来控制P0.1上面接的LED的亮灭。因为P1.1复位后初始状态时高电平,所以我们得给它一个低电平,它才知道外部发生了情况,所以,单片机在I/O中,低电平是很常用的。 一个端口对应了8个管脚,寄存器就有8位,对应那8个管脚的高低电平,哪位是1,哪位就是高电平。如P0拥有8位,分别是P0.0,P0.1,P0.2,P0.3, P0.4,P0.5,P0.6,P0.7。P0中存入的数据也是转化为8位二进制码,最高位对应P0.7,最低位对应P0.0。例如,MOV P0,#7FH,我们发现,7FH转化成二进制是01111111,所以P0.7为低电平,P0.0为高电平。

51单片机初学者学习必须用到的汇编和C语言的例子

1.闪烁灯 1.实验任务 如图4.1.1所示:在P1.0端口上接一个发光二极管L1,使L1在不停地一亮一灭,一亮一灭的时间间隔为0.2秒。 2.电路原理图 图4.1.1 3.系统板上硬件连线 把“单片机系统”区域中的P1.0端口用导线连接到“八路发光二极管指示模块”区域中的L1端口上。 4.程序设计内容 (1).延时程序的设计方法 作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要 求的闪烁时间间隔为0.2秒,相对于微秒来说,相差太大,所以我们在 执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程 序是如何设计呢?下面具体介绍其原理:

如图4.1.1所示的石英晶体为12MHz,因此,1个机器周期为1微秒机器周期微秒 MOV R6,#20 2个机器周期 2 D1: MOV R7,#248 2个机器周期 2 2+2×248=498 20× DJNZ R7,$ 2个机器周期2×248 498 DJNZ R6,D1 2个机器周期2×20=40 10002 因此,上面的延时程序时间为10.002ms。 由以上可知,当R6=10、R7=248时,延时5ms,R6=20、R7=248时, 延时10ms,以此为基本的计时单位。如本实验要求0.2秒=200ms, 10ms×R5=200ms,则R5=20,延时子程序如下: DELAY: MOV R5,#20 D1: MOV R6,#20 D2: MOV R7,#248 DJNZ R7,$ DJNZ R6,D2 DJNZ R5,D1 RET (2).输出控制 如图1所示,当P1.0端口输出高电平,即P1.0=1时,根据发光二极管 的单向导电性可知,这时发光二极管L1熄灭;当P1.0端口输出低电平, 即P1.0=0时,发光二极管L1亮;我们可以使用SETB P1.0指令使P1.0 端口输出高电平,使用CLR P1.0指令使P1.0端口输出低电平。 5.程序框图 如图4.1.2所示

基于51单片机的IIC总线控制程序

////////////////////////////////////////////////////////////////////////////////// //函数功能:void iic_start() 启动信号 // void iic_stop(void) 停止信号 // void iic_check_answer() 应答信号 // void iic_write_byte(uchar dat) 写字节函数 // void iic_write_n_byte(uchar *buffer,uchar n) 写n个字节函数 // void iic_write_at_addr(uchar addr,uchar dat) 指定地址写字节函数// uchar iic_read_byte(void) 读字节函数 // // uchar iic_read_at_addr(uchar addr) 读指定地址字节 /////////////////////////////////////////////////////////////////////////////////// #ifndef __iic_H__ #define __iic_H__ sbit scl=P1^0; sbit sda=P1^1; //延时4us@12mhz void delay_iic() { ;;; } //启动iic总线的函数,当scl为高电平时使sda产生一个负跳变 void iic_start(void) { sda=1; delay_iic(); scl=1; delay_iic(); sda=0; delay_iic(); } //终止iic总线,当scl为高电平时使sda产生一个正跳变 void iic_stop(void) { sda=0;

51单片机的模拟IIC总线程序

/******************************************************************** VI2C_C51.C 此程序是I2C操作平台(主方式的软件平台)的底层的C子程序,如发送数据及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,它很方便的与用户程序连接并扩展..... 注意:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作 一定的修改....(本例是1us机器周期,即晶振频率要小于12MHZ) ********************************************************************/ #include /*头文件的包含*/ #include #define uchar unsigned char /*宏定义*/ #define uint unsigned int #define _Nop() _nop_() /*定义空指令*/ /* 常,变量定义区 */ /*端口位定义*/ sbit SDA=P1^3; /*模拟I2C数据传送位*/ sbit SCL=P1^2; /*模拟I2C时钟控制位*/ /*状态标志*/ bit ack; /*应答标志位*/ /******************************************************************* 起动总线函数 函数原型: void Start_I2c(); 功能: 启动I2C总线,即发送I2C起始条件. ********************************************************************/ void Start_I2c() { SDA=1; /*发送起始条件的数据信号*/

STC_89C51单片机学习手册

S7通讯的编程步骤-----自由口通讯 S7-200 通讯的编程步骤---自由口通讯
S7-200 自由口通讯是基于 RS485 通讯基础的半双工通讯, 因此, 发送和接收指令不能同时执行。 自由口通讯使用 SMB30(口 0)和 SMB130(口 1)来定义通讯口 的工作模式。SMB30/SMB130 各位的定义如下:
图 1:通讯口工作模式寄存器
使用自有口通讯,SM30.0 和 SM30.1(SM130.0 和 SM130.1=0) 必须分别为 1 和 0。 发送指令(XMT) 一、 发送指令(XMT) 使用 XMT 发送指令可以把存于缓冲区中的数据, 一次发送一个或
1

多个字节的数据,最多为 255 个。发送完最后一个字符后还可以连接 到一个发送完中断(端口 0 为 9,端口 1 位 26,见下表) 。
图 2:中断事件表
2

发送缓冲区的格式如下表所示:
图 3:发送缓冲区的格式 说明: T+0:发送信息的字节个数需要提前定义。 T+1~T+255:要发送的数据字节
和 XMT 有关的寄存器:SMB4 的 SM4.5 和 SM4.6。SM4.5=1 时,口 0 发送完毕;SM4.6=1 时,口 1 发送完毕。 由以上可以看出,有两种方法可以检测端口 0 或 1 的数据发送 状态:一种是利用中断,一种是利用寄存器 SMB4 的第 5 位(口 0) 和第 6 位(口 1) 。 接收指令(RCV) 二、 接收指令(RCV) 使用接收指令(RCV)可以从端口 0 或 1 接收一个或多个字节的 数据(最多 255 个) ,并存于数据缓冲区。接收完最后一个字节后可 以连接到一个接收完中断(口 0 是 23,口 1 是 24,见图 2 所示) 。 接收缓冲区的格式如下表所示:
3

I2C总线入门(很详细-很经典)

I2C总线入门 1)最近学习51单片机,学到A/D,D/A转换的时候发现我板子上的转换芯片不是书上所讲的ADC0804和DAC0832而是PCF8591T,看了一下它的数据手册,发现它并不是书上所说的并行传输数据,是使用I2C总线传输的。搞了两天才搞懂,写出来给大家分享一下,不足之处请务必不吝指出。 以上是I2C总线的简单介绍。 就比如说AT24C02存储芯片,和PCF8591数模模数转换芯片都支持I2C端口。(如下图)

2)接下来看如何使用I2C总线进行通信 以上是I2C总线通信的格式。

由上图可以看出进行通信需要以下几个步骤 a.初始化I2C总线 就是把SDA和SCL都变成高电平。 voidinit()?//初始化 { ?SDA=1; ?delay(); SCL=1; delay();? } delay()为延时函数 voiddelay()?//延时4-5个微秒 {;;} b.发送起始信号 就是保持SCL为高电平,而SDA从高电平降为低电平(这是I2C总线的规定,别问我为什么) void start()//起始信号 { ?SDA=1; delay(); SCL=1; ?delay(); SDA=0; ?delay(); }

c.发送地址字(芯片的硬件地址) (8591的数据手册) 前四位对同一种芯片来说是固定的,不同的芯片之间不同。就像pcf8591是1001而at24c02是1010 接下来三位A0,A1,A2是可编程的三个地址位,这里说说的编程并不是通过软件编程,而是把A0,A1,A2三个引脚接不同的电压来确定数值。接VCC表示1,接GND表示0。为什么要有这三个呢?因为有可能你在I2C总线上“并联”了不止一个相同的元件(比如说接了三个8591),那你如何来分辨你要操作的是哪一个芯片呢,就是通过设置A0,A1,A2的数值,来区别。可编程的地址一个有三位,也就是说最多可以接8个相同的芯片在同一个I2C总线上。 最后一位是读/写位,1为读,0为写。 @如何写数据 写数据只需要按照时序图 1.先将SCL置0(只有它为0的时候SDA才允许变化) 2.改变SDA是数值(就是你当前要穿的一位是0还是1)

云龙电子-51单片机视频教程简介

小王老师51单片机视频教程简介本视频教程是针对YL-51单片机开发板讲的配套DVD视频教程目录: 讲次内容细节 第一课如何学好单片机单片机能做什么,学习单片机需要什么,如何学好单片机技术。 第二课预备知识点亮一个发光管认识单片机由来及内部结构,单片机最小工作单元组成;单片机开发软件操作:KEIL软件开发环境认识、单片机烧录软件使用。 第三课预备知识 C51基础知识及流水灯设计简单延时程序、子程序调用、、流水灯同时蜂鸣器响、如何驱动蜂鸣器,及如何驱动继电器,集电极开路的概念及应用。 第四课数码管显示的原理,数码管的静态显示共阳、共阴数码管显示原理、带参数子程序设计。 第五课中断和定时器原理定时器工作方式介绍、重点讲述工作方式2、中断概念及中断函数写法、定时器中断应用 第六课数码管的动态显示原理及应用实现动态扫描概念及定时器、中断加深 第七课按键学习:独立按键和矩阵按键键盘检测、消抖、键盘编码、带返回值函数写法及应用 第八课数模转换(DA)工作原理及应用数字电压与模拟电压的关系、如何使用DAC0832的实成DA转换 第九课模数转换(AD)工作原理及应用模拟电压与数字电压的关系,如何使用ADC0804的实成AD转换 第十课1602液晶显示原理及实现最简单液晶工作原理、如何开始对一个没有任何概念的芯片开始单片机的操作 第十一课串口原理及应用串口通讯工作方式、重点讲述最常用的10位数据通讯、波特率概念及如何根据波特率计算定时器初值 第十二课IIC总线原理和模块化编程方法 IIC总线工作原理、目前非常通用的一种通信机制; 项目开发模块化编程方法。 第十三课红外通信原理及应用红外通信是目前应用最为广泛的通信和遥控手段。在本课程中以红外遥控为代表,具体讲解红外通信的具体过程。

1小时学会51单片机C语言入门教程

1小时学会51单片机C语言入门教程相信很多爱好电子的朋友,对单片机这个词应该都不会陌生了吧。不过有些朋友可能只听说他叫单片机,他的全称是什么也许并不太清楚,更不用说他的英文全称和简称了。单片机是一块在集成电路芯片上集成了一台有一定规模的微型计算机。简称为:单片微型计算机或单片机 (Single Chip Computer)。单片机的应用到处可见,应用领域广泛,主要应用在智能仪表、实时控制、通信、家电等方面。不过这一切都没什么关系,因为我(当然也包括任何人)都是从不知道转变成知道的,再转变成精通的。现在我只想把我学习单片机的经历,详细地讲叙给大家听听,可能有些大虾会笑话我,想:那么简单的东西还在这里卖弄。但是你错了,我只是把我个人学习的经历讲述一遍而已,仅仅对那些想学习单片机,但又找不到好方法或者途径的朋友,提供一个帮助,使他们在学习过程中,尽量少走些弯路而已~ 首先,你必须有学习单片机的热情,不是说今天去图书馆看了一个下午关于单片机的书,而明天玩上半天,后天就不知道那个本书在讲什么东西了。还是先说说我吧,我从大二的第一个学期期末的时候才开始接触单片机,但在这之前,正如上面所说的:我知道有种芯片叫单片机,但是具体长成什么样子,却一点也不知道~看到这里很多朋友一定会忍不住发笑。嘿嘿,你可千万别笑,有些大机长成什么样子呢~而我对单片机的痴迷更是常四毕业的人也同样不知道单片人所不能想象的地步,大二的期末考试,我全放弃了复习,每当室友拿着书在埋头复习的时候,我却捧着自己从图书馆借的单片机书在那看,虽然有很多不懂, 或但是我还是坚持了下来,当时我就想过,为了单片机值不值得我这样去付出,许这也是在一些三流学校的好处吧,考试挂科后,明年开学交上几十元一门

51单片机学习心得

51单片机的那些事儿(一) 记:笔者在大三下学期开始接触51系列单片机,历时120天的苦苦琢磨,方有小成,回首望去,颇有感慨。现将心得分享一下。希望对广大志同道合之士有所启发和帮助。 一,单片机到底是个什么东东 初学单片机,很容易被吓到,看着密密麻麻的管脚,还有一堆什么诸如MOV,DJNZ,AJMP,ORG,EQU等等让人头疼不已的东东,确实摸不着头脑。 不用怕,单片机就是一个数字集成电路,一个芯片,可以以一定的频率执行你规划好的一个过程,快速守时,节能高效,并且指令相对精简,过程明了,是一个很给力的助手。单片机具有其工控方面的独特优势,但是由于51系列是8位的,不适合处理多媒体,只可以做一些相对简单的流程控制。 说得再简单一些,单片机就是个什么也不知道的孩子,你教他做什么,怎么做,他就一遍遍不厌其烦的重复你教他的东西。 二,单片机的内部应用特点 单片机的应用很有特点。大体分为I/O,串行通信,PWM脉宽调制(属于I/O的一部分),定时/计数,中断这几类。至于I/O嘛,就是输入和输出,方式有并行,串行,I2C,PWM脉宽调制等等。以后会一一讲来。 (一),基础I/O应用 单片机最常见的就是I/O应用,一片51单片机,共40个引脚,有32个引脚是负责I/O的,可见单片机就是一个吞吐数据的黑盒子。 单片机首先要看的就是四个I/O端口,什么叫端口,就是负责I/O管脚与外部沟通的数据寄存器。51单片机有4个I/O端口,分别为P0,P1,P2,P3口。我们可以

直接对这四个寄存器写入数值,控制这32个管脚的电平高低,高就是1,低就是0。 这四个端口一共管辖32个管脚,单片机中的布尔操作(按位操作)是很人性化的,我们可以针对这32个管脚中的某一个管脚进行单独控制。例如,我们让P2.1管脚位高电平,那么我们就用汇编语句“SETB P2.1”或者C51语句,“SBIT P2_1=P2^1 P2_1=1”即可实现。 当然,你会发现,很多集成芯片都是用低电平来控制的,这是为什么呢。C51单片机复位之后,P0,P1,P2,P3四个端口的值均被设置为0FF,也就是说,那32个输入输出的管脚都被设置为高电平。如果那些外部芯片的使能信号是高电平有效,还没等我们操作,刚复位,那些外部芯片就开始该干嘛干嘛去了,整个系统岂不乱了套。所以,单片机无论是控制外部电路还是从外部读取数据,一般都是对低电平很敏感。例如,我们想通过P1.1管脚接一个开关来控制P0.1上面接的LED的亮灭。因为P1.1复位后初始状态时高电平,所以我们得给它一个低电平,它才知道外部发生了情况,所以,单片机在I/O中,低电平是很常用的。 一个端口对应了8个管脚,寄存器就有8位,对应那8个管脚的高低电平,哪位是1,哪位就是高电平。如P0拥有8位,分别是P0.0,P0.1,P0.2,P0.3,P0.4,P0.5,P0.6,P0.7。P0中存入的数据也是转化为8位二进制码,最高位对应P0.7,最低位对应P0.0。例如,MOV P0,#7FH,我们发现,7FH转化成二进制是01111111,所以P0.7为低电平,P0.0为高电平。 我们用MOV指令向P0,P1,P2,P3四个端口寄存器写入数值,那32个管脚就会对应出现高低电位,1就是高,0就是低。还可以对某一个管脚单独控制高低电位,例如:让P0.0呈现高电位,则SETB P0.0,让3.1出现低电位,则CLR P3.1。 通过I/O,我们可以实现彩灯循环,彩灯闪烁等等简单的实验,还可以实现按键

51单片机i2c协议示例程序

#include #include #define uint unsigned int #define uchar unsigned char sbit sda=P3^5; sbit scl=P3^4; void start_bit(); void stop_bit(); void slave_ack(); void no_ack(); void write_byte(uchar dat); uchar read_byte(); void write_date(uchar addr,uchar date); uchar read_date(uchar addr); void delay(uint x); void main() { uchar num; write_date(0x01,0xaa); delay(2); num=read_date(0x01); P0=num; while(1); } void start_bit() //开始位 { scl=1; _nop_(); sda=1; _nop_(); sda=0; _nop_(); scl=0; } void stop_bit() //停止位

{ sda=0; _nop_(); scl=1; _nop_(); sda=1; } void slave_ack() //应答信号 { _nop_(); _nop_(); scl=0; _nop_();; sda=1; _nop_(); _nop_(); scl=1; _nop_(); _nop_(); while(sda); //P0=0xfe; scl=0; } void no_ack() //无应答 { sda=1; _nop_(); scl=1; _nop_(); scl=0; } void write_byte(uchar dat) //写一个字节{ uchar i; scl=0; for(i=0;i<8;i++) { if(dat&0x80) sda=1; else sda=0;

相关主题
文本预览
相关文档 最新文档