1.关于 单片机 AT89C51 与单片机 AT89C52 的区别
1、内部FLASH容量不同
AT89C51和AT89C52是单片机的两种型号,AT89C52是AT89C51的各个方面的升级版,AT89C51 有 4K 字节的内部FLASH PERAM,而AT89C52 的内部FLASH PERAM 相比AT89C51 增加了1倍,其容量达到8K。
2、随机存取数据存储器(RAM)不同
AT89C51 有128 字节的内部 RAM,AT89C52 的内部 RAM 扩展为 256 字节。
3、中断源数量不同
AT89C51有6个中断源,AT89C52 除了具备 AT89C51 的定时器/计数器 T0 和定时器/计数器 T1,还额外增加了一个定时器/计数器 T2。
4、定时器数量不同
AT89C51C51有T0、T1两个16位定时器,而AT89C52除了有AT89C51的T0、T1之外,还增加了T2这一16位定时器。
2.关于 单片机 LED 模块的编写
1.需要知道的知识: 首先 LED 灯 是低电平点亮 !
2.看实物单片机的 原理图: (主要是 模块对应的引脚 )
3.编写代码
LED.h 文件
#include
#define uchar unsigned char
#define uint unsigned int
void LED_water_2();//流水灯 //第二种方式的流水灯 从右边先亮
void LED_water();//流水灯 从左边先亮
void delay_s(uint a);// 计时 a秒
void delay(void); //标准的一秒,利用for 循环结构
void close_LED(int i);// 关闭 第 i 个灯
void play_LED(int i);// 开启 第 i 个灯
LED.c
#include "led.h"
sbit led1=P2^0;//LED1 的引脚
sbit led2=P2^1;//LED2 的引脚
sbit led3=P2^2;//LED3 的引脚
sbit led4=P2^3;//LED4 的引脚
sbit led5=P2^4;//LED5 的引脚
sbit led6=P2^5;//LED6 的引脚
sbit led7=P2^6;//LED7 的引脚
sbit led8=P2^7;//LED8 的引脚
void delay(void) //标准的一秒,利用for 循环结构
{
uint i,j;
for(i=124;i>0;i--)
{
for(j=1000;j>0;j--)
{
}
}
}
void delay_s(uint a)// 计时 a秒
{
int i;
for(i=1;i<=a;i++)
{
delay();
}
}
void LED_water()//流水灯 从左边先亮
{
led1=0;
delay();
led2=0;
delay();
led3=0;
delay();
led4=0;
delay();
led5=0;
delay();
led6=0;
delay();
led7=0;
delay();
led8=0;
delay();
led1=1;
led2=1;
led3=1;
led4=1;
led5=1;
led6=1;
led7=1;
led8=1;
}
// 这里有一个知识点
// 引脚的位置 问题 (顺序) 大的在前面
// P2^7 P2^6 P2^5 P2^4 P2^3 P2^2 P2^1 P2^0 === P2
void LED_water_2()//流水灯 //第二种方式的流水灯 从右边先亮
{
//0xff 右移 一位
uint i;
P2=0xff;
for(i=0;i<8;i++)
{
P2=P2>>1;//右移一位
delay();//延时函数
}
P2=0xff;
}
void play_LED(int i)
{
if(i==1)
{
led1=0;
}
if(i==2)
{
led2=0;
}
if(i==3)
{
led3=0;
}
if(i==4)
{
led4=0;
}
if(i==5)
{
led5=0;
}
if(i==6)
{
led6=0;
}
if(i==7)
{
led7=0;
}
if(i==8)
{
led8=0;
}
}
void close_LED(int i)
{
if(i==1)
{
led1=1;
}
if(i==2)
{
led2=1;
}
if(i==3)
{
led3=1;
}
if(i==4)
{
led4=1;
}
if(i==5)
{
led5=1;
}
if(i==6)
{
led6=1;
}
if(i==7)
{
led7=1;
}
if(i==8)
{
led8=1;
}
}
4.编译代码,下载到芯片里面
3.单片机 的 蜂鸣器 (我的单片机的蜂鸣器是 无源蜂鸣器 )
1.有源蜂鸣器 与无源蜂鸣器的 区别
蜂鸣器的驱动方式的区别
无源蜂鸣器是没有正负之分的,类似于喇叭,只要在两个腿上加载不同的频率的电信号就可以实现发声,根据不同的频率所发出的声音也是不一样的。所以如果用直流信号无法令其鸣叫。无源蜂鸣器
需要1.5~2.5kHz
(与蜂鸣器种类有关)的音频信号,这个音频信号即一个高低变化频率为1.5-2.5kHz的方波
。实际上频率小于1.5kHz也是有声音的,只是不那么准了,可能是嘟嘟
声。
有源蜂鸣器是有正负之分的,只需要在两个腿上加上电压信号就会发声,发出的声音音调单一、频率固定。
有源蜂鸣器比无源蜂鸣器内部多了振荡结构,所以有源蜂鸣器在价格上稍微贵一点。
2.单片机 的BEEP 模块 原理图
板子上面带有ULN2003D芯片 使它来驱动蜂鸣器
P1^5输出高 ULN2003D 输出低 所以他们得逻辑关系是相反得!
3.代码编写
BEEP.h
#include
void play_BEEP();//打开蜂鸣器
void Delay10us(unsigned char i); //@11.0592MHz 延迟大约是10微秒
void play_beep_s(int x);//打开蜂鸣器 x 代表几秒
BEEP.c
#include "BEEP.h"
sbit BEEP = P1^5; // 把P2得第5个针脚定义成BEEP
void Delay10us(unsigned char i) //@11.0592MHz 延迟大约是10微秒
{
i = i*2;
while (--i);
}
void play_BEEP()//打开蜂鸣器
{
BEEP = 0; // 低电平 蜂鸣器就是高电平
Delay10us(100); //持续1000微秒也就是1毫秒
BEEP = 1;
Delay10us(100);
}
void play_beep_s(int x)//打开蜂鸣器 x 代表几秒
{
int a=x*1000; //1 ms *1000 * x = x 秒
while(a--)
{
//形成一个方波的信号 所以是 1 和 0 的 信号
BEEP = 0; // 低电平 蜂鸣器就是高电平
Delay10us(100); //持续1000微秒也就是1毫秒
BEEP = 1;
Delay10us(100);
}
}
4.代码编译, 下载到芯片
4.单片机 的独立按键 (k1 -- k4)
1.首先按键原理 按键一端 连接 芯片的引脚 一端连接 GED (接地 ),本来的时候引脚是输出高电平的 , 当我们的按键 按下去的时候 这时候芯片的这引脚 接地了, 这时候这个引脚是为低电平 , 但是当我们 按下的按键 回位之后,按键还是会变为 输出高电平 , 但是这个引脚会有 小段时间内 为低电平!
2.原理图:
3.编写代码:
key.h
#include
#include "led.h"
#include "BEEP.h"
void key_panding();
key.c
#include "key.h"
sbit key1=P3^1;//独立按键 key1
sbit key2=P3^0;//独立按键 key2
sbit key3=P3^2;//独立按键 key3
sbit key4=P3^3;//独立按键 key4
void key_panding()
{
if(key1==0)//按下去了 引脚为 0
{
while(key1==0);//消抖
LED_water(); //流水灯
}
if(key2==0) //按下去了 引脚为 0
{
while(key2==0);//消抖
play_beep_s(2);//蜂鸣器响 2 秒
}
if(key3==0) //按下去了 引脚为 0
{
while(key3==0);//消抖
play_LED(1); //led1 亮
}
if(key4==0) //按下去了 引脚为 0
{
while(key4==0);//消抖
close_LED(1); //led1 灭
}
}
4.代码编译,下载到芯片
5.单片机的 矩形按键模块
1.矩形按键的使用方法:
没有按键按下时,X0~X3是低电平,Y0~Y3是高电平。
某一个按键按下,设置其所在的行低电平,列就会变为低电平。
1、判断有无键被按下
方法是:将全部行线X0~X3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。
2、确定哪个键按下
方法是:在确认有键按下后,依次将行线置为低电平,即在置某根行线为低电平时,其他线为高电平(其实就是屏蔽其他行的按键状态,只有当前检测行的按键状态有效);在确定某根行线位置为低电平后,再逐行检测各列线的电平状态,若某列为低(说明当前检测行有按键按下),则该列线与置为低电平的行线交叉处的按钮就是闭合的按键。
2.原理图:
3.代码编写
key16.h
#include
int key_16_pandaun();//判断那个按键按下了
key16.c
#include"key16.h"
#include "key.h"
0
/*
7 key1 key2 key3 key4
6 key5 key6 key7 key8
5 key9 key10 key11 key12
4 key13 key14 key15 key16
3
2
1
0
*/
//假如引脚接地 会变成 0 但是引脚自己为0 的时候 和接地一样的
int key_16_pandaun()//返回 矩阵按键模块 那个按键 被按
{
int num=0;
//先列
P1=0x0f;//后面 3 2 1 0 的二进制位 为 0
if(P1!=0x0f)//看按键是否按下
{
Delay10us(100000);//消抖 10ms
if(P1!=0x0f)
{
if(P1==0x07)
{
//key 1 对应着 3 7
num+=1;
}
else if(P1==0x0b)
{
//k2 对应着2 7
num+=2;
}
else if(P1==0x0d)
{
//k2 对应着2 7
num+=3;
}
else if(P1==0x0e)
{
//k2 对应着2 7
num+=4;
}
}
}
//在行
P1=0xf0;
if(P1!=0xf0)//看按键是否按下
{
Delay10us(100000);//消抖 10ms
if(P1!=0xf0)
{
if(P1==0x70)
{
//key 1 对应着 3 7
num+=0;
}
else if(P1==0xb0)
{
//k2 对应着2 7
num+=4;
}
else if(P1==0xd0)
{
//k2 对应着2 7
num+=8;
}
else if(P1==0xe0)
{
//k2 对应着2 7
num+=12;
}
}
}
P1=0xff;
return num;
}
main.c
#include
#include
#include "led.h"
#include "BEEP.h"
#include "key.h"
#include "key16.h"
void main()
{
int a;
while(1)
{
a=0;
a=key_16_pandaun();
if(a==1)
{
play_LED(1);
}
else if(a==2)
{
play_LED(2);
}
else if(a==3)
{
play_LED(3);
}
else if(a==4)
{
play_LED(4);
}
else if(a==5)
{
play_LED(5);
}
else if(a==6)
{
play_LED(6);
}
else if(a==7)
{
play_LED(7);
}
else if(a==8)
{
play_LED(8);
}
else if(a==9)
{
close_LED(1);
}
else if(a==10)
{
close_LED(2);
}
else if(a==11)
{
close_LED(3);
}
else if(a==12)
{
close_LED(4);
}
else if(a==13)
{
close_LED(5);
}
else if(a==14)
{
close_LED(6);
}
else if(a==15)
{
close_LED(7);
}
else if(a==16)
{
close_LED(8);
}
}
}
6.编写程序的时候添加头文件 的方式 (是添加头文件的路径 ,离头文件最近 的文件夹)
7.程序添加文件的方式