7.17 51单片机学习

文章介绍了蜂鸣器的工作原理和驱动方式,包括无源和有源蜂鸣器,以及如何通过C语言编程实现蜂鸣器的控制,如播放音符。同时,文章讨论了红外遥控的原理,特别是NEC编码格式,以及如何处理接收信号。此外,还涉及到了直流电机的控制方法,利用定时器进行速度调节。
摘要由CSDN通过智能技术生成

一.蜂鸣器

蜂鸣器是一种将电信号转换为声音信号的器件,按驱动方式可分为有源蜂鸣器和无源蜂鸣器

驱动电路

 

介绍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不亮,接收头输出高电平

发送低电平:红外LED38KHz频率闪烁发光,接收头输出低电平

发送高电平:红外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
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值