当前位置:文档之家› 基于AT89C51单片机的微型PLC详解

基于AT89C51单片机的微型PLC详解

基于AT89C51单片机的微型PLC详解
基于AT89C51单片机的微型PLC详解

基于AT89C51单片机的微型PLC详解

2011-05-19 10:35:57 来源:电子工程网编辑:赵远征作者:佚名评论:0

可编程控制器PC(Programmable Controller),为与个人计算机PC(Personal Computer)相区别,可简称为PLC。它是按照成熟而有效的继电控...

可编程控制器PC(Programmable Controller),为与个人计算机PC(Personal Computer)相区别,可简称为PLC。它是按照成熟而有效的继电控制概念和设计思想,用先进的单片机技术来实现I/O的实时检测和控制,可靠性高,编程简单、易学,因此,得到广泛应用。

将PLC技术引进电工学、电力拖动课程,是课程建设现代化的重要措施。在教学经费相对紧张的情况下,我们自己动手,以AT89C51单片机为核心,设计并研制了LD型微型PLC,应用于继电控制实验,取得了良好的效果。

用单片机构成的PLC,实际上就是一个单片机测控系统。用这样一个程序控制的计算机系统去执行继电控制的梯形图程序,由于继电控制梯形图中各被控电器之间是并行关系,而计算机程序控制中,各被控电器之间在时间上是串行关系,二者显然不协调。若简单地像一般单片机测控系统一样,对梯形图各程序行依次实时采集输入端子状态,进行处理后实时输出,是达不到控制目的的。为此,必须采用一次性采集全部输入端子状态,并将其存入输入缓冲区。然后,按梯形图程序行的逻辑关系,从输入缓冲区读取相应输入端子状态,处理后将待输出的结果存入输出缓冲区。最后,待梯形图程序行全部执行完毕,一次性将输出缓冲区的值输出到相应的输出端子,从而完成一个程序执行周期。如此往复,自动进行下一轮的采集输入端子状态……。这种工作方式即称为扫描方式,它将串行程序工作和电器并行工作两种关系协调了起来。另外,单片机执行一条指令的时间是μs级,执行一个扫描周期的时间为几ms乃至几十ms。相对于电器的动作时间而言,扫描周期是短暂的,可以认为在一个扫描周期内输入端子的状态是不变的,而对其状态变化的采集和处理也是实时的,从而满足了实时控制的要求。

系统硬件配置以AT89C51(以下简称51)单片机为核心,如图1所示。该单片机有4 KB闪存,不必扩展程序存储器,其4个I/O口共32个I/O引脚,都可供用户使用,其中P0.7~0.0,P2.4~2.0共13个脚经光耦隔离后连到相应的输入端子X07~X00,X14~X10。可以用行程开关、液位开关、霍耳开关和手动按钮等进行输入。开关接通时,相应引脚为"0",取反后存入输入缓冲区。

P1.7~1.0共8个引脚用于输出控制:P1.i为"0"时,相应的PNP管导通,继电器Ji线圈通电,其触点Y5i接通,可驱动220 V/3 A的负载。

为了与PC机进行通信,系统扩展了RS-232C接口电路。51单片机的RXD和TXD 信号经RS-232C电平变换后接至9芯插座。由此可与PC机进行串行通信。一方面,在编程状态时,可接收PC机上梯形图汇编程序编译结果的OBJ指令代码,并存入程序存储器;另一方面,在运行状态时,可将I/O口的状态和处理结果实时地发送给上位机。

程序存储器选用有SPI接口的X25045芯片。这是带可编程看门狗和电源监控功能的E2PROM,有512字节,每字节可擦写10万次,数据可保存100年。上电时自动提供200 ms高电平复位脉冲;有三种可编程看门狗周期;电源欠压,VCC降到转折点时,自动提供复位脉冲。E2PROM采用三线总线的串行外设接口SPI,既节省了I/O口线和电路板空间,又降低了系统成本。因此,该芯片是性价比极好的组合芯片。

软件设计分为PC机梯形图汇编程序编译软件和51单片机软件两部分。前者用IBM-PC汇编语言编写,我们称之为PLC编译软件。本机中我们自己设计了一套TD型PLC 的梯形图汇编语言指令系统,有LD/LDI、AN/ANI、OR/ORI、TM/TMI、CN/CNI、MA/MAI、OUT、JP/JE和END等16条基本指令和X00~07、X10~14、Y00~07、CN0~1、TM00~07、MA00~07、10~17等器件。用它们来描述继电器梯形图,即设计梯形图汇编程序。用全屏幕编辑软件将其输入到PC机,即建立了源程序文件。然后用PLC编译软件将其编译成PLC 目标程序文件(OBJ文件),并经串行通信口发送到单片机,由单片机将其写入E2PROM。

51单片机软件由编程软件和运行软件组成。编程软件主要有串行通信和写E2PROM两个模块。此时,须将面版上的手动开关设置P2.7="0",单片机即处于编程状态。当P2.7="1"时,单片机即处于运行状态。运行状态的程序主要有:

(1)输入端子采集模块

该模块两次采集P0口和P1口状态,结果全同时为有效,即将其存入输入缓冲区,否则重新采集。用软件滤波的方法,提高了抗干扰能力。

(2)指令分析模块

该模块从000H地址开始,依次读取E2PROM中的字节内容,先读出操作码,对其分析后转向相应的处理程序;接着读操作数,供处理程序操作,从而完成一条梯形图汇编指令的执行。然后再读取下一条指令的操作码……。遇到OUT指令时,将待输出的数据存入相应的输出缓冲区。

(3)输出模块

当CPU从E2PROM中读到END指令的二进制代码时,表示一次扫描周期结束,即将输出缓冲区的内容一次性输出到P1口,从而完成输出端子的刷新。

该PLC的应用可以用水塔水位控制的例子来说明。

图2(a)是硬件接线图,SB1/SB2是启动/停止按钮;SAC是水池液位开关:水浸到时接通,无水时断开;SAH、SAL分别是水塔的高低液位开关;M是水泵电机。

图2(b)是继电器梯形图,图2(c)是继电器汇编程序,即TD型PLC源程序。其中y50是PLC输出端子,我们将它的软件触点y50作为水位上升或下降的标志:y50="0",表示电机已停,水位下降,此时SAL虽已接通,但电机不动作;y50="1",表示电机正在抽水,水位上升,此时SAL接通,电机通电,继续抽水,直到高水位。

一个单片机小程序编写

一个单片机小程序编写 单片机在家用电器和工业系统中应用广泛,下面给大家介绍一个单片机小程序的编写。 1、设计任务: 如果开关合上,L1亮,开关打开,L1熄灭,如图1所示。监视开关K1(接在P3.0端口上),用发光二极管L1(接在单片机P1.0端口上)显示开关状态。 2、电路原理图: 图1 3、系统板上硬件连线:如图1所示,图中VCC = +5V。 4、程序设计内容: (1)开关状态的检测过程: 开关状态是从单片机的P3.0端口输入信号,当拨开开关K1拨上去(开关断开),即输入高电平;当拨动开关K1拨下去(开关闭合),即输入低电平。可以采用JB BIT,REL 指令来完成对开关状态的检测即可。 (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、程序框图:如图2所示。

图2 6、汇编源程序的编写: ORG 00H START: JB P3.0,D1 CLR P1.0 SJMP START D1: SETB P1.0 SJMP START END 7、用“keil软件编”写好汇编程序,然后转换成HEX文件并保存。 8、用“增强型A51编程器”把刚才写好的HEX文件烧写入单片机中。 9、把已写入程序的单片机,装入图1的电路,然后通电。当拨动开关K1拨下去(开关闭合),发光二极管L1亮;拨开开关K1拨上去(开关断开),发光二极管L1灭。说明刚才编写的程序达到了我们的设计要求。

单片机考试小程序

编程题 1,清零程序 将片外数据存储器中5000h~500ffh单元全部清零 ORG OOOOH MOV DPTR, #5000H MOV R0,#00H CLR A LOOP: MOVX @DPTR,A INC DPTR DJNZ RO,LOOP HERE: SJMP HERH 2.试着编写程序,查找在内部 RAM的20h~40h单元中出现00h这一数据的次数将查到的结果存入41h单元 ORG 0000H MOV R0,#20H MOV R1,#21H MOV 41H,#00H LOOP: CJNE @RO,#00H,NEXT INC 41H NEXT: INC R0 DJNZ RI,LOOP HERE: SJMP HERE 3查找在内部RAM的30h~50单元中是否有0AAH这一数据,若有则将51H单元置为01H;若未找到;则将51H单元置为00H. ORG 0000H MOV R0,#30H MOV R1,#21H LOOP: CJNE @R0,0AAH,NEXT MOV 51H,#01H SJMP HERE NEXT: INC R0 DJNZ R1,LOOP MOV 51H,#00H HERE: SJMP HERE 4编写程序功能为把1000H开始的外部RAM单元中的数据送到内部RAM50H开始的单元中,数据的个数存放在了内部RAM60H单元。 ORG 0000H MOV DPTR #1000H MOV R0,#50H MOV R1,60H LOOP: MOVX A,@DPTR MOV 50H,A INC DPTR INC R0

DJNZ RI,LOOP HERE: SJMP HERE 5.编写请将ROM3000H单元内容送R7. ORG 0000H MOV DPTR, #3000H CLR A MOVC A ,@A+DPTR MOV R7,A END 6.片外RAM2000H单元内容送到片外RAM1000H的单元中。 ORG 0000H MOV DPTR,#2000H MOVX A,@DPTR MOV DPTR,,#1000H\ MOVX @DPTR,A 7.锯齿形波: ORG 2000H START: MOV R0,#0FEH MOV A,#00H LOOP: MOVX @R0,A INC A SJMP LOOP 8三角形波 ORG 2000H START MOV R0,#0FEH MOV A,#00H UP: MOVX @R0,A INC A JNZ UP DOWN: DEC A MOVX @DPTR,A JNZ DOWN SJMP UP

单片机C语言编程实例

单片机C语言编程实例 前言 INTEL公司的MCS-51单片机是目前在我国应用得最广泛的单片机之一.随着 单片机应用技术的不断发展,许多公司纷纷以51单片机为内核,开发出与其兼容的 多种芯片,从而扩充和扩展了其品种和应用领域。 C语言已成为当前举世公认的高效简洁而又贴近硬件的编程语言之—。将C语言向单片机上的移植,始于20世纪80年代的中后期。经过十几年的努力,C语言终于成为专业化单片机上的实用高级语言。用C语言编写的8051单片机的软件,可以大大缩短开发周期,且明显地增加软件的可读性,便于改进和扩充,从而研制出规模更大、性能更完善的系统。因此,不管是对于新进入这一领域的开发者来说,还是对于有多年单片机开发经验的人来说,学习单片机的C语言编程技术都是十分必要的。. C语言是具有结构化.模块化编译的通用计算机语言,是国际上应用最广.最多的计算语言之一。C51是在通用C语言的基础上开发出的专门用于51系列单片机编程的C语言.与汇编语言相比,C51在功能上.结构上以及可读性.可移植性.可维护性等方面都有非常明显的优势。目前 最先进、功能最强大、国内用户最多的C51编译器是Keil Soft ware公司推出的KeilC51。第 一章单片机C语言入门 1.1建立您的第一个C项目 使用C语言肯定要使用到C编译器,以便把写好的C程序编译为机器码, 这样单片机才能执行编写好的程序。KEIL uVISION2是众多单片机应用开发软 件中优秀的软件之一,它支持众多不同公司的MCS51架构的芯片,它集编辑, 编译,仿真等于一体,同时还支持PLM、汇编和C语言的程序设计,它的界面 和常用的微软VC++的界面相似,界面友好,易学易用,在调试程序,软件仿真 方面也有很强大的功能。因此很多开发51应用的工程师或普通的单片机爱好者,都对它十分喜欢。 以上简单介绍了KEIL51软件,要使用KEIL51软件,必需先要安装它。KEIL51是一个商业的软件,对于我们这些普通爱好者可以到KEIL中国代理周 立功公司的网站上下载一份能编译2K的DEMO版软件,基本可以满足一般的个

单片机C语言小程序

单片机C语言小程序 #include #include #define V AR XBYTE[0x00] /*V AR为外部位址0000*/ #define read 0 /*93c46读取的识别码READ=0*/ #define write 2 /*93c46写入的识别码WRITE=2*/ #define ewen 4 /*93C46写致能的识别码EWEN=4*/ #define ewds 6 /*93C46写除能的识别码EWDS=6*/ #define cs INT0 /*93C46 CS接脚=8051 RD P3.2*/ #define clk INT1 /*93C46 CLK接脚=8051 WR P3.3*/ #define di T0 /*93C46 DI接脚=8051 T1 P3.4*/ #define d0 T1 /*93C46 DO接脚=8051 T0 P3.5*/ #define LOW 0x49 /*存放测试温度的下限值*/ #define HIGH 0x51 /*存放测试温度的上限值*/ bit FLAG0=0; /*宣告TIMER0响应旗号*/ //外接工业专用温度传感器时,目前设置测量温度为0-99度: static const char tab[13]={0x3a,0x53,0x6f,0x8a,0xa3, /*0度,10度,20度,30度,40度*/ 0xB8,0xC8,0xD5,0xDE,0xE5, /*50度,60度,70度,80度,90度*/ 0xEA,0xEE}; /*100度,110度*/ //使用板上AD590温度传感器时,目前设置测量温度为0-99度: //static const char tab[13]={0x88,0x8d,0x92,0x97,0x9c, /*0度,10度,20度,30度,40度,*/ // 0xa1,0xa6,0xab,0xb0,0xb5, /*50度,60度,70度,80度,90度*/ // 0xba,0xc0}; /*100度,110度*/ char data1[2]; char C,S,k=0; char MEP[7]; /*显示器值存放阵列*/ //MEP[0]=数码管最低位显示值,温度指示小数点后位 //MEP[1]=数码管次低位显示值,温度指示个位数 //MEP[2]=数码管高位显示值,温度指示十位数 //MEP[3]=数码管最低位显示值,功能显示目前定为1,2,3,4,5 //MEP[4]= //MEP[5]=暂放置温度显示值,高4位为温度指示十位数值,低4位为温度指示个位数值//MEP[6]=在温度显示与电压调整副程式中,将测量值C暂存MEP[6]中 unsigned char combuf[10]; unsigned char ADR46,CH,CL,m,C1,C2; /*ADR46,93C46位址,CH高位元组,CL低*/ int sec,sec1; char ptr=0,ptr1=0x10,psr=0; /*ptr显示器值存放阵MEP[]指标,ptr1显示器扫描指标*/ char count=100,sb=0; void delay (unsigned int value) /*延时副程式*/ { while (value!=0) value--; /*10us延时*/ } void COMP(); /*宣告比较现在温度与设定温度副程式*/ void SET();

单片机c程序编写

单片机C语言编程基础 时间:2011-05-01 22:47:26来源:作者: 单片机的外部结构: 1、DIP40双列直插; 2、P0,P1,P2,P3四个8位准双向I/O引脚;(作为I/O输入时,要先输出高电平) 3、电源VCC(PIN40)和地线GND(PIN20); 4、高电平复位RESET(PIN9);(10uF电容接VCC与RESET,即可实现上电复位) 5、内置振荡电路,外部只要接晶体至X1(PIN18)和X0(PIN19);(频率为主频的12倍) 6、程序配置EA(PIN31)接高电平VCC;(运行单片机内部ROM中的程序) 7、P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1 单片机内部I/O部件:(所为学习单片机,实际上就是编程控制以下I/O部件,完成指定任务) 1、四个8位通用I/O端口,对应引脚P0、P1、P2和P3; 2、两个16位定时计数器;(TMOD,TCON,TL0,TH0,TL1,TH1) 3、一个串行通信接口;(SCON,SBUF) 4、一个中断控制器;(IE,IP) 针对AT89C52单片机,头文件AT89x52.h给出了SFR特殊功能寄存器所有端口的定义。教科书的160页给出了针对MCS51系列单片机的C语言扩展变量类型。 单片机C语言编程基础 1、十六进制表示字节0x5a:二进制为01011010B;0x6E为01101110。 2、如果将一个16位二进数赋给一个8位的字节变量,则自动截断为低8位,而丢掉高8位。 3、++var表示对变量var先增一;var—表示对变量后减一。 4、x |= 0x0f;表示为x = x | 0x0f; 5、TMOD = ( TMOD & 0xf0 ) | 0x05;表示给变量TMOD的低四位赋值0x5,而不改变TMOD的高四位。 6、While( 1 ); 表示无限执行该语句,即死循环。语句后的分号表示空循环体,也就是{;} 在某引脚输出高电平的编程方法:(比如P1.3(PIN4)引脚) #include //该头文档中有单片机内部资源的符号化定义,其中包含P1.3 void main( void ) //void 表示没有输入参数,也没有函数返值,这入单片机运行的复位入口 { P1_3 = 1; //给P1_3赋值1,引脚P1.3就能输出高电平VCC While( 1 ); //死循环,相当LOOP: goto LOOP; } 注意:P0的每个引脚要输出高电平时,必须外接上拉电阻(如4K7)至VCC电源。 在某引脚输出低电平的编程方法:(比如P2.7引脚) #include //该头文档中有单片机内部资源的符号化定义,其中包含P2.7 void main( void ) //void 表示没有输入参数,也没有函数返值,这入单片机运行的复位入口 { P2_7 = 0; //给P2_7赋值0,引脚P2.7就能输出低电平GND While( 1 ); //死循环,相当LOOP: goto LOOP; } 在某引脚输出方波编程方法:(比如P3.1引脚) #include //该头文档中有单片机内部资源的符号化定义,其中包含P3.1 void main( void ) //void 表示没有输入参数,也没有函数返值,这入单片机运行的复位入口 {

STC向单片机发送数据小程序(C语言)

#include"stc12c5a60s2.h" #define uchar unsigned char; void initiate(void); void check_zero(void); void time0_on(void); void send_char(void); uchar shu,t,n=1,i=0; uchar code value[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; //************************************************************** void main() { initiate(); for(;;) check_zero(); } //**************************************************************** void initiate(void) { TMOD=0X21; //定时器T1溢出提供波特率,定时器T0定时。 TL1=0XFD; //fosc=11.0592mHz,波特率9600bps对应初值 TH1=0XFD; PCON=0X00; //波特率不加倍。 SCON=0X50; //串口工作方式一,允许接受。 ET1=0; EA=1; TR1=1; } //***************************************************************** void check_zero(void) { if(RI==1) { if(SBUF==0) { RI=0; SCON=0X40;

教你如何用C++写单片机程序

教你如何用C++写单片机程序 关键词:C++ 面向对象单片机 从大一就开始学习单片机,学51,A VR编程都使用C语言的风格,即面向过程,只要能画出程序流程图,程序基本就born了。我热衷于编程,尤其是C++,当时想有没有一天,C++的类和对象也能出现在单片机中? 历经世事沧桑,事到如今,我终于有机会,和大家一起学习使用真正面向对象的C++来控制单片机。目前单片机编译器大部分只支持C语言,C++还不够普及,但我们有理由相信,有着更先进的面向对象的理念,有更加平易近人的类和继承,C++必将取代C,成为单片机程序的主流。试看将来环球单片机,必是C++的世界! 下面大家跟着我来一起学习怎么用C++给单片机编程序!本文要求大家玩过A VR单片机,有过C语言编程经验,而且要对VC6.0开发环境有一定了解。 必备软件:VC6.0(用于编辑源程序),WinA VR(用于生成Makefile,支持A VR系列单片机),Proteus(用于仿真调试)。 首先,你的电脑上要装有VC6.0,进入后选菜单【file】---【new】新建工程,如图1选择Makefile工程,输入工程名称,路径,点确定。 图1_新建工程 一路OK建好工程,界面如图2。这个工程是专门写makefile脚本的,你如果学A VR单片机使用avr-gcc那应该对makefile有一定了解,如果想多了解一点详见https://www.doczj.com/doc/e54248772.html,/view/974566.html?wtp=tt(呵呵,百度百科)。 你还需要安装WINA VR,这是个免费软件,网上很多资源,这个软件很容易安装,一路Next 就可以啦!为了使用方便,我的WINAVR安装到了C盘根目录下的WINA VR文件夹。安装好后,可以直接用它来编辑源代码,今天我就不讲它的使用方法了,只讲怎么生成makefile。自我感觉用熟悉的VC6.0环境编写程序心情很愉快,大家还是跟我一起来,打造

单片机课程学习总结

《单片机》课程学习总结 《单片机》这门课程我已经学了一个学期了,在这一个学期的学习过程中,我一开始不怎么懂得编程,但慢慢的我现在已经不仅会读程序还会写程序了。真为自己一个学期来努力学到的单片机知识只是而感到高兴。 怎么学单片机?也常看到有人说学了好几个月可就是没有什么进展。当然,受限于每个人受到的教育水平不同和个人理解能力的差异,学习起来会有快慢之分,但我感觉最重的就是学习方法。一个好的学习方法,能让你事半功倍,这里说说我学习单片机的经历和方法。 我觉得学习单片机首先要懂得C语言,因为单片机大多说都是靠程序来实现的,如果看不懂程序或则不懂的编程是很难学会单片机的。学习单片机首先要明白一个程序是怎么走的,要完全懂得程序每一个步骤的意思。其次要懂得每一条指令的意思,不能盲目地去靠背指令,这是记得不牢靠的,最主要的还是靠了解。学习单片机最主要的对89C51芯片内部结构有全方面的,只要了解了89C51才能知道单片机实现什么样的功能和作用,才能对单片机有更深一步的了解。 通过一个学期《单片机》这门课程的学习,我也从中有了不少心得和体会想和大家分享一下。 万事开头难、要勇敢迈出第一步。开始的时候,不要老是给自己找借口,不要说单片机的程序全是英文,自己看不懂。遇到困难要一件件攻克,不懂指令就要勤奋看书,不懂程序就先学它,这方面网上教程很多,随便找找看一下,做几次就懂了。然后可以参考别的人程序,抄过来也无所谓,写一个最简单的,让它运行起来,先培养一下自己的感觉,知道写程序是怎么一回事,无论写大程序还是小程序,要做的工序不会差多少。然后建个程序,加入项目中,再写代码、编译、运行。必须熟悉这一套工序。个人认为,一块学习板还是必要的,写好程序在上面运行一下看结果,学习效果会好很多,仿真器就看个人需要了。单片机是注重理论和实践的,光看书不动手,是学不会的。 知识点用到才学,不用的暂时丢一边。厚厚的一本书,看着人头都晕了,学了后面的,前面的估计也快忘光了,所以,最好结合实际程序,用到的时候才去看,不必说非要把书从第一页看起,看完它才来写程序。比如你写流水灯,完全就没必要看中断的知识,专心把流水灯学好就是了,这是把整本书化整为零,一小点一小点的啃。 程序不要光看不写,一定要自己写一次。最开始的时候,什么都

单片机入门小程序

51单片机的学习是一个动手实践的过程,很多同学在学习单片机的初期总是觉得很难,无法入门。本人根据自己的学习经历,结合自己刚学习单片机的体验,写下几个小的程序供大家参考,如能掌握如下几个小程序的思想与精髓,那么就已经探踏入了单片机的大门。学习单片机的核心就是动手实践,当我们通过自己的努力把第一个LED点亮时,我们就会信心加倍,之后的学习就会变得轻松!希望对大家有所帮助。 一个LED闪烁 #include sbit led=P0^3; unsigned int a; void main() { P0=0x00; while(1) {a=100000; led=1; while(a--); a=10000; led=0; while(a--); } } 两个led闪烁 #include #define uchar unsigned char #define uint unsigned int void delay(); void main() { while(1) { P0=0xaa; delay(); P0=0x00; delay(); } } void delay() { uchar x,y; for(x=110;x>0;x--) for(y=120;y>0;y--); } 流水灯 #include #include void delay(); void main() { unsigned char temp;

P0=0xef; temp=P0; delay(); while(1) { temp=_crol_(temp,1); delay(); } } void delay() { unsigned char x,y; for(x=40;x>0;x--) for(y=200;y>0;y--); } 键控移位信号灯 #include #include #define uchar unsigned char #define uint unsigd neint sbit k1=P1^0; sbit k2=P1^1; void delay(uchar z); void main() { P0=0X18; while(1) { if(k1) P0=_crol_(P0,1); if(k2) P0=_cror_(P0,1); } } void delay(uchar z) { uchar x,y; for(x=z;x>0;x--) for(y=120;y>0;y--) ;} 中断的简单应用 1. 利用定时器中断实现LED闪烁#include #define uchar unsigned char #define uint unsigned int sbit led1=P1^0; uchar num; void main() { P1=0x00;

单片机程序设计方法

第十六课单片机程序设计方法 程序设计是单片机开发最重要的工作程序设计就是利用单片机的指令系统根据应用系统即 目标产品的要求编写单片机的应用程序其实我们前面已经开始这样做过了这一课我们不是讲如何来设计具体的程序而是教您设计单片机程序的基本方法不过在讲解之前还是有必要先了解一下单片 机的程序设计语言 一程序设计语言 这里的语言与我们通常理解的语言是有区别的它指的是为开发单片机而设计的程序语言如果您没有学过程序设计可能不太明白我给大家简单解释一下您知道微软的VB VC 吗VB VC 就是为某些工程应用而设计的计算机程序语言通俗地讲它是一种设计工具只不过这种工具是用来设计计 算机程序的要想设计单片机的程序当然也要有这样一种工具说设计语言更确切些单片机的设计语言基本上有三类 1 完全面向机器的机器语言 机器语言就是能被单片机直接识别和执行的语言计算机能识别什么以前我们讲过--是数字0 或1所以机器语言就是用一连串的0 或1 来表示的数字比如MOV A 40H 用机器语言来表示就是11100101 0100000 很显然用机器语言来编写单片机的程序不太方便也不好记忆我 们必须想办法用更好的语言来编写单片机的程序于是就有了专门为单片机开发而设计的语言 2 汇编语言 汇编语言也叫符号化语言它使用助记符来代替二进制的0 和1比如刚才的MOV A 40H 就是汇编语言指令显然用汇编语言写成的程序比机器语言好学也好记所以单片机的指令普遍采用汇编指令来编写用汇编语言写成的程序我们就叫它源程序或源代码可是计算机不能识别和执行用汇编语言写成的程序啊怎么办当然有办法我们可以通过翻译把源代码译成机器语言这个过程就叫做汇编汇编工作现在都是由计算机借助汇编程序自动完成的不过在很早以前它是靠手工来做的道听途说我也没经历过呵呵

单片机中断小程序

#include #include typedef unsigned char uc; typedef unsigned int ui; typedef unsigned long ul; void udisplay(uc m,uc n); void delay100us(); void delay1ms(); void delay100ms(); sfr P4 = 0xc0; sfr P4SW = 0xbb; sbit DAT_DIS = P0^4; /* 164 595 公用数据线*/ sbit CLK_164 = P0^5; /* 164时钟线*/ sbit CLK_595 = P0^6; /* 595时钟线*/ sbit RCLK_595 = P0^7; /* 595锁存线*/ sbit FMQ = P4^5; /* 蜂鸣器*/ uc code displayduan[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40 }; /* 0 1 2 3 4 5 6 7 8 9 SP - */ //秒分时日月星期年 uc code displaywei[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0xff}; uc a,b,c,d,e,f,g,h; ul sum; /*************************************************************/ /* 功能:在某一位数码管上显示某一个数值 /* 输入:m,n /*************************************************************/ void display(uc m,uc n) { uc wei, duan, i; wei = 0x00; for(i=0; i<8; i++) { /* 关显示*/ DAT_DIS = (bit)(wei & 0x80); wei <<= 1 ; CLK_595 = 0 ;

单片机利用中断实现时分秒时钟的简易小程序(附仿真图)

单片机利用中断实现时分秒时钟(附仿真图) 基于89c51单片机 程序: #include <> #define uchar unsigned char code unsigned char ke[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77}; code unsigned char led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar key(); //声明函数key void delay(i); //声明函数delay void main(void) { uchar i; while(1) { i=key(); P2=0x02; P0=led[i%10]; delay(50); P2=0x01; P0=led[i/10]; delay(50); } } void delay(i) //延时函数 { unsigned char j; for(;i>0;i--) for(j=0;j<120;j++); } uchar key(void) //线反转法 { uchar h,j,a; P1=0x0f; a=P1|0xf0;

if(a==0xff)return(99); { delay(10); P1=0xf0; h=P1|0x0f; P1=0xff; a=a&h; for(j=0;j<16;j++) { if(a==ke[j]) return(j); } } return(99); } 仿真图:

c语言编写使用小程序

3 单片机开发工程案例分析与解析 3.1 定时报警器 设计一个单片机控制的简易定时报警器。要求根据设定的初始值(1-59秒)进行倒计时,当计时到0时数码管闪烁“00”(以1Hz 闪烁),按键功能如下: (1)设定键:在倒计时模式时,按下此键后停止倒计时,进入设置状态;如果已经处于设置状态则此键无效。 (2)增一键:在设置状态时,每按一次递增键,初始值的数字增1。 (3)递一键:在设置状态时,每按一次递减键,初始值的数字减1。 (4)确认键:在设置状态时,按下此键后,单片机按照新的初始值进行倒计时及显示倒计时的数字。如果已经处于计时状态则此键无效。 3.1.2 模块1:系统设计 (1)任务分析与整体设计思路 根据题目的要求,需要实现如下几个方面的功能。 计时功能:要实现计时功能则需要使用定时器来计时,通过设置定时器的初始值来控制溢出中断的时间间隔,再利用一个变量记录定时器溢出的次数,达到定时1秒中的功能。然后,当计时每到1秒钟后,倒计时的计数器减1。当倒计时计数器到0时,触发另一个标志变量,进入闪烁状态。 显示功能:显示倒计时的数字要采用动态扫描的方式将数字拆成“十位”和“个位”动态扫描显示。如果处于闪烁状态,则可以不需要动态扫描显示,只需要控制共阴极数码管的位控线,实现数码管的灭和亮。 键盘扫描和运行模式的切换:主程序在初始化一些变量和寄存器之后,需要不断循环地读取键盘的状态和动态扫描数码管显示相应的数字。根据键盘的按键值实现设置状态、计时状态的切换。 (2)单片机型号及所需外围器件型号,单片机硬件电路原理图 选用MCS-51系列AT89S51单片机作为微控制器,选择两个四联的共阴极数码管组成8位显示模块,由于AT89S51单片机驱动能力有限,采用两片74HC244实现总线的驱动,一个74HC244完成位控线的控制和驱动,另一个74HC244完成数码管的7段码输出,在输出口上各串联一个100欧姆的电阻对7段数码管限流。 由于键盘数量不多,选择独立式按键与P1口连接作为四个按键输入。没有键按下时P1.0-P1.3为高电平,当有键按下时,P1.0-P1.3相应管脚为低电平。电路原理图如图3-1所示。 图3-1 定时报警器电路原理图 1A121A241A361A482A1112A2132A3152A4171Y1181Y2161Y3141Y4122Y192Y272Y352Y431G 1 2G 19U3HC2441A121A241A361A482A1112A2132A3152A4171Y1 181Y2161Y3141Y4122Y192Y272Y352Y431G 1 2G 19U4 HC244 C 9A 2B 6D 11E 12F 3G 8H 10C OM 17C OM 34C OM 25C OM 4 1U5 LED4SC H C 9 A 2B 6D 11E 12 F 3 G 8 H 10C OM 1 7C OM 3 4C OM 2 5C OM 41U6 LED4SC H LED_A LED_B LED_C LED_D LED_E LED_F LED_G LED_H LED_A1LED_B 1LED_C 1LED_D1LED_E1LED_F1LED_G1LED_H1R 2100R 3100R 4100R 6100R 7100R 8100R 9100R 10100LED_A1LED_B 1LED_C 1LED_D1LED_E1LED_F1LED_G1LED_H1LED_A1LED_B 1LED_C 1LED_D1LED_E1LED_F1LED_G1LED_H1L_COM 1L_COM 2L_COM 3L_COM 4L_COM 5 L_COM 6 L_COM 7 L_COM 8 L_COM 1L_COM 2L_COM 3L_COM 4L_COM 5L_COM 6L_COM 7L_COM 8LED_J0LED_J1LED_J2LED_J3LED_J5LED_J6LED_J7LED_J4EA/VP 31X119X218R ESET 9R D 17WR 16INT012INT113T014T115P10/T 1P11/T 2P123P134P145P156P167P178P0039P0138P0237P0336P0435P0534P0633P0732P20 21P2122P2223P2324P2425P2526P2627P2728PSEN 29ALE/P 30TXD 11R XD 10U289S52VCC LED_J0 LED_J1LED_J2LED_J3LED_A LED_B LED_C LED_D LED_E LED_F LED_G LED_H Y111.0592C 1C AP C 2C AP R 1110K R 1100 C 322U VCC S1R ESET R ST R ST KEY1KEY2KEY3KEY4LED_J4LED_J5LED_J6LED_J7R 510K R 1210K R 1310K R 1410K VCC

单片机小程序

单片机最小系统播放欢乐颂及最炫民族风片段 学习单片机,制作单片机最小系统是每个单片机爱好者的都经历过的阶段,单片机最小系统制作好有什么用呢?为提高单片机爱好者学习制作单片机最小系统兴趣,这里介绍一个有趣的单片机小程序,就是用单片机最小系统播放欢乐颂及最炫民族风片段。在按下图制作好单片机最小系统后,再增加三只元件:1个电阻、1个S9012三极管,1个8欧的小喇叭后,即可完成这个单片机最小系统播放欢乐颂及最炫民族风片段的小试验,单片机爱好者通过这个小试验后,一定会大大增强对单片机学习的兴趣。 这个单片机最小系统播放欢乐颂及最炫民族风片段的小试验,由于电路比较简单,所以这里就不画出原理图了,直接给出试验的PCB图,感兴趣的爱好者可以按图进行焊接制作,制作好后向单片机内烧写程序后安装上去就可以工作,感受一下单片机的无穷勉力。 焊好的单片机最小系统播放欢乐颂及最炫民族风片段试验板的实物照片 播放板的单片机最小系统PCB图

焊好的单片机最小系统播放试验板未装单片机的照片

焊好的单片机最小系统播放欢乐颂及最炫民族风片段试验板的实物反面照片 /****************************************************************************** / /**程序名称:单片机播放欢乐颂与最炫民族风片段 /**其他:用于时钟周期为12MHz的STC89C52单片机 /**由电子乐屋整理制作,更详细的制作资料请到电子乐屋下载https://www.doczj.com/doc/e54248772.html,/mifklrxdjqbadoq /****************************************************************************** / #include sbit BUZZER = P3^2; #define uchar unsigned char #define uint unsigned int #define REST 36 //休止符 #define A 0 //低音1 #define AB 1 //低音1.5 #define B 2 //低音2 #define BC 3 //低音2.5

c51单片机C语言编写的PWM程序

89c51单片机C语言编写的PWM程序 PWM, 单片机, C语言, 程序, 编写 分享到:新浪微博 QQ空间开心网人人网 说明:本程序使用STC89C52RC单片机,晶振,要使用本程序需要自己修改,我是用来控制直流电机的,外接了L298驱动电路,有问题或意见请回复,谢谢^_^ #include "" #include "" 转;speed<0.反转(-100~100) 调用:extern int abs(int val); 取绝对值 返回: /******************************************************************/ void motor(char speed1,char speed2) { //==============左边电机============= if (speed1>0) { IN1 =0;IN2 =1;//正转 } else if (speed1<0) { IN1 =1;IN2 =0;//反转 } //==============右边电机============= if (speed2>0) { IN3 =1;IN4 =0;//正转 } else if (speed2<0) { IN3 =0;IN4 =1;//反转 } }

/****************************************************************** 名称:motor_PWM(); 功能:PWM占空比输出 参数:无 调用:无 返回:无 /******************************************************************/ void motor_PWM () { uchar PWM_abs1; uchar PWM_abs2; PWM_abs1=MOTO_speed1; PWM_abs2=MOTO_speed2; if (PWM_abs1>PWMAnd) ENA=1; //左边电机占空比输出 else ENA=0; if (PWM_abs2>PWMAnd) ENB=1; //右边电机占空比输出 else ENB=0; if (PWMAnd>=PWM_COUST) PWMAnd=0; //PWM计数清零 else PWMAnd+=1; } /****************************************************************** 名称:void TIME_Init (); 功能:定时器初始化 指令: 调用:无 返回:无 /******************************************************************/ void TIME_Init () { //=========定时器T2初始化 PWM================== T2CON = 0x00; T2MOD = 0x00; RCAP2H = 0xff; //定时 RCAP2L = 0x47;

4课第一个单片机小程序

上一次我们的程序实在是没什么用,要灯亮还要重写一下片子,下面我们要让灯持续地闪烁,这就有一定的实用价值了,比如能把它当成汽车上的一个信号灯用了。怎样才能让灯持续地闪烁呢?实际上就是要灯亮一段时间,再灭一段时间,也就是说要P10持续地输出高和低电平。怎样实现这个要求呢?请考虑用下面的指令是否可行: SETB P1.0 CLR P1.0 …… 这是不行的,有两个问题,第一,计算机执行指令的时间很快,执行完SETB P1.0后,灯是灭了,但在极短时间(微秒级)后,计算机又执行了CLR P1.0指令,灯又亮了,所以根本分辨不出灯曾灭过。第二,在执行完CLR P10后,不会再去执行SETB P1.0指令,所以以后再也没有机会让灭了。 为了解决这两个问题,我们能做如下设想,第一,在执行完SETB P1.0后,延时一段时间(几秒或零点几秒)再执行第二条指令,就能分辨出灯曾灭过了。第二在执行完第二条指令后,让计算机再去执行第一条指令,持续地在原地兜圈,我们称之为"循环",这样就能完成任务了。 以下先给出程序(后面括号中的数字是为了便于讲解而写的,实际不用输入): ;主程序: LOOP: SETB P1.0 ;(1)熄灭灯 LCALL DELAY ;(2)延时一段时间 CLR P1.0 ;(3)点亮灯 LCALL DELAY ;(4)延时一段时间 AJMP LOOP ;(5)跳转到第一句LOOP处 ;以下子程序 DELAY: MOV R7,#250 ;(6) D1: MOV R6,#250 ;(7) D2: DJNZ R6,D2 ;(8) DJNZ R7,D1 ;(9) RET ;(10) END ;(11) 按上面的设想分析一下前面的五条指令。 第一条是让灯灭,第二条应当是延时,第三条是让灯亮,第四条和第二条一模一样,也是延时,第五条应当是转去执行第一条指令。第二和第四条实现的原理稍后谈,先看第五条,AJMP是一条指令,意思是转移,往什么地方转移呢?后面跟的是LOOP,看一下,什么地方还有LOOP,对了,在第一条指令的前面有一个LOOP,所以很直观地,我们能认识到,它要转到第一条指令处。这个第一条指令前面的LOOP被称之为标号,它的用途就是给这一行起一个名字,便于使用。是否一定要给它起名叫LOOP呢?当然不是,起什么名字,完全由编程序的人决定,能称它为A,X等等,当然,这个时候,第五条指令AJMP后面的名字也得

基于单片机D-A输出程序编写分享

基于单片机D/A输出程序编写分享 D/A 是和A/D 刚好反方向的,一个8 位的D/A,从0~255,代表了0~2.55V 的话,那么我们用单片机给第三个字节发送100,D/A 引脚就会输出一个1V 的电压,发送200 就输出一个2V 的电压,很简单,我们用一个简单的程序实现出来,并且通过上、下按键可以增大或减小输出幅度值,每次增加或减小0.1V。如果有万用表的话,可以直接测试一下板子上AOUT 点的输出电压,观察它的变化。由于PCF8591 的DA 输出偏置误差最大是50mv(由数据手册提供),所以我们用万用表测到的电压值和理论值之间的误差就应该在50mV 以内。 /*****************************I2C.c 文件程序源代码*******************************/ (此处省略,可参考之前章节的代码) /***************************keyboard.c 文件程序源代码****************************/ (此处省略,可参考之前章节的代码) /*****************************main.c 文件程序源代码******************************/ #include unsigned char T0RH = 0; //T0 重载值的高字节 unsigned char T0RL = 0; //T0 重载值的低字节 void ConfigTimer0(unsigned int ms); extern void KeyScan(); extern void KeyDriver(); extern void I2CStart(); extern void I2CStop(); extern bit I2CWrite(unsigned char dat); void main(){

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