单片机学习记录(一)最小系统板,流水灯,独立按键

目录

前言:

一、最小系统板

1.电路图

2.PCB图

3.下载线

二、流水灯

1.电路图

2.PCB图

3.编程

(1)顺序结构编程

(a)出现问题:无法下载

(b)出现问题:不符合想要的状况,速度过慢,只有上半亮起

(c)出现问题:有3个灯不亮

(2)循环结构编程

(3)结构化编程

(4)耍猴戏

(5)课堂作业:编程控制16个LED灯排队逐一出场,指导全部出现,最后逐一从另外一边排队退场。

三、独立按键

1.电路图

2.PCB图

3,编程

(1)原理:

(2)注意!按键抖动

(3)消抖

(4)按键切换流水灯的花样


前言:

怎么?你要烤了我?
怎么?你要烤了我?

一、最小系统板

1.电路图

2.PCB图

3.下载线

二、流水灯

1.电路图

2.PCB图

3.编程

(1)顺序结构编程

芯片选择:At89c52

未写延迟函数

Stc助手写延迟函数

3.下载代码

(a)出现问题:无法下载

解决办法:更改STC芯片选择

(b)出现问题:不符合想要的状况,速度过慢,只有上半亮起

解决方案:更改延迟函数,检查系统板的电路图

(c)出现问题:有3个灯不亮

解决方案:①板子上有塑料隔绝电(错误的),接3条线到电阻处

②实际上是三个灯是坏的(错误的),换上新的灯即可

③代码问题(被老师坑了,没细看视频,哭唧唧),改一改代码

#include <REGX52.H>

void Dealy100ms()		//@11.0592MHz
{
	unsigned char data i, j, k;
	i = 5;
	j = 52;
	k = 195;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{
	while(1)
	{
                                //		P0=1;//测试代码
                                //		P2=1;
		P0=0xfe;Dealy100ms();
		P0=0xfd;Dealy100ms();
		P0=0xfb;Dealy100ms();
		P0=0xf7;Dealy100ms();		
		P0=0xef;Dealy100ms();
		P0=0xdf;Dealy100ms();
		P0=0xbf;Dealy100ms();
		P0=0x7f;Dealy100ms();
		P0=0xff;Dealy100ms();
		
		P2=0x7f;Dealy100ms();
		P2=0xbf;Dealy100ms();
		P2=0xdf;Dealy100ms();
		P2=0xef;Dealy100ms();		
		P2=0xf7;Dealy100ms();
		P2=0xfb;Dealy100ms();
		P2=0xfd;Dealy100ms();
		P2=0xfe;Dealy100ms();
		P2=0xff;Dealy100ms();
	}
}

成功案例

(2)循环结构编程

代码

#include <REGX52.H>
void Dealy100ms()		//@11.0592MHz   100毫秒
{
	unsigned char data i, j, k;
	i = 5;
	j = 52;
	k = 195;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
    unsigned char i;        
	while(1)
	{
			for(i=0;i<8;i++)//i初始值为0,i<8时,i+1
			{
				P0=~(1<<i);	//~是按位取反运算   =是赋值运算   <<是按位左移运算
                            /*意思是:假设i=3,将二进制数1左移3位,得到二进制数1000。
                            对1000取反,得到0111。将0111赋值给P0*/
				Dealy100ms();
			}
		P0=0xff;
			
		for(i=0;i<8;i++)
			{
				P2=~(0x80>>i);
				Dealy100ms();
			}
		P2=0xff;
	}
}

拓展:P0=~(1<<i);

~是按位取反运算   =是赋值运算   <<是按位左移运算
意思是:将二进制数1左移3位,得到二进制数1000。对1000取反,得到0111。将0111赋值给P0

成功案例

(3)模块化编程

#include <REGX52.H>
void Dealy100ms()		//@11.0592MHz   100毫秒
{
	unsigned char data i, j, k;
	i = 5;
	j = 52;
	k = 195;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void LED1()
{
	unsigned char i;
	for(i=0;i<8;i++)
			{
				P0=~(1<<i);	
				Dealy100ms();
			}
		P0=0xff;
}
void LED2()
{
	unsigned char j;	
	for(j=0;j<8;j++)
			{
				P2=~(0x80>>j);
				Dealy100ms();
			}
		P2=0xff;
}

void main()
{
	while(1)
	{
		LED1();
		LED2();
	}
}

(4)4种模式流水灯

从上往下

从下往上

两端往中间

中间往两边

代码

#include <REGX52.H>
void Dealy100ms()		//@11.0592MHz 50毫秒
{
	unsigned char data i, j, k;

	i = 3;
	j = 26;
	k = 223;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void LED11()//从上而下
{
	unsigned char i;
	for(i=0;i<8;i++)
			{
				P0=~(1<<i);	
				Dealy100ms();
			}
}
void LED12()//从下而上
{
	unsigned char i;
	for(i=0;i<8;i++)
			{
				P0=~(0x80>>i);	
				Dealy100ms();
			}
}

void LED21()//从上而下
{
	unsigned char j;	
	for(j=0;j<8;j++)
			{
				P2=~(0x80>>j);
				Dealy100ms();
			}
}

void LED22()//从下而上
{
	unsigned char j;	
	for(j=0;j<8;j++)
			{
				P2=~(1<<j);
				Dealy100ms();
			}
}

void hou1()//从上而下
{
	LED11();
	P0=0xff;
	LED21();
	P2=0xff;
}

void hou2()//从下而上
{
	LED22();
	P2=0xff;
	LED12();
	P0=0xff;
}
 
void hou3()//从外到中间
{	unsigned char i,j;
		for(i=0,j=0;i<8&&j<8;i++,j++)
			{
				P0=~(1<<i);
				P2=~(1<<j);				
				Dealy100ms();
			}
}

void hou4()//从中间到外
{unsigned char i,j;
		for(i=0,j=0;i<8&&j<8;i++,j++)
			{
				P0=~(0x80>>i);
				P2=~(0x80>>j);				
				Dealy100ms();
			}

}

void main()
{
	while(1)
	{
		hou1();		
		hou2();		
		hou3();	
		hou4();
		P2=0xff;
	}
}

示例

(5)课堂作业:16个灯逐一出现 然后从另一边逐一退场

进制表
二进制八进制十进制十六进制
0000
1111
10222
11333
100444
101555
110666
111777
10001088
10011199
10101210A
10111311B
11001412C
11011513D
11101614E
11111715F

更换后的的电路

原理:当P0.0输出一个高电平的时候,相当于跟VCC一样的5V电压,此时整个电路路无电压差无电流,LED熄灭。当P0.0输出一个低电平的时候,相当于跟GND一样的0V电压,此时整个电路接通,LED点亮。可以P0.0输出电平可以通过程序控制。

0000 0000=0x00    →    全亮
1000 0000=0x80
1100 0000=0xc0
1110 0000=0xe0
1111 0000=0xf0
1111 1000=0xf8
1111 1100=0xfc
1111 1110=0xfe
1111 1111=0xff    →    全灭

0111 1111=0x7f
0011 1111=0x3f
0001 1111=0x1f
0000 1111=0x0f
0000 0111=0x07
0000 0011=0x03
0000 0001=0x01

代码

    #include <REGX52.H>
void Dealy100ms()		//@11.0592MHz 50毫秒
{
	unsigned char data i, j, k;

	i = 3;
	j = 26;
	k = 223;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
unsigned char Led1[9]={0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00};
unsigned char Led2[9]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
void hou5()               //一个一个亮
{
	unsigned char i,j;
		for(i=0;i<=8;i++)
			{
				P0=Led1[i];	
				Dealy100ms();
			}		
//			P0=Led2[8];
		for(j=8;j>=0&&j<=8;j--)
			{
				P2=Led2[j];
				Dealy100ms();
			}
}
void hou6()                //一个一个灭
{
	unsigned char i,j;
	
			for(j=0;j<=8;j++)
			{
				P0=0x00;
				P2=Led2[j];
				Dealy100ms();
			}
			
		for(i=8;i>=0&&i<=8;i--)
			{
				P2=0xff;
				P0=Led1[i];	
				Dealy100ms();
			}	
}

void main()
{
	while(1)
	{
		hou5();
		Dealy100ms();
		hou6();
//P2=0x01;
	}
}

示例

 (6)呼吸灯 PWM调节亮度

PWM调节亮度

单片机输出占空比从小到大变化,再从大变小的PWM

#include <REGX52.H>

void Delay()		//@12.000MHz
{
	unsigned char i;
	i = 57;
	while (--i);
}


unsigned char duty,x;
void PWM()
{
	for (x=0;x<100;x++)
	{
		if(x<duty)
		{
			P0=0;
			P2=0;
		}
		else 
		{
			P0=0xff;
			P2=0xff;
		}
		Delay();
	}
}
void main()
{
	while (1)
	{
		for (duty=0;duty<100;duty++)
		{
			PWM();
		}
		for (duty=100;duty>0;duty--)
		{
			PWM();
		}
	}
}

 

三、独立按键

1.电路图

2.PCB图

3,编程

(1)原理:

按键是机械弹性开关,当开关闭合时,线路导通,高电平;当开关断开时,线路断开,低电平。

(2)注意!按键抖动

按键按下和弹起会发生电平抖动。如下图所示。

(3)消抖

硬件消抖:在硬件设计上想办法降低抖动的幅度及时间,这是一种主动消抖。如按键并联电容。

软件消抖:硬件上不可能完全消除抖动,软件上可以绕开抖动的那一段,这是一种逃避式的消抖。

也就是通过延时消抖,延时时间一般为10-15毫秒。
原文链接:https://blog.csdn.net/weixin_42727214/article/details/127913068

(4)课堂作业:按键切换流水灯的花样

不按键,LED灯不亮
按K1,LED灯从上到下点亮一次然后自动熄灭
按K2,LED灯从下到上点亮一次然后自动熄灭
按K3,LED灯从两端到中间一次然后自动熄灭
按K4,LED灯从中间到两头跑,然后自动熄灭

#include <REGX52.H>

sbit K1=P1^0;
sbit K2=P1^1;
sbit K3=P1^2;
sbit K4=P1^3;

/*中间关于灯的代码详见[二,3,(4)]*/

void main()
{
	while(1)
	{
		if(K1==0) hou1();
		if(K2==0) hou2();
		if(K3==0) hou3();
		if(K4==0) hou4();
	}
}

案例

四,延迟函数

附加题:调制两个按键,课控制流水灯的速度

延迟函数的解释:c语言的单片机delay延时函数详解_延时函数delay-CSDN博客

时钟周期、机器周期、指令周期的概念及三者之间的关系-CSDN博客

unsigned int xms;
void Delay(unsigned int xms)		
{
	unsigned char i, j;
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

void speed_k()//快速
{
xms=100;
}
void speed_z()//中速
{
xms=300;
}
void speed_m()//快速
{
xms=500;
}	

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值