51单片机:四位数码管,外部中断方式,始值为0000,按S1加1,按S2减1,按S3清0

具体元器件参数请看我之前的51程序的图,元器件布局一次基本上就够用了,所以并不是重点 

#include <reg52.h>
#include <stdlib.h>		
#define uint unsigned long	
#define uchar unsigned char	

sbit N5 = P1^0;
sbit N6 = P1^1;
sbit N7 = P1^2;
sbit N8 = P1^3;

sbit S1 = P3^7;//加按钮
sbit S2 = P3^6;//减按钮
sbit S3 = P3^5;//清零按钮
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};  //0~916进制共阳极编码

uint num;


void delayms(uint xms)	//延时函数
{		
	uint i,j;
	for(i=xms;i>0;i--)
		for(j=10;j>0;j--);
}
	
void display(unsigned long num)				   
{
	
		N5=0;		
		P0=table[(num%10000)/1000];	
		delayms(1);		
		P0=0XFF;		
		N5=1;		

		N6=0;		
		P0=table[(num%1000)/100];	
		delayms(1);		
		P0=0XFF;		
		N6=1;

		N7=0;		
		P0=table[(num%100)/10];	
		delayms(1);		
		P0=0XFF;		
		N7=1;

		N8=0;		
		P0=table[num%10];	
		delayms(1);		
		P0=0XFF;		
		N8=1;

		}



void main()
{
//采用T0方式,将M1置0,M0置1,是方式一的定时器
	TMOD=0x01;
	EA=1;	//外部中断总开关
	EX0=1;	//	允许外部中断0申请中断。

	num=0;	//初始化0000

		while(1)
		{	
			while(1)
			{																							 
			display(num);
					
				if(S1==0)//判断是否按下
				{
					delayms(50);
					if(S1==0)	 //再次确定
					{
						num++;
					}
					while(!S1);		//消抖
					delayms(50);
					while(!S1);
						
					//跳出所在的第一个while循环
					break;
				}
				else if(S2==0)//判断是否按下
				{
					delayms(50);
					if(S2==0)	 //再次确定
					{
						
						if(num==0){
							num=0;
						}
						else if(num>0){
							num--;
						}
					}
					while(!S2);		//消抖
					delayms(50);
					while(!S2);
						
					//跳出所在的第一个while循环
					break;
				}	
				else if(S3==0)//判断是否按下
				{
					delayms(50);
					if(S3==0)	 //再次确定
					{
						num=0;
					}
					while(!S3);		//消抖
					delayms(50);
					while(!S3);
						
					//跳出所在的第一个while循环
					break;
				}	
			}																							           
	 	}
	
}

以下是一种可以使用TM51单片机驱动4位数码管计数器代码: ``` #include <reg51.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int sbit SCLK = P3^0; // 74HC595 shift register sbit RCLK = P3^1; // 74HC595 shift register sbit DIO = P3^2; // 74HC595 shift register uchar code Tab[] = { 0x3f, // 0 0x06, // 1 0x5b, // 2 0x4f, // 3 0x66, // 4 0x6d, // 5 0x7d, // 6 0x07, // 7 0x7f, // 8 0x6f // 9 }; // 7-segment display digital code table void Write74HC595(uchar dat) { uchar i; for(i=0; i<8; i++) { if(dat & 0x80) DIO = 1; else DIO = 0; dat <<= 1; SCLK = 0; _nop_(); _nop_(); _nop_(); SCLK = 1; } _nop_(); RCLK = 0; _nop_(); _nop_(); _nop_(); RCLK = 1; } void Display(uchar num) { uchar i, j; uchar buffer[4] = {0}; for(i=0; num; i++) { buffer[i] = num % 10; num /= 10; } for(j=0; j<4; j++) { Write74HC595(0x01 << j); Write74HC595(Tab[buffer[j]]); _nop_(); _nop_(); _nop_(); _nop_(); } } void main() { uint cnt = 0; while(1) { Display(cnt++); if(cnt >= 10000) cnt = 0; } } ``` 这个计数器使用了一个74HC595移位寄存器来驱动4位数码管。首先,它定义了一个7段数码管的数字表,然后使用`Write74HC595`函数来将数据写入74HC595。在`Display`函数中,将要显示的数字先转换为每一位数字,然后在循环中使用`Write74HC595`函数将数字写入74HC595,同时使用移位寄存器的输出来选择要显示的位数。在主循环中,计数器不断递增并显示在4位数码管上,当计数器超过9999时将其归零。 需要注意的是,在使用74HC595时需要先将RCLK置为0,才能将数据写入寄存器中心;同时,每写入一位数据时也需要为RCLK和SCLK提供时钟信号。因此,如果想要保证显式质量,可以在写入一位数据后等待一段时间后再写入下一位数据。此外,如果使用的是共阴极的数码管,需要在表中存储每个数字的反码。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wenlong Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值