Go Down

### Topic: Programming PWM for Generating 0~3Mhz  (Read 148 times)previous topic - next topic

#### DrVoid

##### Apr 22, 2018, 11:47 am
Hi guys i need a lot of helps.

I upload sketch file from ard_newbie.
Original code from https://forum.arduino.cc/index.php?topic=396125.0 at #4
And im customizing for mine.

I made a function to use easy.
using 2MHz/CPRD = x Hz -> CPRD = 2000000/xHz

void setCPRD(unsigned int hz){
PWM->PWM_CH_NUM[2].PWM_CPRD=(2000000/hz);
}

Second Question

PIOC->PIO_PDR |= PIO_PDR_P7;
Above the sentence what is that exactly saying.
extra question
I checked due's pin out and see PWMH2.
Does it can ues only labled PWMH2?
I want to know exactly.
Third Question

If i use the code digital pin39 generate 1khz pulse with 5% duty rate?

Forth Question
About PWM_handler is it for test?

#### ard_newbie

#1
##### Apr 22, 2018, 05:01 pm
Have a look at this PWM Library for the DUE:

https://github.com/antodom/pwm_lib

#### DrVoid

#2
##### Today at 01:32 amLast Edit: Today at 08:25 am by DrVoid
Im watching and found some.
https://www.arduino.cc/en/Hacking/PinMappingSAM3X

First about setCPRD i just compiled and compiler gives me error "expression can not be used as a function" but i want to use it as function.

Second when i alloc another pin for pwm to generate to pulse does the pin must be PWMH? or can use PWML?

Code: [Select]
`void setCPRD(int num, unsigned int hz);void setup () {  PWM_Init();  setCPRD(1,1);//output1 :1hz (duty rate 50%) for test  setCPRD(2,2);//Output2 :2hz(duty rate 50%) for test}void loop() {   // Todo : update frequency with PWM_CPRDUPD in loop()  // update duty with PWM_CDTUPD in loop()  } void PWM_Init() {  // PWM Set-up on pins PC7 and PA20 (Arduino Pins 39(PWMH2) : see Datasheet chap. 38.5.1 page 973  PMC->PMC_PCER1 |= PMC_PCER1_PID36;                    // PWM power ON  PWM->PWM_DIS = PWM_DIS_CHID2;                         // Disable PWM channel 2  PWM->PWM_DIS = PWM_DIS_CHID2;                         // Disable PWM channel 3  // Select Instance=PWM; Signal=PWMH2 (channel 2); I/O Line=PC7 (P7, Arduino pin 39, see pinout diagram) ; Peripheral type B  PIOC->PIO_PDR |= PIO_PDR_P7;                          // Set the pin to the peripheral PWM, not the GPIO  PIOC->PIO_ABSR |= PIO_PC7B_PWMH2;                     // Set PWM pin perhipheral type B  //  Select Intancd=PWMl Signal=PWMH3 (channel 2); I/O LIne=PC9 (P9, Arduino pin 41, see pinout diagram) ; Peripheral type B  //Added by me for generate another pulse  PIOC->PIO_PDR |= PIO_PDR_P9;                          // Set the pin to the peripheral PWM, not the GPIO  PIOC->PIO_ABSR |= PIO_PC9B_PWMH3;                     // Set PWM pin perhipheral type B    PWM->PWM_CLK = PWM_CLK_PREB(0) | PWM_CLK_DIVB(28);    // Set the PWM clock rate to 3MHz (84MHz/28).  PWM->PWM_CH_NUM[2].PWM_CMR = PWM_CMR_CPRE_CLKB;       // clock source as CLKB on channel 2, waveform left aligned  //Added by me  PWM->PWM_CH_NUM[3].PWM_CMR = PWM_CMR_CPRE_CLKB;       // clock source as CLKB on channel 3, waveform left aligned   PWM->PWM_CH_NUM[2].PWM_CPRD = 3000;                   // Channel 2 : Set the PWM frequency 3MHz/CPRD = 1 KHz ;  PWM->PWM_CH_NUM[2].PWM_CDTY = 1500;                    // Channel 2: Set the PWM duty cycle to x%= (CDTY/ CPRD)  * 100 % ;  //Added by me for another pulse out  PWM->PWM_CH_NUM[3].PWM_CPRD = 3000;                   // Channel 3 : Set the PWM frequency 3MHz/CPRD = 1 KHz ;  PWM->PWM_CH_NUM[3].PWM_CDTY = 1500;                    // Channel 3: Set the PWM duty cycle to x%= (CDTY/ CPRD)  * 100 % ;   PWM->PWM_IER1 = PWM_IER1_CHID2;                       // Interrupt on Channel 2 Counter match  //Added by me for channel 3  PWM->PWM_IER1 = PWM_IER1_CHID3;                       // Interrupt on Channel 3 Counter match  NVIC_EnableIRQ(PWM_IRQn);                             // Enable interrupt   PWM->PWM_ENA = PWM_ENA_CHID2;                         // Enable PWM Channel 2  //Added by me  PWM->PWM_ENA = PWM_ENA_CHID3;                         // Enable PWM Channel 3}void setCPRD(int num,unsigned int hz){  if(num==1)    PWM->PWM_CH_NUM[2].PWM_CPRD=(3000000/hz);  else (num==2)    PWM->PWM_CH_NUM[3].PWM_CPRD=(3000000/hz);  }`

#### ard_newbie

#3
##### Today at 06:01 am

https://www.arduino.cc/reference/en/language/structure/control-structure/else/

Read the datasheet pages 996 and 1048

#### DrVoid

#4
##### Today at 08:54 amLast Edit: Today at 09:13 am by DrVoid
Umm i reading very carefully and it is pricipal of pwm.
And else cause the compiler says it can not work.

And i see my sourcecode it has same PWM clock rate.
Following datasheet in this case i can use Synchronous Channels(datasheet pages 999 chapter39.6.2.7) and i have a question.
Can output rate could be another if i change?  <- i understood synchronous channels should same output rate & duty rate. And also change interrupt
Am i understand well?

Code: [Select]
`void setCPRD(int num, unsigned int hz);void setup () {  PWM_Init();  setCPRD(1,1);//output1 :1hz (duty rate 50%) for test  setCPRD(2,2);//Output2 :2hz(duty rate 50%) for test}void loop() {   // Todo : update frequency with PWM_CPRDUPD in loop()  // update duty with PWM_CDTUPD in loop()  } void PWM_Init() {  // PWM Set-up on pins PC7 and PA20 (Arduino Pins 39(PWMH2) : see Datasheet chap. 38.5.1 page 973  PMC->PMC_PCER1 |= PMC_PCER1_PID36;                    // PWM power ON  PWM->PWM_DIS = PWM_DIS_CHID2;                         // Disable PWM channel 2  PWM->PWM_DIS = PWM_DIS_CHID2;                         // Disable PWM channel 3  // Select Instance=PWM; Signal=PWMH2 (channel 2); I/O Line=PC7 (P7, Arduino pin 39, see pinout diagram) ; Peripheral type B  PIOC->PIO_PDR |= PIO_PDR_P7;                          // Set the pin to the peripheral PWM, not the GPIO  PIOC->PIO_ABSR |= PIO_PC7B_PWMH2;                     // Set PWM pin perhipheral type B  //  Select Intancd=PWMl Signal=PWMH3 (channel 2); I/O LIne=PC9 (P9, Arduino pin 41, see pinout diagram) ; Peripheral type B  //Added by me for generate another pulse  PIOC->PIO_PDR |= PIO_PDR_P9;                          // Set the pin to the peripheral PWM, not the GPIO  PIOC->PIO_ABSR |= PIO_PC9B_PWMH3;                     // Set PWM pin perhipheral type B    PWM->PWM_CLK = PWM_CLK_PREB(0) | PWM_CLK_DIVB(28);    // Set the PWM clock rate to 3MHz (84MHz/28).  PWM->PWM_CH_NUM[2].PWM_CMR = PWM_CMR_CPRE_CLKB;       // clock source as CLKB on channel 2, waveform left aligned  //Added by me  PWM->PWM_CH_NUM[3].PWM_CMR = PWM_CMR_CPRE_CLKB;       // clock source as CLKB on channel 3, waveform left aligned   PWM->PWM_CH_NUM[2].PWM_CPRD = 3000;                   // Channel 2 : Set the PWM frequency 3MHz/CPRD = 1 KHz ;  PWM->PWM_CH_NUM[2].PWM_CDTY = 1500;                    // Channel 2: Set the PWM duty cycle to x%= (CDTY/ CPRD)  * 100 % ;  //Added by me for another pulse out  PWM->PWM_CH_NUM[3].PWM_CPRD = 3000;                   // Channel 3 : Set the PWM frequency 3MHz/CPRD = 1 KHz ;  PWM->PWM_CH_NUM[3].PWM_CDTY = 1500;                    // Channel 3: Set the PWM duty cycle to x%= (CDTY/ CPRD)  * 100 % ;   PWM->PWM_IER1 = PWM_IER1_CHID2;                       // Interrupt on Channel 2 Counter match  //Added by me for channel 3  PWM->PWM_IER1 = PWM_IER1_CHID3;                       // Interrupt on Channel 3 Counter match  NVIC_EnableIRQ(PWM_IRQn);                             // Enable interrupt   PWM->PWM_ENA = PWM_ENA_CHID2;                         // Enable PWM Channel 2  //Added by me  PWM->PWM_ENA = PWM_ENA_CHID3;                         // Enable PWM Channel 3}void setCPRD(int num,unsigned int hz){ PWM->PWM_CH_NUM[num].PWM_CPRD=(3000000/hz);}`

#### ard_newbie

#5
##### Today at 09:29 am

Your code is still wrong, read Sam3x datasheet page 1048, plus you don't disable PWM channel 3 at the beginning of Pwm_init().

Can output rate could be another if i change?  <- i understood synchronous channels should same output rate & duty rate. And also change interrupt
Am i understand well?
Sorry, I don't understand...

BTW, is it a school assignment ?

#### DrVoid

#6
##### Today at 10:33 amLast Edit: Today at 10:45 am by DrVoid
Thank you for answering my questions every time.
I am an active Korean soldier six months before I leave the army.
I ask you every time during my personal grooming session.
The military can not upload programs to arduino.
What I can do is write the code and compile it.
When I'm out of the army, I make presents for myself with the salaries I collect from the army.
I'm combining their advice and what I want.
Previous people used AstroEQ or ASCOM.
However, I have to create my own telescope control system because it is not compatible with AstroEQ. I am in the process step by step. And i'm struggling with my motordriver.(using 5phase stepping motor)
Also changed about disable PWM channel 3.
still left? may be i needs to watch more.
while output 1 is generating 3hz does output2 should be 3hz or can changable?
if i need to use Synchronous Channels than i have to change my code.
but i add some codes to alloc another pin to generate pulse.
I needs two pulse out and original code can generate one pulse out.
You teach me if i alloc one more another pin could generate pulse.
so i add some codes like orignal style.

#### ard_newbie

#7
##### Today at 10:49 am

In your code, channels are NOT synchro, so PWM channel 2 frequency can be different from PWM channel 3 frequency and you can select any duty cycle.

#### DrVoid

#8
##### Today at 11:16 amLast Edit: Today at 12:09 pm by DrVoid
oh than doese the codes good to generate 0~3Mhz?
and two more question.
Inside of code there is
PWM->PWM_IER1 = PWM_IER1_CHID3;                       // Interrupt on Channel 3 Counter match
i think needs to change this code because PWM_IER1 is for chennel2 how to change?
if i want to increse more than 3mhz
change clock rate for my rate?
Code: [Select]
`void setCPRD(int num, unsigned int hz); void setup () {  PWM_Init();  setCPRD(1,1);//output1 :1hz (duty rate 50%) for test  setCPRD(2,2);//Output2 :2hz(duty rate 50%) for test}void loop() {   // Todo : update frequency with PWM_CPRDUPD in loop()  // update duty with PWM_CDTUPD in loop()  } void PWM_Init() {  // PWM Set-up on pins PC7 and PA20 (Arduino Pins 39(PWMH2) : see Datasheet chap. 38.5.1 page 973  PMC->PMC_PCER1 |= PMC_PCER1_PID36;                    // PWM power ON  PWM->PWM_DIS = PWM_DIS_CHID2;                         // Disable PWM channel 2  PWM->PWM_DIS = PWM_DIS_CHID3;                         // Disable PWM channel 3  // Select Instance=PWM; Signal=PWMH2 (channel 2); I/O Line=PC7 (P7, Arduino pin 39, see pinout diagram) ; Peripheral type B  PIOC->PIO_PDR |= PIO_PDR_P7;                          // Set the pin to the peripheral PWM, not the GPIO  PIOC->PIO_ABSR |= PIO_PC7B_PWMH2;                     // Set PWM pin perhipheral type B  //  Select Intancd=PWMl Signal=PWMH3 (channel 2); I/O LIne=PC9 (P9, Arduino pin 41, see pinout diagram) ; Peripheral type B  //Added by me for generate another pulse  PIOC->PIO_PDR |= PIO_PDR_P9;                          // Set the pin to the peripheral PWM, not the GPIO  PIOC->PIO_ABSR |= PIO_PC9B_PWMH3;                     // Set PWM pin perhipheral type B    PWM->PWM_CLK = PWM_CLK_PREB(0) | PWM_CLK_DIVB(28);    // Set the PWM clock rate to 3MHz (84MHz/28).  PWM->PWM_CH_NUM[2].PWM_CMR = PWM_CMR_CPRE_CLKB;       // clock source as CLKB on channel 2, waveform left aligned  //Added by me  PWM->PWM_CH_NUM[3].PWM_CMR = PWM_CMR_CPRE_CLKB;       // clock source as CLKB on channel 3, waveform left aligned   PWM->PWM_CH_NUM[2].PWM_CPRD = 3000;                   // Channel 2 : Set the PWM frequency 3MHz/CPRD = 1 KHz ;  PWM->PWM_CH_NUM[2].PWM_CDTY = 1500;                    // Channel 2: Set the PWM duty cycle to x%= (CDTY/ CPRD)  * 100 % ;  //Added by me for another pulse out  PWM->PWM_CH_NUM[3].PWM_CPRD = 3000;                   // Channel 3 : Set the PWM frequency 3MHz/CPRD = 1 KHz ;  PWM->PWM_CH_NUM[3].PWM_CDTY = 1500;                    // Channel 3: Set the PWM duty cycle to x%= (CDTY/ CPRD)  * 100 % ;   PWM->PWM_IER1 = PWM_IER1_CHID2;                       // Interrupt on Channel 2 Counter match  //Added by me for channel 3  PWM->PWM_IER1 = PWM_IER1_CHID3;                       // Interrupt on Channel 3 Counter match  NVIC_EnableIRQ(PWM_IRQn);                             // Enable interrupt   PWM->PWM_ENA = PWM_ENA_CHID2;                         // Enable PWM Channel 2  //Added by me  PWM->PWM_ENA = PWM_ENA_CHID3;                         // Enable PWM Channel 3}void setCPRD(int num,unsigned int hz){ PWM->PWM_CH_NUM[num].PWM_CPRD=(3000000/hz);}`

Go Up