(完整word版)pic单片机4位数码管显示 1~9999循环点亮
- 格式:doc
- 大小:12.25 KB
- 文档页数:2
51单片机数码管0到99循环程序代码1. 概述在嵌入式系统的开发中,数码管是一种常见的输出设备,可以用于显示数字、字符等信息。
而51单片机是一种广泛应用的微控制器,其结合了强大的功能和灵活的应用,能够很好地驱动数码管。
本文将介绍如何使用51单片机编写一个循环显示0到99的程序,通过数码管输出这些数字。
2. 电路连接我们需要连接51单片机和数码管。
通常我们使用的是共阴数码管,其连接方式如下:- VCC连接到5V电源- GND连接到GND- DIO(数据输入/输出)连接到51单片机的IO口3. 程序设计下面是一个简单的C语言程序设计,用于控制数码管显示0到99的数字。
```c#include <reg51.h>sbit DIO = P2^0; // 数码管数据输入/输出sbit CL = P2^1; // 数码管片选信号unsigned char code numCode[10] = { 0xc0, // 00xf9, // 10xa4, // 20xb0, // 30x99, // 40x92, // 50x82, // 60xf8, // 70x80, // 80x90 // 9};//延时函数void delay(unsigned int i) {unsigned int j,k;for (j=i;j>0;j--)for(k=110;k>0;k--);}void display(unsigned char num) { CL = 1; //关闭片选DIO = numCode[num / 10]; //十位 delay(2);CL = 0;DIO = 0xff; //消隐delay(2);CL = 1; //关闭片选DIO = numCode[num 10]; //个位 delay(2);CL = 0;DIO = 0xff; //消隐delay(2);}void m本人n() {unsigned char i,j;while(1) {for(i=0;i<10;i++) {for(j=0;j<10;j++) {display(i * 10 + j);}}}}```4. 程序说明- 首先定义了数码管的连接引脚,以及0~9的显示编码。
数码管循环显示0~9程序说明功能说明:用一位数码管循环显示数字0~9,数字间隔时间为0.2秒。
一、电路图数码管循环显示0~9电路图二、所用电子元器件AT89C51:单片机;7SEG—COM—AN—GRN:带公共端共阳七段绿色数码管;CAP、CAP—ELEC:电容、电解电容;CRYSTAL:晶振。
三、程序汇编语言编写的数码管循环显示0~9源程序代码如下:START:MOV DPTR,#TABLEMOV R0,#00HLOOP: MOV A,R0MOVC A,@A+DPTRMOV P0,AACALL DL Y1SINC R0CJNE R0,#10,LOOPJMP STARTDL Y1S:MOV R5,#10HD1: MOV R6,#100HD2: MOV R7,#100HDJNZ R7,$DJNZ R6,D2DJNZ R5,D1RETTABLE:DB 0C0H,0F9H,0A4H,0B0HDB 99H, 92H, 82H, 0F8HDB 80H, 90H, 88H, 83HDB 0C6H,0A1H,86H, 8EHENDProtetus 安装说明使用说明1.先安装Setup71.exe,提示选择Setup Type时默认选择即可;若提示No LICENCE 选择安装文件中"crack"-->MAXIM_LICENCE.lxk,打开安装。
2.安装完成后将crack-->文件夹BIN 和文件夹MODELS 下的文件复制到安装目录相应的文件夹内覆盖。
3.安装proteus.7.x-patch,选择patch,提示can not find the file. search the file,选择yes即可;然后选择bin文件中的ares.exe ;在选择models 中的avr.dll安装完毕退出即可。
注:***"Keil驱动"中的程序为Proteus与Keil联调的驱动。
4位数码管循环4位数码管可以显示0-9的数字,因此可以通过循环实现数字的循环显示。
一种简单的方式是使用四个数码管分别显示个位、十位、百位和千位的数字。
通过循环不断更新这四个数码管的显示内容,就可以实现数字的循环显示。
以下是一个示例代码:```c#include <avr/io.h>#include <avr/delay.h>void displayDigit(uint8_t digit){// 根据数字设置对应的数码管段亮起switch (digit) {case 0:PORTA = 0b00111111;break;case 1:PORTA = 0b00000110;break;case 2:PORTA = 0b01011011;break;case 3:PORTA = 0b01001111;break;case 4:PORTA = 0b01100110;break;case 5:PORTA = 0b01101101;break;case 6:PORTA = 0b01111101;break;case 7:PORTA = 0b00000111;break;case 8:PORTA = 0b01111111;break;case 9:PORTA = 0b01101111;break;default:// 如果传入的数字不在0-9之间,将所有数码管熄灭 PORTA = 0b00000000;break;}}int main(void){// 设置端口A为输出端口DDRA = 0xFF;while (1) {for (int i = 0; i < 10000; i++) {int thousands = i / 1000;int hundreds = (i % 1000) / 100;int tens = (i % 100) / 10;int ones = i % 10;// 分别显示千位、百位、十位和个位的数字displayDigit(thousands);_delay_ms(10);displayDigit(hundreds);_delay_ms(10);displayDigit(tens);_delay_ms(10);displayDigit(ones);_delay_ms(10);}}return 0;}```此代码使用的是ATmega系列的单片机,使用了端口A的8个引脚来控制四个数码管的段的亮灭。
数码管动态显⽰,显⽰从1到9,每⼀位显⽰⼀个数字(单⽚机)//object: 动态显⽰数码管,从1显⽰到9//writer:mike//time: 2020,11,14#include<reg52.h>sbit wei = P2^7;sbit du = P2^6;//数组的类型指的是每⼀个元素的类型, code则指定存储在代码区,⽽⾮code 指存户在内存中。
unsigned int code data1[10] = {0x3F,//00x06,//10x5B,//20x4F,//30x66,//40x6D,//50x7D,//60x07,//70x7F,//80x6F//9};void delay(unsigned int);void main(){while(1){//⾸先打开位选wei = 1;P0 = 0xfe; //让第⼀位显⽰//关闭位选wei = 0;//打开段选du = 1;//显⽰数字1P0 = data1[1];//关闭段选du = 0;//点亮第⼀位之后,延时⼀段时间delay(1);//针对第⼆位数码管//打开位选wei = 1;//设置位选P0 = 0xfd;//关闭位选wei = 0;//打开段选du = 1;//设置段选P0 = data1[2];//关闭段选du = 0;delay(1);//针对第三位数码管//打开位选wei = 1;//设置位选P0 = 0xfb;//关闭位选wei = 0;//打开段选du = 1;//设置段选P0 = data1[3];//关闭段选du = 0;delay(1);//针对第四位数码管//打开位选wei = 1;wei = 0;//打开段选du = 1;//设置段选P0 = data1[4];//关闭段选du = 0;delay(1);//针对第五位数码管 //打开位选wei = 1;//设置位选P0 = 0xef;//关闭位选wei = 0;//打开段选du = 1;//设置段选P0 = data1[5];//关闭段选du = 0;delay(1);//针对第六位数码管 //打开位选wei = 1;//设置位选P0 = 0xdf;//关闭位选wei = 0;//打开段选du = 1;//设置段选P0 = data1[6];//关闭段选du = 0;delay(1);//针对第七位数码管 //打开位选wei = 1;//设置位选P0 = 0xbf;//关闭位选wei = 0;//打开段选du = 1;//设置段选P0 = data1[7];//关闭段选du = 0;delay(1);//针对第⼋位数码管 //打开位选wei = 1;//设置位选P0 = 0x7f;//关闭位选wei = 0;//打开段选du = 1;//设置段选P0 = data1[8];//关闭段选du = 0;delay(1);/* //针对第九位数码管 //打开位选wei = 1;//设置位选wei = 0xff;//关闭位选wei = 0;du = data1[9];//关闭段选du = 0;*/}}void delay(unsigned int x) {unsigned a, b;for(a=x;a>0;a--){for(b=120;b>0;b--); }}。
单片机四位数码管阳极管1 ,2,3,4通常用于控制数码管的显示。
这些阳极管用于选择要显示的数码管,以便单片机可以向其发送相应的数据。
具体来说,单片机通过控制阳极管的导通或截止,来选择要显示的数码管。
例如,如果单片机想要显示数字“1”,它会控制阳极管1、2、3、4都处于截止状态,而阳极管5、6、7、8处于导通状态。
这样,数码管1就会被选通,并显示数字“1”。
此外,阳极管也可以通过编程来实现复用,以便同时控制多个数码管。
这样,单片机可以通过控制阳极管的导通和截止,来同时控制多个数码管的显示。
需要注意的是,具体的控制方式可能会因不同的单片机型号和数码管型号而有所不同。
因此,在使用单片机控制数码管时,需要参考相关的技术文档和数据手册,以确保正确的连接和控制方式。
电子信息工程学院电子设计应用软件训练任务【训练任务】:1、熟练掌握PROTEUS软件的使用;2、按照设计要求绘制电路原理图;3、能够按要求对所设计的电路进行仿真;【基本要求及说明】:1、按照设计要求自行定义电路图纸尺寸;2、设计任务如下:利用51单片机、BCD译码芯片和两位LED构成一个数码管扫描显示系统,两个数码管同时循环显示0~9。
3、按照设计任务在Proteus 6 Professional中绘制电路原理图;4、根据设计任务的要求编写程序,在Proteus下进行仿真,实现相应功能。
【按照要求撰写总结报告】指导教师年月日负责教师年月日学生签字年月日成绩评定表摘要该专业是前沿学科,现代社会的各个领域及人们日常生活等都与电子信息技术有着紧密的联系。
全国各地从事电子技术产品的生产、开发、销售和应用的企事业单位很多,随着改革步伐的加快,这样的企事业单位会越来越多。
为促进市场经济的发展,培养一大批具有大专层次学历,能综合运用所学知识和技能,适应现代电子技术发展的要求,从事企事业单位与本专业相关的产品及设备的生产、安装调试、运行维护、销售及售后服务、新产品技术开发等应用型技术人才和管理人才是社会发展和经济建设的客观需要,市场对该类人才的需求越来越大。
为此电子信息工程专业的人才有着广泛的就业前景,毕业生可从事电子设备、信息系统和通信系统的研究、设计、制造、应用和开发工作。
目录一、任务说明 (1)1.1 专业介绍 (1)1.2 专业背景与市场预测 (1)1.3 本课题分析 (1)二、绘制原理图 (2)2.1 Proteus软件介绍 (2)2.2 原理图绘制说明 (2)2.3 原理图绘制步骤 (3)三、程序编译说明及程序流程图 (6)3.1 Main程序说明 (6)3.2 初始化子程序说明 (6)3.3 display(uchar tmp)子程序说明 (7)3.4 延时子程序说明 (8)3.5 中断子程序说明 (9)四、Proteus仿真说明 (11)4.1 导入仿真文件 (11)4.2 进行仿真 (12)五、课程设计体会及合理化建议 (14)致谢 (16)一、任务说明1.1专业介绍电子信息工程是一门应用计算机等现代化技术进行电子信息控制和信息处理的学科,主要研究信息的获取与处理,电子设备与信息系统的设计、开发、应用和集成。
数字起航—实验零基础电子设计系列课程
主讲人:范秋华
国家级电工电子实验教学中心(青岛大学)
6.1基础实验
6.1.1 一个LED点亮的控制
6.1.2 一位数码管点亮的控制
6.1.3 四位数码管点亮的控制
6.1.4 一个LED动态闪亮的控制
6.1.5 四位数码管自动点亮
6.1.6 加使能端控制四位数码管点亮6.2复杂实验
6.2.1 流水灯的设计
6.2.2 呼吸灯的设计
6.2.3 音乐基础的设计
6.2.4 简易电子琴的设计
6.2.5 乐曲播放器设计
6.3综合试验
6.3.1 音乐彩灯的设计
6.1.5 四位数码管自动点亮的控制
图数码管硬件接线图
实验任务:有四个共阴极数码管。
通电后4个数码管依次自动循环点亮0,1,…,9,A,B,C,D,E,F。
每个点亮1/3秒参数指标:系统时钟100MHz。
管脚约束
CLK---P17
VHDL 程序编写
设计思路:首先设计以分频器,输出高电平1/3秒。
对分频信号16进制计数,把计数值译码给数码管的相应段码,同时制定数码管的位码。
请看下载演示!
数字启航实验内容4国家级电工电子实验教学中心。
一、实验目的1.掌握Keil软件的基本使用2.学习和掌握C语言编写程序的一般格式3.了解数码管与单片机的接口方法;4.了解数码管性能及动态显示编程方法;5.了解并掌握单片机系统中定时器中断控制的基本方法;二、实验内容用定时器中断实现四位数码管动态显示从1234-9999。
三、实验原理3.1基础知识介绍A.数码管是LED的升级,每位数码管里面继承了8个LED,点亮数码管就是点亮数码管里面的LED。
要在数码管上面显示相应的值,就是点亮不同位置的LED。
数码管有共阴和共阳两种,共阴数码管公共端是所有LED的负极连接在一起,相反共阳数码管公共端是所有LED的正极连接在一起。
一般公共端称作“位选”,控制每一个LED的称为“段选”。
数码管主要是利用视觉暂留的效果,通过快速循环点亮数码管方式,将数据呈现出来。
数码管如图1.2所示1.2数码管1.3数码管实物图/B.定时器定时器也可看作是对计算机机器周期的计数器。
因为每个机器周期包含12个振荡周期,故每一个机器周期定时器加1,可以把输入的时钟脉冲看成机器周期信号。
故其频率为晶振频率的1/12。
如果晶振频率为12MHz,则定时器每接收一个输入脉冲的时间刚好为1μs。
定时器有两种工作模式,分别为计数模式和定时模式。
对Px,y 的输入脉冲进行计数为计数模式。
定时模式,则是对MCU的主时钟经过12分频后计数。
因为主时钟是相对稳定的,所以可以通过计数值推算出计数所经过的时间。
计数器的计数值存放于特殊功能寄存器中。
T0(TL0-0x8A, TH0-0x8C), T1(TL1-0x8B, TH1-0x8D)定时器工作原理如下图由上图可见与定时器相关的寄存器主要有下面这几个:TMOD、TCON、TL0、TH0、TL1、TH1。
下面介绍一下这几个寄存器16位加法计数器:是定时计数器的核心,其中TL0、TH0、是定时计数器0的底八位和高八位;TL1、TH1是定时计数器1的底八位和高八位;并且高八位和底八位可单独使用。
--深圳市21EDA电子--开发板型号:A-C8V4--学习4个数码管动态显示原理;--利用计数器自加,并且在数码管上显示--在4个数码管上面分别显示0000到9999的自加--递增方式在4位数码管上向上计数显示从0000-0001->0002……..9999….0000….0001…. --设计了一个4位十进制计数器,并用数码管显示当前计数值--视频教程适合我们21EDA电子的所有学习板library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY LED_0000_9999 ISPORT (clk : IN std_logic; --系统时钟50Mrst : IN std_logic; --系统REST键,KEY1led_out : OUT std_logic_vector(7 DOWNTO 0); --各段数据输出led_bit : OUT std_logic_vector(3 DOWNTO 0)); --数码管的位选择口。
一共8位END LED_0000_9999 ;ARCHITECTURE arch OF LED_0000_9999 ISsignal div_cnt : std_logic_vector(24 downto 0 );signal data4 : std_logic_vector(3 downto 0);signal dataout_xhdl1 : std_logic_vector(7 downto 0);signal en_xhdl : std_logic_vector(3 downto 0);signal cntfirst :std_logic_vector(3 downto 0);signal cntsecond : std_logic_vector(3 downto 0);signal cntthird : std_logic_vector(3 downto 0);signal cntlast : std_logic_vector(3 downto 0);signal first_over: std_logic;signal second_over: std_logic;signal third_over : std_Logic;signal last_over : std_logic;beginled_out<=dataout_xhdl1;led_bit<=en_xhdl;process(clk,rst)beginif(rst='0')thendiv_cnt<="0000000000000000000000000";elsif(clk'event and clk='1')thendiv_cnt<=div_cnt+1;end if;end process;process(div_cnt(24),rst,last_over) ---first 10 counter beginif(rst='0')thencntfirst<="0000";first_over<='0';elsif(div_cnt(24)'event and div_cnt(24)='1')thenif(cntfirst="1001" or last_over='1')thencntfirst<="0000";first_over<='1';elsefirst_over<='0';cntfirst<=cntfirst+1;end if;end if;end process;process(first_over,rst) --second 10 counterbeginif(rst='0')thencntsecond<="0000";second_over<='0';elsif(first_over'event and first_over='1')thenif(cntsecond="1001")thencntsecond<="0000";second_over<='1';elsesecond_over<='0';cntsecond<=cntsecond+1;end if;end if;end process;process(second_over,rst) --second 10 counterbeginif(rst='0')thencntthird<="0000";third_over<='0';elsif(second_over'event and second_over='1')thenif( cntthird="1001")thencntthird<="0000";third_over<='1';elsethird_over<='0';cntthird<= cntthird+1;end if;end if;end process;process(third_over,rst) --second 10 counter beginif(rst='0')thencntlast<="0000";last_over<='0';elsif(third_over'event and third_over='1')thenif( cntlast="1001")thencntlast<="0000";last_over<='1';elselast_over<='0';cntlast<= cntlast+1;end if;end if;end process;---****************显示部分***************--process(rst,clk,div_cnt(19 downto 18))beginif(rst='0')thenen_xhdl<="1110";elsif(clk'event and clk='1')thencase div_cnt(19 downto 18) iswhen"00"=> en_xhdl<="1110";when"01"=> en_xhdl<="1101";when"10"=> en_xhdl<="1011";when"11"=> en_xhdl<="0111";end case;end if;end process;process(en_xhdl,cntfirst,cntsecond,cntthird,cntlast) begincase en_xhdl iswhen "1110"=> data4<=cntfirst;when "1101"=> data4<=cntsecond;when "1011"=> data4<=cntthird;when "0111"=> data4<=cntlast;when others => data4<="1010";end case;end process;process(data4)begincase data4 isWHEN "0000" =>dataout_xhdl1 <= "11000000"; WHEN "0001" =>dataout_xhdl1 <= "11111001"; WHEN "0010" =>dataout_xhdl1 <= "10100100"; WHEN "0011" =>dataout_xhdl1 <= "10110000"; WHEN "0100" =>dataout_xhdl1 <= "10011001"; WHEN "0101" =>dataout_xhdl1 <= "10010010"; WHEN "0110" =>dataout_xhdl1 <= "10000010"; WHEN "0111" =>dataout_xhdl1 <= "11111000"; WHEN "1000" =>dataout_xhdl1 <= "10000000"; WHEN "1001" =>dataout_xhdl1 <= "10010000"; WHEN "1010" =>dataout_xhdl1 <= "10000000"; WHEN "1011" =>dataout_xhdl1 <= "10010000"; WHEN "1100" =>dataout_xhdl1 <= "01100011"; WHEN "1101" =>dataout_xhdl1 <= "10000101"; WHEN "1110" =>dataout_xhdl1 <= "01100001"; WHEN "1111" =>dataout_xhdl1 <= "01110001"; WHEN OTHERS =>dataout_xhdl1 <= "00000011";END CASE;END PROCESS;end arch;。
单只数码管循环显示0~9【任务】在单个数码管上循环显示数字0~9,实现类似于计时(或计数)显示的功能。
【硬件平台】在51单片机最小系统的基础上,以端口P0控制一个七段数码管。
为提高驱动能力,增加了上拉排阻RP1(10k)。
【编程思路】因为这里使用了共阴数码管,所以当P0端口相应引脚为高电平时,点亮相应的数码段。
0~9的段码按相同的时间间隔从单片机内存读到P0口,由此产生从0到9的循环显示效果。
先写下前面三板斧,内涵不赘述:#include <reg51.h>#define uchar unsigned char#define uint unsigned int因为0~9的段码是固定的,不妨将其保存为code类型的数组。
注意是共阴接法,比如要显示“0”,那么P0端口的各引脚电平为:a=b=c=d=e=f=1,g=0,闲置的P0.7=0(按字节给端口赋值,所以闲置位也赋值),表示为二进制是P0.7gfedcba=00111111,对应的十六进制为0x3F。
其余段码可类似分析:uchar code display_code[ ]={0x3F,0x06,0x5B,0x4F,0x66,0x66,0x6D,0x7D,0x7F,0x6F,0x00 }; //0x00表示段码全灭显示不同的数字之间要有时间间隔,须定义一个延时函数以便主函数调用实现间隔延时:最后编写主函数:【代码展示】#include <reg51.h>#define uchar unsigned char#define uint unsigned intuchar codedisplay_code[ ]={0x3F,0x06,0x5B,0x4F,0x66,0x66,0x6D,0x7D,0x 7F,0x6F,0x00};void delay(uint x){uchar i;while(x--) for(i=0;i<100;i++);}void main(){uchar i=0; //定义数组下标变量,用以遍历数组P0=0x00; //数码管初始不亮while(1){P0=display_code[i]; //0~9对应的段码送给P0口,显示9后段码熄灭(0x00)i=(i+1)%10;//从0循环到9,超过10后又回到0,%为取余数算符}}。
第12章与PLC接口的4位LED数字显示表12.2 数显表头软件设计思路12.4 程序清单#include <pic16F87x.h>#include "mydefine.h"#include <pic.h>static int flag,flag0,flag1,flag3,led_d;static int data1[5],data2[5];static int data,data0,data_1,data_2,sdata;//=====================子程序=========================//端口初始化子程序void initport( ){PORTA=0;PORTB=0;PORTC=0;PORTD=0;ADCON1=0x07;TRISA=0x03; //设RA0,RA1为输入TRISB=0xE8; //设RB0,RB1,RB2,RB4为输出TRISC=0xFF; //设C口为输入TRISD=0; //设D口为输出}//判断地址是否相同子程序int adr_jud(int x){int adress,y;adress=PORTA&0x03;x&=0x60;adress=adress<<5;if (adress==x) y=1;else y=0;CLRWDT();return(y);}193//显示初始化子程序void initdis( ){PORTB=0xFE; //选通数码管1PORTD=0xC0;PORTB=0xFD; //选通数码管2PORTD=0xC0;PORTB=0xFB; //选通数码管3PORTD&=0x7F; //选通小数位PORTD=0xC0;PORTB=0xEF; //选通数码管4PORTD=0xC0;}//读5次数据判是否有4次相等int judge(arry)int arry[5];{int i,j,k;for(i=0;i<=4;i++){k=0;for(j=0;j<=4;j++){ if(arry[i]==arry[j]) k++;if(k>=4) {flag1=1;data0=arry[i];return(flag1);}else flag1=0;}}return(flag1);}//数据转换子程序int convert(int d1,int d2){auto int dd1,dd2;int i1,j1,k1,i2,j2,m;dd1=d1;194dd2=d2;j1=0x10;k1=2048;d1=0;for(i1=1;i1<=5;i1++) {if(j1==(dd1&j1)) m=1;else m=0;d1=d1+m*k1;j1=j1/2;k1=k1/2;}j2=0x40;d2=0;for(i2=1;i2<=7;i2++) {if(j2==(dd2&j2)) m=1;else m=0;d2=d2+m*k1;j2=j2/2;k1=k1/2;}data=d1+d2;return(data);}//显示子程序int display(int x){ int l1,l2,l3,l4;l1=x/1000;PORTB=0xFE; //选通数码管1PORTD=led[l1];l2=(x-l1*1000)/100;PORTB=0xFD; //选通数码管2PORTD=led[l2];l3=(x-l1*1000-l2*100)/10;PORTB=0xFB; //选通数码管3PORTD=0x7F;PORTD=led[l3];l4=x-l1*1000-l2*100-l3*10;PORTB=0xEF; //选通数码管4195PORTD=led[l4];}//中断服务子程序void interrupt int_serve( ){PIR1=0;TMR1L=0xE5;TMR1H=0xBE;di( );sdata=PORTC&0x80;ei( );}//开中断子程序void int_open( ){inportc=PORTC&0x80;if(inportc==1) return;else data1[0]=~PORTC;flag=adr_jud(data1[0]);if(flag==0) return; //地址不同返回else data1[1]=~PORTC;data1[2]=~PORTC;if(data1[0]==data1[1])if(data1[0]==data1[2]) {flag3=1;PIR1=0; //开通总中断前,清所有中断标志位TMR1IE=1; //TMR1溢出中断使能PEIE=1;ei( );TMR1L=0xE5;TMR1H=0xBE; //20ms中断1次T1CON=0x01; //设TMR1为1分频,计数器方式工作}else return;}//读第1帧子程序voidread_1( ){ int j0;196for(j0=1;j0<=4;j0++) data1[j0]=~PORTC;flag1=judge(data1);if (flag1==1) {data_1=data0;flag0=1;count1++;}flag=adr_jud(data1[0]);if(flag==1) {for(j0=1;j0<=4;j0++) data1[j0]=~PORTC;flag1=judge(data1);if (flag1==1){data_1=data0;flag0=1;count1++;}}}// 主程序main( ){ int i0,ii,i;flag0=0; //帧标志位flag1=0; //读5次数据判有4次相等标志位flag3=1; //开中断标志位count1=0; //读第1帧计数单元count2=0; //读第2帧计数单元data_1=0;data_2=0;led_d=0;led[0]=0xc0; //0led[1]=0xf9;led[2]=0xa4;led[3]=0xb0;led[4]=0x99;led[5]=0x92;led[6]=0x82;led[7]=0xf8;led[8]=0x80;197led[9]=0x90; //9initport( );OPTION=0xFE; //开看门狗initdis( );while(1) {if(flag3==0) int_open();else{if(sdata==0x80){ //第二帧数据到if(flag0==1){for(i0=0;i0<=4;i0++) data2[i0]=~PORTC;flag1=judge(data2);if (flag1==1) {data_2=data0;flag0=0;count2++;}}}else if(sdata==0) { //第一帧数据到if(flag0==0) {data1[0]=~PORTC;flag=adr_jud(data1[0]);if(flag==1) {for(j0=1;j0<=4;j0++) data1[j0]=~PORTC;flag1=judge(data1);if (flag1==1) {data_1=data0;flag0=1;count1++;}}}}CLRWDT();if(count1==count2) led_d=convert(data_1,data_2 );}display(led_d);}198}199。
原理图:源程序:/*************************************************************标题:定时器中断精确到00.01的秒表效果:能清零重新开始,暂停,继续计时,能精确到0.01秒作者:皖绩小挺说明:使用12M晶振,四位数码管,3个按键****************************************************************/ #include<reg52.h>#define uint unsigned int#define uchar unsigned charuint temp,tt,qian,bai,shi,ge;sbit smg_q=P1^0;sbit smg_b=P1^1;sbit smg_s=P1^2;sbit smg_g=P1^3;sbit key1 = P3^7;sbit key2 = P3^6;sbit key3 = P3^5;uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uchar code table1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //带小数点void keyscan();void display(uint shi,uint ge);void delay(uint z);void init();/************************************************************** 主函数******************************************************************/void main(){init();//初始化子程序while(1){if(tt==1){tt=0;temp++;if(temp==10000){temp=0;}qian=temp/1000;bai=temp%1000/100;shi=temp%100/10;ge=temp%10;}keyscan();display(shi,ge);}}/********************************************************************* 延时***********************************************************************/ void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/*********************************************************************按键控制***********************************************************************/ void keyscan(){if(key1==0) //清零并重新开始计时{temp=0;TR0=1;}if(key2==0) //暂停计时{TR0=0;}if(key3==0) //继续计时{TR0=1;}}/********************************************************************* 显示***********************************************************************/ void display(uint shi,uint ge){smg_q=0;P0=table[qian];delay(1);smg_q=1;P0=0xff;smg_b=0;P0=table1[bai];delay(1);smg_b=1;P0=0xff;smg_s=0;P0=table[shi];delay(1);smg_s=1;P0=0xff;smg_g=0;P0=table[ge];delay(1);smg_g=1;P0=0xff;}/********************************************************************* 初始化***********************************************************************/ void init(){smg_q=1;smg_b=1;smg_s=1;smg_g=1;temp=0;TMOD=0x01;TH0=(65536-10000)/256;TL0=(65536-10000)%256;EA=1;ET0=1;TR0=1;}/********************************************************************* 中断***********************************************************************/ void t0() interrupt 1{TH0=(65536-10000)/256;TL0=(65536-10000)%256;tt++;}。
#include <pic.h> //调用头文件,可以去PICC软件下去查找PIC16F87XA单片机的头文件
__CONFIG(0x1832);
//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡#define DS1 RA1
#define DS2 RA2
#define DS3 RA3
#define DS4 RA5
#define B20 RA4
#define uchar unsigned char
#define uint unsigned int
unsigned char unm;
const unsigned char str[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40} ; //共阴数码管字码表
const unsigned char str1[]={0x0bf,0x86,0x0db,0x0cf,0x0e6,0x0ed,0x0fd,0x87,0x0ff,0x0ef}; //个位带小数点字码表
//const unsigned char wei[4]={COL1+COL2+COL3+COL4};//{0x001,0x002,0x004,0x008};
/**********ds1820程序************/
void delay(unsigned int i) //延时1微秒
{
for(i=100;i--;);
}
void init(void) //主板初始化
{
TRISD=0X00;
TRISA=0X00;
PORTA=0X00;
PORTD=0X00;
}
/************主程序**********/
uchar smg()
{
init();
unsigned char j;
unsigned int i,a,bit1000,bit100,bit10,bit1;
DS1=1;
DS2=1;
DS3=1;
DS4=1;
while(1)
{
for( i=1; i <= 9999;i++)
{
a=i;
bit1000=a/1000;//提取千位
a=a%1000;
bit100=a/100;//提取百位
a=a%100;
bit10=a/10;//提取十位
bit1=a%10;//提取个位
for( j=1; j <= 20;j++)
{
DS4=0;
PORTD=str[bit1];
DS1=1; //个位的位选
delay(2);//*延时5mS*
DS1=0;
PORTD=str1[bit10];
DS2=1; //十位的位选
delay(2);//*延时5mS
DS2=0;
PORTD=str[bit100];
DS3=1; //百位的位选
delay(2);//*延时5mS
DS3=0;
PORTD=str[bit1000];
DS4=1; //千位的位选
delay(2);//*延时5mS*/
}
}
}
}。