校园短号号码的接收与显示电路的软硬件设计

*觉得有用有帮助的评论下,谢谢~

校园短号号码的接收与显示电路的软硬件设计

  • 这次的实验是我的课程设计

课题的内容:话机通过解码电路把按键值输入到单片机中,在通过单片机显示在数码管上,要求话机按下时,数码管显示该数值,按下一次时,数码管之前的数值向前移,同时显示当前的按键值,相当于模拟拨号过程,本次实验,模拟6位号码即可

硬件电路部分

解码电路

解码电路就是把话机按下按键的号码以二进制的形式传给单片机

  • MT8870芯片

  • 输入与解码表

  • 解码电路原理图

原理图中红点的地方焊接时要放置排针,以便检测和连线接电。

芯片的15脚是DTMF信号检测输出,当芯片接收到双音多频信号时,15脚输出高电平,15脚通过反相器接到单片机的外部中断0引脚。

  • 电路分析

我们主要分析的电路时基于MT8870的接收器部分电路,对AT89S52最小系统不作分析。电路P3模块接话机两端,作为话机的信号输入端。而12V则为话机的供电,我们在实验室采取的为15V的稳压直流电源。C4,C5两电容为隔只电容,以减小话机信号的输入干扰。2脚为话机信号的输入端。7,8脚为晶振输入端,我们采用的晶振是3.58M的晶振,此电路晶振没接接地电容,最小系统版的晶振的接地电容起到的作用是反馈,稳定振荡的作用。引脚5,6:IC为内部连接点,应接至VSS端;引脚15:DV为延迟控制输出,当一组有效的双音频信号被接收时输出“1”;否则输出“0”。当有信号输出时,15脚高电平,基极与发射极正偏,集电极低电平,基极与集电极正偏,三极管进入饱和状态,中断发生。J2针脚连P3.2口,以作为中断源输入口。 11脚—14脚为16种DTMF信号所对应的4位二进制并行码数据输出端,分别姐AT89C52的P1口的低四位;具体的真值表图如下图。而最小系统所起的作用的是接收输入的四位二进制数据,之后对应DTMF信号的真值表,译出按键值,因为数码管显示限制,数码管只能显示数字0-9,不能显示*和#,而显示的位数只能显示8位,话机输入信号,数码管将显示其按键值,随着信号输入,显示数字不断左移。

单片机部分

开发板我们实验室是采用 STC15F2K16S2 芯片的开发板

STC15F2K16S2管脚图

  • MT8870芯片的D1D4**分别连接至开发板的**P10P13 IO口,①处则接开发板的外部中管口,即P32

数码管显示

  • 实验室开发板上的数码管为8段8位共阳极数码管,P0口控制数码管的段码P2口控制数码管的位码;数码管的显示原理之前就有写过

软件编程

编程思路

首先观察MT8870的解码表,话机的按键值的二进制即是D1~D4的输出值,而这个值我们刚好可以当数码管显示的段码;而每次按键时,显示位数都要+1,这里就可以设置个变量控制数码管显示的位数,因为是按下按键时才变化,所以这个变量可以放在中断里来控制;而要显示6个不同的数字,可以设6个变量来储存按键按下的数值,作数码管显示的缓冲区

流程图

程序编写
#include <STC15F2K60S2.H>
#include "intrins.h"
#define u8 unsigned char   //定义一个全局常量

u8 code smgduan[]={0xff,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc0};//共阴 段码表 P0
u8 code smgwei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40};//位码表 P2
//u8 code smgbuff[]={0x10,0x10,0x10,0x10,0x10,0x10};		//数码管缓冲区,初值0x10是为了让数码管右下角的点不亮
u8 Number1,Number2,Number3,Number4,Number5,Number6;	 //	用来存储号码
u8 k = 0;          //定义全局变量

void Delay1ms();  //声明延时程序
void Delay20ms();

/*数码管显示函数*/
void smg_display()	
{
	 Number1 = P1&0x0f;		//读取电话输入的数值,并把高四位置0		
    if(k >= 1)  P0 = smgduan[Number1]; P2 = smgwei[0]; Delay1ms(); P0 = 0xff;  //
    if(k >= 2)  P0 = smgduan[Number2]; P2 = smgwei[1]; Delay1ms(); P0 = 0xff;
    if(k >= 3)  P0 = smgduan[Number3]; P2 = smgwei[2]; Delay1ms(); P0 = 0xff;
    if(k >= 4)  P0 = smgduan[Number4]; P2 = smgwei[3]; Delay1ms(); P0 = 0xff;
    if(k >= 5)  P0 = smgduan[Number5]; P2 = smgwei[4]; Delay1ms(); P0 = 0xff;
    if(k >= 6)  P0 = smgduan[Number6]; P2 = smgwei[5]; Delay1ms(); P0 = 0xff;
		
}


/*主函数*/
void main()
{						  
	EA =1 ;   //中断总开关打开
	EX0 = 1;	//外部中断0中断允许位打开
	IT0 = 1;	//设置外部中断0为下降沿触发
	 
	while(1)		
	{											
		smg_display();		//循环数码管显示函数	
	}
}

/*外部中断0函数*/
void exint0() interrupt 0		
{
	
	if(!P32)					//检测中断请求
	{
		Delay20ms();		//延时消抖
		if(!P32)				
		{
			k++;				//k自加
			if(k > 6)			
			{
				k = 1;		 	//重置k
			}				  
		 Number6=Number5;Number5=Number4;Number4=Number3;  //把已经读取的按键值传递到下一个变量让数码管显示
		 Number3=Number2;Number2=Number1; 
		}
		while(!P32);	//等待按键松开
	}
}

/*延时函数*/
void Delay1ms()		//@12.000MHz 延时程序1ms
{
	unsigned char i, j;

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}

void Delay20ms()		//@12.000MHz 延时程序20ms
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 234;
	k = 113;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
之前的调试

测试时,发现第一个数码管不亮,而是从第二个数码管开始亮的

u8 code smgwei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40};

后发现调用数组第一个数据[]里是从0开始的,所以最后我把 smgwei[] 里的第一位放一个0xff让它跳过

拨号时,第一位显示正常,但在按下第二位时,数码管是显示了两位,但之前显示的数值也变成当前按键值,在拨号时,又全都显示为按的那个号

if(k >= 1)  P0 = smgduan[Number1]; P2 = smgwei[0]; Delay1ms(); P0 = 0xff; //Number2=Number1;
if(k >= 2)  P0 = smgduan[Number2]; P2 = smgwei[1]; Delay1ms(); P0 = 0xff; //Number3=Number2;

后发现是我变量赋值的位置放错了,因为数码管显示程序一直在while(1)里循环,所以它一直在移位赋值,导致全都显示为最新的拨号值,而我们预想结果的是拨一次号时,才让变量移位赋值一次,所以该语句应放在中断程序里面。

最终效果

上传不了视频。。。。。。GIF又太大。。。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值