Code translation to generate sine wave PWM

ted
Sun Jun 10, 2018 10:21 pm
How convert this code to stm32

ISR (TIMER1_OVF_vect) {
static uint8_t n=0;
OCR1A = OCR1B= sine_wave[n];
n++;


ted
Mon Jun 11, 2018 8:45 pm
I am trying to modify simple sine wave generator for stm32f103,
uint8_t sine_wave[256] = {
0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
};

void setup(){
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
TCCR1B = (1<<WGM13)|(1<<CS10);
TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<COM1B0);
TIMSK1 = 1<<TOIE1;
ICR1=511; //считать до 255
OCR1A=0; //
OCR1B=0;
}

ISR (TIMER1_OVF_vect) {
static uint8_t n=0;
OCR1A = OCR1B= sine_wave[n];
n++;
}

void loop(){
}


dannyf
Mon Jun 11, 2018 9:35 pm
The code piece is trying to change duty cycles on two compare channels upon timer 1 overflow.

Once you know that, it is a piece of cake to replicate it on a stm32.


ted
Tue Jun 12, 2018 11:59 am
I know that but I don’t know how to modulate.
Similar code is below, this part need to be modulated.
pwmtimer2.setCompare(TIMER_CH4, 5000);

stevestrong
Tue Jun 12, 2018 4:54 pm
You don’t need to declare extra timer instance for timer2, there is one Timer2 already declared by default.
And you have to attach an interrupt service routine to do your job:
volatile uint8_t index;
void Tim2_ISR(void)
{
Timer2.setCompare(TIMER_CH4, sine_wave[index++]);
}
void setup()
{
index = 0;
pinMode(PA3, PWM);
//pinMode(PB11, PWM);
Timer2.pause();
Timer2.setPrescaleFactor(1);
Timer2.setOverflow(10000-1);
Timer2.setCompare(TIMER_CH4, 5000);
Timer2.refresh();
Timer2.attachInterrupt(0, Tim2_ISR); // add this line to activate the Timer2 ISR on update event
Timer2.resume();
}

ted
Tue Jun 12, 2018 6:55 pm
uint8_t sine_wave[256] = {
0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
};
///////////////////////////////////////////

volatile uint8_t index;
void Tim2_ISR(void)
{
Timer2.setCompare(TIMER_CH4, sine_wave[index++]);
}
void setup()
{
index = 0;
pinMode(PA3, PWM);
//pinMode(PB11, PWM);
Timer2.pause();
Timer2.setPrescaleFactor(1);
Timer2.setOverflow(10000-1);
Timer2.setCompare(TIMER_CH4, 5000);
Timer2.refresh();
Timer2.attachInterrupt(0, Tim2_ISR); // add this line to activate the Timer2 ISR on update event
Timer2.resume();
}


ted
Tue Jun 12, 2018 7:08 pm
Should I do something with 5000 ?
5000 it is 1/2 of 10000 = 50% duty cycle

Timer2.setCompare(TIMER_CH4, 5000);


Rick Kimball
Tue Jun 12, 2018 10:45 pm
[ted – Tue Jun 12, 2018 6:55 pm] –
‘volatile uint8_t index’ redeclared as different kind of symbol

index is also a function index() …

rename index to indx or put the entire block in a namespace { your code }


ted
Tue Jun 12, 2018 11:25 pm
No errors and no sine wave, narrow impulses.
uint8_t sine_wave[256] = {
0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
};
///////////////////////////////////////////

volatile uint8_t indx;
void Tim2_ISR(void)
{
Timer2.setCompare(TIMER_CH4, sine_wave[indx++]);
}
void setup()
{
indx = 0;
pinMode(PA3, PWM);
//pinMode(PB11, PWM);
Timer2.pause();
Timer2.setPrescaleFactor(1);
Timer2.setOverflow(10000-1);
// Timer2.setCompare(TIMER_CH4, sine_wave[index++]);
//Timer2.setCompare(TIMER_CH4, 5000);
Timer2.refresh();
Timer2.attachInterrupt(0, Tim2_ISR); // add this line to activate the Timer2 ISR on update event
Timer2.resume();
}


stevestrong
Wed Jun 13, 2018 12:14 pm
This should work, tested:
void setup()
{
indx = 0;
pinMode(PA3, PWM);
//pinMode(PB11, PWM);
Timer2.pause();
Timer2.setOverflow(256); // maximum value of the sine wave, according to the used table
Timer2.setCompare(TIMER_CH4, 128); // half of the maximum value, optional, overwritten by the ISR
Timer2.refresh();
Timer2.attachInterrupt(0, Tim2_ISR); // add this line to activate the Timer2 ISR on update event
Timer2.resume();
}

ted
Wed Jun 13, 2018 1:43 pm
Thanks
Is almost working, I have a sine wave 550Hz, but it is shaking, like modulated with 2 or 3 Hz

Leave a Reply

Your email address will not be published. Required fields are marked *