Hi all
Am using Freescale Micro controller MC9S08SH8. Iam trying to create a PWM using this controller. Though I have carefully set all the registers related to PWM, Am still unable to generate PWM on this.
The main task was to create a edge aligned PWM on all channels of each PWM.
also am using internal oscillator it has.
Can any one give me some example C Codes for the same or try correcting my code.
Tools am using: Codewarrior suite with P&E Programmer
Controller: MC9S08SH8 20pin
Any kind of help is greatly appreciated
Thanks!
My Code
#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations */void main(void) { EnableInterrupts; /* enable interrupts */ //TIMER1 CH0 n CH1 TPM1SC=0b01001000; TPM1C0SC=0b00101000; //Edge aligned pwm with high true pulses TPM1C1SC=0b00101000; TPM1MOD=400; TPM1C0V=400; TPM1C1V=400; //TIMER2 CH0 n CH1 TPM2SC=0b01001000; TPM2C1SC=0b00100100; //Edge aligned pwm with low true pulses TPM2C0SC=0b00100100; TPM2MOD=400; TPM2C1V=400; TPM2C0V=400;while(1){TPM1C0V=300;TPM1C1V=300;TPM2C1V=300;TPM2C0V=300;} }
Hello, and welcome to the forum.
I have successfully used the assembly equivalent of the following code to generate antiphase PWM signals to directly drive a piezo buzzer device. The code was tested on a '9S08SE8, but should also work for the device you are using.
// TPM1 MODULE:// Generates 4 kHz PWM push-pull output from Ch0 and Ch1 for piezo.// Overflow period: 250 us#ifdef LOW_TRIM#define TPM1MODval 999 //(1) (250*4.00 - 1) 4.00 MHz bus#else#define TPM1MODval 1249 //(2) (250*5.00 - 1) 5.00 MHz bus#endif#define TPM1SCval 0x08 /* 0b00001000 TPM1SC register |||||+++- PS Prescaler divisor 1 |||++---- CLKS Bus rate clock ||+------ CPWMS Edge aligned PWM mode |+------- TOIE No overflow interrupt +-------- TOF Read only flagNote: Clearing TPM1SC register will disable TPM1 module*/#define TPM1C0SCval 0x28 /* 0b00101000 TPM1C0SC register ||||++--- ELS0 High true output pulses ||++----- MS0 PWM mode (edge aligned) |+------- CH0IE No channel interrupt +-------- CH0F Read only flag*/#define TPM1C1SCval 0x2C /* 0b00101100 TPM1C1SC register ||||++--- ELS1 Low true output pulses ||++----- MS1 PWM mode (edge aligned) |+------- CH1IE No channel interrupt +-------- CH1F Read only flagNote: Clearing TPM1CnSC register will disable PWM output*//***************************************************************/// TPM1 module initialisationvoid TPM1_init( void){ TPM1MOD = TPM1MODval; TPM1SC = 0; // Initially disable module}/***************************************************************/// TURN AUDIBLE BEEP ON/OFF#define DUTY_50 (TPM1MODval+1)/2 // PWM duty cycle 50%void BUZZ_ON( void){ TPM1SC = TPM1SCval; // Enable TPM1 module TPM1C0SC = TPM1C0SCval; // Enable TPM1 output Ch0 TPM1C1SC = TPM1C1SCval; // Enable TPM1 output Ch1 TPM1C0V = DUTY_50; // PWM duty cycle 50% TPM1C1V = DUTY_50; // PWM duty cycle 50%}void BUZZ_OFF( void){ TPM1C0SC = 0; TPM1C1SC = 0;}
Regards,
Mac
Hello,
I discovered that the code I previously posted was from an early version of the firmware. The later version is different, presumably because of problems experienced during debugging. Only the BUZZ_ON() function is affected, and the modified code follows.
void BUZZ_ON( void){ TPM1SC = 0; // Disable TPM1 module TPM1C0V = DUTY_50; // PWM duty cycle 50% TPM1C1V = DUTY_50; // PWM duty cycle 50% TPM1SC = TPM1SCval; // Enable TPM1 module TPM1C0SC = TPM1C0SCval; // Enable TPM1 output Ch0 TPM1C1SC = TPM1C1SCval; // Enable TPM1 output Ch1}
I now recall that the channel register settings did not update unless the TPM module was first disabled. I apologise for any confusion.
Regards,
Mac
Hey thanks again for the update. I have changed the code to suit my prupose and since I dont need to use it for buzzer, I didn't encounter any problem. I have a few basic doubts.
What does this do?
#ifdef LOW_TRIM
#define TPM1MODval 999 //(1) (250*4.00 - 1) 4.00 MHz bus
#else
#define TPM1MODval 1249 //(2) (250*5.00 - 1) 5.00 MHz bus
#endif
And also How can I generate PWMs with various frequencies. I mean what register should I vary if I have to change the frequency of my PWM.
Thanks!
Hello,
The PWM period is determined by the modulo setting, within the TPMxMOD register. Assuming the TPM module clock is sourced from the bus, and usually with a prescaler division by 1 for PWM, the number of bus cycles per PWM period will be one more than the modulo value.
The purpose of the preprocessor conditional #defines is to allow for PWM period calibration, in this case for a 250 microseconds period, for two different trim settings associated with the internal reference of the ICS module (using FEI mode).
Regards,
Mac
Thank You bigmac, I ll try to work it out and will update you accordingly
Regards