⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 speakercontrol.c

📁 通过车载终端采集GPS数据
💻 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 + -