单片机学习笔记(1)

这篇博客介绍了单片机学习的基础,包括如何点亮LED灯、操作独立按键以及控制蜂鸣器的工作原理和实现代码。通过理解和实践这些基本操作,为后续的单片机应用打下基础。

一.点亮LED灯

1.原理

首先,要知道LED灯为什么会亮--形成闭合回路;其次要知道1其实就是高电频也就是所谓的正极;而0就是低电平也就是所谓的负极;然后要知道不同的单片机上的LED灯亮给的条件可能是不一样的,具体我们看下边这张图。

 像这个原理图,是共阳接VCC的,所以要使灯亮,就要赋予灯的负极对于的脚0,这样才能形成回路使得灯亮;相反的,如果是共阴接GND,这要赋予它1,才能使得灯亮。

2.代码

#include "reg52.h"    //此文件中定义了单片机的一些特殊功能寄存器

sbit led=P2^0;	   //将单片机的P0.0端口定义为led
void main()
{
	led=0;	//P2.0端口设置为低电平	
}

二.独立按键

1.原理

这个也和独立按键是类似的,但是吧,按键没有正负之分,所以如果一边接的事GND,则赋予它另一边1,;如果一边为VCC则赋予另一边0.

 

 2.代码

#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

sbit k1=P3^1;	 //定义P31口是k1

void delay(int i)   //延迟函数  
{
	while(i--);	
}

void keypros()
{
	if(k1==0)		  //检测按键K1是否按下
	{	
		delay(1000);   //消除抖动 一般大约10ms
		if(k1==0)	 //再次判断按键是否按下
		{
			         //写入你要执行的函数
		}
		while(!k1);	 //检测按键是否松开
	}		
}

三.蜂鸣器

1.原理

  • 蜂鸣器有有源和无源,这里的“源”是指震荡源;也就是说,有源蜂鸣器内部带震荡源,所以只要一通电就会叫;而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫,必须用2K-5K的方波去驱动它;有源蜂鸣器往往比无源的贵,就是因为里面多个震荡电路。而我的单片机是无源的蜂鸣器。
  • 而单片机只是用来控制的,不能直接驱动,相反电路图中电路来放大。改变单片机引脚输出波形的频率,可以调节蜂鸣器音调,形成不同的音色;改变输出电压的高低电平占空比(时间长短),则可以控制蜂鸣器的声音大小。
  • 在原理图中的电阻电路其实是放大电路,然后要使得蜂鸣器发声,要用脉冲去驱动,也就是用2k-5k的脉冲去驱动,具体转换就是1k=delay(100)//10ms;具体发生原理图如下。

2.代码

#include<reg52.h>

sbit beep=P1^5;//定义蜂鸣器管脚

void delay(int i)
{
  while(i--);
}

void main()
{
     while(1)
     {
        beep=~beep;//切换高低电平产生脉冲
		delay(100);//改变占空比,进而改变音色音调
	}
}

四.课后小作业

/*【任务】
	 1.按下独立按键2,第二个灯亮,再按,灯灭
   2.按下独立按键1,已亮的灯向右流水两位,再按则再右流两位
   3.按下独立按键3,蜂鸣器响,再按,以第二种声音响
   4.按下独立按键4,已亮的灯向左循环流水
	   【思路】
	 1.解决按键按下后执行程序;
	 2.解决不同按键按下后要执行的程序;
	 3.用一个主函数来执行个各函数模块
	   【问题】
	 1.主要问题是必须先按k2,再按k1或者k3,右移或左移才有意义*/
	 
#include<reg52.h>
#include<intrins.h>
#define led P2   //定义流水灯

sbit k1 = P3^1;     //定义第一个按键
sbit k2 = P3^0;    //定义第二个按键
sbit k3 = P3^2;   //定义第三个按键
sbit k4 = P3^3;   //定义第四个按键
sbit beep=P1^5;  //定义蜂鸣器

int key;       //用来存放按下按键返回的键值

void delay(int i)
{
   while (i--);
}

void key_control ()  
{
	//用if..if..if..也可以,不过if..else if ..else if..的效率要比较高
	 if(k1==0) //判断按键是否有按下
	 {
	    delay(1000);//消除抖动 
		  if(k1==0) //再次判断是否有按下
			{
			  key = 1;//确定按键1已经被按下,返回一个值
			}
			while(!k1);
	 }
	
   else if(k2==0) 
	 {
	    delay(1000);
		  if(k2==0) 
			{
			key = 2;
			}
			while(!k2);
	 }
	 
	 else if(k3==0) 
	 {
	    delay(1000); 
		  if(k3==0) 
			{
				if((key!=3)||(key==5))
			     key = 3;
			  else if(key==3)
				   key = 5;
		  }
			while(!k3);
	 }
	 
	 if(k4==0) 
	 {
	    delay(1000); 
		  if(k4==0) 
			{
			key = 4;
			}
			while(!k4);
	 }
}

/* 上一次按下按键1,这次返回0;执行右移两位 */
void key_1()
{
	 delay(1000);
   led = _crol_(led,2); //右移两位
	 key=0; //为了确保每按下一次就只移动一位,所以这里执行一次右移函数就让这个key值不等于1;等下次再按的时候再进来
	 return;
}
/*     按下按键2,第一个灯亮,再按灭        */
void key_2()
{
    led = 0xfd;//第二个灯亮 1111 1101
	  key_control();
	  if (key!=2) return;
}
/*         第一次按下按按键3               */
void key_3_1()
{
    beep = ~beep;
	  delay(100);
	  key_control();
	  if (key!=3) return;
}
/*         第二次按下按按键3               */
void key_3_2()
{
    beep =~beep;
	  delay(5000);
	  key_control();
	  if (key!=5) return;
}
/*        按下按按键4,执行流水灯          */
void key_4()
{
	  int i,n;
	  for(i=0;i<7;i++)
    {
	    led=_crol_(led,1);
			//delay(5000);
			for(n=0;n<1000;n++)       //改进:上边直接用delay延迟的话,可能按下按键的时候,它还在延迟中
			   {                         //所以设置了每10ms就进行一次判断的程序,是功能切换更为灵敏
			      key_control();             
				    if(key!=4) return;
				    delay(10);
			   }
    }
}

void main()
{
	while(1)
	{
	//led = 1;//都暗,因为我的单片机的LED灯正极接VCC
	key_control();
	switch (key)
	{
		case 1 :
			      key_1();break;
		case 2 :      
			      key_2();break;
		case 3 :
			      key_3_1();break;
		case 4 :
			      key_4();break;
		case 5 :
			      key_3_2();break;
	}
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值