This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/MSP-EXP430F5438:内部闪存音频文本文件的 PWM 输出下的音频播放

Guru**** 2560980 points
Other Parts Discussed in Thread: MSP430F5438A

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/597266/ccs-msp-exp430f5438-audio-play-thorugh-pwm-output-from-internal-flash-audio-text-file

器件型号:MSP-EXP430F5438

工具/软件:Code Composer Studio

您好,

我目前正在使用 MSP-EXP430F5438试验板。

默认用户体验演示程序无法验证音频播放和录制功能。 我是 Hardware enginerr、不熟悉很多编码。

设法通过轮询和中断、计时器 PWM 输出和 LCD 幻灯片放映来启动一些 LED 闪烁程序。

我需要一个人、他已经在通过 PWM 端口从内部闪存(该器件为256KB)播放一个小音频位(如"是"或"无字")。

我尝试过从资源中心获取的一些费用,但到 目前为止没有任何工作。

此致、

VR

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能否指定您尝试过的代码示例?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好

    我已经尝试过 eZ430-Speech MSP430FG4618PlaybackWAV 代码、并根据 MSP430F5438A 资源修改了计时器 B0和 P4.4作为我的 PWM 端口、以通过插孔播放音频。

    当我尝试调试时、它将进入 ISR 陷阱。

    此致、

    Raju

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    将使用其中一个计时器将基本设置为 PWM、其中 CCR0作为周期、CCR1作为占空比。 然后、根据数字化音频的值、您将以与音频信号采样率相同的速率更新占空比。 在硬件侧、您将需要一个截止频率低于 PWM 信号频率的低通滤波器。 您还需要一个用于 LPF 输出的放大器。 您能否起草一个初始代码以便我查看它。 它不应是一个很长的代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Nima Eskandari、您好!

    感谢您的回复并提供支持以查看我的代码。 正如我提到过的、我正在使用 MSP-EXP430f5438试验板、此实验板具有耳机插孔、此插孔已经连接到 P4.4、并且已经有 RC 滤波器和放大器。

    在这里、我可以听到耳机中的一些音频(甚至是噪音)、然后我将转到具有 RC 滤波器的外部扬声器、此扬声器位于具有 PWM 输出的其他 P4.5或 P.4.6引脚上。 我已经从 eZ430语音板的另一个昂贵代码中派生了这个代码。 我已根据电路板更改了所有端口分配。 我想以16MHz 或8MHz 的频率运行 SMCLK、因为我还需要将此代码与 LCD 集成。 我不想尝试 Audio.h,而是尝试一些垃圾数据,thqat 首先会产生噪音。

    #include

    #include

    #include "AUDIO1.h"//来自 eZ430回放源代码的音频文件。

    #include "Audio2.h"//来自 eZ430回放源代码的音频文件。

    typedef unsigned char u8_t

    typedef unsigned short int u16_t

    typedef signed char i8_t

    typedef short int i16_t

    #define buff:SZ 64

    uint8_t Buffer[缓冲区];

    //如果该变量在本地声明为 main 中的 uint32_t,则不是

    //编译器正确分配/处理,除非进行了优化

    //打开

    uint32_t ImgSize = 0;

    uint8_t uAvgCntr;

    uint8_t uAudioSample1;

    uint8_t uAudioSample2;

    int iAudioSampleDifference;

    uint32_t lAudioSampleCnt;

    uint32_t lAudioSampleLength;

    char * pAudio;

    initTA0 ()

    //初始化 PWM 输出的 Timer_A

    TBCTL = TBSSEL_2 | ID_1 | TBCLR;//|TAIE;//时钟= SMCLK /2 = 16MHz / 2

    //溢出中断被启用

    TBCCTL0 = CM_0 | OUTMOD_7 | CCIE;

    TBCCTL4 = CM_0 | OUTMOD_7 | CCIE;// CM_0:比较模式(无捕捉模式)

    // OUTMOD_7设置/休息模式 PWM

    // CCIE:比较中断被启用

    TBCCR0 = 0xFF;//从00h 到 FFh--SRI 的8位计数器注:这通常是 PWM 周期

    //将 P1.2设置为 PWM 信号的输出

    //SRI 注意事项:P1.1不能用于 PWM 输出

    P4DIR |= BIT4;//引脚4-P1.2/TA0.1为输出

    P4SEL |= BIT4;//引脚4-P1.2/TA0.1是 TA1输出、具有 PWM 功能

    #define StartTimer() TBCTL |= MC_1;//以向上计数模式启动计时器

    #define StopTimer() TBCTL |= MC_0;

    readImgSz ()

    //读取二进制映像的标头以获取其大小。 启动

    //从内存地址0读取。

    Buffer[0]= 0x00;

    缓冲区[1]= 0x00;

    // I2CWrite (EEPROM_ADDR,Buffer,2);

    // I2CRead (EEPROM_ADDR,缓冲区,4);

    // 32位大小值

    /*ImgSize =(uint32_t) Buffer[0];

    ImgSize <<= 8;

    imgSize |=(uint32_t) Buffer[1];

    ImgSize <<= 8;

    imgSize |=(uint32_t) Buffer[2];

    ImgSize <<= 8;

    imgSize |=(uint32_t) Buffer[3];*/

    ImgSize = 19878;

    void main (void)

    WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器

    //DCOCTL = CALDCO_16MHz;//选择 DCO@16MHz 作为时钟源

    //BCSCTL1 = CALBC1_16MHz;

    P1DIR |= 0x03;

    //******** 将时钟 SMCLK 配置为8MHz ********* //

    UCSCTL3 |= SELREF_2;//设置 DCO FLL 基准= REFO

    UCSCTL4 |= SELA_2;//设置 ACLK = REFO

    _bis_SR_register (SCG0);//禁用 FLL 控制循环

    UCSCTL0 = 0x0000;//设置可能的最低 DCOx、MODx

    UCSCTL1 = DCORSEL_5;//选择 DCO 范围16MHz 运行

    UCSCTL2 = FLLD_1 + 488;//将 DCO 乘法器设置为8MHz

    //(N + 1)* FLLRef = Fdco

    //(249 + 1)* 32768 = 8MHz,//(488 + 1)* 32768 = 16MHz

    //设置 FLL Div = fDCOCLK/2

    _BIC_SR_register (SCG0);//启用 FLL 控制环路

    //_delay_cycles (250000);

    //循环直到 XT1、XT2和 DCO 故障标志被清除

    操作

    UCSCTL7 &=~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);

    //清除 XT2、XT1、DCO 故障标志

    SFRIFG1 &=~OFIFG;//清除故障标志

    } while (SFRIFG1&OFIFG);//测试振荡器故障标志

    //******** 将时钟 SMCLK 配置为8MHz ********* //

    P11DIR |= 0x07;//将 P11.0、1、2设置为 ACLK、SMCLK 和 MCLK 的 O/P

    P11SEL |= 0x07;//为 ACLK、SMCLK 和 MCLK 启用 P11.0、1、2

    //I2CInit();//初始化 I2C

    //_enable_interrupt ();//启用中断

    initTA0();//Initialize TimerA

    _bis_SR_register (GIE);

    while (1)

    readImgSz();

    //I2CRead (EEPROM_ADDR,缓冲区,2);

    pAudio =(char *)&Audio2;//将指针设置为 Audio2数据字节

    *((((char*)(&lAudioSampleLength))+0)=*(pAudio++);

    *(((char*)(&lAudioSampleLength))+1)=*(pAudio++);

    *(((char*)(&lAudioSampleLength))+2)=*(pAudio++);

    *(((char*)(&lAudioSampleLength))+3)=*(pAudio++);

    uAudioSample1 =缓冲器[0];

    uAudioSample2 =缓冲器[1];

    uAvgCntr = 0;

    StartTimer();

    对于(lAudioSampleCnt = ImgSiz-1;lAudioSampleCnt > 0;lAudioSampleCnt-)

    //_bis_SR_register (LPM0_Bits + GIE);// LPM0:保持 DCO 运行

    //I2CRead (EEPROM_ADDR,缓冲区,1);

    uAudioSample1 = uAudioSample2;

    uAudioSample2 =缓冲器[0];

    StopTimer();

    P1OUT = 0x03;

    //

    // Timer B0中断服务例程

    //

    #pragma vector=TIMERB0_vector

    _interrupt void TIMERB0_ISR (void)

    //计时器中断(PWM、一个采样)

    开关(_偶数_在范围内(TBIV、10))

    情况2://向量2:TBCCR1

    中断;

    情况4://向量4:TBCCR2

    中断;

    案例8://向量4:TBCCR4

    P1OUT = 0x01;

    iAudioSampleDifference =(int) uAudioSample2 -(int) uAudioSample1;

    IF (iAudioSampleDifference > 68)

    TBCTL &=~TAIFG;//清除溢出标志 TAIFG IFG

    TBCTL |= TAIE;//启用溢出中断 TAIFG

    TBCCTL4 &=~CCIE;//关闭 TBCCR4 IFG

    开关(__evo_in_range (uAvgCntr、6))

    案例0:TBCCR4 =(uAudioSample1

    + uAudioSample1

    + uAudioSample1

    + uAudioSample2)>> 2;

    中断;

    案例2:TBCCR4 =(uAudioSample1

    + uAudioSample2)>> 1;

    中断;

    案例4:TBCCR4 =(uAudioSample1

    + uAudioSample2

    + uAudioSample2

    + uAudioSample2)>> 2;

    中断;

    案例6:TBCCR4 = uAudioSample2;

    _BIC_SR_REGISTER_ON_EXIT (LPM4_BITS);

    //清除0 (SR)中的所有 LPM 位

    //这将重新启动音频输出环路

    //并从读取下一个音频样本

    // SPI-Flash 存储器

    中断;

    uAvgCntr +=2;//递增平均计数器(始终为2)

    uAvgCntr = uAvgCntr & 0x06;//平均计数器范围:0、2、4、6

    中断;

    案例10://向量10:TAIFG 标志

    P1OUT = 0x02;

    TBCCTL4 &=~CCIFG;//清除 TBCCR4 IFG

    TBCCTL4 |= CCIE;//启用 TBCCR4 IFG

    TBCTL &=~TBIE;//关闭溢出中断 TAIFG

    中断;

    //_interrupt void TimerA1 (void)

    期待您的回复。

    谢谢、

    Raju

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是否还可以在更改端口分配之前共享原始代码?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Nima Eskandari、您好!

    感谢您的回复。 我使用了以下线程链接和 eZ430 slaa405a\eZ430-Speech\MSP430FG4618PlaybackWAV 软件文件夹作为我的代码的参考。

    https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/219093

    您能为我提供 MSP-EXP430F5438用户体验演示代码吗?此演示代码在我的电路板上从未使用过。 如果我可以使其使用演示用户代码、我可以主要使用它。

    此致、

    Raju

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、让我看看我是否可以获取硬件。 如果没有、我将尝试根据代码向您提供一些反馈。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Nima Eskandari、您好!

    感谢您的回复。

    请找到以下代码。 使用此代码、我可以看到 P4.4和 P4.5上的 PWM 数据切换。

    但是、在4kHz 或更低的 PWM 频率下、我可以听到一些蜂鸣噪声。

    没有超出该频率的语音或音频。 我拥有所有音频头文件、其中8位8ksps 单声道数据串生成了1秒音频的 from.wav 文件。

    我使用了8MHz 的 SMCLK、并针对32KHz PWM 频率尝试了具有 ID_0和256个延迟周期的 TBCTL、针对4kHz 尝试了 ID_3和2048个延迟周期。

    希望这将帮助您为我提供一些输入、以便从 MSP-EXP430f5438试验板的耳机生成音频。

    #include

    #include

    #include "AUDIO1.h"//来自 eZ430回放源代码的音频文件。

    #include "Audio2.h"//来自 eZ430回放源代码的音频文件。

    #include "啁 啾.h"//来自 eZ430回放源代码的音频文件。

    #include "bepeer.h"//来自 eZ430回放源代码的音频文件。

    typedef unsigned char u8_t

    typedef unsigned short int u16_t

    typedef signed char i8_t

    typedef short int i16_t

    #define buff:SZ 64

    uint8_t Buffer[缓冲区];

    //如果该变量在本地声明为 main 中的 uint32_t,则不是

    //编译器正确分配/处理,除非进行了优化

    //打开

    uint32_t ImgSize = 0;

    uint8_t uAvgCntr;

    uint8_t uAudioSample1;

    uint8_t uAudioSample2;

    int iAudioSampleDifference;

    uint32_t lAudioSampleCnt;

    uint32_t lAudioSampleLength;

    char * pAudio;

    无符号计数;

    无符号整型 SYSCLK;

    无符号长整型 FPWM;

    unsigned int D;

    void main (void)

    WDTCTL = WDTPW+WDTHOLD;//停止 WDT

    //******** 将时钟 SMCLK 配置为8MHz ********* //

    unsigned char fd;

    UCSCTL3 |= SELREF_2;//设置 DCO FLL 基准= REFO

    UCSCTL4 |= SELA_2;//设置 ACLK = REFO

    _bis_SR_register (SCG0);//禁用 FLL 控制循环

    UCSCTL0 = 0x0000;//设置可能的最低 DCOx、MODx

    UCSCTL1 = DCORSEL_5;//选择 DCO 范围16MHz 运行

    FD = 244;// N = 244 (对于8MHz)和488 (对于16MHz)

    UCSCTL2 = FLLD_1 + FD;//将 DCO 乘法器设置为8MHz

    //(N + 1)* FLLRef = Fdco

    //(244 + 1)* 32768 = 8MHz,//(487 + 1)* 32768 = 16MHz

    //设置 FLL Div = fDCOCLK/2

    _BIC_SR_register (SCG0);//启用 FLL 控制环路

    _DELAY_CYCLES (250000);

    //循环直到 XT1、XT2和 DCO 故障标志被清除

    操作

    UCSCTL7 &=~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);

    //清除 XT2、XT1、DCO 故障标志

    SFRIFG1 &=~OFIFG;//清除故障标志

    } while (SFRIFG1&OFIFG);//测试振荡器故障标志

    //******** 将时钟 SMCLK 配置为8MHz 的结束********* //

    //P4SEL |= 0xFF;// P4选项选择

    // P4DIR |= 0xFF;// P4输出

    SYSCLK = 32768 *(FD+1);

    P11DIR |= 0x07;//将 P11.0、1、2设置为 ACLK、SMCLK 和 MCLK 的 O/P

    P11SEL|= 0x07;//为 ACLK、SMCLK 和 MCLK 启用 P11.0、1、2

    P2REN |= 0x40;//启用 P1.4内部电阻

    P2OUT |= 0x40;//将 P2.6设置为上拉电阻

    P2IE |= 0x40;// P2.6中断被启用

    P2IES |= 0x40;// P2.6/边沿

    P2IFG &=~0x40;// P2.6 IFG 被清零

    _bis_SR_register (GIE);//输入 LPM4、带中断

    延迟(无符号整型周期)

    unsigned int i;

    对于(i = 0;i<=周期;i++)

    _DELAY_CYCLES (1);

    //端口2中断服务例程

    #pragma vector=port2_vector

    _interrupt void Port_2 (void)

    unsigned int x = 0;

    /*

    *对于8MHz SMCLK、TBSSEL_2和 ID_0、以 SMCLK 为基准、0xFF 的 TBCCR0使其 Fpwm = 31、360KHz、保持延迟周期为0xFF/256

    *对于8MHz SMCLK、TBSSEL_2和 ID_3 (以 SMCLK/8为基准),0xFF 的 TBCCR0使其 Fpwm = 31,360Hz/8 = 3920Hz,保持延迟周期为0xFF*8/256*8 = 2048

    *

    *

    P4SEL |= 0xFF;// P4选项选择

    P4DIR |= 0xFF;// P4输出

    TBCCR0 = 0xFF;// Fpwm = Fclk/tbccr0

    TBCCTL4 = OUTMOD_7;

    TBCCTL5 = OUTMOD_7;

    TBCTL = TBSSEL_2 + TBCLR;// SMCLK (TBSSEL_2)、ACLK (TBSSEL_1)、清除 TBR

    TBCTL |= ID_3;

    FPWM = SYSCLK/TBCCR0;

    D = SYSCLK/FPWM;

    pAudio =(char *)&AUDIO1;//设置音频头文件数据字节的指针

    for (x = 0;x <15516;x++)

    uAudioSample1 =*(pAudio);//读取第一个音频样本

    uAudioSample2 =*(pAudio+1);//读取第二个音频样本

    TBCCR4 = uAudioSample1;// CCR4 PWM 占空比

    TBCCR5 = uAudioSample1;

    TBCTL |= MC_1;//启动 UPMODE 计时器

    _DELAY_CYCLES (2048);

    for (uAvgCntr = 0;uAvgCntr <3;uAvgCntr ++)//要将8ksps 数据外推至32ksps,必须为每个样本创建3个附加样本

    开关(uAvgCntr)

    案例0:TBCCR4 =(uAudioSample1 + uAudioSample1 + uAudioSample1 + uAudioSample2)>> 2;//((s1×3)+ s2)/ 4

    _DELAY_CYCLES (25048);

    中断;

    案例1:TBCCR4 =(uAudioSample1 + uAudioSample2)>> 1;//(s1 + s2)/2

    _DELAY_CYCLES (2048);

    中断;

    案例2:TBCCR4 =(uAudioSample1 + uAudioSample2 + uAudioSample2 + uAudioSample2)>> 2;//(s1 +(s2×3))/ 4

    _DELAY_CYCLES (2048);

    中断;

    默认值:

    uAvgCntr = 0;

    中断;

    __no_operation()

    __no_operation()

    P2IFG &=~0x40;// P2.6 IFG 被清零

    TBCCTL4 &=~(OUTMOD_7 | OUT);// CCR4复位/置位

    TBCCTL5 &=~(OUTMOD_7 | OUT);// CCR4复位/置位

    TBCTL &=~MC_0;

    P4SEL &=~ 0xFF;// P4选项选择

    P4DIR &=~ 0xFF;// P4输出

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能否对缓冲放大器输出端的信号进行示波器测量?
    您还能告诉我 Audio.h 文件中数据的大小吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Nima Eskandari、您好!

    是的、我能够测量缓冲放大器输出端的信号。 它失去了与 P4.4的 PWM 输出类似的频率、只是平滑的信号。我可以在4kHz PWM 频率下听到一些蜂鸣噪声、上面的任何内容都无法从耳机插孔中听到。 但是、我可以在范围内观察到单个值。

    我已经尝试了不同的数据大小、从4004、15536和19378、这些数据是从.wav 文件转换而来的。 您可以使用小缓冲区提供音频播放的示例代码。

    因此、我可以使用我的板尝试该代码。 这是一种简单的解决方案。

    此致、

    Raju

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我可以通过计时器(PWM)来列举一个输出正弦波的快速示例。 这会有帮助吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Nima Eskandari、您好!

     这将会大有帮助。

    如果您可以 通过 P4.4提供一个小型语音(秒)播放代码、那将会非常好。

    告诉我您的联系详情、无论是电话还是电子邮件、我都不会花超过10分钟来解释问题。

    此致、

    Raju

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我已向您发送了一封私人邮件。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    正如我在电子邮件中提到的。 必须将引脚 P6.6拉低以启用音频放大器。 添加代码以启用 P6.6作为数字输出并将引脚拉至低电平后、一切都正常。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    非常感谢 Nima。

    通过 将 P6.6保持 在低电平可以解决音频播放问题。

    谢谢、

    Raju