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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> C51学习笔记(一) -> 正文阅读

[嵌入式]C51学习笔记(一)

开发工具

普中C51单片机:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

新建工程

1. 打开Keil uVision5,面板选择project新建工程
在这里插入图片描述

2. 保存工程名字后会出现下面这个界面,我所用的是STC89C52,这个软件上虽然没有,但可以选用Atmel里的AT89C52,操作方式和功能基本一样。
在这里插入图片描述
3. 然后添加一个C语言程序文件就可以开始写程序了
在这里插入图片描述

LED灯

原理

在这里插入图片描述
LED灯正极连接VCC端是高电平,所以想要LED灯亮,需要在另一个端口给低电平,才能有电流。P2_端口起寄存器作用,CPU通过给寄存器赋值控制电路,用1 / 0表示高低电平,若想D1亮,理论上来讲程序可以写成P2 = 1111 1110,但在c语言它会被默认为十进制,所以要转化成16进制P2 = 0xFE更为方便。

点亮一个LED灯

写好程序烧录到单片机里,需要先生成程序下载的文件。
在这里插入图片描述
然后编译,再在STC-ISP中打开程序文件下载程序,打开单片机开关即可成功点亮D1灯,想要其他的灯亮同理,亮的为0,不亮为1,然后转化成16进制。
在这里插入图片描述
在这里插入图片描述

闪烁的LED灯

让LED灯闪烁无非亮一下暗一下,写个while循环让零一零一交替变换。但当程序只是写成P2 = 0xFE; P2 = 0xFF;时会发现灯几乎没有变化,这是因为LED速度特别快,中间那短短的间隔我们基本分辨不出来,因此看上去就还是一直亮的,所以需要写个函数让LED灯亮与暗之间的时间延长。
在STL-ISP有软件延时计算器,它可以生成延时函数。
在这里插入图片描述
系统频率看单片机晶振上数值
在这里插入图片描述将函数复制到程序,即可实现LED闪烁,改变延时时间就可以改变LED闪烁的周期。
如果每次改变时间都要生成一次函数也有点麻烦,可以先生成一个1毫秒的函数,然后增加变量x,把原本函数的内容循环x次,这样就相当于一个延时1*x毫秒的函数,每次要改变时间就只用改变参数x。

void Delay(unsigned int x)		
{
	unsigned char i, j;
	while(x--)
	{
		_nop_();//需要头文件#include <Intrins.h>
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

LED流水灯

可以通过位运算用循环实现流水灯

void main()
{
	while(1)
	{
		int i=8;
		P2 = 0xFF;//一开始都不亮
		while(i--)
		{
			Delay500ms();
			P2 = P2>>1;//逐一开始一个个亮起,到全部亮重新下一个循环
			Delay500ms();
		}
	}
}

请添加图片描述

稍微改变一下代码可以让LED灯单独一个一个流水亮起

void main()
{
	while(1)
	{
		int i=8;
		P2 = 0xFF;
		while(i--)
		{
			if(P2==0xFF) P2 = P2<<1;
			else P2 = (P2<<1) + 0x1;//左移低位补0,加1去除尾部的0可以保证只有一个0,这样LED灯就可以一个一个流水亮起
			Delay500ms();
		}
	}
}

请添加图片描述
还可以让其以二进制形式从1到255亮

void main()
{
	while(1)
	{
		int i=256;
		while(i--)
		{
			P2 -= 0x1;//或者num=0; num++; P2 = ~num;
			Delay(300);
		}
	}
}

请添加图片描述

独立按键控制LED灯暗灭

在这里插入图片描述
独立按键一头接地 ,一头接 I/O口上,单片机通电时,I/O口默认高电平。寄存器可以检测I/O口电平,再读回寄存器,当没有按下独立按键时,检测I/O口为高电平,按下独立按键时,检测I/O口为低电平,由此可以来判断按键是否按下。
P2控制的是整个8个LED灯,若要控制一个,可以写成P2_0、P2_1等形式,单独控制一个灯。

void main()
{
	while(1)
	{
		if(P3_1==0) P2_0 = 0;//K1键按下P3_1=0,此时P2_0这个灯亮
		else P2_0 = 1;//松开按键灯不亮
	}
}

对于机械开关,在机械触点因弹性作用下在开关闭合、断开时会产生一连串抖动,所以可以在按键按下松开时延时一段时间进行消抖。
在这里插入图片描述
改一下可以实现跟日常开关灯一样,按一次开关后一直亮或一直暗。

void main()
{
	while(1)
	{
		if(P3_1==0)//按下按键
		{
			Delay(20);//按下开关瞬间的延时
			while(P3_1==0);//没松手灯的状态不变,松手后变
			Delay(20);//松开开关瞬间的延时
			P2_0 = ~P2_0;//让灯一次亮一次暗
		}
	}
}

独立按键控制LED灯位移

通过两个按键控制LED左移右移
请添加图片描述

void main()
{
	int num=0;
	while(1)
	{
		if(P3_1==0)//控制LED灯从第一个到第八个方向移动
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			num++;
			if(num==8) num = 0;//此时说明LED灯已经亮到第八个了,继续往下亮应该从第一个重新开始
			P2 = ~(0x01<<num);//1左移的位置取反就是要亮的那个灯
		}
		if(P3_0==0)//控制LED灯反方向移动
		{
			Delay(20);
			while(P3_0==0);
			Delay(20);
			if(num==0) num = 7;
			else num--;
			P2 = ~(0x01<<num);
		}
	}
}

数码管

原理

在这里插入图片描述
common ground即公共端,一般指接地点,所以每一个 “ 8 ” 有一个共阴极,“ 8 ” 的每一个边对应一个引脚,给它的共阴极赋值0(位选),边的引脚赋值1,就可以让 “ 8 ” 对应边亮起(段选),呈现出想要的数字。
在这里插入图片描述
LED1 、 LED2…LED8端接在74HC138译码器输出端,它可以控制输出0还是1,还可以通过P2三个端口控制这八个端口。其按CBA顺序看,如果是000,转化为十进制即0,所以就是Y0为0,其他为1,剩下同理。

显示一个数字

void main()
{
	P2_4 = 0;
	P2_3 = 1;
	P2_2 = 1;//Y3对应LED4
	P0 = 0x7D;//0111 1101对应gfedca边亮
}

在这里插入图片描述

显示多个数字

void main()
{
	while(1){
		P2_4=1;
		P2_3=0;
		P2_2=1;
		P0=0x7D;//LED6显示6
		Delay(1);
		P2_4=1;
		P2_3=1;
		P2_2=0;
		P0=0x4F;//LED7显示3
		Delay(1);
	}
}

可以看到两个LED灯显示间加了延时函数,如果不加,会出现以下现象,它的显示位置错乱。因为数码管显示首先位选然后段选,然后再下一个位选段选,中间特别快这样上一个段选可能就跟下一个的位选结合显示,这样数据就错位了。所以让其中间延时一点可以避免这个现象。
请添加图片描述
但同时也不能延时太长,太长肉眼会很明显的看到两个数字的跳动,延时1毫秒数字依然是跳动的但频率过快人眼看上去就是常亮了。
延时100毫秒

矩阵键盘

原理

在这里插入图片描述
与独立按键类似,按下为0,从其接线可以看出每个按键一个脚和其同一行相连,另一个与其同一列相连,这样可以减少I/O口占用,如果像独立按键每个按键接入一个I/O口将需要16个I/O口,现在就只需要8个。要确定是哪个按键按下,就跟看坐标一样,可以先从行看,也可以先从列看。例如先从行看给P1_7赋0,然后检测P1_3是不是等于0,如果是代表S1被按下。

输出数字

我是跟着江科大自动协51单片机视频学的,利用LCD1602显示数字,LCD1602的程序从他那获取的。
写每个按键代表数字的函数:

unsigned char MatrixKey()
{
	unsigned char ch=0;
	P1 = 0xFF;//开始时全部置1
	P1_7 = 0;//从第一行开始判断
	if(P1_3==0){Delay(20);while(P1_3==0);Delay(20);ch = 1;}
	if(P1_2==0){Delay(20);while(P1_2==0);Delay(20);ch = 2;}
	if(P1_1==0){Delay(20);while(P1_1==0);Delay(20);ch = 3;}
	if(P1_0==0){Delay(20);while(P1_0==0);Delay(20);ch = 4;}
	
	P1 = 0xFF;
	P1_6 = 0;
	if(P1_3==0){Delay(20);while(P1_3==0);Delay(20);ch = 5;}
	if(P1_2==0){Delay(20);while(P1_2==0);Delay(20);ch = 6;}
	if(P1_1==0){Delay(20);while(P1_1==0);Delay(20);ch = 7;}
	if(P1_0==0){Delay(20);while(P1_0==0);Delay(20);ch = 8;}
	
	P1 = 0xFF;
	P1_5 = 0;
	if(P1_3==0){Delay(20);while(P1_3==0);Delay(20);ch = 9;}
	if(P1_2==0){Delay(20);while(P1_2==0);Delay(20);ch = 10;}
	if(P1_1==0){Delay(20);while(P1_1==0);Delay(20);ch = 11;}
	if(P1_0==0){Delay(20);while(P1_0==0);Delay(20);ch = 12;}
	
	P1 = 0xFF;
	P1_4 = 0;
	if(P1_3==0){Delay(20);while(P1_3==0);Delay(20);ch = 13;}
	if(P1_2==0){Delay(20);while(P1_2==0);Delay(20);ch = 14;}
	if(P1_1==0){Delay(20);while(P1_1==0);Delay(20);ch = 15;}
	if(P1_0==0){Delay(20);while(P1_0==0);Delay(20);ch = 16;}
	return ch;
}

主函数:

void main()
{
	unsigned char x;
	LCD_Init();
	while(1)
	{
		x = MatrixKey();
		if(x)//x!=0说明有按键按下并显示那个按键代表数字,可以防止其循环过快看不到数字变化
		{
			LCD_ShowNum(1,1,x,2);
		}
	}
}

请添加图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-24 21:12:15  更:2022-09-24 21:15:15 
 
开发: 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年12日历 -2024/12/28 1:33:27-

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