版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 1. 基本示例分析 2.单片机应用系统设计单片机C语言编程与设计一、基本示例分析:例1、LED的控制 使用805l的Port 1连接8个LED,以产生跑马灯的效果。连接好电路并且完成程序之后,您将可以看到8个LED依次轮流闪烁。 在这次练习中,您将学会如何使用I/O Port输出数据,以及如何使用循环实现时间延迟。 电路图#include void delay (void) /* delay 函数 */ unsigned char i,j; /* 这个函数执行时间的延迟 */ for (i=0;i255;i+) for(j=0;j255;j+) ;void main (void) unsig
2、ned char j=0XFE; /*声明变量 j */ while (1) /* 无穷循环 */ /*依次让LED 0,1,2,3,4,5,6,7闪烁 */ j=(j1) | 0 x01; if(j=0XFF) j=0XFE; P1 = j; /* 将数值输出到Port1,控制LED亮或灭 */ delay(); /* 调用 delay 函数*/ 例2、指拨开关的输入 目的是使用8051的Port l连接到8个LED,Port 2则连接到1个指拨开关,当用户拨动指拨开关时,相对应的LED就会亮或灭。 在这次练习中,您将学会如何使用8051输入数据。 例如,您要从Port 2输入数据给变量te
3、mp时,可以执行temp=P2; 电路图 #include void delay (void) /* delay 函数*/ unsigned char i,j; /*这个函数执行时间的延迟 */ for (i=0;i255;i+) for(j=0;j255;j+); void main (void) unsigned char temp; /* 声明变量temp */ while (1) /* 无穷循环 */ temp=P2; /* 将P2输入的数据直接放入变量temp当中 */ P1=temp; /* 将变量temp中的数据直接输出到Port 1*/ delay(); 例3、七段显示器的控制
4、 目的是使用8051的Port 1连接到一个共阳的七段显示器,然后让8051轮流显示09。当您连接好电路,并且完成程序之后,您将看到七段显示器依次显示09。 在这次练习中,您将学会如何使用805l控制共阳七段显示器的显示。 一个共阳七段显示器的外观和引脚如图所示。这个共阳七段显示器的引脚分别连接到805l的Port l引脚。 电路图#include code seven_seg10=0XC0, 0XF9, 0XA4, 0XB0, 0X99, 0X92, 0X82, 0XF8, 0X80, 0X90;void delay (void) /* 时间延迟的函数 */ unsigned char i,
5、j; for (i=0;i255;i+) for(j=0;j255;j+) ;void main (void) unsigned char i; /* 变量 i 用来储存 09 */ while (1) /* 无穷循环 */ for (i=0; i10; i+) P1 = seven_segi; /* 输出 09 到共阳七段显示器*/ delay(); /* 调用时间延迟函数delay*/ 共阳七段显示器有一共同接点连接到5V,其余的七支引脚分别如图所示 因此如果要让所指定的LED发光时,就必须输出0,反之则输出1,所以我们可以用下表排列出所要显示字符和必须输出的信号。下表中,假设dot点接在
6、最高位,而且不点亮,所以一直都是1 。 将以上的信息编成16进制码,然后存放在定义为seven_ seg的数组中。 我们将共阳七段显示器显示出09的字型码储存在程序存储器中。当用户有固定不变的数据时,就可以储存在程序存储器中。储存在程序存储器的数据必须存声明的变景附加上code,如以下的声明方式:code seven_seg10=0XC0, 0XF9, 0XA4, 0XB0, 0X99, 0X92, 0X82, 0XF8, 0X80, 0X90;例4、计时器Timer0 的溢出中断控制 在前面,我们曾经捉到过使用for循环实现时间延迟并不是很精确,例如,程序会受到中断的执行而影响延迟时间。在这
7、次实习中,您将学会如何使用8051的Timer0计时器溢出中断实现准确的时间延迟。 本练习使用8051的Port 1连接到一个共阳七段显示器,然后利用计时计数器Timer l,让8051在指定的时间间隔内显示出09。当您连接好电路,并且完成程序之后,您将可以看到七段显示器依次显示0 9。#include #define TIMER0_COUNT 0 xEE11 const seven_seg10=0XC0, 0XF9, 0XA4, 0XB0, 0X99, 0X92, 0X82, 0XF8, 0X80, 0X90;unsigned char timer0_tick,i=0;static void
8、 timer0_isr(void) interrupt TF0_VECTOR using 1 TR0=0; TL0=(TIMER0_COUNT & 0 x00FF); TH0=(TIMER0_COUNT 8); TR0=1; timer0_tick+; if (timer0_tick=200) i+; if(i=10) i=0; timer0_tick=0; P1=seven_segi; static void timer0_initialize(void) EA=0; /* 设定系统不接受所有的中断 */ timer0_tick=0; TR0=0; /* 关闭Timer0 */ TMOD =
9、0 x01; /* 设定计时器0为16位的工作模式 */ TL0=(TIMER0_COUNT & 0 x00FF); /* 设定TL0的数值 */ TH0=(TIMER0_COUNT 8); /* 设定TH0的数值 */ PT0=0; /* 设定计时器0有比较高的优先级 */ ET0=1; /* 设定接受Timer0的中断 */ TR0=1; /* 启动Timer0 */ EA=1; /* 设定系统接受中断 */void main (void) timer0_initialize(); while (1); /* 无穷循环*/ 使用计时计数器Timer0之前,必须先执行Timer0的初始化功能
10、。Timer0初始化按照以下的步骤: (1)先暂停接受所有的中断。 (2)关闭Timer0。 (3)设置计时器0的工作模式。 (4)设置计时器0的计数器数值(TL0和TH0数值)。 (5)设置计时器0有比较高的优先级(这一个步骤可以省略)。 (6)设置接受Timer0的中断。 (7)启动Timer0。 (8)设置系统接受中断。 中断定时时间计算: 如果外接石英晶体的频率是12MHz时,因为8051的一个机械周期需要12个石英晶体的振荡周期,所以每秒就有1000 000次的机械周期,换言之机械周期是1us。如果我们希望Timer0每秒中断200次,那么我们就必须让Timer0每数5 000次就中
11、断1次(1 000 000/200=5000)。因为Timer0的溢出中断是Timer0数到65536(16进制表示时是10000H)就产生中断,因此要让Timer0数5 000次就中断1次时就必须设置Timer0等于10000H-(12000000(12200),也就是0 xEE11。接下来我们可以利用以下的指令分别设置Timer0计数器的低8位和Timer0的高8位。 TL0=(TIMER0_COUNT & 0 x00FF); /* 设定TL0的数值 */TH0=(TIMER0_COUNT 8); /* 设定TH0的数值 */Timer0的溢出中断服务程序格式如下所示: static vo
12、id timer0_isr(void) interrupt TF0_VECTOR using 1 加入中断之后必须处理的程序 其中TF0 VECTOR是定义在文件regx51.h中的常量,其数值是1,这是因为Timer0的中断向量是1。 TF0_VECTOR后面所接的using 1,表示进入Timer0的溢出中断服务程序之后会使用寄存器组1(Register Bank 1),而离开Timer0的溢出中断服务程序时编译器也会自动恢复使用原先的寄存器组 8051中有4个寄存器组,分别是寄存器组0到寄存器组3,当8051开始执行时会自动采用寄存器组0。 进入中断服务程序时采用不同的寄存器组,可以避免
13、破坏原先尚未进入Timer0溢出中断服务程序时所使用的寄存器内容。 用户当然也可以采用原先的寄存器,但是此时就必须维护寄存器的内容,一般足存进入中断服务程序前先将使用到的寄存器放入堆栈中,等到要离开之后冉重新由堆栈取出,并恢复原先的数值,这种做法在维护管理上要小心。 例5、外部中断 INT0 本实验使用AT89S51的Port 1连接到8颗LED,Port 1在正常状况下会输出跑马灯,然后通过用户触动外部的硬件来中断INT0,当INT0引脚有低电位的脉冲出现时,8个LED会一闪一灭4次。 在这次练习中,您将学会如何使用外部中断INT0。 电路图#include void delay (void
14、) /* delay 函数 */ unsigned char i,j; /* 这个函数执行时间的延迟 */ for (i=0;i255;i+) for(j=0;j255;j+) ;void delay_4isr (void) /* delay_4isr 函数 */ unsigned char i,j; /* 这个函数执行时间的延迟 */ for (i=0;i255;i+) for(j=0;j255;j+) ;static void xint0_isr(void) interrupt IE0_VECTOR unsigned char i,j=0XFF; /* 变量 j */ for(i=0;i1
15、6;i+) j=j; P1 = j; /* 将数值输出到 LED 输出端口 */ delay_4isr (); void main (void) unsigned char j=0XFF; /* 变量 j */ EA=0; /* 设定系统不接受所有的中断 */ EX0=1; /* 设定接受INT0的中断 */ PX0=1; EA=1; /* 设定系统接受中断 */ while (1) /* 无穷循环 */ /* 依次让LED 0,1,2,3,4,5,6,7闪烁 */ j=(j1) | 0 x01; if(j=0XFF) j=0XFE; P1 = j; /* 将数值输出到 LED 输出端口 */
16、 delay(); /* 调用 delay 函数*/ 例6、按钮检测1 目的是使用805 1的PORT 2连接到一个弹跳式按钮作为输入,PORT 1则连接到1个共阳七段显示器。程序执行时,共阳七段显示器会先显示0,之后当用户每按一次弹跳按钮,共阳七段显示器所显示的数字就会加1,直到9之后又会恢复到0。 电路图#include #define TRUE 1#define FALSE 0code seven_seg10=0XC0, 0XF9, 0XA4, 0XB0, 0X99, 0X92, 0X82, 0XF8, 0X80, 0X90;void delay (void) /* wait funct
17、ion */ unsigned char i,j; /* only to delay for LED flashes */ for (i=0;i96;i+) for(j=0;j255;j+) ; / 函数 keypressed 检查是否有按键按下 int keypressed() do while (P2_0=1); delay(); if(P2_0=0) delay(); if (P2_0=0) return TRUE; while(1);void main (void) int c; P1=seven_segc; do if ( keypressed() ) c+; if(c=10) c=
18、0; P1=seven_segc; while(1); 在这一个程序中,我们写了一个判断按钮是否被按下的函数keypressed,这一个函数在用户按下按钮时就返回TRUE(1)。 因为按下按钮时,必须消除按钮弹起的时间,因此当程序检测到按钮事件时(P2 0等于0时),必须延迟一段时问之后再检查P2_0是否还是0,如果还是0,就表示按钮确实被按下,否则就表示只是无效信息而已。根据这个原理,所以设计出函数keypressed的流程图,如图所示。例7、按钮检测2 上一节的按钮检测程序中,消除弹起的时间是利用循环来延长一段时间之后,然后再检查按钮,这种做法虽然可以消除弹起时间,但是却也造成循环执行时其
19、他工作无法进行的缺点,所以在这一节中,我们把时间延迟的部分交给Timer0来处理,如此一来,就可以让CPU处理其他事情了。 本练习使用8051的PORT 2连接到2个弹跳式按钮作为输入,其中一个是上数的弹跳按钮,另一个则是下数的弹跳按钮。PORT l则连接到1个共阳七段显示器。程序执行时,共阳七段显示器会先显示出0,之后每当用户单击一次上数的弹跳按钮,共阳七段显示器所显示的数字就会加1,直到9之后又会恢复到0。而每当用户按一次下数的弹跳按钮,共阳七段显示器所显示的数字就会减1,直到0之后又会恢复到9。 电路图#include #define TIMER0_COUNT 0XEE11 #defin
20、e TRUE 1#define FALSE 0#define TIMES 25code seven_seg10=0XC0, 0XF9, 0XA4, 0XB0, 0X99, 0X92, 0X82, 0XF8, 0X80, 0X90;int c, ups, downs;static void timer0_initialize(void) EA=0; TR0=0; TMOD &= 0XF0; TMOD |=0 x01; TL0=(TIMER0_COUNT & 0 x00FF); TH0=(TIMER0_COUNT 8); PT0=0; ET0=1; TR0=1; EA=1;void main (v
21、oid) c=0; ups=0; downs=0; timer0_initialize(); P1=seven_segc; while(1);/ 函数 timer0_isr 检查是否有按键按下 static void timer0_isr(void) interrupt TF0_VECTOR using 1 TR0=0; TL0=(TIMER0_COUNT & 0 x00FF); TH0=(TIMER0_COUNT 8); TR0=1; if (ups !=0) /检查ups等于0吗? ups-; /如果ups不等于0,就将ups减1 if (ups=0 & P2_0=0) /如果ups减到0
22、,就检查P2_0=0 c+; / 如果P2_0是0就表示上数的弹跳按钮被按下,所以c加1 if(c=10) c=0; /如果c加到10,就将c恢复为0 else if (P2_0=0) ups=TIMES; /如果ups=0且P2_0=0就将ups设为25 if (downs !=0) /检查downs等于0吗? downs-; /如果downs不等于0,就将downs减1 if (downs=0 & P2_1=0) /如果downs 减到0,就检查P2_1=0 c-; / 如果P2_1是0就表示下数的弹跳按钮被按下,所以c减1 if(c=-1) c=9; /如果c减到-1时,就将c恢复为10
23、 else if (P2_1=0) downs=TIMES; /如果downs=0且 P2_1 =0 /就将downs设为25 P1=seven_segc; 如何计程序可以使用Timer0延迟一段时间呢?在此我们利用变量ups,当第一次检查到P2_0等于0时就设置ups=25,然后每一次Timer0中断之后,就将ups减1,直到0为止,刚好经历25/200秒,接下来再检查P2_0是否依然等于0,就可以判断上数的弹跳按钮是否被单击。程序部分如下所示: if (ups !=0) /检查ups等于0吗? ups-; /如果ups不等于0,就将ups减1 if (ups=0 & P2_0=0) /如果
24、ups减到0,就检查P2_0=0 c+; / 如果P2_0是0就表示上数的弹跳按钮被按下,所以c加1 if(c=10) c=0; /如果c加到10,就将c恢复为0 else if (P2_0=0) ups=TIMES; /如果ups=0且P2_0=0就将ups设为25例8、四个七段显示器的显示控制 本练习使用805 l的Port 1连接到四个七段显示器。这四个共阳七段显示器的a、b、c、d、e、f和 g全部都连接在一起,因此PORT 1所输出的数据按理说应该会在四个共阳七段显示器都显示出来。但足我们利用PORT 0的低4位分别控制这四个共阳七段显示器,让四个共阳七段显示器使用扫描的方式轮流显示
25、数字,因此PORT 1每一次输出的数据恰好只会在其中一个共阳七段显示器显示数字。当您连接好电路,并且完成程序之后,您将可以看到这四个七段显示器上显示09999。在这次实习中,您将学会如何使用轮流驱动的方式,让四个共阳七段显示器轮流显示数字。 电路图程序描述:说明如何使用8051 的Port 1连接到四颗七段显示器,PORT 0的低4位分别控制这四颗共阳七段显示器,让四颗共阳七段显示器使用扫描的方式轮流显示数字。 这四颗七段显示器将显示0到 9999。#include #define TIMER0_COUNT 0 xFC18 code seven_seg10=0XC0, 0XF9, 0XA4,
26、0XB0, 0X99, 0X92, 0X82, 0XF8, 0X80, 0X90;code scan4=0X0E, 0X0D, 0X0B, 0X07;unsigned char counter4=0,0,0,0;unsigned char i=0;int timer0_tick;static void timer0_initialize(void) EA=0; timer0_tick=0; TR0=0; TMOD &= 0XF0; TMOD |=0 x01; TL0=(TIMER0_COUNT & 0 x00FF); TH0=(TIMER0_COUNT 8); PT0=0; ET0=1; TR
27、0=1; EA=1;void main (void) timer0_initialize(); while (1); /* 无穷循环 */static void timer0_isr(void) interrupt TF0_VECTOR using 1 TR0=0; TL0=(TIMER0_COUNT & 0 x00FF); TH0=(TIMER0_COUNT 8); TR0=1; P1=seven_segcounteri; P0=scani; i+; if(i=4) i=0; timer0_tick+; if (timer0_tick=1000) timer0_tick=0; counter
28、0+; / 个位数加1 if (counter0=10) / 如果个位数等于10,则执行以下的部分 counter0=0; / 个位数变成0 counter1+; / 十位数加1 if(counter1=10) / 如果十位数等于10,则执行以下的部分 counter1=0; / 十位数变成0 counter2+; / 百位数加1 if(counter2=10) / 如果百位数等于10,则执行以下的部分 counter2=0; / 百位数变成0 counter3+; / 千位数加1 if(counter3=10) counter3=0; /如果千位数等于10,则变成0 0数到9999的程序部分
29、说明如下。我们利用counter0、counter1、counter2counter3分别来储存个位数、十位数、百位数和千位数。所以每隔一秒就将counter0加1,如果counter0等于10就必须进位,于是将counter0设为0,同时counter1加1。counter1等于10的时候也是同样的道理,依次进位到counter2counter3,程序如下所示: 例9、4*4 小键盘输入 本练习使用前一节的4个七段显示器电路,然后外加一个44的小键盘,其中8051的PORT 2连接到44小键盘输入。程序执行时,用户可以从44小键盘输入数据,而所输入的数据会显示在4个七段显示器上。 电路图函数
30、描述: char gotkey(void) 从44小键盘输入数据,返回015小键盘的连接方式: 主程序:ex-9.c#define TIMER0_COUNT 0 xEE11code seven_seg16=0XC0, 0XF9, 0XA4, 0XB0, 0X99, 0X92, 0X82, 0XF8, 0X80, 0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E;code scan4=0X0E, 0X0D, 0X0B, 0X07;unsigned char counter4=0,0,0,0;unsigned char timer0_tick,k=0;static void t
31、imer0_isr(void) interrupt 1 using 1 TR0=0; TL0=(TIMER0_COUNT & 0 x00FF); TH0=(TIMER0_COUNT 8); TR0=1; P1=seven_segcounterk; P0=scank; k+; if(k=4) k=0; timer0_tick+; if (timer0_tick=200) timer0_tick=0;static void timer0_initialize(void) EA=0; timer0_tick=0; TR0=0; TMOD &= 0XF0; TMOD |=0 x01; TL0=(TIM
32、ER0_COUNT & 0 x00FF); TH0=(TIMER0_COUNT 8); PT0=0; ET0=1; TR0=1; EA=1;void main (void) unsigned char c=0; char ch; timer0_initialize(); do ch=gotkey(); for(c=3;c0;c-) counterc=counterc-1; counter0=ch; while(1);小键盘的输入函数:keypad.c#include code char key_code=0 x7E, 0XBE, 0XBD, 0XBB, 0XDE, 0XDD, 0XDB, 0X
33、EE, 0XED, 0XEB, 0X7D, 0X7B, 0XE7, 0XD7, 0XB7, 0X77;code ksp4=0 x7F,0 xBF,0 xDF,0 xEF;void delay (void) /* 时间延迟函数 */ unsigned char i,j; for (i=0;i5;i+) for(j=0;j255;j+) ;char keypad_scan() char key,i; P2=0 xF0; while (P2!=0 xF0); do for(i=0;i=3;i+) P2=kspi; if(P2!=kspi) delay(); key=P2; if(key!=kspi)
34、 return(key); while(1);/ 检查是否有按键按下char gotkey() char temp,i; temp=keypad_scan(); for (i=0;i=15;i+) if(temp=key_codei) return(i); return(16);1.1 单片机应用系统的基本结构1.1.1 单片机应用系统的硬件组成被控对象单片机光电隔离A/D光电隔离光电隔离D/A扩展存储器显示器、键盘接口功能芯片接口数字量输入模拟量输入开关量输入开关量输出模拟量输出输入输出接口I/O接口 二.单片机应用系统设计1.1.2 单片机应用系统开发的基本过程一系统需求与方案调研 系统需
35、求与方案调研的目的是通过市场或用户了解用户对拟开发应用系统的设计目标和技术指标。通过查找资料,分析研究,解决以下问题:1)了解国内外同类系统的开发水平、器材、设备水平、供应状态;对接收委托研制项目,还应充分了解对方技术要求、环境状况、技术水平,以确定课题的技术难度。2)了解可移植的硬、软件技术。能移植的尽量移植,以防止大量低水平重复劳动。3)摸清硬、软件技术难度,明确技术主攻方向。4)综合考虑硬、软件分工与配合方案。单片机应用系统设计中,硬、软件工作具有密切的相关性。 可行性分析的目的是对系统开发研制的必要性及可行性作出明确的判定结论。根据这一结论决定系统的开发研制工作是否进行下去。 可行性分
36、析通常从以下几个方面进行论证:1)市场或用户的需求情况。2)经济效益和社会效益。3)技术支持与开发环境。4)现在的竞争力与未来的生命力。二可行性分析 系统功能设计包括系统总体目标功能的确定及系统硬、软件模块功能的划分与协调关系。 系统功能设计是根据系统硬件、软件功能的划分及其协调关系,确定系统硬件结构和软件结构。 系统硬件结构设计的主要内容包括单片机系统扩展方案和外围设备的配置及其接口电路方案,最后要以逻辑框图形式描述出来。 系统软件结构设计主要完成的任务是确定出系统软件功能模块的划分及各功能模块的程序实现的技术方法,最后以结构框图或流程图描述出来。三系统功能设计 系统详细设计与制作就是将前面
37、的系统方案付诸实施,将硬件框图转化成具体电路,并制作成电路板,软件框图或流程图用程序加以实现。四系统详细设计与制作 系统调试是检测所设计系统的正确性与可靠性的必要过程。单片机应用系统设计是一个相当复杂的劳动过程,在设计、制作中,难免存在一些局部性问题或错误。系统调试可发现存在的问题和错误,以便及时地进行修改。调试与修改的过程可能要反复多次,最终使系统试运行成功,并达到设计要求。五系统调试与修改 系统硬件、软件调试通过后,就可以把调试完毕的软件固化在EPROM中,然后脱机(脱离开发系统)运行。如果脱机运行正常,再在真实环境或模拟真实环境下运行,经反复运行正常,开发过程即告结束。 六生成正式系统或
38、产品1.2 单片机应用系统的硬件设计1.2.1 硬件系统设计原则 一个单片机应用系统的硬件电路设计包括三个部分内容:一是单片机芯片的选择,二是单片机系统扩展,三是系统配置。一、单片机芯片的选择二、单片机系统扩展 单片机系统扩展是指单片机内部的功能单元(如程序存储器、数据存储器、I/O口、定时器/计数器、中断系统等)的容量不能满足应用系统的要求时,必须在片外进行扩展,这时应选择适当的芯片,设计相应的扩展连接电路;系统配置是按照系统功能要求配置外围设备,如键盘、显示器、打印机、A/D转换器、D/A转换器等,设计相应的接口电路。 三、系统扩展和配置设计遵循的原则 系统扩展和配置设计遵循的原则:(1)
39、尽可能选择典型通用的电路,并符合单片机的常规用法。(2)系统的扩展与外围设备配置的水平应充分满足应用系统当前的功能要求,并留有适当余地,便于以后进行功能的扩充。(3)硬件结构应结合应用软件方案一并考虑。(4)整个系统中相关的器件要尽可能做到性能匹配。(5)可靠性及抗干扰设计是硬件设计中不可忽视的一部分。(6)单片机外接电路较多时,必须考虑其驱动能力。1.2.2 硬件设计一程序存储器二数据存储器三I/O接口四译码电路五总线驱动器六抗干扰电路1.3 单片机应用系统的软件设计 一个应用系统中的软件一般是由系统监控程序和应用程序两部分构成的。其中: 应用程序是用来完成诸如测量、计算、显示、打印、输出控
40、制等各种实质性功能的软件; 系统监控程序是控制单片机系统按预定操作方式运行的程序,它负责组织调度各应用程序模块,完成系统自检、初始化、处理键盘命令、处理接口命令、处理条件触发和显示等功能。 软件设计时,应根据系统软件功能要求,将软件分成若干个相对独立的部分,并根据它们之间的联系和时间上的关系,设计出软件的总体结构,画出程序流程框图。画流程框图时还要对系统资源作具体的分配和说明。根据系统特点和用户的了解情况选择编程语言,现在一般用汇编语言和C语言。 汇编语言编写程序对硬件操作很方便,编写的程序代码短,以前单片机应用系统软件主要用汇编语言编写; C语言功能丰富,表达能力强,使用灵活方便,应用面广,
41、目标程序效率高,可移植性好,现在单片机应用系统开发很多都用C语言来进行开发和设计。1.3.1 软件设计的特点一个优秀的应用系统的软件应具有以下特点:(1)软件结构清晰、简捷、流程合理。(2)各功能程序实现模块化,系统化。这样,既便于调试、连接,又便于移植、修改和维护。(3)程序存储区、数据存储区规划合理,既能节约存储容量,又能给程序设计与操作带来方便。(4)运行状态实现标志化管理。各个功能程序运行状态、运行结果以及运行需求都设置状态标志以便查询,程序的转移、运行、控制都可通过状态标志来控制。(5)经过调试修改后的程序应进行规范化,除去修改“痕迹”。规范化的程序便于交流、借鉴,也为今后的软件模块
42、化、标准化打下基础。(6)实现全面软件抗干扰设计。软件抗干扰是计算机应用系统提高可靠性的有力措施。(7)为了提高运行的可靠性,在应用软件中设置自诊断程序,在系统运行前先运行自诊断程序,用以检查系统各特征参数是否正常。1.3.2 资源分配一程序存储器ROM/EPROM资源的分配 在这些资源分配中,定时/计数器、中断、串行口等分配比较容易,这里介绍程序存储器和数据存储器的分配。 程序存储器ROM/EPROM用于存放程序和数据表格。按照MCS-51单片机的复位及中断入口的规定,002FH以前的地址单元作为中断、复位入口地址区。在这些单元中一般都设置了转移指令,用于转移到相应的中断服务程序或复位启动程
43、序。当程序存储器中存放的功能程序及子程序数量较多时,应尽可能为它们设置入口地址表。一般的常数、表格集中设置在表格区。二次开发,扩展部分尽可能放在高位地址区。 RAM分为片内RAM和片外RAM。片外RAM的容量比较大,通常用来存放批量大的数据,如采样结果数据;片内RAM容量较少,应尽量重叠使用,比如数据暂存区与显示、打印缓冲区重叠。 对于MCS-51单片机来说,片内RAM是指00H7FH单元,这128个单元的功能并不完全相同,分配时应注意发挥各自的特点,做到物尽其用。二数据RAM资源分配1.3.3 单片机应用系统开发工具 一个单片机应用系统经过总体设计,完成硬件开发和软件设计,就进行硬件安装。硬
44、件安装好后,把编制好的程序写入存储器中,调试好后系统就可以运行了。但用户设计的应用系统本身并不具备自开发的能力,不能够写入程序和调试程序,这必须借助于单片机开发系统才能完成这些工作。单片机开发系统是能够模拟用户实际的单片机,并且能随时观察运行的中间过程和结果,从而能对现场进行模仿的仿真开发系统。通过它能很方便的对硬件电路进行诊断和调试,得到正确的结果。 目前国内使用的通用单片机的仿真开发系统很多,如复旦大学研制的SICE系列、启东计算机厂制造的DVCC系列、中国科大研制的KDV系列、南京伟福实业有限公司的伟福E6000以及西安唐都科教仪器公司的TDS51开发及教学实验系统。它们都具有对用户程序
45、进行输入、编辑、汇编和调试的功能。此外,有些还具备在线仿真功能,能够直接将程序固化到EEPROM中。一般都支持汇编语言编程,有的可以通过开发软件,支持C语言编程。例如可通过Keil C51软件来编写C语言源程序,编译连接生成目标文件、可执行文件,仿真、调试、生成代码并下载到应用系统中。 1.4 单片机应用系统的抗干扰设计 1. 干扰源及干扰途径 单片机系统中的干扰有多种类型。 一种是来自空间辐射的干扰。可控硅逆变电源、变频调速器、发射机等特殊设备在工作时会产生很强的干扰,在这种环境中单片机系统难以正常运行; 另一种是来自电源的干扰。各种开关的通断、火花干扰、大电机启停等现象在工业现场很常见,这些来自交流电源的干扰对单片机系统的正常运行危害极大; 还有一种就是来自信号通道的干扰。在实际的应用系统中,测控信号的输入/输出是必不可少的。在工业现场中,这些I/O信号线、控制线有时长达几百米,不可避免地会把干扰引入到系统中。如果受控对象是强干扰源,如可控硅、电焊机等,则单片机系统根本就无法运行。 2、硬件抗干扰措施 根据干扰的产生及传输特点,在硬件上可以采取以下措施:(1)硬件屏蔽。将系统安装在对电磁辐射干扰具有屏
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论