51单片机-蜂鸣器、数码管
蜂鸣器
蜂鸣器:是一种一体化结构的电子讯响器,采用直流电压供电,分为 压电式
蜂鸣器和 电磁式
蜂鸣器(无源和有源), 51
开发板一般是 压电式
的。
根据网上查的资料可以知道无源和有源的区别:
⑴有无震荡源
无源这里的“源”不是指电源,而是指 震荡源
。也就是说,有源蜂鸣器内部带震荡源,所以只要一通电就会叫。而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。
⑵价格不同
有源蜂鸣器往往比无源蜂鸣器 贵
,就是因为里面多个震荡电路。
怎么区分? 有绿色电路板的一种是无源蜂鸣器,没有电路板而用黑胶封闭的一种是有源蜂鸣器。
无源蜂鸣器通过 脉冲频率
才能发声。
代码如下:
# include "reg52.h"
# include "intrins.h"
typedef unsigned int u16;
sbit BEEP=P2^5;
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
void main()
{
u16 i=2000;
while(1)
{
while(i--)
{
BEEP=!BEEP;
delay_10us(100);
}
i=0;//赋0就不会再响了
BEEP=1;//这赋0或者1都行
}
while(1);
}
蜂鸣器模拟枪声
main.c
/*********************************************************************************
* 【函数功能】: 蜂鸣器测试-模拟枪声
* 【使用说明】: 短接蜂鸣器J5跳帽,按下K1按键
**********************************************************************************/
# include <reg51.h>
# include <intrins.h>
# define uchar unsigned char
# define uint unsigned int
sbit BEEP= P2^5;
sbit K1 = P3^1;
uchar H_count,L_count;
/*********************************************************/
void main()
{
P0=0;
BEEP=1;
TMOD=0x01;
TH0=0xff;
TL0=0xa0;
H_count=0xff;
L_count=0xa0;
EA=1;
ET0=1;
while(1)
{
while(K1);
TR0=1;
}
}
/*********************************************************
Time0中断函数
**********************************************************/
void Time0(void) interrupt 1 using 0
{
BEEP=~BEEP;
if( L_count!=0x00 )
{
L_count--;
TH0=H_count;
TL0=L_count;
return;
}else H_count--;
if( H_count!=0xfc )
{
L_count--;
TH0=H_count;
TL0=L_count;
return;
}
else
{
H_count=0xff;
L_count=0xa0;
TH0=H_count;
TL0=L_count;
BEEP=1;
TR0=0;
}
}
门铃
main.c
/*
实验接线:
BEEP-->P15
独立按键模块-->单片机管脚
K1-->P31
实验现象:
按下K1键,蜂鸣器发出”叮咚”门铃声
*/
# include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
sbit beep=P2^5;
sbit k1=P3^1;
u8 ding,dong,flag,stop;
u16 n;
void delay(u16 i)
{
while(i--);
}
void time0init() //定时器0初始化
{
TMOD=0X01; //定时器0 方式1
TH0=0Xff;
TL0=0X06; //定时250us
// TR0=1;
EA=1;
ET0=1;
}
void biaohaoinit() //各个标号初始化
{
ding=0; //叮声音 计数标志
dong=0; //咚声音 计数标志
n=0; //定时0.5s标志
flag=0;
stop=0; //结束标志
}
void main()
{
time0init();
biaohaoinit();
while(1)
{
if(k1==0) //判断按键是否按下
{
delay(1000); //消抖
if(k1==0)
{
TR0=1; //打开定时器0
while(!stop);
}
}
}
}
void time0() interrupt 1
{
n++;
TH0=0Xff;
TL0=0X06; //250us
if(n==2000) //定时0.5s 叮响0.5秒,咚响0.5秒
{
n=0;
if(flag==0)
{
flag=~flag;
}
else
{
flag=0;
stop=1;
TR0=0; //关闭定时器0
}
}
if(flag==0)
{ //通过改变定时计数时间可以改变门铃的声音
ding++; //叮
if(ding==1)
{
ding=0;
beep=~beep;
}
}
else
{
dong++;
if(dong==2) //咚
{
dong=0;
beep=~beep;
}
}
}
按k1响k2停
main.c
/*
实验说明:
此程序兼容了有源和无源蜂鸣器
实验现象:
按下K1键,蜂鸣器发出声音,按下K2键,蜂鸣器停止发声
*/
# include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit k1=P3^1;
sbit k2=P3^0;
sbit beep=P2^5;
u8 start=0;
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
void sound()
{
u8 i=100;
while(i--)
{
beep=~beep;
delay(100);
}
}
void keypros()
{
if(k1==0) //开始
{
delay(1000);
if(k1==0)
{
start=1;
}
while(!k1);
}
if(k2==0) //停止
{
delay(1000);
if(k2==0)
{
start=0;
}
while(!k2);
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
while(1)
{
keypros();
if(start==1)
{
sound();
}
else
{
beep=1;
}
}
}
数码管
动态数码管
动态数码管:静态和动态数码管本质 区别是:静态数码管中只要给了段码数码管就一定工作( 显示只取决于段码端),动态数码管中段码端给了段码值后还需要 COM端(即公共端)配合才能点亮数码管。
快速切换工作的数码管,动态数码管利用了人眼的视觉暂留,则人看到的是所有的数码管都在亮(其实亮度是比静态驱动低的)。肉眼看到的范围是 20-50ms
要学会看芯片手册!!!!
静态数码管
单个数码管循环输出0-9代码:
# include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
# define SMG_A_F_PORT P0//宏定义数码管P0端口
u8 gsmg_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//定义数组存放0-F段码,gsmg中g代表全局变量
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
void main()
{
u8 i=0;
u8 sz=sizeof(gsmg_code)/sizeof(gsmg_code[0]);//数组元素个数
while(1)
{
for(i=0;i<sz-6;i++)//只要0-9所以把A-F的减去
{
SMG_A_F_PORT=gsmg_code[i];
delay_10us(50000);
}
}
while(1);
}
实验现象
3-8译码器
-
头上有一横表示在低电平时有效
-
真值:L:表示低电平0 H:表示高电平1 X:表示无论是高电平还是低电平都不影响真值
代码如下:
# include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
# define SMG_A0_F_PORT P0//宏定义数码管P0端口
sbit A0=P2^2;
sbit A1=P2^3;
sbit A2=P2^4;
u8 gsmg_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//定义数组存放0-F段码,gsmg中g代表全局变量
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
void main()
{
u8 i=0;
while(1)
{
for(i=0;i<8;i++)
{
switch(i)
{
case 0:A0=1;A1=1;A2=1;break;//Y7//板子从左边数第一个数码管,下面以此类推
case 1:A0=0;A1=1;A2=1;break;//Y6
case 2:A0=1;A1=0;A2=1;break;//Y5
case 3:A0=0;A1=0;A2=1;break;//Y4
case 4:A0=1;A1=1;A2=0;break;//Y3
case 5:A0=0;A1=1;A2=0;break;//Y2
case 6:A0=1;A1=0;A2=0;break;//Y1
case 7:A0=0;A1=0;A2=0;break;//Y0
}
SMG_A0_F_PORT=gsmg_code[i];
delay_10us(100);//延时1毫秒左右
SMG_A0_F_PORT=0x00;//消影
}
}
while(1);
}
没消影:
消影后:
例子
main.c
/*
实验说明:
实验现象:
按K4键进入数字设置,按K1和K3键对闪烁的数字进行加和减,按K2键进行数码管移位设置
再次按下K4键退出设置。
*/
# include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3; //定义按键端口
# define KEY1 1
# define KEY2 2
# define KEY3 3
# define KEY4 4
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
u8 DisplayData[8];
char datnum1=0,datnum2=0,datnum3=0,datnum4=0;
u8 setflag=0;
u8 wei_change=0;
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : Timer0Init
* 函数功能 : 定时器0初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0Init()
{
TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0Xd8; //给定时器赋初值,定时10ms
TL0=0Xf0;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
//TR0=1;//打开定时器
}
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 数码管动态扫描函数,循环扫描8个数码管显示
*******************************************************************************/
void DigDisplay()
{
u8 i;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=1;LSB=1;LSC=1; break;//显示第7位
case(1):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(2):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(3):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(4):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(5):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(6):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(7):
LSA=0;LSB=0;LSC=0; break;//显示第0位
}
P0=DisplayData[i];//发送段码
delay(100); //间隔一段时间扫描
P0=0x00;//消隐
}
}
//mode=0 单次 1:连续
u8 KeyScan(u8 mode)
{
static u8 keyen=1;
if(mode==1)
{
keyen=1;
}
if(keyen==1&&(k1==0||k2==0||k3==0||k4==0))
{
delay(1000); //消抖处理
keyen=0;
if(k1==0)return KEY1;
else if(k2==0)return KEY2;
else if(k3==0)return KEY3;
else if(k4==0)return KEY4;
}
else if(k1==1&&k2==1&&k3==1&&k4==1)
{
keyen=1;
}
return 0;
}
void datapros()
{
u8 key;
key=KeyScan(0);
if(key==KEY4) //设置
{
setflag++;
TR0=1; //开启定时器
if(setflag==2)
{
TR0=0; //关闭定时器
setflag=0;
}
}
if(setflag==0) //默认/退出设置显示
{
DisplayData[0]=smgduan[datnum4];
DisplayData[1]=smgduan[datnum3];
DisplayData[2]=smgduan[datnum2];
DisplayData[3]=smgduan[datnum1];
}
else //进入设置 数码管选中闪烁
{
if(key==KEY2) //数据位数移动变化
{
wei_change++;
if(wei_change>3)wei_change=0;
DisplayData[0]=smgduan[datnum4];
DisplayData[1]=smgduan[datnum3];
DisplayData[2]=smgduan[datnum2];
DisplayData[3]=smgduan[datnum1];
}
else if(key==KEY1) //数据加
{
switch(wei_change)
{
case 0: datnum1++;
if(datnum1>9)datnum1=0;
break;
case 1: datnum2++;
if(datnum2>9)datnum2=0;
break;
case 2: datnum3++;
if(datnum3>9)datnum3=0;
break;
case 3: datnum4++;
if(datnum4>9)datnum4=0;
break;
}
}
else if(key==KEY3) //数据减
{
switch(wei_change)
{
case 0: datnum1--;
if(datnum1<=0)datnum1=9;
break;
case 1: datnum2--;
if(datnum2<=0)datnum2=9;
break;
case 2: datnum3--;
if(datnum3<=0)datnum3=9;
break;
case 3: datnum4--;
if(datnum4<=0)datnum4=9;
break;
}
}
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
Timer0Init();
while(1)
{
datapros();
DigDisplay();
}
}
/*******************************************************************************
* 函 数 名 : void Timer0() interrupt 1
* 函数功能 : 定时器0中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0() interrupt 1
{
static u8 i;
TH0=0Xd8; //给定时器赋初值,定时10ms
TL0=0Xf0;
i++;
if(i==50) //500ms
{
switch(wei_change)
{
case 0: DisplayData[3]=0x00;break;
case 1: DisplayData[2]=0x00;break;
case 2: DisplayData[1]=0x00;break;
case 3: DisplayData[0]=0x00;break;
}
}
if(i==100) //1s
{
i=0;
switch(wei_change)
{
case 0: DisplayData[3]=smgduan[datnum1];break;
case 1: DisplayData[2]=smgduan[datnum2];break;
case 2: DisplayData[1]=smgduan[datnum3];break;
case 3: DisplayData[0]=smgduan[datnum4];break;
}
}
}