4、按键
4.1、键盘的基本原理
4.2、抖动的消除
抖动大概10ms~20ms
4.3、键盘的分类
4.4、矩阵键盘键位的识别
4.5、实现效果
代码
#include"reg51.h"
sbit key0=P1^0;
unsigned char s[]={
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};// 供阴0--9
unsigned char num=0,flag=0;
void delay(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i<n;i++)
{
for(j=0;j<120;j++);
}
}
// 按键操作
void key()
{
// if(key0==0)
// {
// num++;
// }
if(key0==0&&flag==0)
{
flag=1;
}
if(flag==1&&key0==1)
{
num++;
flag=0;
}
}
// 数码管操作,利用标志位消除抖动
void seg()
{
P2=s[num];
if(num==10)
{
num=0;
}
}
void main()
{
while(1)
{
key();
seg();
}
}
5、定时器
5.1、定时/计数器的方式和控制寄存器
6、中断
6.1、中断简介
6.2、中断允许控制
标识中带T
的表示与定时器有关
6.3、优先权控制
6.4、各中断服务程序的入口编号
6.5、外部中断
外部中断,低电平,下降沿触发。
6.6、电路图
6.7、代码
实现防抖动操作,按一下键盘num值加一次
#include"reg51.h"
sbit ex=P3^2;
unsigned char s[]={
0x3F,0x06,0x5B,0x4F,0x66,0x7D,0x07,0x7F,0x6F};//供阴极0-9
unsigned char num=0;
void initex()
{
IT0=1;//设置边沿触发
EX0=1;//打开外部中断
EA=1;//进行使能,开启总中断
ex=1;设置为下降沿
}
void display()
{
P2=s[num];
if(num===10)
{
num=0;
}
}
void main()
{
initex();
while(1)
{
display();
}
}
7、串行口通信
以下各位为0时表示可以接受,1表示接收完成
7.1、串行口 控制寄存器SCON
控制串行口的通信方式,串口的区别在于波特率不同,一般方式1用的比较多
7.2、电源控制寄存器PCON
7.3、方式1的工作方式
8、模拟89C51与上位机之间的通信
8.1、电路图
8.2、代码
#include"reg51.h"
unsigned char recdat=0,flag=0;
void initscon()
{
// 串行口控制寄存器
SCON=0x50;// 0101 0000
// 配置波特率,由定时器T1产生,参数为:(是1否0与外部中断有关系,选择定时器0还是计数器1的模式,模式0-13位,01-16位,10-8位)
TMOD=0x20;// 0010 0000
// 配置初值
TH1=256-3;
TL1=256-3;
ES=1;// 串口中断
EA=1;//开启总中断
TR1=1;//打开定时器1
}
// 发送数据
void senddat()
{
SBUF=recdat;
while(!T1);
T1=0;
}
void main()
{
// 初始化串口
initscon();
while(1)
{
//发送数据,通过中断发送
//接收数据,接收返回来的数据
if(flag==1)
{
senddat();
flag=0;
}
}
}
// 串口中断服务函数
// 0是外部中断,1是定时器0的中断,2是外部中断1,3是定时器中断1,4是串口中断
void scon_isr() interrupt 4
{
// SBUF表示缓存
recdat=SBUF;
}
9、LCD1602的应用
9.1、LCD1602概述
LCD1602是2*16字符型液晶显示模块
9.2、常用指令码
9.3、读写时序图
9.4、电路图一
AT89C51和LM016L
9.5、代码一
#include"reg51.h"
sbit RS=P3^0;
sbit RW=P3^1;
sbit E=P3^2;
unsigned char str[]={
"count:"};
void delay(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i<n;i++)
{
for(j=0;j<120;j++);
}
}
void writedat(unsigned char dat)
{
RS=1;
RW=0;
E=0;
P2=dat;
delay(5);
E=1;
E=0;
}
void writecom(unsigned char com)
{
RS=0;
RW=0;
E=0;
P2=com;
delay(5);
E=1;
E=0;
}
void initlcd()
{
// 写入命令
writecom(0x38);
writecom(0x0c);
writecom(0x06);
writecom(0x01);
}
// 显示函数
void display()
{
unsigned int i=0;
writecom(0x80);
delay(5);
// writedat('A');
// delay(5);
// writedat('B');
// delay(5);
while(str[i]!='\0')
{
writedat(str[i]);
delay(5);
i++;
}
writedat(0x36);
delay(5);
}
void main()
{
initlcd();
while(1)
{
display();
}
}
9.6、电路图二
9.7、代码二
#include"reg51.h"
sbit RS=P3^0;
sbit RW=P3^1;
sbit E=P3^2;
unsigned char count=0;
unsigned int hour=0,min=0,sec=0;
unsigned char str1[]={
"clock"};
// 数字转字符用
unsigned char str[]={
"0123456789"};
void delay(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i<n;i++)
{
for(j=0;j<120;j++);
}
}
void writedat(unsigned char dat)
{
RS=1;
RW=0;
E=0;
P2=dat;
delay(5);
E=1;
E=0;
}
void writecom(unsigned char com)
{
RS=0;
RW=0;
E=0;
P2=com;
delay(5);
E=1;
E=0;
}
void initlcd()
{
// 写入命令
writecom(0x38);
writecom(0x0c);
writecom(0x06);
writecom(0x01);
}
// 显示函数
void display()
{
unsigned char i=0;
unsigned char temp0=0,temp1=0,temp2=0,temp3=0,temp4=0,temp5=0;
temp0=hour/10;
temp1=hour%10;
temp2=min/10;
temp3=min%10;
temp4=sec/10;
temp5=sec%10;
writecom(0x80);
delay(5);
while(str1[i]!='\0')
{
writedat(str1[i]);
delay(5);
i++;
}
writecom(0x80+0x40+4);//控制在中间显示
writedat(str[temp0]);
delay(5);
writedat(str[temp1]);
delay(5);
writedat(':');
delay(5);
writedat(str[temp2]);
delay(5);
writedat(str[temp3]);
delay(5);
writedat(':');
delay(5);
writedat(str[temp4]);
delay(5);
writedat(str[temp5]);
delay(5);
}
/*定时器*/
void inittimer()
{
TMOD=0x01;// 选择定时器模式为16位
TH0=(65536-50000)/256;//50ms
TL0=(65536-50000)%256;
ET0=1;//中断
EA=1;//打开中断
TR0=1;//开启定时器0
}
void main()
{
initlcd();
inittimer();
while(1)
{
display();
}
}
//定时器中断函数
void timer0_isr() interrupt 1
{
TH0=(65536-50000)/256;//50ms
TL0=(65536-50000)%256;
count++;
if(count==20)//1s
{
sec=sec+1;
count=0;
}
if(sec==60)
{
min=min+1;
sec=0;
}
if(min==60)
{
hour=hour+1;
min=0;
}
if(hour==24)
{
hour=0;
}
}
9.8、实现电子时钟
10、点阵
10.1、电路图
10.2、代码
实现0
11、DA转换原理及简易波形发生器的实现
12、外部中断
12.1、电路图
12.2、代码
外部中断实现按键:添加外部中断,当按下按键,触发外部中断,低电平,小灯亮,再次按下,小灯电平值取反(或使用下降沿触发,当按下时灯亮,抬起时灯灭)
// 变量定义
uchar key_num; // 键值
// 函数声明
void Delay_function(uint x); //延时函数
void Key_function(void); //按键函数
void Monitor_function(void); // 监测函数
void Display_function(void); // 显示函数
void Manage_function(void); // 处理函数
void Int0_Init(void); // 外部中断0初始化函数
void Int1_Init(void); // 外部中断1初始化函数
// 主函数
void main()
{
Int0_Init(); //外部中断0初始化
Int1_Init(); //外部中断1初始化
while(1)
{
Key_function(void);//按键函数
Monitor_function(void);// 监测函数
Display_function(void);// 显示函数
Manage_function(void);// 处理函数
}
}
//延时函数
void Delay_function(uint x);
{
uint m,n;
for(m=x;m>0;m--)
for(n=110;n>0;n--);
}
//按键函数
void Key_function(void)
// 监测函数
void Monitor_function(void)
{
}
// 显示函数
void Display_function(void)
{
}
// 处理函数
void Manage_function(void)
{
}
// 外部中断0初始化函数
void Int0_Init(void)
{
EA=1;// 打开总中断
EX0=1;// 允许外部中断0触发中断
IT0=1;// 设置外部中断触发方式,方式为下降沿触发
}
// 外部中断1初始化函数
void Int1_Init(void)
{
EA=1;// 打开总中断
EX0=1;// 允许外部中断1触发中断
IT0=1;// 设置外部中断触发方式,方式为低电平触发
}
// 外部中断0中断服务函数
void Int0_IRQHandler(void) interrupt 0
{
LED = ~LED;
}
// 外部中断01中断服务函数
void Int1_IRQHandler(void) interrupt 2
{
LED = ~LED;
}
13、单片机串口
#include<reg51.h>
// 去系统默认的路径查找头文件,不推荐使用#include"reg51.h"
// 先去用户自定义的路径查找,再去系统默认的路径查找,推荐使用