一线控制语音芯片示例代码(非阻塞式的发送)

       最近在做一个带提示语音的项目,需要控制语音芯片,搜了一下大多的语音芯片都是一线、二线、标准串口,但在价格上一线控制OTP的语音芯片是最便宜的。

        可厂家提供的参考例程和网上分享的都是差不多的方式,用阻塞方式延时,发一字节数据基本要十多毫秒,还是自己写一个吧,顺便记录一下。

 先看厂家提供的

        厂家提供的虽然简单但是有硬伤吖。。。

        

        好,言归正转,我分享一下我的想法:

        大概逻辑是在定时器100uS更新中断中调用VoicePlayCommand();(简单来说就是100uS执行一次VoicePlayCommand();,也可以10uS,20uS等等,改对你要的时间间隔就好)。

然后在需要发送语音序号的地方调用PlayAssignNumber(Number);

例如:PlayAssignNumber(0x02);就发送播放语音芯片中序号为2的提示音。

app_Voice.c

#include "app_Voice.h"



uint8_t *OutPtr;                
uint8_t *InPtr;
uint8_t VoicePlay_Flag = 0;
uint8_t VoiceBuff[10] = {0};            // 指令缓存,根据实际使用
e_OneLineStatus StatusStep = Restart;
/**
***********************************************************
* @brief  语音初始化
* @param  无
* @retval 无
* @note   无
***********************************************************
*/
void app_VoiceInit(void)
{
    InPtr = &VoiceBuff[0];
    OutPtr = &VoiceBuff[0];
}

/**
***********************************************************
* @brief  语音控制处理
* @param  无
* @retval 无
* @note   PB7,100us执行一次
***********************************************************
*/
void VoicePlayCommand(void)
{
    static uint8_t AddrData = 0;
    static uint8_t BitCounter = 0;
    static uint8_t TimCounter = 0;

    if (VoicePlay_Flag) {
        if (TimCounter)
            TimCounter--;
        switch (StatusStep) {
            case Restart:
                
                if (!TimCounter) {
                    /* 处理完成默认置高电平 */
                    VOICE_HIGH(); // 置高电平
                    /* 判断缓冲区是否还有数据要处理 */
                    if (InPtr != OutPtr) {
                        AddrData = *OutPtr;
                        StatusStep = Lead;
                        if (&VoiceBuff[(BUFF_MAX - 1)] < ++OutPtr) {
                            OutPtr = &VoiceBuff[0];
                        }
                    } else {
                        VoicePlay_Flag = 0;
                    }
                }
                break;
            case Lead:             /* 引导码6mS */
                VOICE_LOW();             // 置低电平
                TimCounter = TM_6MS; // 引导码时长
                StatusStep = OutHigh;
                break;
            case OutHigh: /* 设置高电平 */
                if (!TimCounter) {
                    VOICE_HIGH(); // 置高电平
                    // 设置输出高电平时长
                    TimCounter = (AddrData & 0x01) ? TM_600US : TM_200US;
                    StatusStep = OutLow;
                }
                break;
            case OutLow: /* 设置低电平 */
                if (!TimCounter) {
                    VOICE_LOW();  // 置低电平
                    // 设置输出低电平时长
                    TimCounter = (AddrData & 0x01) ? TM_200US : TM_600US;
                    AddrData >>= 1; // 数据移位
                    // 一字节数据是否处理完成
                    if (8 <= ++BitCounter) {
                        BitCounter = 0;
                        StatusStep = Restart;
                    } else {
                        StatusStep = OutHigh;
                    }
                }
                break;
            default:
                break;
        }
    }
}
/**
***********************************************************
* @brief  播放指定序号的语音
* @param  PlayNumber:播放语音的地址序号
* @retval 无
* @note   无
***********************************************************
*/
void PlayAssignNumber(uint8_t PlayNumber)
{
    *InPtr = PlayNumber;
    if (&VoiceBuff[(BUFF_MAX - 1)] < ++InPtr)
    {
        InPtr = &VoiceBuff[0];
    }
    VoicePlay_Flag = 1;
}

app_Voice.h

#ifndef _APP_VOICE_H
#define _APP_VOICE_H


#define VOICE_HIGH()     // 根据自己MCU的IO更改
#define VOICE_LOW()     // 根据自己MCU的IO更改
#define TM_200US 2
#define TM_600US 6
#define TM_6MS 60
#define BUFF_MAX 10


typedef enum
{
    Restart,         // 重新开始
    Lead,            // 引导码
    OutHigh,         // 输出高电平
    OutLow           // 输出低电平
} e_OneLineStatus;


void app_VoiceInit(void);
void VoicePlayCommand(void);
void PlayAssignNumber(uint8_t PlayNumber);

#endif

main.c文件,定时器配置此处省略了。

#include "app_Voice.h"


/**
***********************************************************
* @brief  主函数
* @param  无
* @retval 无
* @note   无
***********************************************************
*/
int main(void)
{
    HAL_Init();
    APP_SystemClockConfig();
    app_VoiceInit();
    PlayAssignNumber(0xF3);
    PlayAssignNumber(0x06);
    PlayAssignNumber(0x07);
    PlayAssignNumber(0x08);
  while (1)
  {
    ;
  }
  return 0;
}


/**
***********************************************************
* @brief  TIM14更新中断回调函数
* @param  无
* @retval 无
* @note   无
***********************************************************
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    VoicePlayCommand();
}

 这里演示是组合播放序号6、7、8的语音。波型分析如下:

好啦,就这么点东西了,后期有补的话再补上吧 ,先不说好不好用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值