CY8C4127AZI-S445 TCPWM drive music beep

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
XiaoPing_Yang
Level 4
Level 4
25 replies posted 10 replies posted 10 questions asked

Hi  Sir,

     Now  I  am debugging a program to drive music beep. I have found a problem .  In the project attached , I change PWM frequency to drive the music beep.  The code as follows:

         if(Sound_test==0)    // 1667Hz

          {

              PWM_BUZZ_WritePeriod(0x64);

              PWM_BUZZ_WriteCompare(0x64/2);

          }

        else if(Sound_test==40)

        {

             PWM_BUZZ_WriteCompare(0);

        }

        else if(Sound_test==100)       //2KHz

        {

            PWM_BUZZ_WritePeriod(0x7D);

            PWM_BUZZ_WriteCompare(0x7D/2);

            Watch3 = PWM_BUZZ_PERIOD_REG;

            Watch3 = PWM_BUZZ_PERIOD_REG;

         }

        else if(Sound_test==140)

        {

            PWM_BUZZ_WriteCompare(0);

        }

        else if(Sound_test==200)     //2.48HZ

        { 

            PWM_BUZZ_WritePeriod(0x95);  

            PWM_BUZZ_WriteCompare(0x95/2);

         }

        else if(Sound_test==300)     //stop

        {

             PWM_BUZZ_WriteCompare(0);

        }

        Sound_test++;   

        if(Sound_test>=600)   ///delay

        {

             Sound_test= 0;

        }

       If the TCPWM works, there will be three ring. But in fact ,sometimes only  one.    So , I use an oscilloscope to detect PWM output pins,I found the wave lost.

       I don't know why.I have checked  the register,but  the address in  the registers TRM and  the project really confuse me . Please kindly help to check the TCPWM configuration and   test the program .

       Thanks.

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Xiaopingyang-san,

I slightly modified my sample to be safer about PWM setup,

as I thought changing period/compare during the PWM running is not quite safe.

Meantime I cleared the counter of PWM using WriteCounter(0) so that PWM will start from 0

next time it gets enabled.

So I think if you still have time when PWM output is not generated when it is supposed to be generating output,

something else must be preventing the output from being generated.

For example, although I could not read from your source, PWM_BUZZ_EN may be disabling the output,

or something like that. 

Attached is my project for CY8C4146LQI-S433 board, aka TSoC.

==========================

#include "project.h"

#include "stdio.h"

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_TEST_UartPutString(str) ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    UART_TEST_Start() ;

    PWM_BUZZ_Start() ;

}

void splash(void)

{

    sprintf(str, "PWM BUZZ Test (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

void Set_Buzzer_Period(uint32_t period)

{

    PWM_BUZZ_Stop() ;

    PWM_BUZZ_WriteCounter(0) ;

    PWM_BUZZ_WritePeriod(period) ;

    PWM_BUZZ_WriteCompare(period/2) ;

    PWM_BUZZ_Enable() ;

}

void Stop_Buzzer(void)

{

    PWM_BUZZ_Stop() ;

    PWM_BUZZ_WriteCounter(0) ;

    PWM_BUZZ_WriteCompare(0) ;

    PWM_BUZZ_Enable() ; // may be not necessary

}

int main(void)

{

    int Sound_test = 0 ;

    uint32_t Watch3 = 0 ;

   

    init_hardware() ;

   

    splash() ;

    for(;;)

    {

        switch(Sound_test) {

        case 0:

            Set_Buzzer_Period(0x64) ;

            break ;

        case 40:

            Stop_Buzzer() ;

            break ;

        case 100:

            Set_Buzzer_Period(0x7D) ;

            Watch3 = PWM_BUZZ_PERIOD_REG ;

            break ;

        case 140:

            Stop_Buzzer() ;

            break ;

        case 200:

            Set_Buzzer_Period(0x95) ;

            break ;

        case 300:

            Stop_Buzzer() ;

            break ;

        }

        Sound_test = (Sound_test + 1) % 600 ;

        CyDelay(1) ;

    }

}

==========================

Best Regards,

23-Apr-2019

Motoo Tanaka

View solution in original post

0 Likes
8 Replies
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Since your attached sample was too complicated,

I duplicated only the beep part and made a simple project.

And all I heard was some low noise, always same tone.

At first I was suspecting the sequence so I let the program

write each PWM set up lines.

001-TeraTerm-log.JPG

And it seems doing fine.

Then I saw your schematic,

002-org-schematic.JPG

To me 4MHz clock seemed to be too high, for a sound

so I modified it to 40KHz

000-schematic.JPG

And I added a CyDelay(10) before Sound_Test++, so that the sound lasts longer.

Now I can hear 3 different tones, even with my old ears 😉

Following is main.c I used for testing

===========================

#include "project.h"

#include "stdio.h"

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_TEST_UartPutString(str) ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    UART_TEST_Start() ;

    PWM_BUZZ_Start() ;

}

void splash(void)

{

    sprintf(str, "PWM BUZZ Test (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

int main(void)

{

    int Sound_test = 0 ;

    uint32_t Watch3 = 0 ;

   

    init_hardware() ;

   

    splash() ;

    for(;;)

    {

        if(Sound_test==0)    // 1667Hz

        {

            print("1667Hz\n") ;

            PWM_BUZZ_WritePeriod(0x64);

            PWM_BUZZ_WriteCompare(0x64/2);

        }

        else if(Sound_test==40)

        {

            print("Stop\n") ;

            PWM_BUZZ_WriteCompare(0);

        }

        else if(Sound_test==100)       //2KHz

        {

            print("2KHz\n") ;

            PWM_BUZZ_WritePeriod(0x7D);

            PWM_BUZZ_WriteCompare(0x7D/2);

            Watch3 = PWM_BUZZ_PERIOD_REG;

            Watch3 = PWM_BUZZ_PERIOD_REG;

        }

        else if(Sound_test==140)

        {

            print("Stop\n") ;

            PWM_BUZZ_WriteCompare(0);

        }

        else if(Sound_test==200)     //2.48HZ

        {

            print("2.48(k?)Hz\n") ;

            PWM_BUZZ_WritePeriod(0x95); 

            PWM_BUZZ_WriteCompare(0x95/2);

        }

        else if(Sound_test==300)     //stop

        {

            print("Stop\n") ;

            PWM_BUZZ_WriteCompare(0);

        }

        CyDelay(10) ; /* 500ms delay */

        Sound_test++;  

        if(Sound_test>=600)   ///delay

        {

            Sound_test= 0;

        } 

    }

}

===========================

Since I don't have a board with CY8C4127AZI-S445,

I used a TSoC board which has CY8C4146LQI-S433,

but I hope that the main and schematic should be used for both PSoCs.

moto

0 Likes

Hi Motoo Tanaka,

    Thank you very much!

     I have a prescaler 16x in the configuration.I have tried you program , but I  change CyDelay(10) to CyDelay(1). That is right ,you will hear 3 different tones first.If there is no problem , the 3 differents tones will be continuous.

     Listen carefully . There are some stops . The PWM pin does not  output. You can use  an oscilloscope to detect .  I suspect the PWM output does not work sometimes.But when you read the period or compare time , the value is correct.  That is what confused me!!

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Xiaopingyang-san,

Yes, I have noticed that there are three rests between tones,

as the TeraTerm log showed "Stop".

4MHz vs 40KHz is 100, so 16x prescaler may not have been enough.

So did you here 3 tones with my program?

Meantime did my program also had time when PWM did not output even with assigned period and compare?

And if so please let me know which note or was it random?

Best Regards,

23-Apr-2019

Motoo Tanaka

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Xiaopingyang-san,

I slightly modified my sample to be safer about PWM setup,

as I thought changing period/compare during the PWM running is not quite safe.

Meantime I cleared the counter of PWM using WriteCounter(0) so that PWM will start from 0

next time it gets enabled.

So I think if you still have time when PWM output is not generated when it is supposed to be generating output,

something else must be preventing the output from being generated.

For example, although I could not read from your source, PWM_BUZZ_EN may be disabling the output,

or something like that. 

Attached is my project for CY8C4146LQI-S433 board, aka TSoC.

==========================

#include "project.h"

#include "stdio.h"

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_TEST_UartPutString(str) ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    UART_TEST_Start() ;

    PWM_BUZZ_Start() ;

}

void splash(void)

{

    sprintf(str, "PWM BUZZ Test (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

void Set_Buzzer_Period(uint32_t period)

{

    PWM_BUZZ_Stop() ;

    PWM_BUZZ_WriteCounter(0) ;

    PWM_BUZZ_WritePeriod(period) ;

    PWM_BUZZ_WriteCompare(period/2) ;

    PWM_BUZZ_Enable() ;

}

void Stop_Buzzer(void)

{

    PWM_BUZZ_Stop() ;

    PWM_BUZZ_WriteCounter(0) ;

    PWM_BUZZ_WriteCompare(0) ;

    PWM_BUZZ_Enable() ; // may be not necessary

}

int main(void)

{

    int Sound_test = 0 ;

    uint32_t Watch3 = 0 ;

   

    init_hardware() ;

   

    splash() ;

    for(;;)

    {

        switch(Sound_test) {

        case 0:

            Set_Buzzer_Period(0x64) ;

            break ;

        case 40:

            Stop_Buzzer() ;

            break ;

        case 100:

            Set_Buzzer_Period(0x7D) ;

            Watch3 = PWM_BUZZ_PERIOD_REG ;

            break ;

        case 140:

            Stop_Buzzer() ;

            break ;

        case 200:

            Set_Buzzer_Period(0x95) ;

            break ;

        case 300:

            Stop_Buzzer() ;

            break ;

        }

        Sound_test = (Sound_test + 1) % 600 ;

        CyDelay(1) ;

    }

}

==========================

Best Regards,

23-Apr-2019

Motoo Tanaka

0 Likes

Hi Motoo Tanaka,

    I will try your new program  ,today.

0 Likes

Hi Motoo Tanaka,

       Thank you very much again! Your method works.  I think that  it is not safe changing  PWM  period  when PWM running. And if the  PWM  period is fixed ,changing pcompare during the PWM running  may be allowed.

   

Hi Motoo Tanaka,

    I have tried  your  program ,not mine. I  change CyDelay(10) to CyDelay(1), and still have the problem.

0 Likes
IssacGabriel
Level 1
Level 1
First reply posted Welcome!

I  change CyDelay(10) to CyDelay(1)

0 Likes