iot-fan

联系: iotfan123#163.com
注意:
1,本博客之内容来源于网上收集以及相关技术人员提供,如果有侵犯到您的权益,请电邮我沟通;
2,本博客之内容乃分享,交流,学习,研究之目的,作者不对内容的真实性,有效性,及时性负责,也不对因本博客的任何内容导致的任何后果负责;
3,本博客之内容禁止转发到CSDN网站,转到别的网站请保留出处.

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

待编辑

CH57x,ch58x的 PWM的能力以及实现

本文所用的PWM为ch57x,58x的timer的pwm功能,而不是那个简单的专用的pwm外设

选择合适的音源

音源的关键参数:采样率,量化位宽

  • 采样率:每秒采多少次,单位为Hz,这个跟我们的PWM的频率相关,不对应会导致我们的实际音频速度快或慢,这个值的大小会影响声音的沉闷程度,人的听觉范围是20k左右,根据奈奎斯特采样定理,要进行最小2倍的采样速度,所以一般我们听的音乐使用44.1Khz的采样率
  • 量化位宽:每次采样按照多少个位的ADC去量化(这里还要分均匀量化,和非均匀量化,这里我们需要线性均匀量化的LPCM编码)

ch57x/58x对应的pwm播放音频在常用主频下不同的量化位宽的音源的最大采样率:

主频 8bit 12bit(用16bit音源)
60M 234.375K 14.6484375 K
48M 187.5K 11.71875K
32M 125K 7.8125K

音频转换工具

  • ffmpeg(本文使用)
  • cooledit\Au
  • 其他能转换为wav文件的工具

音频文件处理

#把其他的音频文件转换成wav文件,LPCM 8bit 无符号,单声道,14648hz采样率,注意转换后的大小
ffmpeg -i windows_phone.mp3 -bitexact -acodec pcm_u8 -ac 1 -ar 14648 windows_phone_8bit_14648hz.wav
#wav文件转换成hex文件(烧录方便),这里我们把偏移地址设置为40K的地方,前面放我们的代码
bin2hex.exe --offset=40960 windows_phone_8bit_14648hz.wav windows_phone_8bit_14648hz.wav.hex

代码实现

初始化PWM

void ch57x_timer2_pwm_init(uint8_t remap_enable) {
    if(remap_enable) {
        //timer2 remap gpio at GPIOB
        GPIOPinRemap(ENABLE, RB_PIN_TMR2);
        GPIOB_ResetBits( GPIO_Pin_11 );
        GPIOB_ModeCfg( GPIO_Pin_11, GPIO_ModeOut_PP_20mA );
    }else{
        GPIOPinRemap(DISABLE, RB_PIN_TMR2);
        GPIOA_ResetBits( GPIO_Pin_11 );
        GPIOA_ModeCfg( GPIO_Pin_11, GPIO_ModeOut_PP_20mA );
    }
    //active high
    //oversampling = 16,
    TMR2_PWMInit( High_Level, PWM_Times_16 );

    //disable out here
    TMR2_Disable();

    //8bit
    //60M/16/256 = 14648Hz ,so the wav file should be 14648Hz
    //actual output = 60M/256 = 234375hz
    TMR2_PWMCycleCfg( 255 );

    TMR2_ITCfg(ENABLE,RB_TMR_IE_FIFO_HF);
    //clear interrupt flag
    TMR2_ClearITFlag(0XFF);
#ifdef CH573
    //enable interrupt
    PFIC_EnableIRQ( TMR2_IRQn );
#else
    NVIC_EnableIRQ( TMR2_IRQn );
#endif
}

分析wav文件

见附件,主要是获取采样率,位宽,声道,和长度信息, 由于不是做通用的wav播放器,这里我们用了长度信息,其他信息只是打印了出来

送入wav波形给到pwm


#ifdef CH573
__attribute__((interrupt("WCH-Interrupt-fast")))
__attribute__((section(".highcode")))
void TMR2_IRQHandler(void) {
#else
void TMR2_IRQHandler(void) {
#endif
    if(TMR2_GetITFlag(TMR0_3_IT_FIFO_HF)) {
        TMR2_PWMActDataWidth(((uint32_t)*current_sample_addr));
        sample_current ++;
        current_sample_addr++;
        if(sample_current >= sample_cnt) {
            current_sample_addr = (uint8_t *)(WAV_START_ADDR+44);
            sample_current = 0;
        }
   }
   //clear all interrput flag
    TMR2_ClearITFlag(0XFF);
}

合并音频与烧录

合并上面我们处理好的音频文件

mergehex.exe -m ch58x_pwm_wav_player.hex windows_phone_8bit_14648hz.wav.hex -o ch58x_wav_player_windows_phone_8bit_14648hz.hex

烧录最终输出的hex文件:(可以参考文章:https://www.cnblogs.com/iot-fan/p/13498088.html)
ch58x_wav_player_windows_phone_8bit_14648hz.hex

不足

  • wav文件体积过大

改进

  • 引入音频编解码算法,烧录压缩后的文件大大降低音源的大小

附件

posted on 2022-03-25 11:46  iot-fan  阅读(1677)  评论(0编辑  收藏  举报