IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 单片机学习进阶案例 -> 正文阅读

[嵌入式]单片机学习进阶案例

根据单片机100案例所做,适合初学者进一步学习单片机的案例.

单片机案例11

结合proteus和keil

11 INT0中断计数器

原理图

在这里插入图片描述

程序
/*
	名称:INT0中断计数
	说明:按下计数键K1触发中断,中断程序累加计数
		计数值显示在三个数码管上,按下清零键K2数码管清零

*/
#include<reg51.h>
#include<intrins.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,
	0xFF//黑屏
};
//计数器值分解后的给位
INT8U show_buffer[]={0,0,0};
INT16U count=0;
sbit clear_key=P3^6;
//延时
void delay_ms(INT16U x)
{
	INT8U t;
	while(x--)
	{
		for(t=0;t<120;t++);
	}
}
//数码管显示计数值
void refresh_show()
{
	//获取三个数位
	show_buffer[0]=count/100;
	show_buffer[1]=count%100/10;
	show_buffer[2]=count%10;

	if(show_buffer[0]==0)//高位为0时不显示
	{
		show_buffer[0]=10;
		//高位为0时,第二位为0,也不显示
		if(show_buffer[1]==0)
			show_buffer[1]=10;
	}
	P0=CA_Table[show_buffer[0]];
	P1=CA_Table[show_buffer[1]];
	P2=CA_Table[show_buffer[2]];

}
void main()
{
	//初始化显示端口
	P0=0xFF;
	P1=0xFF;
	P2=0xFF;
	IE=0x81;//允许INT0中断
	IT0=1;//下降沿触发
	while(1)
	{
		if(clear_key==0)//清零
			count=0;
		refresh_show();//持续则刷新显示
	}
}

//INT0中断函数
void ex_int0() interrupt 0
{
	EA=0;//禁止中断
	delay_ms(10);//消抖
	count++;//计数值递增
	EA=1;//开中断
}

单片机案例12

结合proteus和keil

12 INT0与INT1中断计数

原理图

在这里插入图片描述

程序
/*
	名称:INT0和INT1中断计数
	说明:按下计数键K1计数值显示在右边数码管上,
		按下计数键K2计数值显示在左边数码管上,
		按下清零键K3,K4数码管清零

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

sbit K3=P3^4;//清零
sbit K4=P3^5;
//共阳极0-9的数码管段码表
code INT8U CA_Table[]=
{
	0xC0,0xF9,
	0xA4,0xB0,
	0x99,0x92,
	0x82,0xF8,
	0x80,0x90,
	0xFF//黑屏
};

code INT8U scan_bits[]=
{
	0x20,0x10,
	0x08,0x04,
	0x02,0x01
};
//两组计数的显示缓冲,前3为一组,后3一组
INT8U show_buffer[]=
{
	0,0,0,
	0,0,0
};
INT16U count_a=0;
INT16U count_b=0;

//延时
void delay_ms(INT16U x)
{
	INT8U t;
	while(x--)
	{
		for(t=0;t<120;t++);
	}
}
//数码管显示计数值
void refresh_show()
{
	INT8U i;
	//分解count_a
	show_buffer[5]=count_a/100;
	show_buffer[4]=count_a%100/10;
	show_buffer[3]=count_a%10;

	if(show_buffer[5]==0)//高位为0时不显示
	{
		show_buffer[5]=10;
		//高位为0时,第二位为0,也不显示
		if(show_buffer[4]==0)
			show_buffer[4]=10;
	}

	//分解count_b
	show_buffer[2]=count_b/100;
	show_buffer[1]=count_b%100/10;
	show_buffer[0]=count_b%10;

	if(show_buffer[2]==0)//高位为0时不显示
	{
		show_buffer[2]=10;
		//高位为0时,第二位为0,也不显示
		if(show_buffer[1]==0)
			show_buffer[1]=10;
	}


	for(i=0;i<6;i++)
	{
		P0=0xFF;//暂时关闭段码
		P2=scan_bits[i];//位码
		P0=CA_Table[show_buffer[i]];//段码
		delay_ms(1);
	}

}
void main()
{
	IT0=1;//下降沿触发
	IT1=1;
	PX0=1;//设置优先级
	IE=0x85;//允许INT0,INT1中断

	while(1)
	{
		if(!K3)//清零
			count_a=0;
		if(!K4)//清零
			count_b=0;
		refresh_show();//持续则刷新显示
	}
}

//INT0中断函数
void ex_int0() interrupt 0
{
	EA=0;//禁止中断
	delay_ms(10);//消抖
	count_a++;//计数值递增
	EA=1;//开中断
}
//INT1中断函数
void ex_int1() interrupt 2
{
	EA=0;//禁止中断
	delay_ms(10);//消抖
	count_b++;//计数值递增
	EA=1;//开中断
}

单片机案例13

结合proteus和keil

13 TIMER0控制单只LED闪烁

原理图

在这里插入图片描述

程序
/*
	名称:定时器控制单只LED闪烁
	说明:TIMER0控制LED闪烁

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

INT16U count=0;
//主程序
void main()
{
	TMOD=0x00;//T0工作于模式0(13位模式)

	//5ms定时
	TH0=(8192-5000)>>5;//等同于:TH0=(8192-5000)/32;
	TL0=(8192-5000)&0x1F;//等同于:TH0=(8192-5000)%32;

	IE=0x82;//允许T0中断
	TR0=1;//启动T0
	while(1);
}

//T0中断函数
void led_flash() interrupt 1
{
	TH0=(8192-5000)>>5;
	TL0=(8192-5000)&0x1F;
	if(++count==50)//累加形成5ms*50=250ms定时开关LED
	{
		P0=~P0;//P0端口的LED整体闪烁
		count=0;
	}
}

单片机案例14

结合proteus和keil

14 定时器控制数码管显示

原理图

在这里插入图片描述

程序
/*
	名称:TIMER0控制数码管动态显示
	说明:数码管显示:年月日时分秒
		使用定时器实现

*/
#include<reg51.h>
#include<intrins.h>
#define INT8U unsigned char
#define INT16U unsigned int 
#define METHOD1 1
//共阳极0-9的数码管段码表
code INT8U CA_Table[]=
{
	0xC0,0xF9,
	0xA4,0xB0,
	0x99,0x92,
	0x82,0xF8,
	0x80,0x90,
	0xBF//'-'的段码,索引为10
};
//待显示数据
code INT8U show_date[][8]=
{
	{2,2,10,0,2,10,1,4},
	{2,3,10,5,9,10,5,9}
};
INT8U i=0;
INT8U j=0;
INT16U t=0;

#if METHOD1
//主程序:使用方法1,使用定时器中断控制数码管刷新显示
void main()
{
	TMOD=0x01;//T0工作于模式1(16位模式)

	//4ms定时
	TH0=(65536-5000)>>8;
	TL0=(65536-5000)&0xFF;

	IE=0x82;//允许T0中断
	TR0=1;//启动T0
	while(1);
}
#else 
//方法2:不使用定时器中断控制,不需要中断函数
void main()
{
	TMOD=0x01;//T0工作于模式1(16位模式)

	//4ms定时
	TH0=(65536-5000)>>8;
	TL0=(65536-5000)&0xFF;

	IE=0x82;//允许T0中断
	TR0=1;//启动T0
	while(1)
	{
		if(TF0)
		{
			TF0=0;
			TH0=(65536-5000)>>8;
			TL0=(65536-5000)&0xFF;
			P0=0xFF;//先暂时关闭段码
			P2=~(1<<j);//输出位码
			P0=CA_Table[show_date[i][j]];//输出段码
			j=(j+1)%8;//数组第i行的下一数字索引
			if(++t!=350)//每组的8个字符位保持刷新一段时间
				continue;
			t=0;
			//刷新若干遍后切换
			i=(i+1)%2;//数组行i=0时,显示年月日,i=1时显示时分秒
		}
	}
}
#endif 

//T0中断函数
void seg_show() interrupt 1
{
	TH0=(65536-5000)>>8;
	TL0=(65536-5000)&0xFF;
	P0=0xFF;//先暂时关闭段码
	P2=~(1<<j);//输出位码
	P0=CA_Table[show_date[i][j]];//输出段码
	j=(j+1)%8;//数组第i行的下一数字索引
	if(++t!=350)//每组的8个字符位保持刷新一段时间
		return;
	t=0;
	//刷新若干遍后切换
	i=(i+1)%2;//数组行i=0时,显示年月日,i=1时显示时分秒

}

单片机案例15

结合proteus和keil

15 定时器控制8乘8点阵显示

原理图

在这里插入图片描述

程序
/*
	名称:TIMER0控制8*8点阵显示数字
	说明:点阵屏显示:0-9
		使用T0定时器溢出中断实现

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

//数字点阵

INT8U code DotMatrix[] =
{ 
	0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00,//0
	0x00,0x00,0x00,0x21,0x7F,0x01,0x00,0x00,//1
	0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00,//2
	0x00,0x22,0x49,0x49,0x49,0x36,0x00,0x00,//3
	0x00,0x0C,0x14,0x24,0x7F,0x04,0x00,0x00,//4
	0x00,0x72,0x51,0x51,0x51,0x4E,0x00,0x00,//5
	0x00,0x3E,0x49,0x49,0x49,0x26,0x00,0x00,//6
	0x00,0x40,0x40,0x40,0x4F,0x70,0x00,0x00,//7
	0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00,//8
	0x00,0x32,0x49,0x49,0x49,0x3E,0x00,0x00//9
};


//主程序
void main()
{
	TMOD=0x00;//T0工作于模式0(13位模式)

	//2ms定时
	TH0=(8192-2000)>>5;
	TL0=(8192-2000)&0x1F;
	TR0=1;//启动T0
	IE=0x82;//允许T0中断

	while(1);
}


//T0中断函数
void seg_show() interrupt 1
{
	static INT8U i=0;
	static INT8U num_idx=0;
	static INT8U t=0;
	TH0=(8192-2000)>>5;
	TL0=(8192-2000)&0x1F;
	P2=0xFF;//先暂时关闭段码
	P3=1<<i;//输出列码(列共阳)
	P2=~DotMatrix[num_idx*8+i];//输出行码
	if(++i==8)//每屏一个数字点阵由8个字节构成
		i=0;
	if(++t==200)//每个数字刷新显示一段时间
	{
		t=0x00;
		if(++num_idx==10)
			num_idx=0;//显示下一个数字
	}

}

单片机案例16

结合proteus和keil

16 TIMER0控制蜂鸣器发出门铃声

原理图

在这里插入图片描述

程序
/*
	名称:TIMER0控制门铃声输出
	说明:按下按键时,蜂鸣器发出叮咚的门铃声

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

sbit key=P1^7;
sbit doorBell=P3^0;
INT16U p=0;

//延时函数
void delay_ms(INT16U x)
{
	INT8U t;
	while(x--);
	for(t=0;t<120;t++);
}
//主程序
void main()
{
	IE=0x82;//允许T0中断
	TMOD=0x00;//T0工作于模式0(13位模式)
	//初始定时700us
	TH0=(8192-1000)/32;
	TL0=(8192-1000)%32;
	while(1)
	{
		if(key==0)//按下K1时,启动定时器
		{
			delay_ms(10);//消抖
			if(key==0)//按键释放后启动T1
			{
				while(!key);
				TR0=1;
			}
		}
	}
	

	while(1);
}


//T0中断函数
void timer0() interrupt 1
{
	doorBell=~doorBell;
	p++;
	//调整400和800,将声音拖长
	//高音
	if(p<400)
	{
		TH0=(8192-700)/32;
		TL0=(8192-700)%32;
	}
	else if(p<800)//低音
	{
		TH0=(8192-1000)/32;
		TL0=(8192-1000)%32;
	}
	else//关闭
	{
		TR0=0;
		p=0;
	}
}

单片机案例17

结合proteus和keil

17 TIMER0控制交通指示灯

原理图

在这里插入图片描述

程序
/*
	名称:TIMER0控制交通指示灯
	说明:绿灯黄灯红灯根据设置循环闪烁

*/

#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 Time_Count=0;
//闪烁次数
INT8U Flash_Count=0;
//灯闪烁方式
INT8U type=1;

//T0中断
void Timer0() interrupt 1
{
	TH0=-50000/256;
	TL0=-50000%256;
	switch(type)
	{
		case 1:
		{
			//东西方向绿灯亮
			RED_EW=0;
			YELLOW_EW=0;
			GREEN_EW=1;
			//南北方向红灯亮
			RED_SN=1;
			YELLOW_SN=0;
			GREEN_SN=0;

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

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

//主程序
void main()
{
	TMOD=0x01;//定时器0工作在方式1
	IE=0x82;//允许定时器0中断
	TR0=1;//启动定时器0
	while(1);
}

单片机案例18

结合proteus和keil

18 TIMER1控制音阶演奏

原理图

在这里插入图片描述

程序
/*
	名称:TIMER1控制音阶演奏
	说明:使用定时器中断控制演奏一段音阶,K1控制播放

*/

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

INT8U i=0;//音符索引
sbit SPK=P2^0;//扬声器输出引脚
sbit K1=P3^6;//按键输入引脚
//14个音符在TIMER1模式0下的定时/计数寄存器初值表
code INT8U hight_list[]=
{
	0,226,229,232,234,
	236,238,240,241,243,
	244,245,246,247,248
};
code INT8U lower_list[]=
{
	0,4,12,9,20,
	2,8,6,2,22,
	5,26,1,4,2
};

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

//T1中断
void Timer1() interrupt 3
{
	SPK=!SPK;//音频脉冲输出
	TH1=hight_list[i];//加载第i个音符的延时初值
	TL1=lower_list[i];

}

//主程序
void main()
{
	IE=0x88;//T1中断
	TMOD=0x00;//模式0
	while(1)
	{
		if(!K1)
		{
			delay_ms(10);//消抖
			if(!K1)
			{
				for(i=1;i<15;i++)//输出14个音符
				{
					TR1=1;
					delay_ms(500);//播放一个音符
					TR1=0;
					delay_ms(50);//播放停顿50ms
				}
			}
		}
	}
}

单片机案例19

结合proteus和keil

19 T0T1T2实现外部计数二进制显示

原理图

在这里插入图片描述

程序
/*
	名称:TIMER0,TIMER1,TIMER2实现外部信号计数与显示
	说明:T0,T1均工作于计数器方式,T2工作于16位自动重装方式
		均实现了对外部输入信号的计数功能
		计数值最大均为65535,即:0xFFFF

*/

#include<reg52.h>
sfr T2MOD =0xC9;//reg52.h中没定义,在此添加sfr定义
sbit SW1=P1^5;
sbit SW2=P1^6;
sbit SW3=P1^7;
//主程序
void main()
{
	//设置T/C0,T/C1为计数器,工作于方式1(16位)
	TMOD=0x55;
	//设置T2引脚计数时钟输入,默认为递增计数
	T2MOD=0x00;
	//设置TIMER2为计数器
	C_T2=1;
	//T2工作于自动重装模式(上溢时重装0x0000)
	RCAP2H=0x00;
	RCAP2L=0x00;
	//三者初值均为0x00
	TH0=0x00;
	TL0=0x00;
	TH1=0x00;
	TL1=0x00;
	TH2=0x00;
	TL2=0x00;
	//启动三个定时器/计数器
	TR0=1;
	TR1=1;
	TR2=1;
	while(1)
	{
		if(!SW1)//通过P2,P0端口显示T0二进制计数值
		{
			P2=~TH0;
			P0=~TL0;
		}
		else if(!SW2)//通过P2,P0端口显示T1二进制计数值
		{
			P2=~TH1;
			P0=~TL1;
		}
		else if(!SW3)//通过P2,P0端口显示T2二进制计数值
		{
			P2=~TH2;
			P0=~TL2;
		}
	}
}

单片机案例20

结合proteus和keil

20 T0T1INT0中断控制报警器与旋转灯

原理图

在这里插入图片描述

程序
/*
	名称:TIMER0,TIMER1,INT0中断控制报警器与旋转灯
	说明:定时器控制报警灯旋转显示,并发出警报声

*/

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

sbit SPK=P3^7;
INT8U FRQ=0x00;

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

//主程序
void main()
{
	P2=0x00;//关闭所有LED
	TMOD=0x11;//两个定时器均工作在模式1
	TH0=0xFE;//定时器初值为0xFE00
	TL0=0x00;
	IT0=1;//下降沿触发INT0中断
	IE=0x8B;//开启0,1,3号中断(INT0,T0,T1)
	IP=0x01;//INT0设为高优先级
	TR0=0;//定时器启停由INT0中断控制,初始为关闭
	TR1=0;
	while(1)//循环过程中递增频率,溢出后再次递增
	{
		FRQ++;
		delay_ms(1);
	}
}

//INT0中断
void ex0_int() interrupt 0
{
	TR0=!TR0;//开启或停止两个定时器,分别控制报警声和LED旋转
	TR1=!TR1;
	if(P2==0x00)
		P2=0xE0;//开启三个灯旋转(0xE0即1110 0000)
	else
		P2=0x00;//关闭所有LED	
}

//TIMER0中断
void Timer0() interrupt 1
{
	TH0=0xFE;
	TL0=FRQ;
	SPK=~SPK;
}

//TIEMR1中断
void Timer1() interrupt 3
{
	TH1=-45000>>8;
	TL1=-45000&0x1F;
	P2=_crol_(P2,1);
}
如果觉得对你有帮助的话,不妨点个赞呗^_^
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-15 00:16:35  更:2022-04-15 00:17:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:43:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码