文章目录
目录
前言
1.3.1 硬件清单列表
振动传感器模块,继电器模块,433M无线模块,反应出来的代码都是高低电平,跟以上学习按键点亮
LED 并没有区别 ,但是做出来有乐趣,好玩刺激!
器件连接图:
1.3.2 振动传感器控制灯
通过我们已经掌握的LED
来了解下振动传感器是怎么回事
- 如何知道是否发生振动
- 振动后的信号表现又是什么
- 振动传感器控制灯
#include "reg52.h"
#include "intrins.h"
sbit led1 = P3^7;//根据原理图(电路图),设备变量led1指向P3组IO口的第7口
sbit vibrate = P3^3;//Do接到了P3.3口
void Delay2000ms() //@11.0592MHz
{
unsigned char i, j, k;
// _nop_();
i = 15;
j = 2;
k = 235;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
//查询方式判断是否发生震动
while(1)
{
if(vibrate == 0)//模块说明告诉我们,震动的话,D0输出低电平
{
led1 = 0;//亮灯
Delay2000ms();
led1 = 1;
}
else
{
led1 = 1;//灭灯
}
}
}
1.3.3 继电器工作逻辑
其实就是电子开关,怎么开怎么关弄清楚就可以了
- 怎么控制“闭合”开关呢
- 怎么控制"断开"开关呢
通过继电器来控制电路,比如智能插座,比如 220V 的灯,比如我们项目不带开关的傻瓜式报警器 当设置继电器为低电平处罚时,STC89C52RC 的 IO 输出低电平,就会导致 COM 口和 NO 口闭合,也 就是完成报警器的串联电路,开始响 现在我们就可以来写程序,完成振动控制警报的功能
#include "reg52.h"
#include "intrins.h"
sbit vibrate = P3^3;//Do接到了P3.3口
sbit switcher = P1^1;
void Delay2000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 15;
j = 2;
k = 235;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
//查询方式判断是否发生震动
while(1)
{
if(vibrate == 0)//模块说明告诉我们,震动的话,D0输出低电平
{
//当发生震动适合,导通继电器,给继电器IN一个低电平
switcher = 0;
Delay2000ms();
switcher = 1;//高电平,继电器N0和COM不通
}
else
{
switcher = 1;
}
}
}
1.3.4 遥控发送接收433M
https://wenku.baidu.com/view/8fe8f444bed5b9f3f80f1c33.html
- 遥控按下后信号怎么被接收
- 接收后的信号表现又是什么
- 遥控控制LED
#include "reg52.h"
sbit D0_ON = P1^2;
sbit D1_OFF = P1^3;
sbit switcher = P1^1;
void main()
{
//查询方式哪个按键被按下
while(1)
{
if(D0_ON == 1)//收到遥控信号A,D0表现为高电平
{
//A被按下,我们导通继电器,给继电器IN一个低电平
switcher = 0;
}
if(D1_OFF == 1)//收到遥控信号C,D1表现为高电平
{
//B被按下,我们不导通继电器,给继电器IN一个高电平
switcher = 1;
}
}
}
1.3.5 项目开发
- 接线
- 开发流程代码
#include "reg52.h"
#include<intrins.h>
#define J_ON 1
#define J_OFF 0
sbit switcher = P1^0;
sbit D0_ON = P1^1;
sbit D1_OFF = P1^2;
sbit vibrate = P1^3;
void Delay2000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 15;
j = 2;
k = 235;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
int mark = J_OFF;
while(1)
{
//1. 如果a按键被按下,设定为开启警报模式
if(D0_ON == 1){
//长响,表示进入警报模式
switcher = 0;
Delay2000ms();
switcher = 1;
//设定警报模式标记
mark = J_ON ;
}
//2. 如果b按键被按按下,设定为关闭警报模式
if(D1_OFF == 1)
{
//短响,表示进入解除警报模式
switcher = 0;
Delay500ms();
switcher = 1;
//设定警报解除模式标记
mark = J_OFF ;
}
//3. 如果标记是在警报模式下
if(mark == J_ON)
{
//3.1 如果发生了震动
if(vibrate == 0)
{
//喇叭响,给继电器低电平,导通
switcher = 0;
}
else
{ //3.2 如果不发生震动
//喇叭不响,给继电器高电平,不导通
switcher = 1;
}
}
}
}
二. 定时器
1.4 简介
- C51中的定时器和计数器是同一个硬件电路支持的,通过寄存器配置不同,就可以将他当做定时器 或者计数器使用。
- 确切的说,定时器和计数器区别是致使他们背后的计数存储器加1的信号不同。当配置为定时器使 用时,每经过1个机器周期,计数存储器的值就加1。而当配置为计数器时,每来一个负跳变信号 (信号从P3.4 或者P3.5引脚输入),就加1,以此达到计数的目的。
- 标准C51有2个定时器/计数器:T0和T1。他们的使用方法一致。C52相比C51多了一个T2
1.4.1
概念解读
- 定时器和计数器,电路一样
- 定时或者计数的本质就是让单片机某个部件数数
- 当定时器用的时候,靠内部震荡电路数数
- 当计数器用的时候,数外面的信号,读取针脚的数据
1.5 定时器怎么定时
定时器的本质原理: 每经过一个机器周期,就加
1 :
寄存器
思考:
- 什么是晶振
晶振 ( 晶体震荡器 ) ,又称数字电路的 “ 心脏 ” ,是各种电子产品里面必不可少的频率元器件。数字电 路的所有工作都离不开时钟,晶振的好坏、晶振电路设计的好坏,会影响到整个系统的稳定性。
- 什么是时钟周期
时钟周期也称为 振荡周期 ,定义为 时钟频率 的 倒数 。时钟周期是计算机中最基本的、最小的 时间单 位 。在一个时钟周期内, CPU 仅完成一个最基本的动作。时钟周期是一个时间的量。更小的时钟周 期就意味着更高的工作频率
- 什么是机器周期
机器周期也称为 CPU 周期。在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶 段(如取指、译码、执行等),每一阶段完成一个基本操作。完成一个基本操作所需要的时间称为 机器周期。一般情况下,一个机器周期由若干个时钟周期组成
- 加1经过了多少时间
当晶振频率是 11.0592MHz 的时候,等于 11059.2KHz = 11059200Hz机器周期 = 12 x 时钟周期 =12 x (1/ 时钟频率 ) 秒 = 12 / 时钟频率 秒 = 12 / 11059200 秒 = 12 000 000 / 11059200 微秒 = 1.085 微秒
1.6 定时器编程
相关寄存器:
- 在哪里加1,最大计数时间,也就是爆表了能计算多长
在 TH0/1 和 TL0/1 寄存器中加 1 ,默认是从 0 开始数数,最多能数 65536 下,累计计时 71ms
- 如何算出10ms定时器的初值
就不让他从0 开始数数, 10ms 需要数 9216 下,你让他从 65536-9126=56320 ( 16 进制表示为 0xDC00)开始数数这样TL0=0x00; TH0=0xDC
- 关于TCON
- 怎么知道爆表
TCON 寄存器的 bit5 ( TF0 )能表示爆表:当爆表的时候,硬件会修改 bit5(TF0) 位上面的数据,改成 1(置 1 ),如果不用中断,我们代码清零
- 怎么开始计时
TCON 寄存器的 bit4 ,通过编程让这个位为 1 的时候,开始计时,相当于按下了闹钟
- 定时器使用是有很多种模式的
定时器模式寄存器:TMOD 来选择定时器模式,选择工作方式 1 , TMOD 的 bit0 bit1 配置成 0 1 : 16 的定时器功能
- 四个二进制数表示一位的16进制数
- 8421法进制的转换(方便人类来看,对计算机底层来说,不关心进制010101010)
- 配寄存器推荐用按位操作,清零的时候,对应的需要清零的位与上0,不需要清零的位与上1
- 置1的时候,需要置1的位置或1,不需要置一的位置或0
/*通过定时器0,控制LED亮一秒,灭一秒,晶振11059200Hz*/
#include "reg52.h"
sbit led = P3^6;
void main()
{
int cnt = 0;
led = 1;
//1. 配置定时器0工作模式位16位计时
TMOD = 0x01;
1.4 定时器中断方式控制中断寄存器
CPU能响应定时器0中断的条件:需要配置IE寄存器的bit1: ET0 bit7:EA
1. ET0中断允许要置一 ET0 = 1
2. EA总中断要置一 EA = 1
硬件内部设计逻辑如下图:
//2. 给初值,定一个10ms出来
TL0=0x00;
TH0=0xDC;
//3. 开始计时
TR0 = 1;
TF0 = 0;
while(1)
{
if(TF0 == 1)//当爆表的时候,硬件会修改bit5(TF0)位上面的数据,改成1
{
TF0 = 0;//不用中断,必须软件清零
cnt++; //统计爆表的次数
//重新给初值
TL0=0x00;
TH0=0xDC;
if(cnt == 100)
{
//爆表100次,经过了1s
cnt = 0; //当100次表示1s,重新让cnt从0开始,计算下一次的1s
led = !led;//每经过1s,翻转led的状态
}
}
}
}
1.7 定时器中断方式控制
中断寄存器
CPU能响应定时器0中断的条件:需要配置IE寄存器的bit1: ET0 bit7:EA
1. ET0中断允许要置一 ET0 = 12. EA总中断要置一 EA = 1
硬件内部设计逻辑如下图:
#include "reg52.h"
sbit led = P3^6;
sbit led1 = P3^7;
int cnt = 0;
void Time0Init()
{
//1. 配置定时器0工作模式位16位计时
TMOD = 0x01;
//2. 给初值,定一个10ms出来
TL0=0x00;
TH0=0xDC;
//3. 开始计时,定时器"数数"
TR0 = 1;
TF0 = 0;
//4. 打开定时器0中断
ET0 = 1;
//5. 打开总中断EA
EA = 1;
}
void Delay300ms() //@11.0592MHz 软件延时,CPU“数数”
{
unsigned char i, j, k;
i = 3;
j = 26;
k = 223;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
led = 1;
Time0Init();
while(1)
{
led1 = 0;
Delay300ms();
led1 = 1;
Delay300ms();
}
}
void Time0Handler() interrupt 1
{
cnt++; //统计爆表的次数
//重新给初值
TL0=0x00;
TH0=0xDC;
if(cnt == 100)
{
//爆表100次,经过了1s
cnt = 0; //当100次表示1s,重新让cnt从0开始,计算下一次的1s
led = !led;//每经过1s,翻转led的状态
}
}