Unexpected behavior on Output Compare Registers B and C for Timers 4 and 5 on the ATmega1280

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


Hello Everyone! 

I am working on a personal project that needs 12 PWM outputs. When testing it in simulation (I am using Proteus 8) I observed an odd behavior on OCR4B, OCR4C, OCR5B, and OCR4C.

In my code, I take a value from an array and put it in each of the OCR registers I am using. When it comes to the aforementioned registers the value in memory is different from the value in the register.

Below I attached the relevant part of my code and the register/memory values from the simulation.

 

int main(void){
    pwm_init();

    for(;;){
        pwm_set();
    }
    return (0);
}

void pwm_init(){
    TCCR1A |= _BV(WGM11) | _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1);
    TCCR3A |= _BV(WGM31) | _BV(COM3A1) | _BV(COM3B1) | _BV(COM3C1);
    TCCR4A |= _BV(WGM41) | _BV(COM4A1) | _BV(COM4B1) | _BV(COM4C1);
    TCCR5A |= _BV(WGM51) | _BV(COM5A1) | _BV(COM5B1) | _BV(COM5C1);

    TCCR1B |= _BV(WGM13) | _BV(WGM12) | _BV(CS11);
    TCCR3B |= _BV(WGM33) | _BV(WGM32) | _BV(CS31);
    TCCR4B |= _BV(WGM43) | _BV(WGM42) | _BV(CS41);
    TCCR5B |= _BV(WGM53) | _BV(WGM52) | _BV(CS51);

    ICR1 = 0x0FFF;
    ICR3 = 0x0FFF;
    ICR4 = 0x0FFF;
    ICR5 = 0x0FFF;

    DDRB |= _BV(DDB5) | _BV(DDB6) | _BV(DDB7);
    DDRE |= _BV(DDE3) | _BV(DDE4) | _BV(DDE5);
    DDRH |= _BV(DDH3) | _BV(DDH4) | _BV(DDH5);
    DDRL |= _BV(DDL3) | _BV(DDL4) | _BV(DDL5);
}

void pwm_set(){
    OCR1A = duty_cycles[0];
    OCR1B = duty_cycles[1];
    OCR1C = duty_cycles[2];
    OCR3A = duty_cycles[3];
    OCR3B = duty_cycles[4];
    OCR3C = duty_cycles[5];
    OCR4A = duty_cycles[6];
    OCR4B = duty_cycles[7];
    OCR4C = duty_cycles[8];
    OCR5A = duty_cycles[9];
    OCR5B = duty_cycles[10];
    OCR5C = duty_cycles[11];
}

 

 

Here there is the memory value for the elements of the duty_cycle array (index 0 is on address 0x0206)

 

Here there is the value in the registers (OCR1 on line 0x0080, OCR3 on line 0x0090, OCR4 on line 0x00A0, OCR5 on line 0x0120, and it is organized in the format OCRnAL, OCRnAH, OCRnBL, OCRnBH, OCRnCL, OCRnCH)

 

Could anyone help me find out if I made any mistakes in the code? Or this behavior only happens in a simulation?

 

Thanks for your help!

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

Welcome to AVRFreaks!

 

Well, your code above does not show how dutycycle[] array gets set, so we are unable to verify the differences you show are valid....

As for the simulator you will need to contact the support center at Labcenter, as only they can help you there.

 

Jim

 

FF = PI > S.E.T

 

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

I am gobsmacked by the obsessive use of |=

 

Hey-ho.  The RESET values of TCCR1A, TCCR1B, ... are 0 but it just seems wrong to me.

 

Anyway.  You have chosen WGM = mode #14 (Fast PWM).  TOP = 0xFFF,  OCRnx = 0 .. 0xFFF.

 

I have no idea what your duty_cycle() function does.   I assume it is 0 .. 99 for 0 .. 99% duty.  e.g.

OCRnx = (4096uL * duty) / 100;

 

Obviously you have to worry about overflow / underflow in int arithmetic.

 

I have no idea what your memory dump is supposed to show.

 

David.

Last Edited: Tue. May 10, 2022 - 12:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can just set them to 0x0FFF and the same behavior happens:

int main(void){
	pwm_init();

	for(;;){
		debug();
		pwm_set();
	}
	return (0);
}
void debug(){
	duty_cycles[0] = 0x0fff;
	duty_cycles[1] = 0x0fff;
	duty_cycles[2] = 0x0fff;
	duty_cycles[3] = 0x0fff;
	duty_cycles[4] = 0x0fff;
	duty_cycles[5] = 0x0fff;
	duty_cycles[6] = 0x0fff;
	duty_cycles[7] = 0x0fff;
	duty_cycles[8] = 0x0fff;
	duty_cycles[9] = 0x0fff;
	duty_cycles[10] = 0x0fff;
	duty_cycles[11] = 0x0fff;	
}

 

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

Go on.   We have no idea what your duty_cycles() function does.

From #4 I am guessing that it is a macro with an argument that selects the appropriate OCRnx register.

 

From #1 it looks like the argument is a duty percentage value.

 

I would guess that a valid Proteus licence would simulate correctly.

But I (and many readers) possess real-life Arduino MEGA2560.   So we can run the code on real hardware.

 

David.

Last Edited: Tue. May 10, 2022 - 01:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


To save anyone else going to look it up (shame OP didn't include this!)...

 

Also:

 

 

So:

&OCR1A = 0x88
&OCR1B = 0x8A
&OCR1C = 0x8C

&OCR3A = 0x98
&OCR3B = 0x9A
&OCR3C = 0x9C

&OCR4A = 0xA8
&OCR4B = 0xAA
&OCR4C = 0xAC

&OCR5A = 0x128
&OCR5B = 0x12A
&OCR5C = 0x12C

In Studio 7's simulator I see this..

 

 

So it looks a lot like a bug in Proteus. HOWEVER I would suggest trying exactly just this in Proteus and see what the result is...

 

#include <avr/io.h>
#include <avr/cpufunc.h>

int main(void) {
    OCR1A = 0xFFF;
    OCR1B = 0xFFF;
    OCR1C = 0xFFF;

    OCR3A = 0xFFF;
    OCR3B = 0xFFF;
    OCR3C = 0xFFF;

    OCR4A = 0xFFF;
    OCR4B = 0xFFF;
    OCR4C = 0xFFF;

    OCR5A = 0xFFF;
    OCR5B = 0xFFF;
    OCR5C = 0xFFF;

    while(1) {
        _NOP();
    }
}

Get rid of all the duty_cycle[] array nonsense until the core issue has been identified (the problem *could* be that the array is corrupt before the values are written!).

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

My apologies I had misread the square brackets as parentheses.

So the duty_cycles[] array holds the OCRnx addresses or possibly the values.

 

You would need to assign the correct SFR type to the array.   Especially if you want to read and write to the specific hardware SFRs.

 

Yes,  you can get the Compiler to do this but it would be a bit hairy.

Much easier to just use a read_duty(n) and write_duty(n, value) functions that uses a big switch block.

You are not short of Flash memory on a mega1280.

 

David.

 

Edit.   It might be fun to write the hairy struct / typedef array.   Perhaps Cliff will oblige.

Last Edited: Tue. May 10, 2022 - 02:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
array holds the OCRnx addresses or possibly the values.
It holds the values. He's just doing a very circuitous:

OCR1A = 1234;

by actually doing:

uint16_t duty_cycles[10];

...
    duty_cycles[0] = 1234;
...
    OCR1A = duty_cycles[0];
etc.

Only he's writing 0xFFF to all of them but the simulator/debuggers is finding things like 0xF7E in some when it's supposed to be 0xFFF

 

So one of two things is going wrong here. Either between loading 0xFFF into the array and the array being written to OCRnx the 0xFFF is being "stomped on" and becomes 0xF7E. Or the value makes it all the way to assignment but the simulator/debugger's view of OCRxn is showing it to wrongly hold 0xF7E

 

(sure would have helped if OP had just said this in #1 !!)

 

I'm suggesting to him he just uses the raw:

OCRxn = 0xFFF;

style for now and see if the debugger/simulator shows it correct. If it does the chances are its an array stomping. If not it's a bug in the simulator.

 

For comparison I showed that (using the raw access) the AS7 simulator DOES seem to show correct behaviour.

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

Thank you for all the help!

 

david.prentice wrote:

We have no idea what your duty_cycles() function does.

It is actually an array that will store the value to be set in the correspondent OCR.

 

clawson wrote:

 

To save anyone else going to look it up (shame OP didn't include this!)...

Indeed, I am sorry for not including it. I actually did not know that those pages were there. Next time I will study deeper the datasheet. Thanks for showing me this section.

 

clawson wrote:
So it looks a lot like a bug in Proteus. HOWEVER I would suggest trying exactly just this in Proteus and see what the result is...

 

I did it, and the same behavior happened. So I will conclude it is indeed a Proteus bug.

Again, thanks for all the help!

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

Look at the value in 0x80/0x90/0xA0/0x120. Should they all the the same per counter as each counter is working in the same mode?

 

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

Last Edited: Tue. May 10, 2022 - 02:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah-ha.   So the duty_cycles[ ] just contains raw values.   No worries about SFR behaviour.

 

And all OCRnx registers are initialised in one go.   i.e. in pwm_set()

 

If you want to change a specific channel you would have to assign to the specific OCRnx  e.g. via a write_duty(n, value)

 

Even more apologies.   I suggest you just run Cliff's program in Proteus.   Compare it to his AS7.0 Simulator memory.

 

David.

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


The WGM bits are in TCCRnA/TCCRnB which are at:

&TCCR1A = 0x80
&TCCR1B = 0x81

&TCCR3A = 0x90
&TCCR3B = 0x91

&TCCR4A = 0xA0
&TCCR4B = 0xA1

&TCCR5A = 0x120
&TCCR5B = 0x121

so basically:

 

It is curious that the two that "work" have 0x1AAA in them and the two that don't have 0x1A00 in them.

 

It's like someone forgot to set TCCR4A and TCCR5A ??

 

(yet in OPs code - the one with all the needless "|=" stuff going on - it looks like all the As and Bs are being set to the same thing?

 

BTW the columns with the 0x0075 and 0x0076s in them are the TCNTs - perhaps not a surprise that they counting up as ther CS bit in the B registers have been set.

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

We need to see the .ASM output of the OPs's code.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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


The consequence of the TCCR4A and TCCR5B being left at default (0x00) rather than setting the WGMn1 bit looks like it should have just changed mode 14 to mode 12 but both those modes use TOP=ICRn so I wouldn't have expect it to have any masking effect on the bits in OCR registers ?

 

When I added OP's pwm_init() function to my own test and look at what happens in the AS7 simulator I see:

 

 

All working as expected - the A/B register pairs have 0x1AA2

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

There's something odd with the OP's compiled code. How do I know? Because I've just compiled the source in CVAVR and uploaded it into my (legit) copy of Proteus and I can see the control registers being initialised correctly.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

I have just run it with GCC in AS7.0.   And it is really weird.   The DATA_mapped_IO window does not seem to show the correct contents.   Nor does the IO Register Window.

 

I added a CV project.   AS7.0 Simulator behaves the same.

 

I don't have a m1280.   I suppose that I could use JTAG on a MEGA2560 Board.

 

David.

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

Well, I've eliminated any problems with Proteus and with CV. So it's looking like a Studio problem, or something odd with the OP's project.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

This is my GCC:

 

#include <avr/io.h>

void pwm_init(){
    TCCR1A |= _BV(WGM11) | _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1);
    TCCR3A |= _BV(WGM31) | _BV(COM3A1) | _BV(COM3B1) | _BV(COM3C1);
    TCCR4A |= _BV(WGM41) | _BV(COM4A1) | _BV(COM4B1) | _BV(COM4C1);
    TCCR5A |= _BV(WGM51) | _BV(COM5A1) | _BV(COM5B1) | _BV(COM5C1);

    TCCR1B |= _BV(WGM13) | _BV(WGM12) | _BV(CS11);
    TCCR3B |= _BV(WGM33) | _BV(WGM32) | _BV(CS31);
    TCCR4B |= _BV(WGM43) | _BV(WGM42) | _BV(CS41);
    TCCR5B |= _BV(WGM53) | _BV(WGM52) | _BV(CS51);

    ICR1 = 0x0FFF;
    ICR3 = 0x0FFF;
    ICR4 = 0x0FFF;
    ICR5 = 0x0FFF;

    DDRB |= _BV(DDB5) | _BV(DDB6) | _BV(DDB7);
    DDRE |= _BV(DDE3) | _BV(DDE4) | _BV(DDE5);
    DDRH |= _BV(DDH3) | _BV(DDH4) | _BV(DDH5);
    DDRL |= _BV(DDL3) | _BV(DDL4) | _BV(DDL5);
}

void pwm_set(){
    OCR1A = 0xFFF;
    OCR1B = 0xFFF;
    OCR1C = 0xFFF;

    OCR3A = 0xFFF;
    OCR3B = 0xFFF;
    OCR3C = 0xFFF;

    OCR4A = 0xFFF;
    OCR4B = 0xFFF;
    OCR4C = 0xFFF;

    OCR5A = 0xFFF;
    OCR5B = 0xFFF;
    OCR5C = 0xFFF;
}

int main(void){
    pwm_init();

    for(;;){
        pwm_set();
    }
    return (0);
}

 

and this is the CV version

 

#include <io.h>
#define _BV(x) (1 << (x))
#define WR_SFR16(r, v)   { r ## H = v >> 8; r ## L = v & 0xFF; }

void pwm_init(){
    TCCR1A |= _BV(WGM11) | _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1);
    TCCR3A |= _BV(WGM31) | _BV(COM3A1) | _BV(COM3B1) | _BV(COM3C1);
    TCCR4A |= _BV(WGM41) | _BV(COM4A1) | _BV(COM4B1) | _BV(COM4C1);
    TCCR5A |= _BV(WGM51) | _BV(COM5A1) | _BV(COM5B1) | _BV(COM5C1);

    TCCR1B |= _BV(WGM13) | _BV(WGM12) | _BV(CS11);
    TCCR3B |= _BV(WGM33) | _BV(WGM32) | _BV(CS31);
    TCCR4B |= _BV(WGM43) | _BV(WGM42) | _BV(CS41);
    TCCR5B |= _BV(WGM53) | _BV(WGM52) | _BV(CS51);

    WR_SFR16(ICR1, 0x0FFF);
    WR_SFR16(ICR3, 0x0FFF);
    WR_SFR16(ICR4, 0x0FFF);
    WR_SFR16(ICR5, 0x0FFF);

    DDRB |= _BV(DDB5) | _BV(DDB6) | _BV(DDB7);
    DDRE |= _BV(DDE3) | _BV(DDE4) | _BV(DDE5);
    DDRH |= _BV(DDH3) | _BV(DDH4) | _BV(DDH5);
    DDRL |= _BV(DDL3) | _BV(DDL4) | _BV(DDL5);
}

void pwm_set(){
    WR_SFR16(OCR1A, 0xFFF);
    WR_SFR16(OCR1B, 0xFFF);
    WR_SFR16(OCR1C, 0xFFF);

    WR_SFR16(OCR3A, 0xFFF);
    WR_SFR16(OCR3B, 0xFFF);
    WR_SFR16(OCR3C, 0xFFF);

    WR_SFR16(OCR4A, 0xFFF);
    WR_SFR16(OCR4B, 0xFFF);
    WR_SFR16(OCR4C, 0xFFF);

    WR_SFR16(OCR5A, 0xFFF);
    WR_SFR16(OCR5B, 0xFFF);
    WR_SFR16(OCR5C, 0xFFF);
}

void main(void){
    pwm_init();

    for(;;){
        pwm_set();
    }
}

 

I will dig out the Arduino MEGA2560 board.   See what happens in real life.

I can't believe that the AS7.0 Simulator is wrong on both m1280 and m2560.

 

David.

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

david.prentice wrote:

This is my GCC:

 

What's the .LST look like?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Absolutely normal.  e.g. TCCR1A is assigned 0xAA.   Even though the Simulator shows TCCR1A as 0xA2.

 

void pwm_init(){
    TCCR1A |= _BV(WGM11) | _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1);
  f6:    e0 e8           ldi    r30, 0x80    ; 128
  f8:    f0 e0           ldi    r31, 0x00    ; 0
  fa:    80 81           ld    r24, Z
  fc:    8a 6a           ori    r24, 0xAA    ; 170
  fe:    80 83           st    Z, r24

 

 

I have just run on a m2560 with a PicKit4 JTAG debugger.   TCCR1A shows as 0xAA.   (as expected)

Note that AS7.0 defaults to -Og

If I use a sensible -O1 and a more sensible =

void pwm_init(){
    TCCR1A = _BV(WGM11) | _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1);
  f6:    8a ea           ldi    r24, 0xAA    ; 170
  f8:    80 93 80 00     sts    0x0080, r24    ; 0x800080 <__TEXT_REGION_LENGTH__+0x7e0080>

 

Hey-ho.   It makes no difference to the Simulator.   I still get 0xA2

 

David.

Last Edited: Tue. May 10, 2022 - 04:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have some explanations.

 

The m1280 Simulator : TCCRnA only registers 0xA2 when written as 0xAA

The m328p Simulator : TCCRnA only registers 0xA2 when written as 0xA2  (because 328p has no COMnC bits)

 

The OCRnx values only register in Memory Window or IO Window when the first PWM BOTTOM is reached.

 

I changed the main() function:

 

int main(void){
        pwm_set();
    pwm_init();

    for(;;){
        asm("nop");  //handy for a breakpoint
    }
    return (0);
}

 

Now OCRnx values get set before the Timers start running.

 

I ran the AS7.0 projects on both Win10-64 and Win7-32.   Simulators behaved exactly the same.

 

I conclude that the m1280/m2560 Simulator is wrong for COMnC.

But the m2560 debugger reads TCCRnA correctly via JTAG.

 

So it seems possible that Proteus Simulator is not perfect.

Ask Proteus for help.   But first off,  I advise you to call set_pwm() before you start the Timers.  See how Proteus deals with it.

 

I am intrigued.   The m2560/m1280 are well established and widely used.   I would expect AS7.0 Simulator problems to have been noticed by now.

 

I doubt if Proteus has many full licence holders and use m1280.   Obviously there are lots of m328p users and many educational licence users.

 

David.

Last Edited: Tue. May 10, 2022 - 07:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

The OCRnx values only register in Memory Window or IO Window when the first PWM BOTTOM is reached.

 

Which, for the avoidance of doubt, is the correct behaviour.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

I still want to see the OP's .lst file while shows the problem.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

I don't have a Proteus licence.

 

As far as I know,  Proteus users write a program which is built with GCC, Codevision , ... or whatever Tool Set.

But Proteus simulates from the generated ELF file (or COFF file)

 

So I would guess that the OP's LST file will look just like my AS7.0 LSS file.   i.e. it will write 0xAA to TCCRnA.

 

However the Proteus Simulator gets it correct for TCCR1A, TCCR3A i.e. 0xAA at 0x0080, 0x0090

And gets it wrong for TCCR4A, TCCR5A i.e. 0x00 at 0x00A0, 0x0120.

 

In other words.   AS7.0 Simulator is wrong.   Proteus Simulator is wrong.

 

If someone has AS4.0 on their PC,  they could try the AS4.0 Simulator.

 

I would check TCCRnA behaviour first.   Before worrying about OCRnx behaviour.

All the same,  I am surprised.   I would have expected both of the Simulators to work 100% for Timers.   Even if not all peripherals are attempted e.g. TWI.

 

David.

 

It takes 2 minutes to create an AS7.0 project that they can test with the code in #18

And show the wrong memory values at 0x0080, 0x0090, 0x00A0, 0x0120  as in #14

 

Likewise,  if there is a member with a full Proteus licence she can create a Proteus project from #18

Last Edited: Wed. May 11, 2022 - 07:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


 

I was intrigued and being an MPLABX user I tried the #18 program in MPLABX 6.00

 

 

I guess that means the Simulator in MPLABX works correctly. (I'm using ATmega_DFP 3.0.158 if that makes a difference)

 

<edit>

Here's something I didn't expect. The OCR4A, OCR4B, OCR4C values are shown at 16-bit but only 8-bits were loaded. (The ASM does load 16-bits)

 

Last Edited: Wed. May 11, 2022 - 08:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Woo-hoo.   That is interesting.   I will create an MPLABX project.

 

David.

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


david.prentice wrote:

...However the Proteus Simulator gets it correct for TCCR1A, TCCR3A i.e. 0xAA at 0x0080, 0x0090...And gets it wrong for TCCR4A, TCCR5A i.e. 0x00 at 0x00A0, 0x0120.

 

In other words.   AS7.0 Simulator is wrong.   Proteus Simulator is wrong.

 

Nope. I do have a full licence and this is what I see...

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

It's at this point that we really do need the OP to come back and engage with us. So many questions..........

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

I would actually like to see a COMPLETE test program - not just "snippets". I wonder if there's something being done in the bits we can't see that is either corrupting the array entries before they can be ne used or that is corrupting the timer registers after they are initially written. I think we'd all like to see a LST/LSS of the thing too.

 

I wonder if OP is waiting for notifications? As my mod power let me see the email address on the account I may drop a line just to point out that there are updates ;-)

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

Random thought...

 

when the OP writes something like this...

 

    OCR1A = duty_cycles[0];
    OCR1B = duty_cycles[1];

...does the compiler know how to correctly write to 16-bit registers, irrespective of optimisation settings?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Yes,  the compiler should know how to assign to OCR1A etc.   Whatever the expression.

 

I created an MPLABX project.   TCCRnA is set correctly.

If I call pwm_set() before pwm_init() the OCRnx registers register immediately.

If I call pwm_set() after pwm_init() and just have a NOP in the while loop() you can observe OCR1AH, OCR1AL ... as they get written.

e.g.

int main(void){
//        pwm_set();
    pwm_init();
        pwm_set();

    for(;;){
        asm("nop");
    }
    return (0);
}

 

And this does not look correct to me.   Put a breakpoint on the NOP.  Observe the I/O Memory (SFRs)

 

@Brian.

How often do you use Proteus ?

 

David.

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

david.prentice wrote:

@Brian.

How often do you use Proteus ?

 

Only got it a few weeks ago and then went down with Covid which gave me severe brain fog. So I'm still learning. I bought it because I often find myself away from the office for work but with lots of time on my hands to do other things.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Sorry for vanishing, the last days were a bit scary at university. 

I am uploading here my c code and the outputs from the compiler as some of you wanted to see it.

I will read all the posts carefully to see the other questions I need to answer as well.

 

And again, thank you all for the responses.

Attachment(s): 

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


So, I take your code.hex file and dropit into my copy of Proteus...

 

 

...looks OK to me.

 

What version Proteus are you using?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Brian Fairchild wrote:
What version Proteus are you using?

I am using Proteus 8.6