51单片机复习程序例举001

http://blog.csdn.net/dragon12345666/article/details/22114899 本文对应复习笔记

1、点亮闪烁的LED灯。

#include

sbit LED00=P0^0;  //位定义,定义单片机引脚


void delay(int t)
{
	int i , j ;
	for(i = 0 ; i < 100*t ; i++)
	{
		for(j = 0 ; j < 125 ; j++)
		{
			;
		}
	}
}

void main(void)
{
  while(1)
  {
  
    LED00 = 0 ;	 //此开发板是低电平点亮
   	delay(5) ;
    LED00 = 1 ;	 //此开发板是高电平熄灭
   	delay(5) ;

  }


}


2、流水灯。

/******************************************************************************
 *	说明:AT89S52芯片,12M晶振
 *	P0、P1两个8位端口分别连接8个LED灯
 *	低电平点亮,高电平熄灭。
 ******************************************************************************/

#include
#include //是循环左移、右移函数的头文件,参考网址如下
	//http://baike.baidu.com/view/1745068.htm?fromTaglist
	//http://wenku.baidu.com/view/06ba3d00b52acfc789ebc97b.html

//sbit LED00=P0^0;  //位定义,定义单片机引脚


void delay(int t)
{
	int i , j ;
	for(i = 0 ; i < 100*t ; i++)
	{
		for(j = 0 ; j < 125 ; j++)
		{
			;
		}
	}
}

void main(void)
{

	P0 = 0xfe ; //0b11111110 
	P1 = 0x7f ; //0b01111111 

  while(1)
  {
  	P0 = _crol_(P0 , 1);  //循环左移,每次循环1位
	P1 = _cror_(P1 , 1);  //循环右移,每次循环1位
   	delay(5) ;

  }


}

3、继电器的控制。

/******************************************************************************
 *	说明:AT89S52芯片,12M晶振
 *	此开发板继电器的控制端口和单片机的P3^7引脚相连接
 *	因为继电器的工作电流比较大,
 *	所以P3^7连接的是一个三极管,通过三极管驱动继电器
 ******************************************************************************/

#include

sbit JDQ = P3^7 ; //位定义,定义单片机引脚

void delay(int t)
{
	int i , j ;
	for(i = 0 ; i < 100*t ; i++)
	{
		for(j = 0 ; j < 125 ; j++)
		{
			;
		}
	}
}

void main(void)
{

  while(1)
  {
	JDQ = 0 ;
   	delay(5) ;	//延时0.5s
	JDQ = 1 ;
	delay(5) ;

  }


}

4、控制无源蜂鸣器每隔1s响1s (有一个疑问)

/******************************************************************************
 *	说明:AT89S52芯片,12M晶振
 *	此开发板蜂鸣器的控制端口和单片机的P3^6引脚相连接
 *	用三极管进行驱动  
 *	无源蜂鸣器:需要写函数产生1KHz左右的声音频率(方波)
 ******************************************************************************/

#include

sbit FMQ = P3^6 ; //位定义,定义单片机引脚

/******************************************************************************
 *	名称:delay1ms()
 *	功能:延时1ms
 *	参数:int t
 *	返回:无
 ******************************************************************************/
void delay1ms(int t)
{
	unsigned char i ;
	while(t--)
	{
		for(i = 0 ; i < 125 ; i++)
		{
			;
		}
	}
}


/******************************************************************************
 *	名称:delay500us()
 *	功能:延时500us
 *	参数:无
 *	返回:无
 ******************************************************************************/
void delay500us(void)
{
	int i ;

	for(i = 0 ; i < 63 ; i++)
	{
		;
	}

}

/******************************************************************************
 *	名称:beep_sound()
 *	功能:产生FMQ发声需要的1KHz的声音频率
 *	参数:无
 *	返回:无
 ******************************************************************************/
void beep_sound(void)
{
	FMQ = 0 ;
	delay500us();
	FMQ = 1 ;
	delay500us();

}


void main(void)
{
  int i	, t;

  while(1)
  {

  	t = 1000 ; //蜂鸣器发声1000*1ms 1KHz频率的方波,一个周期是1ms
	for(i = 0 ; i < t/3 ; i++)	//for( ; ; )循环自身每循环一次占用3个指令周期
	{
		beep_sound();	
	}

	FMQ = 1 ;  //关掉FMQ 1s(延时) 
	delay1ms(1000) ;

  }


}
注意:尽量使用定时器产生标准频率的方波,或用延时函数产生时,函数最好不要通过参数来改变延时效果。
疑问:把500us延时函数改成可以传参数t的形式,结果蜂鸣器发出的声音频率和发声的时长变得面目全非,很无解。有经验的朋友欢迎通过评论的方式讨论一下。
改过后的delay500ms()函数 和 beep_sound()函数内容如下:
/******************************************************************************
 *	名称:delay500us()
 *	功能:延时500us
 *	参数:int t
 *	返回:无
 ******************************************************************************/
void delay500us(int t)
{
	int i ;

	for(i = 0 ; i < 63*t ; i++)
	{
		;
	}

}

/******************************************************************************
 *	名称:beep_sound()
 *	功能:产生FMQ发声需要的1KHz的声音频率
 *	参数:无
 *	返回:无
 ******************************************************************************/
void beep_sound(void)
{
	FMQ = 0 ;
	delay500us(1);
	FMQ = 1 ;
	delay500us(1);

}

5、点亮一位数码管,循环显示 0---F

/******************************************************************************
 *	说明:AT89S52芯片,12M晶振
 *	此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上
 *	数码管共阳 
 *	本程序:在一个数码管上显示0-F
 ******************************************************************************/

#include

sbit SMG_1 = P2^7 ; //位定义,定义单片机引脚

unsigned char code S8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。
//这样就节省了芯片内部宝贵的RAM资源。
//但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错

/******************************************************************************
 *	名称:delay1ms()
 *	功能:延时1ms
 *	参数:int t
 *	返回:无
 ******************************************************************************/
void delay1ms(int t)
{
	unsigned char i ;
	SMG_1 = 0 ;
	while(t--)
	{
		for(i = 0 ; i < 125 ; i++)
		{
			;
		}
	}
}



void main(void)
{
  int i ;

  while(1)
  {

	for(i = 0 ; i < 16 ; i++)
	{
		P0 = S8[i] ;
		delay1ms(500);
	}


  }


}

6、在8位数码管上流水式循环显示0---F

/******************************************************************************
 *	说明:AT89S52芯片,12M晶振
 *	此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上
 *	数码管共阳 
 *	本程序:在8位数码管上流水式循环显示0-F
 ******************************************************************************/

#include
#include
#define SMG_NUM P2


unsigned char code S8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。
//这样就节省了芯片内部宝贵的RAM资源。
//但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错

/******************************************************************************
 *	名称:delay1ms()
 *	功能:延时1ms
 *	参数:int t
 *	返回:无
 ******************************************************************************/
void delay1ms(int t)
{
	unsigned char i ;

	while(t--)
	{
		for(i = 0 ; i < 125 ; i++)
		{
			;
		}
	}
}



void main(void)
{
  int i ;
  SMG_NUM = 0xfe ;

  while(1)
  {

	for(i = 0 ; i < 16 ; i++)
	{	
		P0 = S8[i] ;
		delay1ms(500);
		SMG_NUM = _crol_(SMG_NUM , 1);
	}


  }


}

7、独立按键。按键使数码管上的数据增加。

/******************************************************************************
 *	说明:AT89S52芯片,12M晶振
 *	此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上
 *	数码管共阳 
 *	本程序:独立按键,按键使数码管上的数字循环增加
 ******************************************************************************/

#include
#include

sbit SMG = P2^0 ;	//要选通的数码管
sbit K5 = P1^4 ;	//独立按键对应的单片机输入引脚


unsigned char code S8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。
//这样就节省了芯片内部宝贵的RAM资源。
//但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错

/******************************************************************************
 *	名称:delay1ms()
 *	功能:延时1ms
 *	参数:int t
 *	返回:无
 ******************************************************************************/
void delay1ms(int t)
{
	unsigned char i ;

	while(t--)
	{
		for(i = 0 ; i < 125 ; i++)
		{
			;
		}
	}
}


void main(void)
{
	int num = 0 ;
	SMG = 0 ;  	//选通数码管
	P0 = S8[num]; //数码管初始显示0
	while(1)
	{  
	//1、判断K5键是否按下,按下,软件消抖
		if(K5 == 0)
		{
			delay1ms(15);  //软件消抖,延时大约15ms
			if(K5 == 0)
			{	//2、有键按下,数码管显示的数字+1
				P0 = S8[++num];
				//3、判断按键是否松开
				while(!K5)
				{ ; }
			}
		}
	//4、数码管循环显示0--F
		if(num == 15)
		{
			num = 0 ;
		}	
	}
	
}

8、矩阵键盘,逐行扫描法获取键值。

注意:AT89S52单片机,要进行读端口时,必须在读端口之前给端口写1(其实是写入到内部的锁存器中)

http://wenwen.soso.com/z/q184033008.htm

/******************************************************************************
 *	说明:AT89S52芯片,12M晶振
 *	此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上
 *	数码管共阳 
 *	本程序:矩阵键盘,逐行扫描获取键值
 ******************************************************************************/

#include
#include

sbit SMG = P2^0 ;	//要选通的数码管
sbit K5 = P1^4 ;	//独立按键对应的单片机输入引脚


unsigned char code S8[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xBF};
//数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。
//这样就节省了芯片内部宝贵的RAM资源。
//但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错

/******************************************************************************
 *	名称:delay1ms()
 *	功能:延时1ms
 *	参数:int t
 *	返回:无
 ******************************************************************************/
void delay1ms(int t)
{
	unsigned char i ;

	while(t--)
	{
		for(i = 0 ; i < 125 ; i++)
		{
			;
		}
	}
}


/******************************************************************************
 *	名称:display_num()
 *	功能:根据参数num在数码管上显示0--F
 *	参数:int num
 *	返回:无
 ******************************************************************************/
void display_num(int num)
{
	SMG = 0 ;  	//选通数码管
	P0 = S8[num]; //数码管初始显示0
}

void main(void)
{
	unsigned char temp ;
	display_num(16) ; //显示 - 
	while(1)
	{
		P1 = 0xff ;	//先向端口写1,使端口处于读的状态
		//判断是否有键按下
		P1 = 0xf0 ;
		temp = P1 ;
		if(temp != 0xf0)
		{
			delay1ms(15);
			if(temp != 0xf0)
			{
			//有键按下,扫描方式判断键值,并通过数码管显示
			/*-----------对你第一行扫描-----------------*/	
				P1 = 0xfe ; //写端口
				temp = P1 ;	//读端口
				switch(temp)
				{
					case 0xee: display_num(0) ; break ;
					case 0xde: display_num(1) ; break ;
					case 0xbe: display_num(2) ; break ;
					case 0x7e: display_num(3) ; break ;
				}
	
			/*-----------对你第二行扫描-----------------*/	
				P1 = 0xfd ; //写端口
				temp = P1 ;	//读端口
				switch(temp)
				{
					case 0xed: display_num(4) ; break ;
					case 0xdd: display_num(5) ; break ;
					case 0xbd: display_num(6) ; break ;
					case 0x7d: display_num(7) ; break ;
				}
	
			/*-----------对你第三行扫描-----------------*/	
				P1 = 0xfb ; //写端口
				temp = P1 ;	//读端口
				switch(temp)
				{
					case 0xeb: display_num(8) ; break ;
					case 0xdb: display_num(9) ; break ;
					case 0xbb: display_num(10) ; break ;
					case 0x7b: display_num(11) ; break ;
				}
	
			/*-----------对你第四行扫描-----------------*/	
				P1 = 0xf7 ; //写端口
				temp = P1 ;	//读端口
				switch(temp)
				{
					case 0xe7: display_num(12) ; break ;
					case 0xd7: display_num(13) ; break ;
					case 0xb7: display_num(14) ; break ;
					case 0x77: display_num(15) ; break ;
				}
			
			}
		}
	

	}
	
}

9、矩阵键盘,线反转法扫描按键

/******************************************************************************
 *	说明:AT89S52芯片,12M晶振
 *	此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上
 *	数码管共阳 
 *	本程序:矩阵键盘,线反转法扫描按键 , 数码管上显示按下了哪一个按键
 ******************************************************************************/

#include
#include

sbit SMG = P2^0 ;	//要选通的数码管
sbit K5 = P1^4 ;	//独立按键对应的单片机输入引脚

unsigned char code key_code[]={0xee,0xde,0xbe,0x7e,
							   0xed,0xdd,0xbd,0x7d,
							   0xeb,0xdb,0xbb,0x7b,  
							   0xe7,0xd7,0xb7,0x77};
unsigned char code S8[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xBF};
//数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。
//这样就节省了芯片内部宝贵的RAM资源。
//但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错

/******************************************************************************
 *	名称:delay1ms()
 *	功能:延时1ms
 *	参数:int t
 *	返回:无
 ******************************************************************************/
void delay1ms(int t)
{
	unsigned char i ;

	while(t--)
	{
		for(i = 0 ; i < 125 ; i++)
		{
			;
		}
	}
}


/******************************************************************************
 *	名称:display_num()
 *	功能:根据参数num在数码管上显示0--F
 *	参数:int num
 *	返回:无
 ******************************************************************************/
void display_num(unsigned char num)
{
	SMG = 0 ;  	//选通数码管
	P0 = S8[num]; //数码管初始显示0
}

/******************************************************************************
 *	名称:key_scan()
 *	功能:线反转法扫描按键
 *	参数:无
 *	返回:key
 ******************************************************************************/
unsigned char key_scan(void)
{
	unsigned char  key_scan_line , key_scan_row , key_scan_temp ;
	unsigned char i , key ;
	//1、列扫描
	P1 = 0Xf0 ;
	key_scan_line = P1;
	if(key_scan_line != 0xf0)
	{
		delay1ms(8);
		if(key_scan_line != 0xf0)
		{
			delay1ms(8) ;
			if(key_scan_line != 0xf0)
			{
			//2、翻转,行扫描
				P1 = 0X0f ;
				key_scan_row = P1 ;
				if(key_scan_row != 0x0f)
				{
		
				//3、列、行扫描到键值后,将列与行的键值安位相或得到实际完整的键值
					key_scan_temp = key_scan_line | key_scan_row ;

				//4、释放按键,否则等待
					while(P1 != 0xf0)  //如果按键还没释放,读到的端口值和写入端口的值不同
					{
						P1 = 0xf0 ;	  //给端口写一个值
					}
					
	
				//5、通过键值 判断具体是键盘上的哪一个键按下 , 返回键值
					for(i = 0 ; i < 16 ; i++)
					{
						if(key_scan_temp == key_code[i])
						{
							key = i ;
							return(key) ;
						}	
					}
	
	
				}			
			}

		}
	}
	else P1 = 0xff ;
	return 16 ;

}




void main(void)
{
	unsigned char key ;
	//1、初始状态数码管显示 - 
	display_num(16) ; 

	//2、向端口写1,使端口处于读的状态
	P1 = 0xff ;	
	while(1)
	{
	//3、判断是否有键按下,然后进入按键扫描函数,(大大降低了干扰)
		P1 = 0xf0 ;
		if( (P1&0xf0) != 0xf0 )
		{
		    key = key_scan() ;
			display_num(key) ;				
		}
	//4、延时一段时间,按键是机械部件实现的,需要一定的反应时间
		delay1ms(100) ;

	}
	
}

















你可能感兴趣的:(51单片机复习笔记)