单片机实验练习代码

流水灯实验

#include <reg52.h>
#include <iostream>
void delay(unsigned int cnt) //
{
while(--cnt);
}
main()
{
unsigned char i;
P2=~0x01;//1111 1110
while(1)
 {
for (i=0;i<=7;i++)
 {
 delay(30000);//
 P2<<=1;//
 P2|=0x01;//保证补位的零变成1
 }
 //P2=0111 1111
 P2=0x7f;
 for (i=0;i<=7;i++)
 {
 delay(30000);//
 P2>>=1;//
 P2|=0x80;//1000 0000
 }
P2=~0x01;
 }
}

综合性实验

#include "reg52.h"			

typedef unsigned int u16;	 
typedef unsigned char u8;

#define GPIO_DIG P2
#define GPIO_KEY P1
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数码管的码表
                				
u8 n=0;
u8 n1=0;
unsigned char second=0; //秒
unsigned char fen=0;  //分
unsigned char hour=0;  //小时
	
sbit k3=P3^2;  //按键接在P3.2
int flag = 0;  //做按键中断的标值位

sbit LSA=P3^5;  //三八译码器控制数码管输出的数值
sbit LSB=P3^6;
sbit LSC=P3^7;

u8 KeyValue;	//用来存放读取到的键值



				
/*******************************************************************************
延时函数,i=1是大约10微秒
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}		
	
void choose(int i, int num)
{
		switch(i)	
		{
			case(0):
				LSA=0;LSB=0;LSC=0; break;//显示第0位
			case(1):
				LSA=1;LSB=0;LSC=0; break;//显示第1位
			case(2):
				LSA=0;LSB=1;LSC=0; break;//显示第2位
			case(3):
				LSA=1;LSB=1;LSC=0; break;//显示第3位
			case(4):
				LSA=0;LSB=0;LSC=1; break;//显示第4位
			case(5):
				LSA=1;LSB=0;LSC=1; break;//显示第5位
			case(6):
				LSA=0;LSB=1;LSC=1; break;//显示第6位
			case(7):
				LSA=1;LSB=1;LSC=1; break;//显示第7位
		}
		P0=smgduan[num];
		delay(50); //间隔时间扫描	
		P0=0x00;//消隐
}	
			
/*******************************************************************************
功能:检测是否由按键按下
*******************************************************************************/
void KeyDown(void)
{
	char a=0;
	GPIO_KEY=0x0f;
	if(GPIO_KEY!=0x0f)//读取是否有按键按下
	{
		delay(1000);//延时消抖
		if(GPIO_KEY!=0x0f)//再次检查按键是否按下
		{	
			//列
			GPIO_KEY=0X0F;
			switch(GPIO_KEY)
			{
				case(0X07):	KeyValue=0;break;
				case(0X0b):	KeyValue=1;break;
				case(0X0d): KeyValue=2;break;
				case(0X0e):	KeyValue=3;break;
			}
			//行
			GPIO_KEY=0XF0;
			switch(GPIO_KEY)
			{
				case(0X70):	KeyValue=KeyValue;break;
				case(0Xb0):	KeyValue=KeyValue+4;break;
				case(0Xd0): KeyValue=KeyValue+8;break;
				case(0Xe0):	KeyValue=KeyValue+12;break;
			}
			
		}
	}
	while((a<50)&&(GPIO_KEY!=0xf0))	 //松开检测
	{
		a++;
	}
}					
/*******************************************************************************
外部中断初始化函数
*******************************************************************************/
void Int0Init()
{
	//INT0中断
	IT0=1;//下降沿触发
	EX0=1;//INT0的中断允许
	EA=1;//总中断
}

/*******************************************************************************
两个定时器初始化
*******************************************************************************/
void Timer1Init()
{
	TMOD|=0X10;//定时器1模式,工作方式1

	TH1=0XFC;	//定时器1  1ms
	TL1=0X18;	
	TH0=0XF3;	//定时器2  波特兰4800
	TL0=0XF3;
	ET1=1;      //定时器1中断允许
	EA=1;       //总中断打开
	TR1=1;      //定时器1打开
	ES=1;		//接收中断
	TR0=1;		//定时器0打开	
}

/*******************************************************************************

*******************************************************************************/
void main()
{	
	Int0Init();
	Timer1Init();  //¶¨Ê±Æ÷1³õʼ»¯
	
	while(1)
	{
		choose(0, hour/10);
		choose(1, hour%10);
		choose(2, fen/10);
		choose(3, fen%10);
		choose(4, second/10);
		choose(5, second%10);
		KeyDown();		   //按键判断函数
		GPIO_DIG=~smgduan[KeyValue];	
	}
}

/*******************************************************************************
外部中断0
*******************************************************************************/
void Int0()	interrupt 0		//
{
	delay(1000);	 //延时消抖
	if(k3==0)
	{
		if(flag == 0)   //标志位确定工作方式
		{
			flag = 1;
		}
		else
		{
			flag = 0;
		}
	}
}


/*******************************************************************************
定时器中断函数
*******************************************************************************/
void Timer1() interrupt 3
{
	static u16 i;
	
	TH1=0XFC;	//定时1ms
	TL1=0X18;
	i++;
	if(flag == 1)
	{
		if(i>1000)
		{
			i=0;
//			choose(n, n);
			second++;//
			if(second>=60)
			 {
				 second=0; //
				 fen++;
				 if (fen>=60)
				 {
						fen=0;
						hour++;
					  if (fen>=60)
						{
							hour = 0;
						}
				 }  
			 }
			
			n++;
			if(n==9)
			{
				
			}
		}	
	}	
}
void Usart() interrupt 1
{
	u8 receiveData;

	receiveData=SBUF;//接收数据
	RI = 0;//清楚接收中断标志位
	SBUF=receiveData;//将接收到的数据放入寄存器
	while(!TI);			 //等待数据发送完成
	TI=0;						 //清楚发送完成标值位
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值