mega16a pwm problem

Go To Last Post
31 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I want some help as i cannot be able to create pwm in oc1b & oc2 instead i create what i need to the others two oc0 & oc1a!!! in mega 8515 everything is ok and i use ( assembly) this:

as i have told , with 8515 i an be able to controll the pwm in mega 16a in not!! i use the same way  with ofcourse the changes that are necessarily as the output ports and the include file..

if somebody could help me i thank you in advance.

Attachment(s): 

This topic has a solution.
Last Edited: Thu. Mar 14, 2019 - 06:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To prevent others from having to open that potentially dangerous .docx file all it contains is:

.include "m8515def.inc"   
 .cseg
 .org 0
 rjmp reset
 reset:
 ldi r16,high(ramend)
 out sph,r16
 ldi r16,low(ramend)
 out spl,r16
 ldi r16,0xff; setting of interesting ports as outputs
 out ddrb,r16
 out ddrd,r16
 out ddre,r16
 out porte,r16
 ldi r16,0x05; duty cycle out of ff( 255)
 out ocr0,r16
 ldi r16,0x74
 out tccr0,r16; setting of pwm0
 ldi r16,0xf1
 out tccr1a,r16
 ldi r16,0x04
 out tccr1b,r16
 ldi r16,0xaf
 out ocr1al,r16
 ldi r16,0xf0
 out ocr1bl,r16

What it appears to be doing is:

SP = RAMEND;
DDRB = 0xFF;
DDRD = 0xFF;
DDRE = 0xFF;
PORTE = 0xFF;
OCR0 = 5;
TCCR0 = (1 << WGM0) | (3 << COM00) | (1 << CS02); // timer 0: Mode 1 = PWM phase correct, Set on compare match, FCPU/256
TCCR1A = (3 << COM1A0) | (3 << COM1B0) | (1 << WGM10); // timer1: Mode 1 = 8bit PWM phase correct, Set 1A/1B on compare
TCCR1B = (1 < <CS12) ; FCPU/256
OCR1AL = 0xAF;
OCR1BL = 0xF0;

I would have thought this would be very similar for mega16 ??

 

But I don't really understand the post. Is he asking to switch OC0, OC1A, OC1B to other PWM channels /pins in the move to mega16 ?

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

i want to have in oc2,oc1a,oc1b pwm control but i cannot!! only in oc1a, and if i change oc2 with oc0 in oc0 i have pwm!!i have change three avrs but the same problem..

Last Edited: Thu. Mar 14, 2019 - 06:18 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To do a 16-bit write, the high byte must be written before the low byte.

For a 16-bit read, the low byte must be read before the high byte.

 

From page 86 of the ATmega16 datasheet.  

 

The clawson listing shows that the OP is writing to OCR1AL and OCR1BL,  but the OCR1AH and OCR1BH registers are not written first.

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

Thank you but in mega 8515 my program runs ok and what about oc2?? Firstly I run pwm 8 bit....secondly oc0 runs ok too, but oc2 and oc1b not

Last Edited: Thu. Mar 14, 2019 - 06:19 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The problem is that i can have pwm on ocia, oc0 but ,with out be undestood by my, not in oc1b, oc2 - Is some thing missing by my? i can control the pins of oc2 and oc1b as outputs ( send 0 and i have 0volt send 1 and i have 5 volts) but not to activate pwm! i want to control peltier coolers Any ideas please? It seems like the avr have problem but is it this the right answer? As i have already told i have change three cips of avr mega 16a....

 

Last Edited: Thu. Mar 14, 2019 - 06:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well one thing that is wrong with your code is that there isn't an infinite loop at the end so it will run on to the end of memory and back to the start and reset the timer repeatedly.

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

athmio wrote:

... oc0 runs ok too, but oc2 and oc1b not

 

But I don't see any code to initialise OC2

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

SORRY I DID NOT WRITE IT HERE BUT THERE IS A LOOP AT THE END OF MY PROGRAM .. AS I SAID IN 8515 RUNS OK ... ONLY IN 16 I CAN NOT CONTROL PWM IN OC2 OC1B

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

I write an example of my code if i use oc0 ok if i use oc2 no ! in that case insted of tccr0 i write to tccr2 and insted of ocr0 to ocr2...

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

athmio wrote:

SORRY I DID NOT WRITE IT HERE BUT THERE IS A LOOP AT THE END OF MY PROGRAM .. 

 

 

1) PLEASE DON'T SHOUT, it is considered rude.

 

2) Please post all your code as it is written. If you only show us parts of it then how can we help?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

I do not shout!! why you said something like that?????

The code i send here is what is runs on 8515 the same ( but with correct include..) runs on m16a where only oc1a and oc0 can play pwm..

the include is: .include"m16adef.inc"

Attachment(s): 

Last Edited: Thu. Mar 14, 2019 - 09:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

athmio wrote:

The code i send here is what is runs on 8515 the same ( but with correct include..) runs on m16a where only oc1a and oc0 can play pwm..

the include is: .include"m16adef.inc"

 

Sorry but I am not going to open a .docx file from a stranger.

 

Use cut and paste to paste your code here in the forum. 

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

athmio wrote:

I do not shout!! why you said something like that?????

 

athmio wrote:

SORRY I DID NOT WRITE IT HERE BUT THERE IS A LOOP AT THE END OF MY PROGRAM .. AS I SAID IN 8515 RUNS OK ... ONLY IN 16 I CAN NOT CONTROL PWM IN OC2 OC1B

 

Err. because you did...

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

At great risk - here is the text from the attachment in #12:

 

.include "m16αdef.inc"   
 .cseg
 .org 0
 rjmp reset
 reset:
 ldi r16,high(ramend)
 out sph,r16
 ldi r16,low(ramend)
 out spl,r16
 ldi r16,0xff; setting of interesting ports as outputs
 out ddrb,r16
 out ddrd,r16

 ldi r16,0x05; duty cycle out of ff( 255)
 out ocr2,r16
 ldi r16,0x74
 out tccr2,r16; setting of pwm0

 ldi r16,0xf1; setting of pwm1a,1b
 out tccr1a,r16
 ldi r16,0x04
 out tccr1b,r16
 ldi r16,0xaf
 out ocr1al,r16
 ldi r16,0xf0
 out ocr1bl,r16
 e:
 rjmp e

The problem is that i can have pwm on ocia, oc0 but ,with out be undestood by my, not in oc1b, oc2 - Is some thing missing by my? 
i can control the pins of oc2 and oc1b as outputs ( send 0 and i have 0volt send 1 and i have 5 volts) but not to activate pwm! 
i want to control peltier coolers Any ideas please? It seems like the avr have problem but is it this the right answer? 
As  i have change three cips of avr mega 16a....

It's no easier to follow than last time he posted it!

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

no i am not! i simply wrote something with capital letters and i continued to answer you with out  pressing cap lock...

Last Edited: Thu. Mar 14, 2019 - 10:57 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

is something else that i could send to you to be better understood ?i use ( as only that i know)  assembly

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

Surely you should learn to read C.

Even if you use ASM,  it is wise to use official BIT_NAMEs.    I am happy with AVRs but I have no idea what your magic values mean.

 

     //Mega16: OC0=PB3, OC1A=PD5, OC1B=PD4, OC2=PD7
     DDRB = (1<<PB3);
     DDRD = (1<<PD5)|(1<<PD4)|(1<<PD7);
     TCCR0 = (1<<WGM01)|(1<<WGM00)|(2<<COM00)|(1<<CS00); //PWM#3, non-inverting, div1
     OCR0 = 16;  //set duty-cycle 16/256
     TCCR1A = (2<<COM1A0)|(2<<COM1B0)|(1<<WGM11)|(1<<WGM10); //non-inverting, PWM#7
     TCCR1B = (1<<WGM12)|(1<<CS10); //PWM#7, div1
     OCR1AH = 0;
     OCR1AL = 5; //duty-cycle = 5 / 1024
     OCR1BH = 3;
     OCR1BL = 0; //duty-cycle = 3*256 / 1024
     TCCR2 = (1<<WGM21)|(1<<WGM20)|(2<<COM20)|(1<<CS20); //PWM#3, non-inverting, div1
     OCR2 = 100;  //set duty-cycle 100 / 256
     while (1) ;      

To convert this to ASM is nothing more than

 

     ldi r16, (1<<PB3)    ; OC0 
     out DDRB, r16        ; write to special function register DDRB
     ...
     ; some SFRs might need STS instead of OUT
     ...
loop:
     rjmp loop            ; while (1) ; 

Untested.   You can run it in the Simulator.

 

The complicated part of ASM or C is looking up the BIT_NAMEs in the datasheet.

 

David.

 

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

So what you suppose the problem is? my assembly runs on mega 8515 ! runs too to mega 16a but only for ocr1a,oc0... ( the half of the four pwm outputs) ..???

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

athmio wrote:
( the half of the four pwm outputs)
But your code only programs:

OCR0 = 5;
TCCR0 = (1 << WGM0) | (3 << COM00) | (1 << CS02); // timer 0: Mode 1 = PWM phase correct, Set on compare match, FCPU/256
TCCR1A = (3 << COM1A0) | (3 << COM1B0) | (1 << WGM10); // timer1: Mode 1 = 8bit PWM phase correct, Set 1A/1B on compare
TCCR1B = (1 < <CS12) ; FCPU/256
OCR1AL = 0xAF;
OCR1BL = 0xF0;

That only attempts to create THREE PWM outputs (not four). It is programming timer 0 for one output that should appear on pin PB3, physical pin 4 (aka "OC0"). It is programming A and B outputs on timer 1. They should appear on pins PD4 and PD5,. physical pins 18 ("OC1B") and 19 ("OC1A").

 

You seem to be confirming that pin 4 and pin 19 are working to produce PWM on the mega16? So are you saying there is no activity on pin 18 (OC1B)? Which other pin were you expecting to see PWM output on?

 

As far as I can see mega16 only has the for PWM channels: OC0, OC1A, OC1B and OC2 but there's nothing in your code to access timer 2 so OC2 is not going to be active. 

 

It is true that if you see nothing on OC1B (pin 18) then that is odd because, like OC1A, you do appear to be enabling that to produce a signal.

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

thank you for your reply, my code is an example not the real program . For example instead of tccr0 and ocr0 i can write tccr2 ,ocr2 is it the same and when i use ocr0 tccr0 i have pwm on oc0 output when i use tccr2 ocr2 i have nothing , the same is on oc1b where there is nothing but on oc1a everything is ok. so simply the half of the avr works! and i have used three avrs till know in case there is a failure on the chip

Last Edited: Thu. Mar 14, 2019 - 12:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

not only that but according to datasheet if you enable pwm than you are not be able to control this pin as normal output ! But i can .. on oc1a no on oc0  no where in both i have pwm on oc2 and oc1b  i can control then as normal outputs! it seems as there is nothing in side the avr that produce pwm on oc2-oc1b!!!!

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

I wonder if it would be easier for you to post in your natural language then use Google Translate. So far I haven't a clue what it is you are trying to achieve here. Are you saying that the code you have been posting is NOT the code you are asking about? If not then how on earth do you expect anyone to be able to help without seeing the real code you are trying to use??

 

Of the code you have posted so far (and please don't use .docx again - they can be full of viruses!) it only appears to be trying to configure three PWM channels yet you seem to have some expectation that four channels should be activated. So is that some other code??

 

If you do post code again then use this:

and paste the text of your program into the box that appears. That will put it inline into the post here like:

.include "m8515def.inc"   
 .cseg
 .org 0
 rjmp reset
 reset:
 ldi r16,high(ramend)
etc.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
.include"m16adef.inc"
.cseg
.org 0
rjmp reset
reset:
ldi r16,high(ramend)
out sph,r16
ldi r16,low(ramend)
out sph,r16
ldi r16,0xff
out ddrb,r16
ldi r16,0x65
out ddrd,r16; only 0,2,4,5,7 are out-6,3,1 are in
ldi r16,0xc6
out ocr0,r16
out ocr2,r16
ldi r16,0x74
out tccr0,r16
out tccr2,r16
ldi r16,0xf1
out tccr1a,r16
ldi r16,0x03
out tccr1b,r16
ldi r16,0xc6
out ocr1al,r16
out ocr1bl,r16
e:
rjmp e

this is my program , what do we expect if we run this? do we expect pulses on oc0,oc2,oc1a,oc1b?Yes? but no! i have pulses only in oc0,0c1a! why?

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

Thank you in advance all of you for your reply and for your help . i found that if i make all pind as outputs then it works! if i make only same of them then no! even if pins with pwm are wrote as outputs ..i don't know why but that is   if somebody knowswhy this happened please let me explain thank you again.

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

Seriously.   You will get on much better if you use the official bit-names.

     //Mega16: OC0=PB3, OC1A=PD5, OC1B=PD4, OC2=PD7
     DDRB = (1<<PB3);
     DDRD = (1<<PD5)|(1<<PD4)|(1<<PD7);
//   DDRB = 0b10110000
//   DDRB = 0xB0
// you had  0x65
// which is 0b01100101

You might be able think in hexadecimal but most humans do not.

It takes a few minutes to type the correct symbols, expressions.

It will stop you wasting hours when something does not work.

 

David.

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

yes i have 65h because i need some of portd pins as out too and the rest as inputs  in binary is 10110101

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
//   DDRB = 0b10110000  //0xB0
// you have 0b01100101  //0x65

You can see the difference.   Only DDRB.4 is still true.   PORTB.4 is OC1B

 

OC1A and OC2 are no longer Outputs.    So PWM is disabled on OC1A, OC2

 

David.

Last Edited: Thu. Mar 14, 2019 - 08:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

YOU ARE RIGHT! my calculator gave me b5 but i recognize it as 65 ...it is so embarrassing thank you again..

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

That assembler accepts binary you know? If you wanted 10110101 and don't immediately recognize this as B5 (just break it up into blocks of 4 then do 0000..11111 = 0..F translation) then use:

ldi r16, 0b10110101

In fact I seem to remember that to make things easier to read it accepts '_' as a group divider so:

ldi r16, 0b1011_0101

which is possibly easier to read?

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

Thank you very much!