一.蜂鸣器
蜂鸣器是一种将电信号转换为声音信号的器件,按驱动方式可分为有源蜂鸣器和无源蜂鸣器
驱动电路
介绍C1-C2升高8度。往右升高,往左降低:相邻半音黑白,1对应中央C1,i表示升即C2部分,降低8度下面加一个点,降低2个8度,下面加两个点(白键);黑升音#,降音b
-表示时长,665-表示5占两个时长
音符
蜂鸣器提示音
运用到延迟,数码管,按键模块
#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Nixie.h"
#include "Buzzer.h"
unsigned char KeyNum;
void main()
{
Nixie(1,0); //开始显示0
while(1)
{
KeyNum=Key();
if(KeyNum) //按键检查
{
Buzzer_Time(100);//蜂鸣器设置
Nixie(1,KeyNum);
}
}
}
蜂鸣器模块化代码
#include <REGX52.H>
#include <INTRINS.H>
//蜂鸣器端口:
sbit Buzzer=P1^5;
/**
* @brief 蜂鸣器私有延时函数,延时500us
* @param 无
* @retval 无
*/
void Buzzer_Delay500us() //@12.000MHz
{
unsigned char i;
_nop_();
i = 247;
while (--i);
}
/**
* @brief 蜂鸣器发声
* @param ms 发声的时长,范围:0~32767
* @retval 无
*/
void Buzzer_Time(unsigned int ms)
{
unsigned int i;
for(i=0;i<ms*2;i++)
{
Buzzer=!Buzzer;
Buzzer_Delay500us();
}
}
播放音乐
1)运用到定时器模块,延时模块
2)中断
#include "Timer0.h"
//蜂鸣器端口定义
sbit Buzzer=P1^5;
void main()
{
Timer0Init();
while(1)
{
}
}
void Timer0_Routine() interrupt 1
{
TLO=0x18;
THO=0xFC;
Buzzer=!Buzzer;
}
3)中断TLO\THO计数来一个脉冲就计数,时钟一个为结束标志位,决定中断时间的,时间一到就中断了:20行代码,半个周期翻转一次
#include "Timer0.h"
//蜂鸣器端口定义
sbit Buzzer=P1^5;
void main()
{
Timer0Init();
while(1)
{
}
}
void Timer0_Routine() interrupt 1
{
if(FreqTable[FreqSelect]) //如果不是休止符
{
/*取对应频率值的重装载值到定时器*/
TL0 = FreqTable[FreqSelect]%256; //设置定时初值
TH0 = FreqTable[FreqSelect]/256; //设置定时初值
Buzzer=!Buzzer; //翻转蜂鸣器IO口
}
}
4)64580重装值,到时间重新中断计数
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
//蜂鸣器端口定义
sbit Buzzer=P1^5;
//索引与频率对照表
unsigned int FreqTable[]={
0,
63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,
64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,
65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,
};
void main()
{
Timer0Init();
while(1)
{
}
}
5)显示第一个低音
void main()
{
Timer0Init();
while(1)
{
}
}
void Timer0_Routine() interrupt 1
{
if(FreqTable[FreqSelect]) //如果不是休止符
{
/*取对应频率值的重装载值到定时器*/
TL0 = FreqTable[FreqSelect]%256; //设置定时初值
TH0 = FreqTable[FreqSelect]/256; //设置定时初值
Buzzer=!Buzzer; //翻转蜂鸣器IO口
}
}
void main()
{
Timer0Init();
while(1)
{
if(Music[MusicSelect]!=0xFF) //如果不是停止标志位
{
FreqSelect=Music[MusicSelect]; //选择音符对应的频率
MusicSelect++;
Delay(SPEED/4*Music[MusicSelect]); //选择音符对应的时值
MusicSelect++;
TR0=0;
Delay(5); //音符间短暂停顿
TR0=1;
}
else //如果是停止标志位
{
TR0=0;
while(1);
}
}
}
二.红外遥控(外部中断)
左边的发射电路,当IN给高电平时,电路不导通,红外LED不亮,接收头输出高电平。而当IN给低电平时,电路导通红外LED以38KHz频率闪烁发光,接收头输出低电平。中间那个也是类似的,只不过需要自己去模拟38KHZ的发射信号。
接收电路,将数据传入红外接收器,经过滤波以及各种解码操作,他就会通过OUT口输出,我们对输出的信号进行分析就行。
•空闲状态:红外LED不亮,接收头输出高电平
•发送低电平:红外LED以38KHz频率闪烁发光,接收头输出低电平
•发送高电平:红外LED不亮,接收头输出高电平
NEC编码
红外NEC编码与我们之前学的东西有点不一样,首先,他有一个起始信号以及重复信号,而且都是通过低电平切换到高电平来实现的,只是两者的持续时间不一样。0、1信号也是不一样的,也是通过低电平切换到高电平来实现的,同样是时间不同,与我们之前接触到的都是不一样的,具体如图所示。 然后数据格式也是不一样的,一共是32位,前8位是地址码,后8位是地址码的反码,再后八位是命令码,跟在后面的8位也是命令码的反码,用来校验数据。
红外调控
// Timer0.c
#include <REGX52.H>
/**
* @brief 定时器0初始化
* @param 无
* @retval 无
*/
void Timer0_Init(void)
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0; //设置定时初值
TH0 = 0; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 0; //定时器0不计时
}
/**
* @brief 定时器0设置计数器值
* @param Value,要设置的计数器值,范围:0~65535
* @retval 无
*/
void Timer0_SetCounter(unsigned int Value)
{
TH0=Value/256;
TL0=Value%256;
}
/**
* @brief 定时器0获取计数器值
* @param 无
* @retval 计数器值,范围:0~65535
*/
unsigned int Timer0_GetCounter(void)
{
return (TH0<<8)|TL0;
}
/**
* @brief 定时器0启动停止控制
* @param Flag 启动停止标志,1为启动,0为停止
* @retval 无
*/
void Timer0_Run(unsigned char Flag)
{
TR0=Flag;
}
// Int0.c
#include <REGX52.H>
/**
* @brief 外部中断0初始化
* @param 无
* @retval 无
*/
void Int0_Init(void)
{
IT0=1;
IE0=0;
EX0=1;
EA=1;
PX0=1;
}
/*外部中断0中断函数模板
void Int0_Routine(void) interrupt 0
{
}
*/
直流电机
// Motor.c
#include <REGX52.H>
#include "Timer1.h"
//引脚定义
sbit Motor=P1^0;
unsigned char Counter,Compare;
/**
* @brief 电机初始化
* @param 无
* @retval 无
*/
void Motor_Init(void)
{
Timer1_Init();
}
/**
* @brief 电机设置速度
* @param Speed 要设置的速度,范围0~100
* @retval 无
*/
void Motor_SetSpeed(unsigned char Speed)
{
Compare=Speed;
}
//定时器1中断函数
void Timer1_Routine() interrupt 3
{
TL1 = 0x9C; //设置定时初值
TH1 = 0xFF; //设置定时初值
Counter++;
Counter%=90; //计数值变化范围限制在0~99
if(Counter<Compare) //计数值小于比较值
{
Motor=1; //输出1
}
else //计数值大于比较值
{
Motor=0; //输出0
}
}