AVR ATmega2560 Timer1 Mode10 expecting PWM on PB7 pin but nothing!

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#ifndef F_CPU
	#define F_CPU 16000000L // Specify oscillator frequency
#endif

#include <avr/io.h>
#include <util/delay.h>
#define myPWM_TMODE 10
 void myPWM_init()
 {
		 ICR1=20000;
		 DDRB|=(1<<7);
		 TCCR1A=((myPWM_TMODE & 0x03)<<WGM10)|(1<<COM1C0);
		 OCR1C=(ICR1>>1)-1;		//50% dutycycle
		 TCCR1B=(((myPWM_TMODE & 0x0C)>>2)<<WGM12)|(1<<CS11)|(0<<CS10);		//pres scaler 0x04=256 0x03=64	//0x02=8	//0x01=1
 }
 
int main(void)
{	
	myPWM_init();		
    while(1)
    {
		OCR1C=9999;
    }
}

I am expecting 50Hz Freq on PB7/OC1C pin but nothing happens. I am doing it for servo motor, after programming LED on arduino mega 2560 doesnt blink at all i.e. L.

This topic has a solution.

AVR Rocks but can be Bricked too smiley

Last Edited: Tue. Aug 15, 2017 - 07:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
 TCCR1A=((myPWM_TMODE & 0x03)<<WGM10)|(1<<COM1C0);

I think you want COM1C1 ?

 

[when doing sanity-check work, it helps my hairline to do Fast  PWM first]

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tried this but , Arduino mega 2560 pin 13 is has internal LED which is not blinking.
 

AVR Rocks but can be Bricked too smiley

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OMG! actually that code works but it was funny to know that led was blinking so fast :) i reduced freq 25Hz and now its blinking i can see! thanks.

 

#ifndef F_CPU
    #define F_CPU 16000000L // Specify oscillator frequency
#endif

#include <avr/io.h>
#include <util/delay.h>
 #define myPWM_TMODE 10
 void myPWM_init()
 {
        //COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10---- TCCR1A
         //
         ICR1=5000; //25Hz
         //    ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10 TCCR1B
         //PORTB|=(1<<5);
         DDRB|=(1<<7);//PORTB|=(1<<7);
         TCCR1A=((myPWM_TMODE & 0x03)<<WGM10)|(1<<COM1C1)|(0<<COM1C0);
         OCR1C=(ICR1>>1)-1;        //50% dutycycle
         TCCR1B=(((myPWM_TMODE & 0x0C)>>2)<<WGM12)|(1<<CS11)|(1<<CS10);        //pres scaler 0x04=256 0x03=64    //0x02=8    //0x01=1
 }
int main(void)
{    
    myPWM_init();        
    while(1)
    {
               
    }
}


 

 

AVR Rocks but can be Bricked too smiley

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you sure that you are loading the correct build results?

 

Perhaps show the code you are using now.

 

Perhaps use a simpler mode such as CTC to see if the LED is actually working the way you think.  Are there other output pins you can experiement with?

 

I Googled for Arduino Mega pin mapping, and the list I found agrees that digital pin 13 is PB7.

 

CodeVision Wizard agrees with your setup...

 

...
// Port B initialization
// Function: Bit7=Out Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRB=(1<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
...
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 2000.000 kHz
// Mode: Ph. correct PWM top=ICR1
// OC1A output: Disconnected
// OC1B output: Disconnected
// OC1C output: Non-Inverted PWM
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 20 ms
// Output Pulse(s):
// OC1C Period: 20 ms Width: 9.999 ms
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (1<<COM1C1) | (0<<COM1C0) | (1<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (0<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x4E;
ICR1L=0x20;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x27;
OCR1CL=0x0F;

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#ifndef F_CPU
	#define F_CPU 16000000L // Specify oscillator frequency
#endif

#include <avr/io.h>
#include <util/delay.h>
 #define myPWM_TMODE 10
 void myPWM_init()
 {
		//COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10---- TCCR1A
		 //
		 ICR1=20000;
		 //	ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10 TCCR1B
		 //PORTB|=(1<<5);
		 DDRB|=(1<<7);//PORTB|=(1<<7);
		 TCCR1A=((myPWM_TMODE & 0x03)<<WGM10)|(0<<COM1C1)|(1<<COM1C0);
		 OCR1C=(ICR1>>1)-1;		//50% dutycycle
		 TCCR1B=(((myPWM_TMODE & 0x0C)>>2)<<WGM12)|(1<<CS11)|(0<<CS10);		//pres scaler 0x04=256 0x03=64	//0x02=8	//0x01=1
 }
int main(void)
{	
	myPWM_init();		
    while(1)
    {	
    }
}

Timer 1 mode 10 ; PWM freq=50Hz with 50% duty cycle; PB7 pin of Arduino Mega 2560. Thanks now its OK.

AVR Rocks but can be Bricked too smiley

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

engineer.pk wrote:
Thanks now its OK.

???

 

But you have the same issue that I pointed out in #2  ?!?

 

 TCCR1A=((myPWM_TMODE & 0x03)<<WGM10)|(0<<COM1C1)|(1<<COM1C0);

According to the datasheet table, COM1:0 value of 0:1 is a pin disconnected from the timer in that mode.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Tue. Aug 15, 2017 - 07:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
TCCR1A=((myPWM_TMODE & 0x03)<<WGM10)|(1<<COM1C1)|(0<<COM1C0);

Works as you pointed out, THanks,

AVR Rocks but can be Bricked too smiley

Last Edited: Tue. Aug 15, 2017 - 07:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everyone,

I am not sure if posting to this thread is as it is marked solved is a good thing to do but as I have the same problem it seemed silly to start another one.

 

I am using a ATMega2560 on a Arduino Mega2560 board to drive a 3 Phase Brushless DC motor with a 20KHz PWM signal from the 3 outputs of Timer1 in mode 10.

Output from A & B on device pins 24 & 25 (Digital Pins 11/12) are fine, however device pin 26 (Digital Pin 13) just sits at 0V.

 

I am aware from section 19 of the device data sheet that pin 26 (Digital Pin 13) shares its PWM output with the A output of Timer 0 and that which one is presented at the pin is dependent on the COMnx bits of the relevant TCCRnx registers. Unless I have been very unfortunate in that both boards/devices I have tried are broken I can only assume the problem must be with my code/device set up, I have cut my code down to be bare minimum to try and isolate the problem although I must be code blind as I still cannot find it, it looks correct to me.

I am coding and uploading using the Arduino IDE and its default fuse setting for the board, can anyone see where I have gone wrong?

 

//Load required Includes - Complete 31/03/2017
#include <avr/wdt.h>    //Include for Watchdog Timer - sgm June 2017

//*** Assign Alias's to Arduino board I/O pin numbers *** - complete 06/06/2017
//MOTOR CONTROL
#define PWM_SPARE 11    //Spare PWM output (OC1A)
#define DCM_PWM 12    //DC Load Machine PWM/Inhibit (OC1B) - rename DC PWM.
#define PWM 13          //PWM source for single BLDCM phase PWM signal / Always high gate for individual BLDCM phase PWM signals (OC1C) 

void setup() {

TCCR0A = TCCR0A & 0x3F;           //Disconnect Timer OCOA output from Digital Pin 13 (PB7) so that it can be used by Timer 1.
TCCR1A = (TCCR1A & 0x00) | 0xAA;  //Ensure TCCR1A is clear then Set for Phase Correct PWM, TOP = ICRn, output = A, B & C (1010 1010)
TCCR1B = (TCCR1B & 0x00) | 0x11;  //Ensure TCCR1B is clear then set for PWM, no Prescaling 0001 0001 - DO NOT CHANGE bit 7:3
TCCR1C = (TCCR1C & 0x00);         //Ensure TRRC1C is clear, TCCR1C not used, just belt & braces code
ICR1 = 0x0190;                    //Use IRCn to Set TOP for a 20KHz PWM Frequency  = 400 ($0190) 

//Set up Baud rate for Serial (USB) coms - Complete
//Serial.begin(19200);

//Set up initial state for Infineon Motor drivers & PWM Signal- Complete 07/06/2017
digitalWrite(PWM_SPARE, LOW);  //No PWM - Output in Tristate condition
digitalWrite(DCM_PWM, LOW);  //No DC Load Machine PWM - Output in Tristate condition
digitalWrite(PWM, LOW);  //No PWM - Output in Tristate condition

//*** Set up I/O status of Infineon Motor driver control & PWM output pins ***
//Set DC Load Machine PWM control pins to Outputs (Digital Pins) - Complete 06/06/2017
pinMode(DCM_PWM, OUTPUT);
pinMode(PWM, OUTPUT);
pinMode(PWM_SPARE, OUTPUT);

//Set Modulation depth (Testing only)
analogWrite(PWM, 100);        //25% Modulation depth
analogWrite(DCM_PWM, 200);    //50% Modulation depth
analogWrite(PWM_SPARE, 300);  //75% Modulation Depth

WDTO_2S;  //2 Second Time out (Watchdog Timer enabled at power up)
}
// END OF SETUP

//=========================
//=== Main Program loop === does not return data (Void) - basically done needs a few tweeks
//=========================
void loop() {

//Reset Watchdog Timer (AVR/wdt.h)
wdt_reset();
//asm volatile("wdr");  //Reset Watchdog Timer using Assembler command - I hope?
}
//=== END OF Main Program Loop ===

Regards,

Stephen

Last Edited: Thu. Oct 19, 2017 - 08:58 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What follows might not be a solution to your problem, but is at least advice on how to make your code more easily debugged, and more easily read by yourself and all of us here:

 

TCCR1A = (TCCR1A & 0x00) | 0xAA;

Don't over-complicate things. First anything & 0 is 0, so now we have

TCCR1A = 0 | 0xAA;

Next, 0 | something is something, so we're left with

TCCR1A = 0xAA;

Then make things clearer: refrain from using magic numbers (like 0xAA) where you and us need to decipher to 1010 1010 and go back to the data sheet to check out what those bits of TCCR1A are: COM1A1, COM1B1, COM1C1, WGM11. Now the shift-operator comes in handy and we do some bit-wise operations that actually makes for clearer, more easily read code:

 

TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<COM1C1) | (1<<WGM11);

From that code it is instantly clear what bits are set.

 

Likewise for TCCR1B, we get

TCCR1B = (1<<WGM13) | (1<<CS10);

and for TCCR1C the simple

TCCR1A = 0;

 

So we have mode 10 if my reading is correct, i.e. phase correct PWM with TOP in ICR1. Seems just about right.

 

For the COMnA1:0 bits we have the value (binary) 10 which is "clear on compare match". Also OK, it seems.

 

You're never setting OCR1A or OCR1B though. A duty-cycle of 0% is not a far-fetched hypothesis..

 


 

Next, it makes no little sense to me to use hex notation when setting the TOP/ICR1 value. This is perhaps better

ICR1 = 400;

but the real clarity would come from an expression stating explicitly how you got to 200.

 


 

I have not checked that your assumptions of mappings of pins from 2560 pin numbers to Arduino pin numbers are correct.

 

I am a bit suspicious about the comment 

Disconnect Timer OCOA output from Digital Pin 13 (PB7) so that it can be used by Timer 1.

but am too lazy ;-) to check whether Timer/Counter0 and Timer/Counter1 actually interfere with one another in this way.

 


Side notes:

TCCR1B = (TCCR1B & 0x00) | 0x11;  //Ensure TCCR1B is clear then set for PWM, no Prescaling 0001 0001 - DO NOT CHANGE bit 7:3

The comment is wrong. The statement does not in any way guarantee that bit 7:3 is left untouched. The statement always sets bits 7:5 and 3:1 to zero. Bits 4 and 0 are set to one.

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Thu. Oct 19, 2017 - 10:22 AM