Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

What code can be acceptable on ATmega32A ?

Status
Not open for further replies.

Georg

New Member
Dear friends! Please, help me to solve one trouble.

I have connected R-2R DAC to ATmega32A on port P.
Digit capacity of DAC is 8 bits, so far as all of outputs of P are attach to R-2R DAC .

This code shall assign on port P:
PORTP=00000001;
PORTP=00000010;
PORTP=00000100;
PORTP=00001000;
etc.
PORTP=11111111;


This code manage R-2R DAC which forms output voltage.
Output voltage is minimum when code is 00000001.
Output voltage is maximum when code is 11111111.


My question: How to write the cycle for such code?
P.S Write the code sorting all importances from 00000001 before 11111111 is not good.
 
Last edited:
You can built a for loop, that adresses a Value Table.

flash unsigned char uc_table[256]={0x01,0x03,0x04,...0xFD};
volatile unsigned char uc_count=0;

for(uc_count=0,uc_count<=255,uc_count++)
{
PORTP=uc_table[uc_count];
};

So you can generate every periodic Waveform that was pre calculated and stored into the table variable.

To change the Frequency, you can put it into a counter interrupt and count up the uc_count variable by incrementation ( uc_count++; ).

ISR (TIM0_OVF_INT)
{
ui_loopcounter++;
if(ui_loopcounter>ui_time)
{
PORTP=uc_table[uc_count];
uc_count++;
ui_loopcounter=0;
};
};

The Variable definations differ a little bit, depeding from the used Compiler.

EDIT!
I've corrected the Value 0x253 to 0xFD
 
Last edited:
Or you could make a function that does that without a large chunk of code, but this depends on how fast do you need the result. Calculating the result will be a few clock cycles slower than using a lookup table, but lookup table wastes more ram and possibly code space.
For example:
Code:
if(i<7)PORTP=(1<<i);
else PORTP=0xff;

But anyway, since when does any atmega have a port P? Also, are you sure you want the output exactly as you written in the first post?
 
Last edited:
Yes, I have done the misprint. I meant the A port of ATmega32.)

wkrug, what means the 0x01 ? (I'm beginner in microcontroller programming and have some difficult)
uc_table[256]={0x01,0x03,0x04,...0x253};

Should code be this ?

#include <stdio.h>;
int main ();
int values[255];
for(i=0;i<256;i++);
{
values=i
}
for(j=0;j<256;j++);
{
delay_ms(...);
PORTA=values[j];
}
 
0xff for example is a hexadecimal notation of nuber 255. Wkrug made a mistake, the series should obviously end in 0xff or 255, but not 0x255 which is 597.

Georg, do you notice that series 0b00000001, 0b00000010, 0b00000100,0b00010000... is not equivalent to 1,2,3,4... but rather 1,2,4,8... ? (the b in 0b01110111 stands for binary notation, as oposed to hexadecimal)
And also from your first post it seems you want to have 0b11111111 right after 0b10000000, thus only 9 values total?

..Also in the previous post you have a mistake, you should have there int values[256], since the index goes from 0 to 255, so you have 256 writes. If you do that mistake in a microcontroller you will almost certainly overwrite some other variable.
 
Last edited:
kubeek, thank you for your explanation. It will be of great value to me. I will continue in this direction.
 
You only have an 8 bit D/A Converter ( R2R Network ) so there are 8 bit variables large enough in the Lookup table.

The Idea is to pre calculate the wave form and store that values into a lookup table.

So you can generate different waveforms only by switching between different tables.

When using a 8 Bit variable as pointer of the values into the table, it overflows automaticly when the value exceeds 255. The Pointer is then 0 again.

To get a faster Output you can shorten the Lookup table to 64 or 128Byte, but that degrades the output signal quality.

To differ the output frequency, You only have to change the time between the reading out's of the table.

To get independency of other tasks of the controller, I'll suggest you to use a periodic interrupt to change the values of the lookup table.

To get that easy you can use a counter variable into the timer overflow interrupt, or a comparematch interrupt with CTC ( Clear Timer on Comparematch ) function.

To decision what the best parameters and method are, You have to know what is the lowest and the highest wished Output Frequency.

I've done this with an 2kHz Sine Signal and an 64Byte lookup table that AM modulates a DDS Chip from Analog Devices via SPI.
It can generate Sine Triangle and Rectangular waves, only by switching between the different tables.

P.S.
0x255 was wrong. I've corrected this to 0xFF.
 
Last edited:
shortening your lookup table to 64 or 128 will not increase your lookup speed, as the fastest way to use a lookup table is to set your index register to the table_base and then add the offset (pointer) to the index register. It doesn't matter if you're adding 0-63, 0-127, or 0-255, the add commands will take the same amount of time.
 
shortening your lookup table to 64 or 128 will not increase your lookup speed
That's right, but it increases the output frequency, because a lower count of values must be adressed.

It doesn't matter if you're adding 0-63, 0-127, or 0-255
That's right to, but when make steps of 2, You can also shorten the lookup table, because only every 2'nd value will be adressed.
And the table will be shorter, that saves memory space.

Another possible Way is to use an DDS frequency generation.
There will be a very huge value table. The output frequency setting will be done by change the increments of the pointer variable.
But when I would do that solution, it is better to use a dedicated DDS Chip, because the quality and frequency of the output signal increases and the load of the Controller go down. It cost's money, of course.
 
Last edited:
Dear wkrug and Mike odom your discussion and proposals are interesting, but output code switching is not so much exigent in this case.
Your consideration of above mentioned problem is advanced aerobatics in comparison with my skills now !)))
 
.....comparison with my skills now
To use a lookup table is one of the easyest thing's in controller programming.
You make a table, the values could be precalculated in EXCEL.
Than the calculated Values e.g. for a sine would be taken into a variable.
unsigned char uc_sine[256]={0x00,0x01,...0xFF};
unsigned char uc_pointer=0;

Now when make a periodic reading with increments of a pointer from that table and put the Values to Your R2R Network, then occours there a sine Wave.

while(1)
{
PORTC=uc_sine[uc_pointer]; //Read out the actual Value for the R2R Network
uc_pointer++; //Increment Pointer to address the next value in table
delay_us(20); //Delay function to slow down the output frequency. Higher values give lower frequency
}

This little part of code is the whole generation loop!

The Problem is, when other tasks are running while outputting the wished wave, the output frequency will not be constant and the output waveform has dissortion.
So you had to make a function, that does not depend from the tasks in main loop.
To do that, You can write an interrupt function that interrupts the actual main loop to change to the next value in the table and put it out to R2R Network.
Timer Overflow or Timer Comparematch Interrupts are ideal for such a solution.

Try it out and put an Oscilloscope at the Output of the R2R Network. You would see there will occour a Wave.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top