📄 speakercontrol.c
字号:
#include "typedef.h"
#include "speakercontrol.h"
#define SPEAK_FIRST_ACC 2 /*第一次按键计次*/
#define SPEAK_CONTINUE_ACC 10 /*连续按键间隔计次*/
#define SPEAK_RELEASE_ACC 2 /*按键释放间隔次数*/
static char speakCode; /*保存按键码*/
static Byte speakStatus; /*当前声音控制状态*/
static Byte speakState;
static Byte speakAcc;
static Uint8 speakKeep;
extern Uchar volatile xdata D12_Y2;//原来的xCONTROLBYTE82;//键盘扫描后的输出地址,用到4-7
extern Uchar volatile xdata D12_Y1;//原来的xCONTROLBYTE81K
extern idata Uchar D16CS;//D12_Y1的寄存器,原来的xConByte81KValue
void speak_init()
{
speakState = 0;
speakAcc = 0;
speakKeep = SPEAK_NULL;
speakCode = CONTROL_NOSPEAKER;
speakStatus = CONTROL_NOSPEAKER;
set_speakmode(speakStatus);
}
/***************************************
*用来具体控制喇叭的函数
*mode:取值为CONTROL_BOARDINNER、CONTROL_BOARDOUTER、CONTROL_MICINNER、CONTROL_MICOUTER、CONTROL_NOSPEAKER
****************************************/
void set_speakmode(Byte mode)
{
D16CS &= 0xf0;//0x0f;
D16CS |= mode;//控制语音报站在车厢内
D12_Y1 = D16CS;
}
/*******************************************************
/*对MIC喇叭进行控制处理,需要在扫描完后调用
*********************************************************/
void speak_miccontrol()
{
if (CONTROL_NOSPEAKER == speakCode)
{
if ((speakStatus == CONTROL_MICOUTER) || (speakStatus == CONTROL_MICINNER))
{
speakStatus = speakCode;
set_speakmode(speakStatus);
}
}
else
{
if (speakStatus != speakCode)
{
speakStatus = speakCode;
set_speakmode(speakStatus);
}
}
}
/*********************************************
*报站喇叭控制
*mode:取值为CONTROL_BOARDINNER、CONTROL_BOARDOUTE、CONTROL_NOSPEAKER
*********************************************/
void speak_boardcontrol(Byte mode)
{
if ((speakStatus != CONTROL_MICOUTER) && (speakStatus != CONTROL_MICINNER))
{
speakStatus = mode;
set_speakmode(mode);
}
}
/************************************
*
话筒扫描处理流程:
1)通过比较上一次的按键值来消除抖动。不相同就清除计次,相同就累加计次。
2)累加到一定次数认为是按键稳定,发送蜂鸣声,判断按键类型。
3)当按键持续一定时间后定时发送蜂鸣声和按键类型。
4)按键释放要有一定的时间。即两次连续按键要有一定时间间隔。
5)考虑本产品的实际情况,向上和向上按键允许连续,取消和确认只能是单次按键。
当有效按键后要发送蜂鸣声。
通过简单的状态机处理按键的抖动、单次按键、连续按键。
keyState有以下几个状态:
0:第一次按键状态,消除抖动状态。不相同就清除计次,相同就累加计次,到一定的次数认为是有效按键。
1:连续按键状态。
2:释放按键状态。
*
*************************************/
void speak_process(void)
{
Uint8 tmpValue;//最终保存结果
tmpValue = D12_Y2;
tmpValue &= 0x06;//获取实际对话筒的控制
/*通过计次来达到消除抖动的目的*/
if( tmpValue == speakKeep )
{
speakAcc ++;
}
else
{
speakAcc = 0;
speakKeep = tmpValue;
}
switch(speakState)
{
case 0: /*第一次按键状态*/
if( speakKeep == SPEAK_NULL )
{
speakAcc = 0;
break;
}
if( speakAcc == SPEAK_FIRST_ACC )
{
speakState = 1;
if (INNER_MIC == speakKeep)
{
speakCode = CONTROL_MICINNER;
}
else if (OUT_MIC == speakKeep)
{
speakCode = CONTROL_MICOUTER;
}
else
{
speakState = 0;
speakAcc = 0;
}
}
break;
case 1: /*连续按键状态*/
if( speakAcc == SPEAK_CONTINUE_ACC )
{
speakAcc = SPEAK_FIRST_ACC; /*防止计数溢出*/
}
else if( speakAcc == 0 )
{ /*按键有变化*/
speakState = 2;
}
break;
case 2: /*释放按键状态*/
if( (speakAcc >= SPEAK_RELEASE_ACC) && (speakKeep==SPEAK_NULL) )
{
speakState = 0;
speakCode = CONTROL_NOSPEAKER;
}
break;
default:
speakState = 0;
break;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -