what is wrong with my two pwm and adc sketch for atmeg4809 {SOLVED}

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

the idea is to control the brightness of two LEDs independently, this issue is that both potentiometers control both lights

 

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

void main(void) {
    SREG = 0b10000000; //enable global interrupts
  PORTA.DIR = 0b111; //set output pins for the pwm
    TCA0.SINGLE.CTRLB = 0b1110011; //enables compare channel and

    TCA0.SINGLE.PER = 0x3FF; //set period
    ADC0.CTRLC = 0b1010000; //set sample capacitance for above 1 volt and set the reference to VDD
    ADC0.CALIB = 0b1; //this is recommended for peripheral frequencies above 1.5 MHz

    ADC0.INTCTRL = 0x1; //allow interrupts on this peripheral
    TCA0.SINGLE.CTRLA = 0x1; //enable the timer
    ADC0.MUXPOS = 0x0; //set the starting analog input at port d pin 0
    ADC0.CTRLA = 0x1; //enable the adc
ADC0.COMMAND = 0x1; //star a conversion 

    while(1){

    }

}
ISR(ADC0_RESRDY_vect)
{
    switch (ADC0.MUXPOS){
            case 0x0:
                TCA0.SINGLE.CMP0 = ADC0.RES;
                ADC0.MUXPOS = 0x1;
                break;
           case 0x1:
               TCA0.SINGLE.CMP1 = ADC0.RES;
               ADC0.MUXPOS = 0x0;
               break;

    }
  ADC0.COMMAND = 0x1;
}

 

Corrected word in title and code blocked application - JGM

This topic has a solution.
Last Edited: Fri. Nov 26, 2021 - 10:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry, but I only read as far as this:

JJJJAMES wrote:
SREG = 0b10000000; //enable global interrupts

 

Don't write directly to SREG when programming in C. It can have unpredictable results, since you are changing all the flags - you are setting the interrupt flag, but clearing all the others.

Use

sei();

instead (it's defined in <avr/interrupt.h> ).

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

thanks for the tip and ill make sure to use it from now on but nothing changed

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

JJJJAMES wrote:
  PORTA.DIR = 0b111; //set output pins for the pwm

 

Which pins of Port A?  THeres 8 of them.

 

 

THeres quite a bit that you need to fix in MAIN loop.  Much of it only needs to be run once, and that should be in an INIT loop thats only run once.

 

 

 

Are you using the Arduino environment, or the Studio environment?  Sketches are done in Arduino predominntly

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

El Tangas wrote:
Don't write directly to SREG when programming in C. I
Also don't enable the interrupts at the start of your initialization . Make sure all interrupting peripherals are fully initialized and only THEN enable the interrupt system.

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

@Moderator: perhaps the word "two" is better than "dual"- can you correct the title.

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


"dual" would be fine, but it actually says "duel" - which is something completely different

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
completely different

 

...total of 29 hits in Forums search- dangerous word it is. Word two can be better, guess.

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

I made a few 'tweaks' to the OP.

 

Now, onward.....

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

JJJJAMES wrote:
issue is that both potentiometers control both lights

 

So what investigation / testing / debugging have you done to find out what's going on ?

 

As always, break the problem down into manageable chunks - don't try to do multiple things all at once.

 

For a start, leaving aside any PWM, are you able to separately read 2 pots?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At first glance I don't see any errors.

On the AVR-0/1 series, interrupt flags in general need to be cleared explicitly inside the ISR by writing a "1" to the flag bit. However, the ADC is an exception and reading the result also clears the interrupt flag. It should be ok the way you did it.

 

This means I would need to setup a test (I do have a few DIP mega4809 somewhere) and now it's a bit late around here. Maybe tomorrow.

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

after messing around with the code a bit i finally got it to work, thank you for your help

 

 

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

void main(void) {
   
  PORTA.DIR = 0b111; //set output pins for the pwm
    TCA0.SINGLE.CTRLB = 0b1110011; //enables compare chanle and
    
    TCA0.SINGLE.PER = 0x3FF; //set period
    ADC0.CTRLC = 0b1010000; //set sample capacatnce for above 1 volt and set the refrince to VDD
    ADC0.CALIB = 0b1; //this is recomended for periferal fequincies above 1.5 mhz
    
    ADC0.INTCTRL = 0x1; //allow interupts
    TCA0.SINGLE.CTRLA = 0x1; //enable the timer
    ADC0.MUXPOS = 0x0; //set the starting analog input at port d pin 0
    ADC0.CTRLA = 0x1; //enable the adc
ADC0.COMMAND = 0x1; //star a conversion
     sei(); //enable global interupts 
    while(1){
     

    
    
    }

    
}
ISR(ADC0_RESRDY_vect)
{
    int in_1;
    int in_2;
    switch (ADC0.MUXPOS){
            case 0x0:
                in_1 = ADC0.RES;
                TCA0.SINGLE.CMP0 = in_1;
                ADC0.MUXPOS = 0x1;
                in_1 = 0;
                break;
           case 0x1:
                 in_2 = ADC0.RES;
                TCA0.SINGLE.CMP1BUF = in_2;
                ADC0.MUXPOS = 0x0;
                in_2 = 0;
                break;

    }
  ADC0.COMMAND = 0x1;        

}

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

See Tip #1 in my signature, below, for how to properly post source code - as Jim did to your initial post.

 

Also Tip #5 for how to mark a thread as solved - no need to edit the title:

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

sorry, I'll do that next time