460 likes | 605 Views
项目三 数码管显示. 教学目的. 掌握数字、字符转换成显示段码的软件译码方法; 掌握静态显示的原理; 掌握动态显示的原理; 掌握数码管程序设计的方法。 P130. 工作模块 6 数码管循环显示 0~9. 利用 AT89S51 单片机的 P1 端口的 P1.0 - P1.7 连接到一个共阴数码管的 a - h 的笔段上,数码管的公共端接地。在数码管上循环显示 0 - 9 数字。. 工作模块 6. #include <AT89X51.H>
E N D
教学目的 掌握数字、字符转换成显示段码的软件译码方法; 掌握静态显示的原理; 掌握动态显示的原理; 掌握数码管程序设计的方法。 P130
工作模块6 数码管循环显示 0~9 • 利用AT89S51 单片机的P1 端口的P1.0-P1.7 连接到一个共阴数码管的a-h 的笔段上,数码管的公共端接地。在数码管上循环显示 0-9 数字。 工作模块6
#include <AT89X51.H> unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char dispcount; void delay (void) { unsigned char i,j,k; for(i=40;i>0;i--) for(j=40;j>0;j--) for(k=248;k>0;k--); } void main(void) { while(1) { for(dispcount=0;dispcount<10;dispcount++) { P1=table[dispcount]; delay (); } } } 数码管显示程序(C程序)
思 考 如何在数码管上循环显示 9 - 0数字?
A F B G E C D DP 认识数码管(P132) • 数码管结构图
共阴数码管 共阳数码管 片选 片选 数码管电路图
74LS245 • 74LS245是8路同相三态双向数据总线驱动芯片,具有双向三态功能,既可以输出,也可以输入数据。 • /G为低电平有效; • DIR=“1”,信号由 A 向 B 传输。 • 引出端符号: • A总线端 • B总线端 • /G三态允许端(低电平 有效) • DIR方向控制端
关系运算符和关系表达式(P77) • 所谓“关系运算”实际上是两个值作一个比较,判断其比较的结果是否符合给定的条件。 • 关系运算的结果只有2种可能,即“真”和“假”。 • 例如: 3>2的结果为真,而3<2 的结果为假。
关系运算符 • C语言一共提供了6种关系运算符: • 小于: “<”; • 小于等于:“<=”; • 大于: “>”; • 大于等于:“>=”; • 等于: “==”; • 不等于: “!=”。
关系表达式 • 用关系运算符将两个表达式连接起来的式子,称为关系表达式。 • 例如:a>b,a+b>b+c,(a=3)>=(b=5) • 在 C 语言中,没有专门的逻辑型变量,如果运算的结果是“真”,用数值“1”表示,而运算的结果是“假”则用数值“0”表示。 • 例如:x1=3>2的结果是x1等于1 原因是3>2的结果是“真”,即其结果为1,该结果被“=”号赋给了x1。 • 又如:x2=3<=2的结果是x2=0,请自行分析。
逻辑运算符 • C语言提供了三种逻辑运算符: • “&&”(逻辑与); • “||”(逻辑或); • “!”(逻辑非)。
逻辑表达式 • 用逻辑运算符将关系表达式或逻辑量连接起来的式子,称为逻辑表达式。 • C语言编译系统在给出逻辑运算的结果时: • 用“1”表示真,而用“0”表示假。 • 在判断一个量是否是“真”时,以0代表“假”,而以非0代表“真”,这一点务必要注意。 • 若a=10,则!a的值为0,因为10被作为真处理; • 如果a=-2,结果与上完全相同,初学时常会误以为负值为假,所以这里特别提醒注意; • 若a=10,b=20,则a&&b的值为1,a||b的结果也为1。
if语句(P54) • 用if语句构成分支结构。 • 分支结构又称选择结构,它体现了程序的判断能力。 • 这种结构根据程序的判断结果,来确定某些操作是做还是不做,或者从多个操作中选择一个操作来执行。
单分支if语句 • 单分支if语句的基本形式为: if(表达式)语句 • 如果表达式的结果为真,则执行语句,否则不执行。 单分支if语句
双分支if语句 • 双分支if语句语句的基本形式为: if(表达式)语句1 else 语句2 • 如果表达式的结果为真,则执行语句1,否则执行语句2 双分支if语句
多分支if语句 • 多分支if语句的基本形式为: if(表达式 1) 语句1 else if(表达式 2) 语句2 else if(表达式 3) 语句3 … else if(表达式 m) 语句m else 语句n
if语句的嵌套 • 当if语句中的语句体又包含一个或多个if语句,称为if语句的嵌套。其一般形式如下: if(表达式) if(表达式1) 语句11 else 语句12 else if(表达式2) 语句21 else 语句22 • 应当注意if与else的配对关系,C语言规定:else总是与它上面的最近的if配对
swich语句 • Switch的一般形式如下: switch(表达式) { case 常量表达式1:语句1 case 常量表达式2:语句2 …… case 常量表达式n:语句n default:语句n+1 } • 当表达式的值与某一个case后面的常量表达式相等时,就执行此case后面的语句; • 若所有的case中的常量表达式的值都没有与表达式值匹配的,就执行default后面的语句; • 每一个case的常量表达式的值必须不相同; • 各个case和default的出现次序不影响执行结果。
swich语句特别说明 • 执行完一个case后面的语句后,并不会自动跳出switch,转而去执行其后面的语句; • 通常在每一段case的结束加入“break;”语句,使程序退出switch结构,即终止switch语句的执行。 • 如: switch (x) { case 1: y=1; case 2: y=2; case 3: y=0; } 假如x的值是1,y=?
循环结构控制语句 • 在一个实用的程序中,循环结构是必不可少的。 循环是反复执行某一部分程序行的操作。通过下面C语言程序,来看如何利用这些循环语句编写循环程序。 void Delay() void main() { { unsigned char i, j; while(1) for (i=0;i<255;i++) {;} {……} } } • 这段程序中有两处用到了循环语句,首先是主程序使用了: while(1) {……} • 这样的循环语句写法,在{}中的所有程序将会不断地循环执行,直到断电为止;其次是延时程序,使用了for循环语句的形式。
while语句 • 当型循环,即当给定的条件成立时,执行循环体部分,执行完毕回来再次判断条件,如果条件成立继续循环,否则退出循环。其一般形式如下: while(表达式) 循环体语句 • 当表达式为非0值(真)时,执行while语句中的内嵌语句。 • 其特点是:先判断表达式,后执行语句。
do-while语句 • 直到型循环,即先执行循环体,然后判断给定的条件,只要条件成立就继续循环,直到判断出给定的条件不成立时退出循环。其一般形式如下: do 循环体语句 while(表达式) • do-while语句特点是先执行循环体,然后判断循环条件是否成立。 • 对同一个问题,既可以用while语句处理,也可以用do-while语句处理,但是这两个语句是有区别的。
for语句 • C语言中的for语句使用最为灵活,不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定而只给出循环结束条件的情况。for语句的一般形式为: for(表达式1;表达式2;表达式3) 循环体语句 • 执行步骤如下: (1)先求解表达式1; (2)求解表达式2,其值为真,则执行for语句中指定的内嵌语句(循环体),然后执行第(3)步,如果为假,则结束循环; (3)求解表达式3; (4)转回第2步继续执行。
break语句 • break语句强行结束循环,转向执行循环语句的下一条语句。 • 在一个循环程序中, 可以通过循环语句中的表达式来控制循环程序是否结束。除此之外,还可以通过break语句从循环体内跳出循环体,即提前结束循环,接着执行循环下面的语句。 • 一般形式: break; • 注意:break语句不能用于循环语句和switch语句之外的任何其他语句中;break语句是结束整个循环过程,不再判断执行循环的条件是否成立。
continue语句 • continue语句作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定。 • 对于for循环,跳过循环体其余语句,转向循环变量增值表达式的计算;对于while和do-while循环,跳过循环体其余语句,但转向循环继续条件的判定。 • 一般形式: continue; • 注意:continue只能用于循环语句中;continue语句只结束本次循环,而不是终止整个循环的执行。
工作模块7 LED动态扫描显示 • 动态显示,也称扫描显示; • 显示器由6个共阴极LED数码管构成; • P0口输出显示段码,经由一片74LS245驱动输出给LED管; • P1口输出位码(片选),经由74LS05输出给LED管。
动态显示特点 • 在多位LED显示时,为了降低成本和功耗,将所有位的段选控制端并联起来,由一个8位端口控制(本任务中用P0口);各位数码管的公共端(com端),用作“位选端”,由另一个端口进行显示位的控制(本任务中用P1口)。 • 由于段选端是公用的,要让各位数码管显示不同的字符,就必须采用扫描方式,即动态扫描显示方式。动态扫描是采用分时的方法轮流点亮各位数码管的显示方式,它在某一时间段,只让其中一位数码管的“位选端”(com端)有效,并送出相应的字型编码。
动态扫描过程 • 首先从段选线上送出字型编码,再控制位选端,字符就显示在指定数码管上,其他位选端无效的数码管都处于熄灭状态,持续1.5ms时间,然后关闭所有显示; • 接下来又送出新的字型编码,按照上述过程又显示在另外一位数码管上,直到每一位数码管都扫描完为止,这一过程即为动态扫描显示。 • 数码管其实是轮流依次点亮的,但由于人的视觉驻留效应,因此当每个数码管点亮的时间小到一定程度时,人就感觉不出字符的移动或闪烁,觉得每位数码管都一直在显示,达到一种稳定的视觉效果。
思考题 • 如何修改程序,实现六位LED数码管只显示其中的两位?
定义段码表 • #include <AT89X52.h> • unsigned char code Tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C}; • unsigned char code Col[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; • void Delay() • { unsigned char i; • for(i=0;i<250;i++);}
主函数 • void main() // 同时显示123456 • { unsigned char j; • while(1) • { for(j=1;j<7;j++) • { P0=Tab[j]; • P1=Col[j-1]; //开第一个(共阴)数码管 • Delay(); • P1=0xff; //关数码管 • Delay();} • } • }
一维数组(P86) • 在C语言中数组必须要先定义,后使用。一维数组的定义方式为: 类型说明符 数组名[整型表达式]; • 类型说明符是任一种标准数据类型或构造数据类型,是数组中各个元素的数据类型。 • 数组名是用户定义的数组标识符。 • 方括号中的常量表达式表示数据元素的个数,也称为数组的长度。 • 例如: • int a[9]; //定义整型数组a,有9个元素,下标从0到8。 • float b[5]; //定义实型数组b,有5个元素,下标从0到4。 • char ch[10]; //定义字符数组ch,有10个元素,下标从0到9。
注意事项 • 数组的类型是指构成数组的元素的类型。对于同一个数组,其所有元素的数据类型都是相同的。 • 数组名的书写规则应符合标识符的命名规则,并且不能与其它变量同名。 • 常量表达式可以是符号常量或常量表达式,但是不能包含变量,即不能对数组的大小作动态定义。
工作模块8 0-99计数器 • 利用AT89S52单片机来制作一个0~99计数器。要求使用一个手动计数按钮,实现0~99的计数,并且通过两个共阴数码管显示计数结果,数码管显示采用静态显示方式。 • 静态显示; • 显示器由2个共阴极数码管组成;
静态显示的概念 • 静态显示是指显示驱动电路具有输出锁存功能,待显示的字符编码被CPU送出后,数码管会一直显示该字符不变,CPU不需要再控制数码管,如果要显示新的字符,CPU只要再次送出即可。 • 采用静态显示方式,较小的电流就可以获得较高的亮度,且占用CPU时间较少,编程简单,显示便于检测和控制,但其占用的I/O口线较多,硬件电路复杂,成本高,只适合显示位数较少的场合。
0-99计数显示c语言程序 • #include <AT89X52.H> //包含AT89X52.H头文件 • /*定义0~9十个数字的字型码表*/ • unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66, • 0x6d,0x7d,0x07,0x7f,0x6f}; • unsigned char Count; //定义变量放置计数数值 • void delay10ms(void) //定义10ms延时函数 • { • unsigned char i,j; • for(i=20;i>0;i--) • for(j=248;j>0;j--); • }
void main(void) { Count=0; //计数变量初始为0 P0=table[Count/10]; //十位管显示 P2=table[Count%10]; //个位显示 while(1) //计数显示处理 { if(P1_0==0) //键按下? { delay10ms(); //延时去抖动 if(P1_0==0) //确定键按下 { Count++; //计数加1 if(Count==100) //计数到100? { Count=0; //到100回0 } P0=table[Count/10]; //显示十位数 P2=table[Count%10]; //显示个位数 while(P1_0==0); //等键释放 } } } 0-99计数显示c语言程序
C语言函数 • 函数的分类和定义 • 函数分类 • 无参函数 • 有参函数 • 函数定义 函数类型说明符 函数名([形式参数表]) { 函数体 }
函数的调用 • 函数调用的一般形式如下: 函数名 (实参列表); • 例如 void mDelay(unsigned int Delay) { …… for(;Delay>0;Delay--) …… } • 函数中Delay就是一个形式参数,而在主函数中调用时写的: mDelay(1000);
函数的返回值 • 在C中,一般使用return语句由被调函数向主调函数返回值,该语句有下列用途: • 它能立即从所在的函数中退出,返回到调用它的程序中去; • 返回一个值给调用它的函数。 • 返回语句一般有如下的形式: return; 或 return 表达式; 或 return(表达式);
技能拓展 七段字形译码器74LS47 • 74LS47是由与非门、输入缓冲器和7 个与或非门组成的BCD-7段数码管译码器/驱动器,是输出低电平有效的七段字形译码器。 • 能将4位二进制编码—十进制数(BCD码)转化成七段字形码,然后去驱动一个七段显示器。 • 也就是说74LS47可以直接把数字转换为数码管的显示数字,从而可以简化程序,节约单片机的IO开销。
使用74LS47实现0-99计数显示 • 显示电路采用硬件译码输出字型码控制显示内容,数码管是共阳极数码管。
0-99计数显示c语言程序 • void main(void) • { • Count=0; //计数变量初始为0 • P2=0x0; //十位、个位数码管显示0 • while(1) //按键扫描,计数显示处理 • { • …… • /*十位数BCD码(Count/10<<4)和个位数BCD码(Count%10)相或*/ • P2=(Count/10<<4)|(Count%10); • while(P1_0==0); //等键释放 • …… • } • }