基于51单片机的测速模块数码管显示
- 格式:doc
- 大小:27.50 KB
- 文档页数:2
实验一八段数码管显示1、实验目的:(1)了解数码管动态显示的原理。
(2)了解74LS164扩展端口的方法。
2、实验要求:利用实验仪提供的显示电路,动态显示一行数据.3、实验电路图LED1LED2LED3LED4LED5LED64、实验器材:(1)超想-3000TB综合实验仪 1 台(2)超想3000仿真器 1 台(3)计算机 1 台5、实验连线无 6、实验说明:(1)本实验仪提供了8段码LED 显示电路,学生只要按地址输出相应数据,就可以实现对显示器的控制。
显示共有6位,用动态方式显示。
8段数码管是由8155的PB0、PB1经74LS164“串转并”后输出得到。
6位位码由8155的PA0口输出,经Ua2003反向驱动后,选择相应显示位。
74LS164是串行输入并行输出转换电路,串行输入的数据位由8155的PB0控制,时钟位由8155的PB1控制输出。
写程序时,只要向数据位地址输出数据,然后向时钟位地址输出一高一低两个电平就可以将数据位移到74LS164中,并且实现移位。
向显示位选通地址输出高电平就可以点亮相应的显示位。
本实验仪中数据位输出地址为0e102H ,时钟位输出地址为0e102H ,位选通输出地址为 0e101H 。
本实验涉及到了8155 I0/RAM 扩展芯片的工作原理以及74LS164器件的工作原理。
(2)七段数码管的字型代码表显示字形g f e d c b a 段码 0 0 1 1 1 1 1 1 3fh 1 0 0 0 0 1 1 0 06h 2 1 0 1 1 0 1 16bh 3 1 0 0 1 1 1 1 4fh 4 1 1 0 0 1 1 0 66h 5 1 1 0 1 1 0 1 6dh 6 1 1 1 1 1 0 1 7dh 7 0 0 0 0 1 1 1 07h 8 1 1 1 1 1 1 1 7fh 9 1 1 0 1 1 1 1 6fh A 1 1 1 0 1 1 1 77h B 1 1 1 1 1 0 0 7ch C 0 1 1 1 0 0 1 39h D 1 0 1 1 1 1 05ehE 1 1 1 1 0 0 1 79h F1111 71hab c def g dp7、程序框图8、实验步骤1.将KEIL仿真器上40芯排线一端和实验箱上51CPU板上的40芯排针连接起来,将仿真器连接的USB或串口线与PC机对应的USB或串口连接起来,打开实验箱电源。
33第2卷 第22期产业科技创新 2020,2(22):33~34Industrial Technology Innovation 基于51单片机实现LED数码管静态与动态显示的设计浅析龙 志(广州大学松田学院,广州 增城 511370)摘要:随着社会的发展,在我们日常的生活中,数码管的应用随处可见,尤其是在电子应用设计显示等方面常常发挥着非常重要的作用,因此研究数码管的显示有非常重要的现实意义。
数码管我们可以分为静态显示和动态显示,这两种显示有着本质的区别,静态显示的特点是占用CPU 时间少,显示便于监测和控制,显示字形稳定,而动态数码管的显示,效果相对静态显示亮度差少许,但成本较低。
本设计主要是基于51单片机,先通过结合集成芯片74HC573对LED 数码管静态显示的硬件电路设计与分析,进一步拓展到采用芯片74HC138与LED 数码管动态显示的硬件电路设计与分析,最终实现两种不同的电路设计显示的方法。
关键词:LED 数码管;静态显示;动态显示;51单片机中图分类号:TP368.12 文献标识码:A 文章编号:2096-6164(2020)22-0033-02随着电子应用技术的不断发展,显示电路在电子设计应用方面更加广泛,尤其是LED 数码管显示在各行各业中的应用更加重要,如红绿交通灯显示,电子时钟显示,家电产品功能显示等方面都需要用到LED 数码管作为显示。
因此,对LED 数码管的显示控制有着非常重要的现实意义。
因此我们要实现LED 数码管的熟练显示控制,我们必须要根据数码管的特点来进行分析和设计,数码管有静态显示和动态显示的两种方法,接下对这两种电路作详细的分析与设计,最终实现对LED 数码管静态与动态的两种不同显示设计方法。
1 数码管静态显示电路设计数码管静态显示设计是利用MCS-51单片机结合两片集成芯片74HC573,实现对4个LED 数码管的显示控制。
具体设计如图1所示:图1 数码管静态显示设计电路图本电路设计主要是利用单片机的P0口来实现对数码管的位选控制与段选的控制,P0口之所以能够正确的对数码管进行位选与段选的控制,关键是在于设计中使用了芯片74HC573。
基于单片机的按键控制LED数码管共阴极动态显示电路设计报告毕业论文本篇报告将详细介绍基于单片机的按键控制LED数码管共阴极动态显示电路的设计。
一、引言LED数码管是一种常用的数字显示器件,广泛应用于各种计数器、时钟和计时器等电子设备中。
本设计旨在利用单片机实现对LED数码管的动态显示,并通过按键控制显示的数字。
二、设计方案1.系统结构本系统采用基于单片机的数字显示方案,其中包括一个单片机、数码管显示模块和按键模块。
单片机负责接收按键输入信号,并根据输入信号控制数码管显示相应的数字。
2.系统设计(1)数码管显示模块:该模块由共阴极LED数码管组成,共阴极接地,通过接通不同的端口线来控制数码管显示不同的数字。
(2)按键模块:该模块由多个按键组成,用于用户输入指定的数字。
每个按键接一个IO脚,通过按下不同的按键,触发不同的端口输入。
(3)单片机:本设计选用51单片机作为控制核心,通过IO口与数码管显示模块和按键模块连接。
单片机根据按键输入信号的变化,对数码管进行动态显示。
3.设计过程(1)针对单片机的接线设计:将单片机的IO口分别与数码管显示模块和按键模块连接。
将数码管的共阳极接电源正极,数码管的各段(即a、b、c、d、e、f、g)接单片机的IO脚。
(2)针对单片机软件设计:设计单片机程序实现按键输入的检测和数码管动态显示的控制。
首先初始化IO口,设置按键引脚为输入端口,设置数码管引脚为输出端口。
然后循环检测按键的状态。
当检测到按键被按下时,根据按键的不同选择分别显示不同的数字。
4.功能要求(1)按下不同的按键,数码管能够显示相应的数字,实现动态显示。
(2)按键输入具有去抖功能,避免误触发。
(3)程序运行稳定,能够正确响应按键输入,显示正确的数字。
三、实验结果经过实验验证,本设计实现了按键控制LED数码管共阴极动态显示的功能要求。
按下不同的按键,数码管能够正确显示相应的数字,程序运行稳定,无误触发现象。
51单片机(四位数码管的显示)程序基于单片机V1或V2实验系统,编写一个程序,实现以下功能:1)首先在数码管上显示“P_ _ _”4个字符;2)等待按键,如按了任何一个键,则将这4个字符清除,改为显示“0000”4个字符(为数字的0)。
最佳答案下面这个程序是4x4距阵键盘,LED数码管显示,一共可以到0-F显示,你可以稍微改一下就可以实现你的功能了,如还有问题请发信息,希望能帮上你!#include<at89x52.h>unsigned char codeDig[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1 ,0x86,0x8e}; //gongyang数码管0-F 代码unsigned char k; //设置全局变量k 为键盘的键值/************************************键盘延时函数****************************/void key_delay(void) //延时函数{int t;for(t=0;t<500;t++);}/************************************键盘扫描函数******************************/void keyscan(void) //键盘扫描函数{unsigned char a;P2 = 0xf0; //键盘初始化if(P2!=0xf0) //有键按下?{key_delay(); //延时if(P2!=0xf0) //确认真的有键按下?{P2 = 0xfe; //使行线P2.4为低电平,其余行为高电平key_delay();a = P2; //a作为缓存switch (a) //开始执行行列扫描{case 0xee:k=15;break;case 0xde:k=11;break;case 0xbe:k=7;break;case 0x7e:k=3;break;default:P2 = 0xfd; //使行线P2.5为低电平,其余行为高电平a = P2;switch (a){case 0xed:k=14;break;case 0xdd:k=10;break;case 0xbd:k=6;break;case 0x7d:k=2;break;default:P2 = 0xfb; //使行线P2.6为低电平,其余行为高电平a = P2;switch (a){case 0xeb:k=13;break;case 0xdb:k=9;break;case 0xbb:k=5;break;case 0x7b:k=1;break;default:P2 = 0xf7; //使行线P2.7为低电平,其余行为高电平a = P2;switch (a){case 0xe7:k=12;break;case 0xd7:k=8;break;case 0xb7:k=4;break;case 0x77:k=0;break;default:break;}}}break;}}}}/****************************** ***主函数*************************************/ void main(void){while(1){keyscan(); //调用键盘扫描函数switch(k) //查找按键对应的数码管显示代码{case 0:P0=Dig[0];break;case 1:P0=Dig[1];break;case 2:P0=Dig[2];break;case 3:P0=Dig[3];break;case 4:P0=Dig[4];break;case 5:P0=Dig[5];break;case 6:P0=Dig[6];break;case 7:P0=Dig[7];break;case 8:P0=Dig[8];break;case 9:P0=Dig[9];break;case 10:P0=Dig[10];break;case 11:P0=Dig[11];break;case 12:P0=Dig[12];break;case 13:P0=Dig[13];break;case 14:P0=Dig[14];break;case 15:P0=Dig[15];break;default:break; //退出}}}/**********************************end***************************************/。
基于51单片机和霍尔传感器的测速1. 小项目简介主要采用stc89c51/52单片机作为主控,由霍尔传感器作为测速的基本模块,采用按键控制速度快慢,数码管显示当前速度。
最后成品图如下:2.电源部分1.电源供电的功率尽可能的稍微大一些,我是采用罗马仕充电宝供电(5V,2.1A输出口)。
因为电源功率过小,将造成电机无法带动,或者数码管闪烁等硬件上的bug。
2.如果电源的电压高于5V,需要在电源输入端使用一个稳压电路,将输入电压稳压到5V给单片机,和其他外设供电。
防止电压过高造成器件损坏。
3.硬件部分1. stc89c51/52的最小系统注意:如果使用一般的USB接口供电,当电机转动时候,可能照成单片机的管脚供电不稳定,所以需要在单片机的IO的外接上拉排阻。
P3口不需要。
9针排阻如下:有小点的一端是公共端,需要和电源5V连接,其余口和单片机管脚一一对应焊接就行。
2. 霍尔传感器注意引脚,窄的一面来看引脚顺序:这里的VOUT口可以直接连接单片机的外部中断1口,可以经过一个电压比较器lm393之类的在给单片机。
3. 直流电机马达驱动51单片机的IO口输出的电流过小,驱动直流电机马达效果不明显,达不到后期变速,需要使用一个三极管(9015\9013这类都可以)放大电路去驱动马达:示范电路如下:(电阻根据自己需要修改)4. 共阴数码管//数码管位选sbit S1=P2^4;sbit S2=P2^5;sbit S3=P2^6;sbit S4=P2^7;//数码管段选:P1的八个IO口。
连线的时候一定根据下列图示的段选(注意注意注意:容易连错)4.软件部分1.软件工程整体图:2.main.c文件代码:自己创建一个51单片机的keil工程文件,将下面代码拷贝到自己工程文件下的main.c文件替换即可/************************************************************** ************************* 基于51单片机测速* 实现现象:按下按键K1减速按下按键K2加速外部中断1对应IO口P3^3注意事项:电机速度不能过快,否则会造成数码管显示不稳定*************************************************************** ************************/#include 'reg52.h' //此文件中定义了单片机的一些特殊功能寄存器typedef unsigned int u16; //对数据类型进行声明定义typedef unsigned char u8;//测试端口(根据自己需要决定)sbit led=P0^0; //将单片机的P0.0端口定义为led/************************************************************** ****************************************************核心部分**************************************************************************************************************** ************************///占空比u16 time = 0; // 定义占空比的变量u16 count=30; //定义占空比上限sbit PWM=P0^1;// P0.1输出pwm//速度u16 zhuansu=0; //转速初值为0u16 jishu = 0; //jishu的变量初值为0u8 flag = 0; //定时器1计数变量//按键sbit k1=P2^0;sbit k2=P2^1;sbit k3=P2^2;sbit k4=P2^3;//数码管位选sbit S1=P2^4;sbit S2=P2^5;sbit S3=P2^6;sbit S4=P2^7;//数码管位选:P1的八个IO口//共阴数码管段选u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值//数码管存储中间变量unsigned char Display_data[4];/************************************************************** ****************** 函数名 : delay* 函数功能 : 延时函数,i=1时,大约延时10us*************************************************************** ****************/void delay(u16 i){while(i--);}//定时器和外部中断1的初始化函数void InitSyetem(){//配置外部中断1:采集霍尔传感器触发下降沿IT1 = 1; //选择下降沿触发EX1 = 1; //打开外部中断1//定时器0,1工作方式1TMOD=0x11; //定时或者计数模式控制寄存器//定时器0配置:产生PWM波TH0=(65536-10)/256;//赋初值定时10usTL0=(65536-10)%256;//sET0=1;//开定时器0中断TR0=1;//启动定时器0//定时1:测速TH1=(65536-10000)/256;//赋初值定时10msTL1=(65536-10000)%256;ET1=1;//开定时器0中断TR1=1;//启动定时器0PX1=1;//设置优先级PT1=1;//设定定时器1为最高优先级EA=1;//开总中断}//外部1中断服务函数void Service_Int1() interrupt 2{jishu++; //霍尔下降沿一次就记一次数if(jishu == 100) //累加计数有100次,总时间为100 * 10ms = 1s{led^=led; //led闪烁}}//定时0处理函数产生PWM 调速原理———在PWM高电平时候驱动电机转动在PWM低电平时候让电机停止转动void Service_Timer0() interrupt 1{TR0=0;//赋初值时,关闭定时器TH0=(65536-10)/256;//赋初值定时TL0=(65536-10)%256;//0.01msTR0=1;time++; //计数变量if(time>=100) time= 0; //清零标志变量if(time<=count) //小于设定值,输出高电平{PWM = 1;}elsePWM = 0;}//定时器1中断处理显示转速void Service_Timer1() interrupt 3{TR1=0;//赋初值时,关闭定时器TH1=(65536 - 10000) / 256;TL1=(65536 - 10000) % 256;//定时10msTR1=1;flag++; //计数变量加if(flag==100) //计时到达1s 测量此时的转速{// led=~led; //led状态取反zhuansu = jishu; //监测霍尔传感器总共计数次数jishu=0; //转速置0flag=0; //清除计数变量}}//数码管处理函数void Deal_data(){Display_data[3]=smgduan[zhuansu/1000]; //数码管高位Display_data[2]=smgduan[zhuansu/100%10];//去第二位Display_data[1]=smgduan[zhuansu/10%10];Display_data[0]=smgduan[zhuansu%10]; //数码管低位}/************************************************************** ****************** 函数名 : DigDisplay* 函数功能 : 数码管动态扫描函数,循环扫描4个数码管显示*******************************************************************************/void DigDisplay(){u8 i;for(i=0;i<4;i++){switch(i) //位选,选择点亮的数码管,{case 0 : S1 = 0; S2 = 1; S3 = 1; S4 = 1;break; //点亮第一位数码管case 1 : S2 = 0; S1 = 1; S3 = 1; S4 = 1;break;case 2 : S3 = 0; S1 = 1; S2 = 1; S4 = 1;break;case 3 : S4 = 0; S1 = 1; S2 = 1; S3 = 1;break;}P1=Display_data[i];//发送段码delay(5); //间隔一段时间扫描时间越少,一起亮且显示越稳定;时间越多,是流水点亮P1=0x00;//消隐时间过快时,每个数码管将会有重影}}/************************************************************** ****************** 函数名 : keypros* 函数功能 : 按键处理函数,判断按键K1是否按下*************************************************************** ****************/void keypros(){if(k1==0) //检测按键K1是否按下{delay(100); //消除抖动一般大约10ms 时间的估算100*n=1(s) if(k1==0) //再次判断按键是否按下{led=~led; //led状态取反count+=10;if(count >= 90) //设置一个上限count+=90;}while(!k1); //检测按键是否松开为假时候说明按键没有释放}if(k2==0) //检测按键K1是否按下{delay(100); //消除抖动一般大约10msif(k2==0) //再次判断按键是否按下{led=~led; //led状态取反count-=10;if(count <= 10){count = 10;}}while(!k2); //检测按键是否松开}}/************************************************************** ****************** 函数名 : main* 函数功能 : 主函数* 输入 : 无* 输出 : 无*************************************************************** ****************/void main(){led = 0; //上电熄灭小灯P1 = 0x00; //上电初始化熄灭数码管InitSyetem();//定时器和外部中断1的初始化函数while(1){keypros(); //按键处理函数Deal_data(); //数据处理函数DigDisplay(); //数码管显示函数}}。
51单片机实验报告一、引言51单片机是一种广泛应用于嵌入式系统开发的微控制器芯片。
本实验旨在通过对51单片机的实验研究,加深对该芯片的理解和应用。
二、实验一:LED灯闪烁控制本实验通过编写程序,控制51单片机上的LED灯以特定的频率闪烁。
为了实现这个目标,我们首先需要了解51单片机的引脚布局,确定LED灯的连接方式。
然后,通过编写相应的汇编程序,控制引脚的电平变化,从而实现LED灯的闪烁。
三、实验二:数码管显示数码管是一种常见的输出设备,通过控制引脚的输出来显示特定的数字。
本实验中,我们通过编写程序,实现通过51单片机控制数码管的显示。
通过对数码管的驱动原理和编程的学习,我们可以灵活地控制数码管的显示内容和频率。
四、实验三:蜂鸣器发声蜂鸣器是一种常见的声音输出设备,通过控制引脚的输出来产生特定的声音。
本实验中,我们通过编写程序,实现通过51单片机控制蜂鸣器的发声。
通过学习蜂鸣器的驱动原理和编程,我们可以根据需要产生不同频率和节奏的声音。
五、实验四:温湿度检测温湿度检测是一种常见的环境监测需求。
本实验中,我们通过引入温湿度传感器,实现通过51单片机获取环境的温度和湿度信息。
通过编写程序和读取传感器的数据,我们可以实时监测环境的温湿度,并进行相应的控制和反馈。
六、实验五:红外遥控红外遥控是一种常见的无线通信方式,通过发送和接收红外信号来实现远程控制。
本实验中,我们通过引入红外发射和接收模块,实现通过51单片机进行红外遥控。
通过编写相应的程序,设置红外遥控的编码和解码方式,我们可以实现对外部设备的遥控操作。
七、实验六:定时器应用定时器是51单片机中的重要模块,它可以实现定时和计数等功能。
本实验中,我们通过学习定时器的工作原理和编程,实现通过51单片机进行定时和计数的应用。
通过编写相应的程序和设置定时器的参数,我们可以实现不同的定时和计数功能,满足各种需要。
八、实验七:串口通信串口通信是一种常见的数据通信方式,通过串口接口发送和接收数据。
//DS18B20的读写程序,数据脚P3.3 ////温度传感器18B20汇编程序,采用器件默认的12位转化////最大转化时间750微秒,显示温度-55到+125度,显示精度////为0.1度,显示采用4位LED共阳显示测温值////P0口为段码输入,P24~P27为位选///***************************************************/#include "reg51.h"#include "intrins.h" //_nop_();延时函数用#define Disdata P0 //段码输出口#define discan P2 //扫描口#define uchar unsigned char#define uint unsigned intsbit DQ=P3^3; //温度输入口sbit DIN=P0^7; //LED小数点控制uint h;uchar flag;//**************温度小数部分用查表法***********//uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};//uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//共阳LED段码表"0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-" uchar code scan_con[4]={0x7f,0xbf,0xdf,0xef}; //列扫描控制字uchar data temp_data[2]={0x00,0x00}; //读出温度暂放uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个运算暂用///////***********11微秒延时函数**********///void delay(uint t){for(;t>0;t--);}///***********显示扫描函数**********/scan(){char k;for(k=0;k<4;k++) //四位LED扫描控制{Disdata=0xff;Disdata=dis_7[display[k]];if(k==1){DIN=0;}discan=scan_con[k];delay(90);discan=0xff;}}/////***********18B20复位函数**********/ow_reset(void){char presence=1;while(presence){while(presence){DQ=1;_nop_();_nop_();DQ=0; //delay(50); // 550usDQ=1; //delay(6); // 66uspresence=DQ; // presence=0继续下一步}delay(45); //延时500uspresence = ~DQ;}DQ=1;}/////**********18B20写命令函数*********///向1-WIRE 总线上写一个字节void write_byte(uchar val){uchar i;for (i=8; i>0; i--) //{DQ=1;_nop_();_nop_();DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us DQ = val&0x01; //最低位移出delay(6); //66usval=val/2; //右移一位}DQ = 1;delay(1);}///*********18B20读1个字节函数********///从总线上读取一个字节uchar read_byte(void){uchar i;uchar value = 0;for (i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ = 0; //_nop_();_nop_();_nop_();_nop_(); //4usDQ = 1;_nop_();_nop_();_nop_();_nop_(); //4us if(DQ)value|=0x80;delay(6); //66us}DQ=1;return(value);}///***********读出温度函数**********///read_temp(){ow_reset(); //总线复位write_byte(0xCC); // 发Skip ROM命令write_byte(0xBE); // 发读命令temp_data[0]=read_byte(); //温度低8位temp_data[1]=read_byte(); //温度高8位ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令}///***********温度数据处理函数**********/ void work_temp(){uchar n=0;uchar doth,dotl;uchar flag3=1,flag2=1; //数字显示修正标记if((temp_data[1]&0xf8)!=0x00){temp_data[1]=~(temp_data[1]);temp_data[0]=~(temp_data[0])+1;n=1;flag=1;}//负温度求补码if(temp_data[0]>255){temp_data[1]++;}display[4]=temp_data[0]&0x0f;display[0]=ditab[display[4]];doth=display[0]/10;dotl=display[0]%10;display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x07)<<4); display[3]=display[4]/100;display[2]=display[4]/10%10;display[1]=display[4]%10;if(!display[3]){display[3]=0x0a;flag3=0;if(!display[2]){display[2]=0x0a;flag2=0;}}//最高位为0时都不显示if(n){display[3]=0x0b;//负温度时最高位显示"-"flag3=0;}}/////**************主函数****************/main(){Disdata=0xff; //初始化端口discan=0xff;for(h=0;h<4;h++){display[h]=8;}//开机显示8888ow_reset(); // 开机先转换一次write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令for(h=0;h<500;h++){scan();} //开机显示"8888"2秒while(1){read_temp(); //读出18B20温度数据work_temp(); //处理温度数据scan(); //显示温度值2秒}}////*********************结束**************************//。
计算机技术系项目工作报告课程名称单片机开发板设计与制作实训班级学号姓名项目名称超声波测距,数码管显示实训日期/时间2015.6.23-2015.7.5 地点指导教师同组成员仪器设备(参考资料)计算机、Keil uVision2、Proteus ISIS 电烙铁、开发板、HC-SR04超声波模块实训内容(任务安排)1焊接开发板2自选课题3开发与调试4项目汇报与总结一、项目名称与要求项目名称:超声波测距,数码管显示功能描述:采用HC-SR04超声波模块,STC89C52单片机以及数码管显示设计的一种超声波测距显示器,可以实现测量物体到仪器距离以及显示等功能,可以测量范围为2cm –450cm ,精确度为1cm。
是一种结构简单、性能稳定、使用方便、价格低廉的超声波距离测量器,具有一定的实用价值。
二、项目设计思路1、硬件资源单片机开发板(携带数码管);HC-SR04超声波模块;STC89C52芯片;2、软件设计思路软件设计采用C语言编程,运用模块化程序设计思想,对不同功能模块的程序进行分别编程,以便移植或调用,这样使软件层次结构清晰,有利于软件的调试修改。
软件设计思路是:系统初始化、发射脉冲串、计时、接收输入脉冲,接收串口输入速度值、计算距离、显示距离值、重复。
超声波测距算法设计如下:超声波发生器T在某一时刻发出一个超声波信号,当这个超声波遇到被测物体后反射回来,就会被超声波接收器R接收到。
这样,只要计算出从发出超声波信号到接收到返回信号所用的时间,就可算出超声波发生器于反射物体的距离。
该距离的计算公式如下:d=s/2(v×t)/2其中:d为被测物于测距器的距离;s为声波的来回路程;v为声速;t为声波来回所用的时间。
超声波测距原理图如下:3、项目涉及的知识点说明HC-SR04超声波模块简介:实物图:正面:背面:HC-SR04 超声波测距模块可提供 2cm-400cm 的非接触式距离感测功能,测距精度可达高到 1cm;模块包括超声波发射器、接收器与控制电路。
测量转速,使用霍尔传感器,被测轴安装有12只磁钢,即转轴每转一周,产生12个脉冲,要求将转速值(转/分)显示在数码管上。
程序如下:DISPBUF EQU 5AH ;显示缓冲区从5AH开始SeCCoun EQU 59HSpCoun EQU 57H ;速度计时器单元57H和58H,高位在前(57H单元中)Count EQU 56H ;显示时的计数器SpCalc bit 00h ;要求计算速度的标志Hidden EQU 16 ;消隐码ORG 0000HAJMP STARTORG 1BHJMP TIMER1 ;定时中断1入口ORG 30HSTART: MOV SP,#5FH ;设置堆栈MOV P1,#0FFHMOV P0,#0FFHMOV P2,#0FFH ;初始化,所有显示器、LED灭MOV TMOD,#00010101B ;定时器T1工作于方式1,定时器0工作方式1 MOVTH1,#HIGH(65536-4000)MOV TL1,#LOW(65536-4000)SETB TR1SETB ET1 ;开定时器1中断SETB EALOOP: JNB SpCalc,LOOP ;如果未要求计算,转本身循环;标号:MULD功能:双字节二进制无符号数乘法;入口条件:被乘数在R2、R3中,乘数在R6、R7中。
;出口信息:乘积在R2、R3、R4、R5中。
;影响资源:PSW、A、B、R2~R7 堆栈需求:2字节MOV R2,SpCounMOV R3,SpCoun+1MOV R6,#0MOV R7,#5 ;测得的数值是每秒计数值,转为每分转速(每一转测12次,故乘5而非60)CALL MULD;标号:HB2功能:双字节十六进制整数转换成双字节BCD码整数;入口条件:待转换的双字节十六进制整数在R6、R7中。
;出口信息:转换后的三字节BCD码整数在R3、R4、R5中。
;影响资源:PSW、A、R2~R7 堆栈需求:2字节MOV A,R4MOV R6,AMOV A,R5MOV R7,A ;将乘得的结果送R6R准备转换,这里结果不可能超过2字节CALL HB2CBCD:MOV DISPBUF,R3 ;最高位MOV A,R4 ;ANL A,#0F0H ;去掉低4位SWAP A ;将高4位切换到低4位MOV DISPBUF+1,AMOV A,R4ANL A,#0FHMOV DISPBUF+2,AMOV A,R5ANL A,#0F0HSWAP AMOV DISPBUF+3,AMOV A,R5ANL A,#0FHMOV DISPBUF+4,ACLR SpCalc ;清计算标志JMP LOOP;主程序到此结束TIMER1: PUSH ACC;ACC入栈PUSH PSW ;PSW入栈SETB RS0 ;工作区1JNB TR0,SETTR0 ;如果T0未运行,则开启T0 JMP GO1SETTR0:SETB TR0GO1:INC SecCoun ;秒计数器加1MOV A,SecCounCJNE A,#251,Go2 ;如果未到1s则转CLR TR0 ;1s到了,则停止T0的运行MOV SpCoun,TH0MOV SpCoun+1,TL0 ;读取计数值CLR AMOV TH0,AMOV TL0,A ;清计数器SETB SpCalc ;要求主程序计算速度MOV SecCoun,#0 ;清秒计数器Go2:INC COUNT ;用于显示的计数器MOV A,COUNTCLR CSUBB A,#6JZ N1JMP N2N1: MOV COUNT,#0N2: MOV A,#DISPBUFADD A,COUNTMOV R0,A ;指向当前要显示的显示缓冲区MOV A,@R0 ;取第一个待显示数MOV DPTR,#DISPTAB ;字形表首地址MOVC A,@A+DPTR ;取字形码MOV P0,A ;将字形码送P0位(段口)MOV A,COUNTMOV DPTR,#BitTab ;字位表首地址MOVC A,@A+DPTRORL P2,#11111100BANL P2,AMOV TH1,#HIGH(65536-4000)MOV TL1,#LOW(65536-4000)POP PSWPOP ACCRETIBitTab: DB 7Fh,0BFH,0DFH,0EFH,0F7H,0FBHDISPTAB:DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH,0F FH……其他数学运算程序(略)主程序在对定时器、计数器、堆栈等进行初始化后即判断标志SpCalc是否为1,如果为1,说明要求对数据进行计算处理,首先将SpCalc标志清零,以保证下次能正常判断,然后进入数据处理程序,由于这里的闸门时间为1s,而显示要求为转/分,因此,要将测到的数据进行转换,转换的方法是将测得的数据乘以60,但由于转轴上安装有12只磁钢,每旋转一周可以得到12个脉冲,因此,要将测得的数据除以12,所以综合起来,将测得的数据乘以5即可得到每分钟的转速。
基于proteus的51单片机仿真实例六十、8位数码管显示实例1、本例实现在8位数码管上同时显示多个不同字符。
2、本例使用了8只集成式7段共阳数码管(pruteus中元件标识为7seg-mpx8-ca-blu,共阳为ca,共阴为cc),所有8个数码管的段码引脚a,b,c,d,e,f,g,dp都是分别并联在一起,任何时候发送的段码均会传送到所有数码管上,所有的数码管的共阳极是独立的,本例中个数码管的共阳极分别与8只NPN三极管射极相连,程序运行时,任意时刻仅允许一只数码管的共阳极连接+5V,当向连接段码的端口发送段码值时,相应数字只会显示在某一只数码管上。
3、为了使不同数码管显示不同字符,本例使用的是集成式多位数码管常用的动态扫描显示技术,他利用了人的视觉暂留特征,选通第一只数码管时,发送1的段码;选通第二只数码管时,发送2的段码,...每次仅选通一只数码管,发送相应的段码,每次切换选通下一数码管并发送相应段码的时间间隔非常短,视觉惰性使人感觉不到字符是一个接一个显示在不同的数码管上的,而会觉得所有的字符很稳定的同时显示在不同数码管上。
在控制两位数码管选通的时间间隔时,要注意全屏的扫描频率要高于视觉暂留频率16-20Hz。
对于程序中的点亮一位数码管的延时时间,我们可以尝试将延时时间改为其他数值,观察会出现什么样的效果。
4、在keil c51中新建工程ex48,编写如下程序代码,编译并生成ex48hex文件/***************************************************************************** * LED数码管显示演示程序** 在8个LED数码管上依次显示1,2,3,4,5,6,7,8 ******************************************************************************** /#include <reg51.h> //包含头文件#include <intrins.h> //包含移位函数头文件//段码表unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3 0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off//毫秒级延时函数void delay(unsigned int x){unsigned char i;while(x--){for(i=0;i<120;i++);}}//主函数void main(){unsigned char k,m=0x80; //变量定义P0 = 0xff; //先关闭数码管P2 = 0x00; //while(1){for(k = 0;k < 8;k++) //循环8次{P2 = 0x00; //每显示一位都要关闭位选端口一次m=_crol_(m,1); //循环左移P2=m; //每次选通一个位选端口P0=dis_code[k+1]; //段码送P0口delay(2);}}}5、在proteus中新建仿真文件ex48.dsn,电路原理图如下所示6、将ex48.hex文件载入at89c51中,启动仿真,观察程序运行结果,下图是程序运行结果。
51单片机数码管显示实验报告实验目的:1.学习51单片机的编程方法和硬件连接方法;2.掌握使用51单片机驱动数码管显示的方法。
实验器材:1.51单片机开发板;2.公共阳极共阳向数码管一个;3.若干杜邦线。
实验原理:数码管是一种数字显示器件,由7个发光二极管和若干个选通器件构成。
每个发光二极管可以发出两种颜色的光,通常使用红色和绿色。
这篇实验报告以共阳数码管为例,共阳数码管的每个发光二极管的阳极都连接到电源VCC上,而七个阴极分别用来选择一些数字进行显示。
当要选择一些数码管显示时,需要对对应的阴极进行低电平使能,而使能其他阴极保持高电平,这样就可以通过控制每个数码管的阴极低电平使能来选择要显示的数字。
实验步骤:1.将51单片机开发板上的数码管连接到51单片机开发板的P1口和P0口上,连接方式如下图所示:```-----------------VCC-P0.0--,a,-----------------P0.1--,b,------P0.2--,c,---,数字2P0.3--,d,------P0.4--,e,------P0.5--,f,---,数字1P0.6--,g,------P0.7--,h,-----------------------P1.0P1.1```2. 在Keil µVision中新建工程,编写程序。
3.利用P0口控制数码管的阴极,利用P1口选择数码管要显示的数字。
4.在主程序中循环选择每个数码管,并通过P0口设置要显示的数字。
实验结果:```---------------------------------P1.0P1.1P0.6P0.7空空数字2数字1abcdefgh---------------------------------```实验结论:通过本次实验,学习了51单片机的编程方法和硬件连接方法,并掌握了使用51单片机驱动数码管显示的方法。
同时,还了解了数码管的工作原理和编程的基本步骤。
#include<regx52.h> //器件配置文件#include <intrins.h>#define TX P1_2 //Trig#define RX P1_3 //Echo#define LCM_RS P2_5 //定义LCD引脚#define LCM_RW P2_6#define LCM_E P2_7#define LCM_Data P0#define Busy 0x80 //用于检测LCM状态字中的Busy标识#define uint unsigned int#define uchar unsigned charsbit P10=P2^1;//控制左电机前进sbit P11=P2^2;//控制左电机后退sbit P12=P2^3;//控制右电机前进sbit P13=P2^4;//控制右电机后退sbit P14=P1^4;//寻迹左sbit P15=P1^5;//寻迹中sbit P16=P1^6;//寻迹右sbit P17=P1^7;//避障void LCMInit(void);void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData); void Delay5Ms(void);void Delay400Ms(void);void Decode(unsigned char ScanCode);void WriteDataLCM(unsigned char WDLCM);void WriteCommandLCM(unsigned char WCLCM,BuysC);void fun2(void);void fun3(void);void fun4(void);void fun5(void);unsigned char ReadDataLCM(void);unsigned char ReadStatusLCM(void);unsigned char code mcustudio[] ={"…………. "};unsigned char code email[] = {"………… "};unsigned char code Cls[] = {"……………"};unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};static unsigned char DisNum = 0; //显示用指针unsigned int time=0;unsigned long S=0;bit flag =0;unsigned char disbuff[4] ={ 0,0,0,0,};bit Flg_5ms=0;unsigned char Counter_100ms=0;unsigned char buf[5]={0,0,0,0,0};unsigned int Speed;unsigned int speed_frequency; // frequencyunsigned int speed_catch1; //catch 1unsigned int speed_catch2; //catch 2unsigned char speed_t2_ovf_count_temp; //T1 overflow counter temp register unsigned char speed_t2_ovf_count; //T1 overflow counter register unsigned char speed_catch_p; //catch pointer//写数据void WriteDataLCM(unsigned char WDLCM){ReadStatusLCM(); //检测忙LCM_Data = WDLCM;LCM_RS = 1;LCM_RW = 0;LCM_E = 0; //若晶振速度太高可以在这后加小的延时LCM_E = 0; //延时LCM_E = 1;}//写指令void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM;LCM_RS = 0;LCM_RW = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;}//读数据unsigned char ReadDataLCM(void){LCM_RS = 1;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;return(LCM_Data);}//读状态unsigned char ReadStatusLCM(void){LCM_Data = 0xFF;LCM_RS = 0;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;while (LCM_Data & Busy); //检测忙信号return(LCM_Data);}void LCMInit(void) //LCM初始化{LCM_Data = 0;WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示WriteCommandLCM(0x01,1); //显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0F,1); // 显示开及光标设置}//按指定位置显示一个字符void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData) {Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; //算出指令码WriteCommandLCM(X, 1); //发命令字WriteDataLCM(DData); //发数据}//按指定位置显示一串字符void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) {unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]>0x19) //若到达字串尾则退出{if (X <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;X++;}}}//5ms延时void Delay5Ms(void){unsigned int TempCyc = 5552;while(TempCyc--);}//400ms延时void Delay400Ms(void){unsigned char TempCycA = 5;unsigned int TempCycB;while(TempCycA--){TempCycB=7269;while(TempCycB--);};}/********************************************************/ void Conut(void){time=TH0*256+TL0;TH0=0;TL0=0;S=(time*1.7)/100; //算出来是CMif((S>=700)||flag==1) //超出测量范围显示"-"{flag=0;DisplayOneChar(0, 1, ASCII[11]);DisplayOneChar(1, 1, ASCII[10]); //显示点DisplayOneChar(2, 1, ASCII[11]);DisplayOneChar(3, 1, ASCII[11]);DisplayOneChar(4, 1, ASCII[12]); //显示M}else{disbuff[0]=S%1000/100;disbuff[1]=S%1000%100/10;disbuff[2]=S%1000%10 %10;DisplayOneChar(0, 1, ASCII[disbuff[0]]);DisplayOneChar(1, 1, ASCII[10]); //显示点DisplayOneChar(2, 1, ASCII[disbuff[1]]);DisplayOneChar(3, 1, ASCII[disbuff[2]]);DisplayOneChar(4, 1, ASCII[12]); //显示M}}/********************************************************/ void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围{flag=1; //中断溢出标志}/********************************************************/ void StartModule() //启动模块{TX=1; //启动一次模块_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();TX=0;}//--------------------------------------------void fun2(void){ P10=1;P11=0;P12=1;P13=0;} //前进void fun3(void){ P10=0;P11=0;P12=1;P13=0;}//左转void fun4(void){ P10=1;P11=0;P12=0;P13=0;} //右转void fun5(void){ P10=0;P11=0;P12=0;P13=0;}//停止/********************************************************/void timer1() interrupt 3 //T0中断用来计数器溢出,超过测距范围{Flg_5ms=1;TH1=0xee;TL1=0;TF1=0;if(P14==1&&P15==0&&P16==1) fun2();if((P14==0&&P15==0&&P16==1)||(P14==0&&P15==1&&P16==1)) fun3();if((P14==1&&P15==0&&P16==0)||(P14==1&&P15==1&&P16==0)) fun4();if((P14==1&&P15==1&&P16==1)||(P14==0&&P15==0&&P16==0)||(P17==0)) fun5(); }//-------------------------------------------void Timer2() interrupt 5 //定时器2捕捉中断,溢出中断{if(TF2){if(speed_t2_ovf_count_temp < 2) speed_t2_ovf_count_temp++;else{speed_frequency = 0; // frequencyspeed_catch1 = 0; //catch 1speed_catch2 = 0; //catch 2speed_catch_p = 0; //catch pointerspeed_t2_ovf_count_temp = 0; //T2 overflow counter temp registerspeed_t2_ovf_count = 0; //T2 overflow counter registerSpeed=0;}TF2=0;}if(EXF2){switch(speed_catch_p){case 0:speed_catch1 = RCAP2H;speed_catch1 <<=8;speed_catch1 += RCAP2L;speed_catch_p++;break;case 1:speed_catch2 = RCAP2H;speed_catch2 <<=8;speed_catch2 += RCAP2L;speed_t2_ovf_count = speed_t2_ovf_count_temp;speed_catch_p++;break;default:break;}speed_t2_ovf_count_temp = 0;EXF2=0;}}/*********************************************************/void main(void){unsigned char TempCyc;unsigned long temp;Delay400Ms(); //启动等待,等LCM讲入工作状态LCMInit(); //LCM初始化Delay5Ms(); //延时片刻(可不要)DisplayListChar(0, 0, mcustudio);DisplayListChar(0, 1, email);ReadDataLCM();//测试用句无意义for (TempCyc=0; TempCyc<10; TempCyc++)Delay400Ms(); //延时DisplayListChar(0, 1, Cls);Speed=0;speed_frequency = 0; // frequencyspeed_catch1 = 0; //catch 1speed_catch2 = 0; //catch 2speed_catch_p = 0; //catch pointerspeed_t2_ovf_count_temp = 0; //T2 overflow counter temp registerspeed_t2_ovf_count = 0; //T2 overflow counter registerwhile(1){TMOD=0x11; //设T0为方式1,GATE=1;TH0=0;TL0=0;TH1=0xee;TL1=0;T2CON = 0x09; //捕捉模式ET0=1; //允许T0中断ET1=1; //允许T0中断ET2=1;EA=1; //开启总中断TR1=1; //开启计数TR2=1;while(1){if(Flg_5ms){Flg_5ms=0;if(Counter_100ms<39){Counter_100ms++;if(Counter_100ms==20){if(speed_catch_p > 1){temp =(unsigned long)(( 65536UL * speed_t2_ovf_count)+ speed_catch2 - speed_catch1); //calculate TSpeed= (unsigned int)(9584640UL / temp);speed_catch_p = 0;}if(Speed >9999U) Speed=9999U;buf[0]=Speed/1000;buf[1]=(Speed/100)%10;buf[2]=(Speed/10)%10;buf[3]=Speed %10;DisplayOneChar(8, 1, ASCII[buf[0]]);DisplayOneChar(9, 1, ASCII[buf[1]]);DisplayOneChar(10, 1, ASCII[buf[2]]);DisplayOneChar(11, 1, ASCII[buf[3]]);DisplayOneChar(12, 1, 'm'); //显示MDisplayOneChar(13,1, 'm'); //显示MDisplayOneChar(14,1, '/');DisplayOneChar(15,1, 's');}}else{Counter_100ms=0;StartModule();// DisplayOneChar(0, 1, ASCII[0]);TH0=0;TL0=0;while(!RX); //当RX为零时等待TR0=1; //开启计数while(RX); //当RX为1计数并等待TR0=0; //关闭计数Conut(); //计算}}}}}。
基于51单片机的红外反射式光电传感器测速机的简易设计——基于红外反射式的测速机引言在工程实践中,经常会遇到各种需要测量转速的场合。
转速是电动机极为重要的一个状态参数,在很多运动系统的测控中,都需要对电机的转速进行测量,不论是直流调速系统还是交流调速系统,只有转速的高精度检测才能得到高精度的控制系统。
迄今为止,测速可分为两类:模拟电路测速和数字电路测速。
随着微电子技术的发展,计算机技术的广泛应用,出现了以计算机为核心的数字测速装置。
这样的速度测量装置测量范围宽、工作方式灵活多变、适应面广,具有普通数字测速装置不可比拟的快速性、精确性和优越性。
一:设计思路用一个红外发光二极管和一个接受红外光的二极管组成一套光电管。
当检测到物表面为黑色时,反射光很弱,接收端检测到的光线可以忽略,使接收端呈现一种状态,例如开关管截止;当被检测物表面为白色时,反射光强烈,发射端发射的红外线被接收端全部接收,使接收端呈现另一种相反的状态,例如开关管开通。
这两种相反的状态表现在电路中,就是高低电平组成的脉冲信号。
由此,我想到用一个比较器来比较两种接受到的信号,从而输出“0”“1”两种高低电平,并把两种信号传给单片机进行统计,然后利用设定算法进行计算,最后通过数码显示管显示计算结果。
二:所需模块本测速系统共有两个模块构成,一个为光电传感器部分,用于接收光信号并转换为电信号,即高低电平信号;另一个为单片机部分,用于接收高低电平信号并通过内部计算,然后再通过数码显示管显示测出的结果。
(一) 光电传感器部分(1)LM339工作原理及管脚图:LM339类似于增益不可调的运算放大器。
每个比较器有两个输入端和一个输出端。
两个输入端中的一个称为同相输入端,用“+”表示,另一个称为反相输入端,用“-”表示。
当用作比较两个电压时,任意一个输入端加一个固定电压做参考电压(也称为门限电平,它可选择LM339输入共模范围的任何一点),另一端加一个待比较的信号电压,当“+”端电压高于“-”端时,输出管截止,相当于输出端开路。
#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit du=P2^6;sbit we=P2^7;uchar num;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; void delays(uint);void main(){we=1;//打开U2锁存器P0=0xc0;//送入位选信号we=0;while(1){du=1;P0=table[0];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xfe;we=0;delays(500);du=1;P0=table[1];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xfd;we=0;delays(500);du=1;P0=table[2];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xfb;we=0;delays(500);du=1;P0=table[3];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xf7;we=0;delays(500);du=1;P0=table[4];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xef;we=0;delays(500);du=1;P0=table[5];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xdf;we=0;delays(500);du=1;P0=table[6];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xfe;we=0;delays(500);du=1;P0=table[7];P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xfd;we=0;delays(500);du=1;P0=table[8];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xfb;we=0;delays(500);du=1;P0=table[9];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xf7;we=0;delays(500);du=1;P0=table[10];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xef;we=0;delays(500);du=1;P0=table[11];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;we=0;delays(500);du=1;P0=table[12];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xfe;we=0;delays(500);du=1;P0=table[13];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xfd;we=0;delays(500);du=1;P0=table[14];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xfb;we=0;delays(500);du=1;P0=table[15];du=0;P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱we=1;P0=0xf7;we=0;delays(500);}}void delays(uint xs){uint i,j;for(i=xs;i>0;i--)for(j=110;j>0;j--);//延时x秒}。