- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
And it seems doing fine.
Then I saw your schematic,
To me 4MHz clock seemed to be too high, for a sound
so I modified it to 40KHz
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo Tanaka,
I will try your new program ,today.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo Tanaka,
I have tried your program ,not mine. I change CyDelay(10) to CyDelay(1), and still have the problem.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content