atmega4809 ADC example code

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

Hi,

 

I am trying to make the ADC for the Atmega4809 work and print to the uart. (insignal 0-3.3V)

I was just woundering if anyone know if there is any example code for the ADC on the Atmega 4809?

 

I am a bit new to working with these parts so if there where any examples to look at that might help.. =)

I have been looking around on internet but not really found anything helpful for this part (since it is quite new and diffrent from others I assume)

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

Have you seen what "Atmel Start" has to offer? I think they are making a point of trying to support all these very recent released chips.

 

EDIT: yup, when I select 4809 it has these drivers on offer:

 

 

 

 

PS "Start" is probably your best hope because these chips are so new there's not been a lot of example code published on the internet for them otherwise so far. that's the downside of trying to ride the "bleeding edge" of technology ;-)

Last Edited: Wed. Sep 19, 2018 - 12:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thank you for your reply.

yes, I noticed that they had that too. 

literaly the only place i could find anything at all about this subject.

I was just hoping that there would some other place to look at aswell.

becuase the code in the example project was just a bit...messy...or a bit big or whatever.

for a beginner it is not so easy to follow what is really happening in that code.

 

oh well... if there is nothing else to look at I guess I will have to make due with that..

If i get my code to work i will publish it here so anyone else that is in the same situation as me can get help in the future. 

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

It took about a decade for their to be widespread code for something like mega48..328 so ask again in 10 years!

 

(actually what prompted a real proliferation of 328 code was "Arduino" - I believe there is going to be a 4809 based Arduino - if so that could really get the ball rolling in a year or two)

 

PS You don't have much trouble finding example code for mega8, 16, 32, 128 etc - they date from the turn of the millenium ;-)

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

mannen wrote:

I have been looking around on internet but not really found anything helpful for this part (since it is quite new and different from others I assume)

Surely the datasheet is there. You just need to read it and start coding.

- configure ADC - take all ADC registers one by one and change them if the default setting is not what you need

- do the same for the USART

- start a conversion

- wait for the conversion to complete

- read the ADC result

- send it out to USART (maybe use a buffer in between)

This would give a satisfaction that now you master (oops, that you have under control) the ADC and USART and you become independent.

 

Maybe it is only me that I started with assembler, coming from the hardware side, learned in school how to build AND, OR, .. gates from diodes and resistors, D flip-flop registers etc and now all these peripherals look so simple and easy to understand and now I can't get to peoples mind of how they need help handling an ADC and USART.

 

I still think that embedded programming should start from low up and not from up down. However, I see here comments that it should start from up down. However, this is the result.

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

mannen wrote:

becuase the code in the example project was just a bit...messy...or a bit big or whatever.

Interesting -- a sample code or Wizard code or similar is "too big".  The people that put it together added random unneeded "stuff" just to throw people off?

 

That said, the "0" series configuration has many options, and that results in a double-handful of configuration registers.  I'd suggest a combination of earlier suggestions -- take the "big" sample code and study it with the aid of the datasheet.

 

If this "0" series chip is too daunting, then perhaps you should use something simpler for your app?

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: Wed. Sep 19, 2018 - 02:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

theusch wrote:
The people that put it together added random unneeded "stuff" just to throw people off?
There speaks a man who has never studied an ASF project! ;-)

 

A one line "PORTB |= (1 << 3)" type operation in ASF-speak becomes a nest of 10 functions that "virtualize" the port/pin number and then later unwind it all again until it finally reaches the bit setting code. It throws away any possibility of optimization so a 1 opcode operation becomes about 200 opcodes.

 

To give them their due it seems they have done a much better job in "Start" with far more hardware targetted code but anything offering a hardware abstraction layer (so the higher levels look the same whether it is AVR-0, Xmega, AVR32, ARM) is bound to suffer from some level of bloat and inefficiency.

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

yeah, It´s like they get payed per letter or something..

I get a headache just to start trying trying to get an idea about what they are doing in their code.

 

Angelu: 

well yeah, I have also studied assembler, AND or gates and all that back in the day..

But that does not help me much now when i am rusty within this area (beacuase I have not used it for a while) and there is like literaly no exaples around for this chip (except for this crazy one that comes with Atmel studio). 

 

Nope, can´t change the chip to an old one. it´s already on the PCB. and becides: I prefair learning new parts then old parts. 

 

so no kind soule have any code that I can look at? =)

Last Edited: Wed. Sep 19, 2018 - 02:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mannen wrote:
so no kind soule have any code that I can look at? =)
Believe me, you really are one of the first venturing into this area. You could try a search simply for "4809" here where you may find the odd snippet but these things really are too youg for there to be any amount of established code. In fact (depending on your commercial circumstances) consider posting back anything you come up with as you could be one of the trail blazers here.

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

clawson wrote:

mannen wrote:

so no kind soule have any code that I can look at? =)

 

Believe me, you really are one of the first venturing into this area. You could try a search simply for "4809" here where you may find the odd snippet but these things really are too youg for there to be any amount of established code. In fact (depending on your commercial circumstances) consider posting back anything you come up with as you could be one of the trail blazers here.

 

oh crap.. well, well.. If I get it to work I promiss I will post my code here so next in line don´t have to suffer like I do now ;)

 

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

The Wizard in the latest version of CodeVisionAVR mentions support for that chip family.

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

mannen wrote:

clawson wrote:

 

Believe me, you really are one of the first venturing into this area. You could try a search simply for "4809" here where you may find the odd snippet but these things really are too youg for there to be any amount of established code. In fact (depending on your commercial circumstances) consider posting back anything you come up with as you could be one of the trail blazers here.

 

 

oh crap.. well, well.. If I get it to work I promiss I will post my code here so next in line don´t have to suffer like I do now ;)

 

 

Yup, you're a pioneer. I played a bit with this family, not this exact chip, though. So far, I used the event system, the configurable logic and the UPDI.

Recently someone was trying to figure out the details of using the USART with the multiplexer to use the alternate pins: https://www.avrfreaks.net/forum/...

 

Regarding the ADC, I don't recall anyone mentioning it before.

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

Thanks, theusch and El Tangas.

I will check those out. 

With a bit of luck maybe i sort it out..

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

For what it's worth, here's a simple quick-and-dirty code I just wrote and tested on an ATmega4809. IDE is Atmel Studio 7.0.1931.

I only include the ADC-related parts, and apologies for the hard-coded numbers :-)

 

 This is the setup:

 

// Set up ADC for PD0 (AIN0)
// Based on datasheet DS40002015A , pages 413-414 ("Functional description") and 421-429 ("Register description").

// The pin is input by default, but we need to disable its "digital input buffer"
// [Note: No apparent effect of this with a simple 10K potentiometer output]
PORTD_PIN0CTRL = 0x04;

// 8-bit resolution, NOT free-running mode, not enabled yet
ADC0_CTRLA = ADC_RESSEL_8BIT_gc;

// Reduced sampling capacitance, Voltage reference is Vdd, clock prescaler is DIV4 (system clock is the default 3.33MHz)
ADC0_CTRLC = 0x51;

// Select AIN0 as input channel
ADC0_MUXPOS = 0x00;

// Enable the ADC
ADC0_CTRLA |= ADC_ENABLE_bm;

 

And when you want to read the voltage, do this:

 

// Trigger an ADC conversion
ADC0_COMMAND |= ADC_STCONV_bm;

// Wait for it to finish. Alternatively, use the interrupt flag RESRDY in ADC0_INTFLAGS.
while (ADC0_COMMAND & ADC_STCONV_bm) {
}

// Read result
/* Your variable here */ = ADC0_RESL;

 

* Sorry also for the poor code formatting, I can't get the "insert code" thingy to behave :-/

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

Thank you very much for the code, igendel!! =)

I really appreciate it.

 

it looks like it will be a great help when I try to make this work.

 

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

Hi again, 

 

the codes works i think. 

But when I want to check the result in the terminal program by sending it to UART i get into some trouble..

 

The uart itself works fine because when i hardcode something (like sending 'A' to get A in terminal program) it comes out in the terminal correct. 

But when I try to send what i get from the ADC i get nonsens in the terminal program. 

I have concluded that the problem must be because i need to do an conversion from the ADC output to ASCII caracters. 

I tried to do this by this part of the code (see code below)since i read that this would transfer number to ascii value somewhere on the internet:

send = stuff +'0';

but it does not work..

 

When I put the ADC pin at ground level i get consistently the same nonsens caracter and the same when i put it vcc level. so I think its safe to say that the problem here is that I am not to good with programing (because I have not been doing for a long time). 

Anyone see what I am doing wrong here? or what I am missing to do?

 

#include <atmel_start.h>
#include <avr/io.h>
#include <util/delay.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void SetupADC();
int TriggerADC();
void USART_Transmit1(char data1);

int main(void)
{
	/* Initializes MCU, drivers and middleware */
	atmel_start_init();
	PORTB.DIRSET   = PIN5_bm;  //lamp for debugging
	SetupADC();

	while (1) {
		_delay_ms(1000);   //wait for a second

		char send=0;			//maybehere is the problem?
		char stuff=0;			//maybehere is the problem?
		stuff = TriggerADC();  //maybehere is the problem?
		send = stuff +'0';    //maybehere is the problem?

		//char send=63;		//hardcoded ascii sign "?"  this i get in the terminal program correctly
		USART_Transmit1(send);
	}
}

void USART_Transmit1(char data1)
{
		while (!(USART3.STATUS & USART_DREIF_bm))
		;
		USART3.TXDATAL = data1;
}

void SetupADC() {
// Set up ADC for PD0 (AIN0)
// Based on datasheet DS40002015A , pages 413-414 ("Functional description") and 421-429 ("Register description").

// The pin is input by default, but we need to disable its "digital input buffer"
// [Note: No apparent effect of this with a simple 10K potentiometer output]
PORTD_PIN0CTRL = 0x04;

// 8-bit resolution, NOT free-running mode, not enabled yet
ADC0_CTRLA = ADC_RESSEL_8BIT_gc;

// Reduced sampling capacitance, Voltage reference is Vdd, clock prescaler is DIV4 (system clock is the default 3.33MHz)
ADC0_CTRLC = 0x51;

// Select AIN0 as input channel
ADC0_MUXPOS = 0x00;

// Enable the ADC
ADC0_CTRLA |= ADC_ENABLE_bm;
}

int TriggerADC() {
// Trigger an ADC conversion
ADC0_COMMAND |= ADC_STCONV_bm;

// Wait for it to finish. Alternatively, use the interrupt flag RESRDY in ADC0_INTFLAGS.
while (ADC0_COMMAND & ADC_STCONV_bm) {
}

// Read result
char result=0;
result = ADC0_RESL;

return result;
}

 

Last Edited: Mon. Sep 24, 2018 - 04:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You want itoa() to convert ADC readings to human viewable (aka ASCII)

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

clawson wrote:
You want itoa() to convert ADC readings to human viewable (aka ASCII)
Next the OP will ask why no values higher than 255 are ever returned.

 

 

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

theusch wrote:

clawson wrote:

You want itoa() to convert ADC readings to human viewable (aka ASCII)

 

Next the OP will ask why no values higher than 255 are ever returned.

 

 

 

well it´s 8 bit resolution ADC.

or what do you mean?..

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

mannen wrote:
well it´s 8 bit resolution ADC.

 

Not according to my DS!

 

Jim

 

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

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

well, in the code above it is set to 8 bit (thou you can set it to 10 bit):

from iom4809.h:

 

/* ADC Resolution select */
typedef enum ADC_RESSEL_enum
{
    ADC_RESSEL_10BIT_gc = (0x00<<2),  /* 10-bit mode */
    ADC_RESSEL_8BIT_gc = (0x01<<2),  /* 8-bit mode */
} ADC_RESSEL_t;

 

So with this setting it can only return 255 as the highest number.

thats how I see it anyway. 

 

 

Last Edited: Mon. Sep 24, 2018 - 10:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The code is working =)

 

I attach the code for if anyone else want to use it in the future (It´s just annoying when people ask questions on forums and then never share what they find the solution to be). 

 

terminal program settings (i used br@y++ terminal version 20130116B) : 

baud: 9600, databits: 8, parity: none, stop bits 1.

 

The code for this atmega 4809 uses PD0 for ADC input and PB4 and PB5 for sendin and reciving data to UART.

ADC from 0 (min value) to 255 (max value).

I used atmel studio version 7.0.1931

 

of course the code is mainly thanks to igendel. I added some documentation and uart code. 

thanks for all the help =)

 

Attachment(s): 

Last Edited: Tue. Sep 25, 2018 - 09:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for sharing your solution, as example code for these new AVR's is scarce!

 

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"