单片机新手入门案例

根据单片机100案例所做,适合初学者入门单片机的简单案例.

单片机学习进阶版-点这里

单片机案例1

结合proteus和keil

1 闪烁的LED灯

原理图

在这里插入图片描述

程序
/*
	名称:闪烁的LED
	说明:LED按照设定的时间间隔闪烁
*/
#include<reg52.h>
#define INT8U unsigned char
#define INT16U unsigned int 

sbit LED=P2^0;	//LED连接在P2.0引脚

//延时函数
void delay_ms(INT16U x)
{
    
    
	INT8U t;
	while(x--);
	for(t=0;t<120;t++);
}

//主程序
void main()
{
    
    
	while(1)
	{
    
    
		LED=~LED;//取反,形成LED闪烁效果
		delay_ms(150);//延时
	}
}

单片机案例2

结合proteus和keil

2 双向流水灯

原理图

在这里插入图片描述

程序
/*
	名称:8只LED灯双向来回闪亮
	说明:利用了头文件intrins.h提供的循环移位函数:
	_crol_向左
	_cror_向右

*/

#include<reg51.h>
#include<intrins.h>

#define INT8U unsigned char
#define INT16U unsigned int 

//延时
void delsy_ms(INT16U x)
{
    
    
	INT8U t;
	while(x--)
	{
    
    
		for(t=0;t<120;t++);
	}
}

//主程序
void main()
{
    
    
	INT8U i;
	P2=0x01;
	delsy_ms(150);
	while(1)
	{
    
    
		for(i=0;i<7;i++)
		{
    
    
			P2=_crol_(P2,1);//P2口,循环向左移动一位
			delsy_ms(60);
		}

		for(i=0;i<7;i++)
		{
    
    
			P2=_cror_(P2,1);//P2口,循环向右移动一位
			delsy_ms(200);
		}
	}
}

单片机案例3

结合proteus和keil

3 变化多样的流水灯

原理图

在这里插入图片描述

程序
/*
	名称:变换流水灯
	说明:16只LED灯分两组,多种变换进行显示
*/

#include<reg52.h>

#define INT8U unsigned char
#define INT16U unsigned int 

code INT16U array[]=
{
    
    
	0xFCFF,0xF9FF,0xF3FF,0xE7FF,0xCFFF,0x9FFF,0x3FFF,0x7FFE,0xFFFC,
	0xFFF9,0xFFF3,0xFFE7,0xFFCF,0xFF9F,0xFF3F,0xFFFF,0xE7E7,0xDBDB,
	0xBDBD,0x7E7E,0xBDBD,0xDBDB,0xE7E7,0xFFFF,0xE7E7,0xC3C3,0x8181,
	0x0000,0x8181,0xC3C3,0xE7E7,0xFFFF,0xAAAA,0x5555,0x1818,0xFFFF,
	0xF0F0,0x0F0F,0x0000,0xFFFF,0xF8F8,0xF1F1,0xE3E3,0xC7C7,0x8F8F,
	0x1F1F,0x3F3F,0x7F7F,0x7F7F,0x3F3F,0x1F1F,0x8F8F,0xC7C7,0xE3E3,
	
	0xF1F1,0xF8F8,0xFFFF,0x0000,0x0000,0xFFFF,0xFFFF,0x0F0F,0xF0F0,	
	0xFEFF,0xFDFF,0xFBFF,0xE7FF,0xEFFF,0xDFFF,0xBFFF,0x7FFF,0xFFFE,
	0xFFFD,0xFFFB,0xFFF7,0xFFEF,0xFFDF,0xFFBF,0xFF7F,0xFF7F,0xFFBF,

	0xFFDF,0xFFEF,0xFFF7,0xFFFB,0xFFFD,0xFFFE,0x7FFF,0xBFFF,0xDFFF,
	0xEFFF,0xF7FF,0xFBFF,0xFDFF,0xFEFF,0xFEFF,0xFCFF,0xF8FF,0xF0FF,

	0xE0FF,0xC0FF,0x80FF,0x00FF,0x00FE,0x00FC,0x00F8,0x00F0,0x00E0,
	0x00C0,0x0080,0x0000,0x0000,0x0080,0x00C0,0x00E0,0x00F0,0x00F8,
	0x00FC,0x00FE,0x00FF,0x80FF,0xC0FF,0xE0FF,0xF0FF,0xF8FF,0xFCFF,
	0xFEFF,0x0000,0xFFFF,0x0000,0xFFFF,0x0000,0xFFFF,0x0000,0xFFFF
};


//延时
void delay_ms(INT16U x)
{
    
    
	INT8U t;
	while(x--)
	{
    
    
		for(t=0;t<120;t++);
	}
}

//主程序
void main()
{
    
    
	INT8U i;
	while(1)
	{
    
    
		//从数组中读取数据,在P0和P2端口显示
		for(i=0;i<136;i++)
		{
    
    
			P0=array[i]>>8;//依次发送每个数组元素的高8位
			P2=array[i];//依次发送每个数组元素的低8位
			delay_ms(60);
		}
	}
}

单片机案例4

结合proteus和keil

4 LED模拟交通信号灯

原理图

在这里插入图片描述

程序
/*
	名称:LED模拟交通信号灯
	说明:绿灯黄灯红灯根据设置循环闪烁

*/

#include<reg52.h>
#define INT8U unsigned char
#define INT16U unsigned int 

sbit RED_EW=P0^0;//东西方向
sbit YELLOW_EW=P0^1;
sbit GREEN_EW=P0^2;

sbit RED_SN=P0^3;//南北方向
sbit YELLOW_SN=P0^4;
sbit GREEN_SN=P0^5;


//闪烁次数
INT8U Flash_Count=0;
//灯闪烁方式
INT8U type=1;

//延时
void delay_ms(INT16U x)
{
    
    
	INT8U t;
	while(x--)
	{
    
    
		for(t=0;t<120;t++);
	}
}


//交通信号灯变化方式
void traffic_light()
{
    
    
	switch(type)
	{
    
    
		case 1:
		{
    
    
			//东西方向绿灯亮
			RED_EW=1;
			YELLOW_EW=1;
			GREEN_EW=0;
			//南北方向红灯亮
			RED_SN=0;
			YELLOW_SN=1;
			GREEN_SN=1;

			delay_ms(2000);
			type=2;//切换变化方式
			break;
		}
		case 2:
		{
    
    
			delay_ms(500);
			//关闭绿灯
			GREEN_EW=1;
			//东西方向黄灯闪烁
			YELLOW_EW=~YELLOW_EW;
			if(++Flash_Count!=10)
				return;
			Flash_Count=0;
			type=3;
			break;
		}
		case 3:
		{
    
    
			//东西方向红灯亮
			RED_EW=0;
			YELLOW_EW=1;
			GREEN_EW=1;
			//南北方向绿灯亮
			RED_SN=1;
			YELLOW_SN=1;
			GREEN_SN=0;

			delay_ms(2000);
			type=4;
			break;
		}
		case 4:
		{
    
    
			delay_ms(500);
			//南北方向黄灯闪烁
			YELLOW_SN=~YELLOW_SN;
			GREEN_SN=1;
			if(++Flash_Count!=10)
				return;
			Flash_Count=0;
			type=1;//循环
			break;
		}
	}
}

//主程序
void main()
{
    
    
	while(1)
	{
    
    
		traffic_light();
	}
}

单片机案例5

结合proteus和keil

5 单只数码管(共阴极)显示数字

原理图

在这里插入图片描述

程序
/*
	名称:单只数码管(共阴极)循环显示0-9
	说明:将0-9的段码送到P0口,循环在数码管中显示

*/
#include<reg51.h>
#define INT8U unsigned char
#define INT16U unsigned int 

//0-9的共阴极数码管段码表
code INT8U CC_Table[]=
{
    
    
	0x3F,0x06,
	0x5B,0x4F,
	0x66,0x6D,
	0x7D,0x07,
	0x7F,0x6F
};

//延时
void delay_ms(INT16U x)
{
    
    
	INT8U t;
	while(x--)
	{
    
    
		for(t=0;t<120;t++);
	}
}

void main()
{
    
    
	INT8U i=0;
	while(1)
	{
    
    
		P0=CC_Table[i];//发送段码
		i=(i+1)%10;//0-9
		delay_ms(200);
		
	}


}

单片机案例6

结合proteus和keil

6 集成式数码管动态扫描显示数字

原理图

在这里插入图片描述

程序
/*
	名称:集成式数码管动态扫描显示
	说明:在集成的数码管上动态扫描显示数字

*/
#include<reg51.h>
#define INT8U unsigned char
#define INT16U unsigned int 

//共阳极0-9的数码管段码表
code INT8U CA_Table[]=
{
    
    
	0xC0,0xF9,
	0xA4,0xB0,
	0x99,0x92,
	0x82,0xF8,
	0x80,0x90
};
//显示的数字
code INT8U array[]=
{
    
    
	2,0,2,2,
	0,2,
	0,9
};



//延时
void delay_ms(INT16U x)
{
    
    
	INT8U t;
	while(x--)
	{
    
    
		for(t=0;t<120;t++);
	}
}

void main()
{
    
    
	INT8U i;
	while(1)
	{
    
    
		for(i=0;i<8;i++)//扫描显示8位
		{
    
    
			P0=0xFF;//暂时关闭段码
			P2=1<<i;//输出扫描位码
			P0=CA_Table[array[i]];//输出数组里的数字
			delay_ms(5);
		}
	}
}

单片机案例7

结合proteus和keil

7 按键控制数码管显示

原理图

在这里插入图片描述

程序
/*
	名称:按键调节数码管显示数字
	说明:按键分别为加,减,确定修改,取消修改
		 调节过程中数字闪烁显示

*/
#include<reg51.h>
#define INT8U unsigned char
#define INT16U unsigned int 

//按键定义
sbit K1=P3^4;//加
sbit K2=P3^5;//减
sbit K3=P3^6;//确定修改
sbit K4=P3^7;//取消修改
//共阳极0-9的数码管段码表
code INT8U CA_Table[]=
{
    
    
	0xC0,0xF9,
	0xA4,0xB0,
	0x99,0x92,
	0x82,0xF8,
	0x80,0x90
};
//显示的数字
INT16U num=2022;//设置显示的初值
INT16U temp;//临时变量
INT8U array[]={
    
    0,0,0,0};//保存数位分解结果的数组
INT8U isAdjust=0;//是否处于调节的状态
INT8U preKey=0xF0;//保存上次按键的状态


//延时
void delay_ms(INT16U x)
{
    
    
	INT8U t;
	while(x--)
	{
    
    
		for(t=0;t<120;t++);
	}
}

//数位分解(分解成4个数位)
void resolve(INT16U n)
{
    
    
	array[0]=0;
	while(n>=1000)
	{
    
    
		array[0]++;
		n-=1000;
	}
	array[1]=0;
	while(n>=100)
	{
    
    
		array[1]++;
		n-=100;
	}
	array[2]=0;
	while(n>=10)
	{
    
    
		array[2]++;
		n-=10;
	}
	array[3]=n;
}

//按键处理
void key_handle()
{
    
    
	P3|=0xF0;//P3高4位先置为高电平
	if(preKey==(P3&0xF0))//按键状态未改变时继续
		return;
	preKey=P3&0xF0;

	if(!K1)//递增,进入调节状态
	{
    
    
		delay_ms(10);//消抖
		if(!K1)
		{
    
    
			if(temp==0)
				temp=num;//备份temp,当按下取消时恢复
			num++;
			isAdjust=1;//调节状态
		}
	}

	if(!K2)//递减,进入调节状态
	{
    
    
		delay_ms(10);
		if(!K2)
		{
    
    
			if(temp==0)
				temp=num;//备份temp,当按下取消时恢复
			num--;
			isAdjust=1;//调节状态
		}

	}
	if(!K3)//确定修改,正常显示
	{
    
    
		delay_ms(10);
		if(!K3)
		{
    
    
			isAdjust=0;
			temp=0;
		}
	}

	if(!K4)//取消修改,正常显示之前的数字
	{
    
    
		delay_ms(10);
		if(!K4)
		{
    
    
			if(temp)
				num=temp;
			temp=0;//还原num,temp清零
			isAdjust=0;
		}
	}

}
void main()
{
    
    
	INT8U i;
	INT16U t;
	while(1)
	{
    
    
		// 正常显示
		for(t=0;t<35;t++)//保持数码管稳定显示
		{
    
    
			resolve(num);//数位分解
			for(i=0;i<4;i++)//4位数码管扫描显示
			{
    
    
				P0=0xFF;//暂时关闭段码
				P3=(P3&0xF0)|(1<<i);//P3低4位为位码,高4位接按键
				P0=CA_Table[array[i]];//发送段码
				delay_ms(2);
			}
			key_handle();//按键处理
		}
		//调节状态
		if(isAdjust)
		{
    
    
			P0=0xFF;//关闭所有数码管
			for(t=0;t<15;t++)//在循环中保存对按键的响应
			{
    
    
				delay_ms(10);
				key_handle();
			}
		}
	}
}

单片机案例8

结合proteus和keil

8 4乘4按键显示

原理图

在这里插入图片描述

程序
/*
	名称:数码管显示4*4键盘矩阵按键序号
	说明:按下键后,在数码管上显示该按键的序号

*/
#include<reg51.h>
#define INT8U unsigned char
#define INT16U unsigned int 

//共阳极0-F的数码管段码表
code INT8U CA_Table[]=
{
    
    
	0xC0,0xF9,
	0xA4,0xB0,
	0x99,0x92,
	0x82,0xF8,
	0x80,0x90,
	0x88,0x83,
	0xC6,0xA1,
	0x86,0x8E,
	0xFF//黑屏
};

sbit BEEP=P3^0;
INT8U preKey=0xFF;//保存上次按键序号 //0xFF表示无按下
INT8U curKey=0xFF;//保存当前按键序号


//延时
void delay_ms(INT16U x)
{
    
    
	INT8U t;
	while(x--)
	{
    
    
		for(t=0;t<120;t++);
	}
}

//键盘矩阵扫描
void key_scan()
{
    
    
	//高4位置0,放入4行,扫描4列
	P1=0x0F;
	delay_ms(1);
	if(P1==0x0F)//无按键时,提前返回
	{
    
    
		curKey=0xFF;
		return;
	}

	//判断是哪一列
	switch(P1)
	{
    
    
		case 0x0E://第0列
		{
    
    
			curKey=0;
			break;
		}
		case 0x0D://第1列
		{
    
    
			curKey=1;
			break;
		}
		case 0x0B://第2列
		{
    
    
			curKey=2;
			break;
		}
		case 0x07://第3列
		{
    
    
			curKey=3;
			break;
		}
		default://无按键按下,返回
		{
    
    
			curKey=0xFF;
			return;
		}
	}

	//低4位置0,放入4列,扫描4行
	P1=0xF0;
	delay_ms(1);
	//判断按键在哪一行
	switch(P1)
	{
    
    
		case 0xE0://第0行
		{
    
    
			curKey+=0;
			break;
		}
		case 0xD0://第1行
		{
    
    
			curKey+=4;
			break;
		}
		case 0xB0://第2行
		{
    
    
			curKey+=8;
			break;
		}
		case 0x70://第3行
		{
    
    
			curKey+=12;
			break;
		}
		default://无按键按下
		{
    
    
			curKey=0xFF;
		}
	}
}

//蜂鸣器
void beep()
{
    
    
	INT8U i;
	for(i=0;i<100;i++)
	{
    
    
		delay_ms(1);
		BEEP=~BEEP;
	}
	BEEP=1;
}

//主程序
void main()
{
    
    
	P0=0xFF;//数码管初始为黑屏
	while(1)
	{
    
    
		key_scan();//扫描键盘获取键值
		//无按键延时,继续扫描
		if(curKey==0xFF)
		{
    
    
			delay_ms(10);
			continue;
		}
		//显示键值,输出蜂鸣声
		P0=CA_Table[curKey];
		beep();
		//没有释放,等待
		while(curKey!=0xFF)
		{
    
    
			key_scan();
		}
	}
}

单片机案例9

结合proteus和keil

9 普通开关和拨码开关(报警器)

原理图

在这里插入图片描述

程序
/*
	名称:普通开关与拨码开关
	说明:SW1是普通开关,控制显示开关
		 SW2是拨码开关,控制报警器

*/
#include<reg51.h>
#include<intrins.h>
#define INT8U unsigned char
#define INT16U unsigned int 

//0-9的共阴极数码管段码表
code INT8U CC_Table[]=
{
    
    
	0x3F,0x06,
	0x5B,0x4F,
	0x66,0x6D,
	0x7D,0x07,
	0x7F,0x6F
};

INT8U show_buff[]={
    
    0,0,0};//显示缓冲
sbit BEEP=P3^3;//蜂鸣器
sbit SW1=P3^0;//控制显示
sbit SW2=P3^6;//控制报警器
sbit CE=P2^0;//74LS245的使能控制端


//延时
void delay_ms(INT16U x)
{
    
    
	INT8U t;
	while(x--)
	{
    
    
		for(t=0;t<120;t++);
	}
}

//报警声
void alarm(INT8U t)
{
    
    
	INT8U i,j;
	for(i=0;i<150;i++)
	{
    
    
		BEEP=~BEEP;//输出声音
		for(j=0;j<t;j++);//输出不同频率
	}	
}

//主程序
void main()
{
    
    
	INT8U i;
	CE=0;

	while(1)
	{
    
    
		if(SW1)//断开
		{
    
    
			CE=1;//不显示
		}
		else//闭合
		{
    
    
			CE=0;//显示
			//由P1端口读取的拨码开关值分解数位
			show_buff[0]=P1/100;
			show_buff[1]=P1/10%10;
			show_buff[2]=P1%10;
			//刷新显示
			for(i=0;i<3;i++)
			{
    
    
				P0=0x00;//暂时关闭段码
				P2=(~(0x20<<i))&0xF0;//发送位码
				P0=CC_Table[show_buff[i]];//发送段码
				delay_ms(5);
			}
		}
		if(SW2)//报警器发声
		{
    
    
			alarm(100);
			alarm(150);
		}
	}
}

单片机案例10

结合proteus和keil

10 继电器控制照明设备

原理图

在这里插入图片描述

程序
/*
	名称:继电器控制照明设备
	说明:K1是继电器开关

*/
#include<reg51.h>
#define INT8U unsigned char
#define INT16U unsigned int 

sbit K1=P0^0;//继电器控制按键
sbit RELAY=P2^0;//继电器控制引脚


//延时
void delay_ms(INT16U x)
{
    
    
	INT8U t;
	while(x--)
	{
    
    
		for(t=0;t<120;t++);
	}
}
|  |  |
|--|--|
|  |  |

//主程序
void main()
{
    
    
	RELAY=1;//关闭灯泡
	while(1)
	{
    
    
		if(K1==0)//闭合继电器开关
		{
    
    
			delay_ms(10);
			if(K1==0)
			{
    
    
				while(K1==0);
				RELAY=~RELAY;
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/kdnnnd/article/details/123967834