Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

!!Programming AVR for this task!!

Status
Not open for further replies.

somf0872

Member level 5
Joined
Oct 14, 2003
Messages
92
Helped
1
Reputation
2
Reaction score
0
Trophy points
1,286
Activity points
917
winavr bitwise two constants

Hi everybody,

I have to develop a routine for AVR ATMega162 in C-language (C-compiler WINAVR) which does the following operation:

1) PB1.1 as an output pin giving a regular clock pulse with a frequency of 20MHz i.e (high level = 25ns and low level = 25ns).

2) PB1.2 as an output pin that gives a data (it could be any data 1 or 0) for total 12 clock pulses.

3) Usually PB1.3 is on high state
When 12 bits of data is send on PB1.2 with 12 clock pulses on PB1.1, then I have to make PB1.3 low for 25ns from its original high state.

Does anyone can guide me how to proceed with this outline? Actually I am new in the world of Microcontroller programming. Need some push up or similar example sort of codes from experts.

Note: I am working on DAC8043A in which serial data is clocked into the input register on the rising edge of the CLOCK pulse. When the new data word has been
clocked in, it is loaded into the DAC register with the LD input pin. Data in the DAC register is converted to an output current by the D/A converter.

Any help?

--X--
 

Hello

For the clock pulse you need to generate try making it by an interruption, managing the interrupt clocks for this task. The data output wont be a trouble, just put the output code on the same interruption to make sure the data starts when the clock changes states, then with a counter, which you will increase every clock up to 12, start the clock only when you start sending data over PB1.2...

I would put the whole code in one interruption, make sure your code doesn't take more tha 25 ns to execute or you will have trouble, and try not to make any loops on the interruption either. i think a couple of instruccionts and some flag bit would do the trick. It's been long sisnce i don't programm on a ucontroller else i would post some codes...

Hope this helps out
 

How can I make sure that my code doesn't take more than 25 ns? I mean how can I calculate it?

plus ..........

anyone can put some sample C codes for that particular task which I mentioned in my first message or if its possible give me some helpful links containg such example where I can learn that how one can code in C for AVRs?

--X--
 

You can simulate your code and watch the clock for the system or you can add up the number of cycles for each instrction you execute and sum up the cycles, as you know the frecuency of you controller, you can calculate the time the code needs to execute.

I would help you out with the programming but my C is very very rusty... i don't remember anything about it...
 

I think WINAVR has functions for delays ms and us. Check the manual
 

Thanks DarkJedi

I will send u my code soon with the comments ...............

Then we can discuss in detail.

Nowadays I am just reading the interrupt and timer of AVR .......... that how to control these things.

Soon, I will develop something (I hope something useful) .

--X--
 

somf0872 said:
1) PB1.1 as an output pin giving a regular clock pulse with a frequency of 20MHz i.e (high level = 25ns and low level = 25ns).

Note: I am working on DAC8043A in which serial data is clocked into the input register on the rising edge of the CLOCK pulse. When the new data word has been
clocked in, it is loaded into the DAC register with the LD input pin. Data in the DAC register is converted to an output current by the D/A converter.

--X--

Your requirement it's a killer task for AVR ATMega162.
The uC execute one instruction during 1 clock period but that's 1/16 MHz = 62,5ns
How do you think you'll be able to drive your pin 25ns up, 25ns down and even more counting 12 such clocks ?
Nevertheless that toggling output pin need some constraints due to pipeline execution.
Even using the hardware peripheral like included timers you won't be able to solve your problem.

Looking further to your request I think I get the point.
You're new to world of microcontroller but definitely must know how to read a data sheet.
The 25 ns clock pulse width (high or low) is the minimum required of the DAC8043 interface.
You need such narrow pulses as long as the current settling time of the DAC8043 is 1 micro seconds.

My question is what is the period of the signal applied to /LD pin. I mean how often do you want to update the 12-bit shift register ?
What are you doing with the current delivered by the DAC8043 ? What's your application ?

Just because you can load the 12-bit shift register with pulses period of let's say 1ms (by far more relax for AVR) and being able to convert your numerical code into current 12ms after.

Don't bother with 25ns if you don't need to.
 

    somf0872

    Points: 2
    Helpful Answer Positive Rating
Hi Silvio,

Well, thanks a lot ..................

I do admit my blunder mistake!!!

Surely 25ns is the min. time for in order for current settling. Well, my application is not a very time sensitive. Although the datsheet indicates that the max current settling time is Ts= 1us.

Actually I used that DAC circuit with some op-amp in order to vary the voltage from -12V to +12V using digital bits from microcontroller. Now, I want to check the hardware. Therefore, I need some clock pulses and serial data bits.

The three pins (CLK, SRI, /LD) of DAC have to be controlled through AVR.

What datasheet states that the /LD pin should be normally high when data bits are being transferred to 12 bit shift register. Once the 12 bit data is stored in shift register on 12 clock pulses, then /LD pin is taken momentarily low so that data is transfeered to DAC register and hence u get output current from DAC.

Since, I have to just check my hardware therefore /LD periodicity is not a problem for me. I just want to send some of digital codes, make /LD low until I get the output.

Anyways, thanks for ur concern. I have also browsed those links u have given on other subject topic of AVR of this forum posted by me. I am in a process of learning the timer and interrupt control of AVR so that I can able to implement the code for checkiing my hardware.

Need ur guidance too.

--X--
 

I'll be glad to help you further if I can.
 

Hi Silvio and Markjeddy,

After getting some initial basics of AVR and C-programming, I develop this routine. Pls have a look on the file attached and guide me if I am on right track.


Description of Program:
1) Control the CLK, SRI and /LD pin of DAC8043A.
2) Send the regular clock pulses on PB0. With the low level of clock signal, the data bit is given on PB1.
3)When the complete 12 bit data is stored in shif register on 12 clock pulses, timer is stopped and /LD is made logic low on PB2.

----------------

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


//constant definitions

#define XTAL 3690000L // Crystal frequency in Hz
int level = 0;// this variable is used for CLK high and low level selection
int count = 0;//variable is used to send data bits in the form 111111 & 0000000
int loop = 1;// this variable is used to control the 12 clock pulses

SIGNAL(SIG_OVERFLOW0) //signal handler for tcnt0 overflow interrupt
{
if (level==0)
{
PORTB &= 0xFE; // CLK(low level) to DAC,PB0 becomes logic 0
level = 1;

if (count == 6)
{
PORTB &= 0xFF; // Data bit to DAC, PB1 becomes logic 1
count = 0;
}
else
{
count++;
PORTB &= 0xFD; // Data bit to DAC, PB1 becomes logic 0
}

}
else
{
PORTB &= 0xFF;
level=0;
}

TCNT0 = 0x1A; // reset counter to get this interrupt again

}


int main(void)
{
DDRB |= _BV(PB0); // use PB0 pin as a CLK (setting it as output)
DDRB |= _BV(PB1); // use PB1 pin as a data (setting it as output)
DDRB |= _BV(PB2); // use PB2 pin as a /LD (setting it as output)
PORTB = 0xFF; // logic high on all pins of Port B; initialization



TCCR0 = _BV(CS01); // use CLK/8 prescale value, it means 1 instruction = 21.68us //
TCNT0 = 0x1A;// Intializing timer from 1a, i.e. FF-1A = (E5=229), complete counting takes 0.4964msec//
TIFR = _BV(TOV0); // clearing overflow flag from any previous interrupts
TIMSK = _BV(TOIE0); // enable Output interrupt enable
sei(); // enable interrupts
loop++;

if (loop == 24)
{
TCCR0 = 0;
PORTB &= 0xFB; // /LD becomes logic low after sending 12 clock signal and 12 data bits, PB2 becomes logic low//
}

}

-----------------

Note: I have also some other possibilities in my mind as to use two timers at a time or OC1A pin in toggling mode for CLK. Anyhow, this is really a start-up. Need feedback from u guys.

--X--[/code]
 

Hi Hans,

At first glance I don't see inside int main(void) a while(1) endless loop interrupted by timer ISR.
How do you think "loop" variable will be incremented in order to be tested at "if(loop==24)" ?

You're lucky that after sending 6 bits of "0" you don't send not even 1 bit of "1".
Just because with "PORTB &= 0FF" you can't set a bit to "1" which has been previous reset to "0".
Hope you figure out that you need OR, not AND bitwise operator.
PORTB |= 0x02; // Data bit to DAC, PB1 becomes logic 1

Do you think that doing TCCR0 = _BV(CS01); you set the CS01 bit ?
How about TCCR0 |= _BV(CS01);
To be honest I don't like bit value macro _BV
 

HI Silvio,

Thanks a lot for ur feedback. And at the same time sorry for crunching ur mind.

Well, I think I got ur point. But the way .............. I thought was in this sense.

In case of having an interrupt, the program jumps to execute the procedure of timer ISR. After then it returns back at the same point where it leaves for the interrupt. So I put loop++ just after sei();

sei(); // enable interrupts
loop++;

But the question is what will happen WHEN interrupt occurs again as soon as program return from TIMER ISR? And secondly THERE is no endless loop to continue this program. It will run just once and then stop.

I think remedy to these problems are:-

I must put an endless loop after sei();
such as for(;;) {} or while(1);

Secondly the statement loop++ and if condition for checking loop==24 shall be in TIMER ISR, so that every time interrupt routine runs, loop is incremented by 1 and when loop =24, just stop the timer by giving TCCR0=0.

I hope this will solve the issue.

--X--
 

somf0872 said:
But the question is what will happen WHEN interrupt occurs again as soon as program return from TIMER ISR? And secondly THERE is no endless loop to continue this program. It will run just once and then stop.

You're a smart guy.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top