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.

Help with AVR ATmega128

Status
Not open for further replies.

skott23

New Member
hi there.
we r doing a greenhouse project where we r using avr ATmega128 . To be honest i have totally no idea what so ever abt whts going on bt m trying my best . My part is nw to write a program for serial interface . what i understand is that i need to write something which will help us to connect with the serial port of PC.. would i do for my program.would u pls help me??!!
 
Last edited:
You have to use the USART of the Chip.
Therefor must be done some settings in the according registers.

Following settings must be done:
Protocol - Most Asynchron, 8 Data, 1 Stop Bit, No parity.
Speed - You should take one the fit's with one of your PC.
Activate Transmitter, Activate Receiver.
Now something thats in your opinion. Transmitting interrupt driven oder by polling ? Receiveing interrupt driven or by polling.

Polling has the advantage that is easyer to use, but You're blocking the Controller while transmission is active.
Interrupt Handling is a little bit harder to handle, but the Controller only will blocked while changing of some register values.

When all that settings are done you can write a Byte into the UDR Register of the ATMEGA 128 and it will be transmitted via your serial interface by controller Hardware.

You know the ATMEGA 128 has 2 USART's. For exaple a USART initialisation i used at one of my last projects.
It runs with a 8MHz crystal.

Code:
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: Off
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 38400
UCSR0A=0x00;
UCSR0B=0x48;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x0C;

// USART1 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART1 Receiver: On
// USART1 Transmitter: On
// USART1 Mode: Asynchronous
// USART1 Baud Rate: 38400
UCSR1A=0x00;
UCSR1B=0xD8;
UCSR1C=0x06;
UBRR1H=0x00;
UBRR1L=0x0C;

To figure out what that settings do, you should read the USART Chapter of the ATMEGA 128 Data Sheet.

To connect the M128 to the PC you have to install a RS232 Level Shifter, like the MAX232, or better use a USB Bridge like the FT232R. With FT232R your Application has USB Support.

When you tell me what settings you want i let generate it by the Automatic Program Generator of my CodeVision Compiler ( C - Language ). Or You load down the free Version of that Compiler to make that by yourself.

Something Different:
For USART capability you should use a external Crystal or Ceramic resonator for proper work.
The internal Clock sources has to much drift.
Be Careful with the Fuse settings of the ATMEGA 128. The JTAGEN and the ATMEGA 103 compatibility Fuse are set as default. When not using JTAG you should disable the JTAGEN Fuse.
When using the ATMEGA128 as ATMEGA 128 you should disable the ATMEGA 103 Fuse.
Additional the Programming Pins are not on MISO MOSI SCK but on other Pins of the controller.
 
Last edited:
hi,thanks for ur reply..:)
actually we are using Atmega 1284p....i tried to find usart part from the data sheet bt i couldnt find anything...:-(...(https://www.electro-tech-online.com/custompdfs/2012/03/8059S.pdf)
bt i gt a few idea abt wht the usart is basically...nd hw to install MAX232...or hw to make usb bridge..nd do i hav to buy max 232 if i want to use it..
nd wht kinda settings u meant.??m sorry if i sound lyk a stupid..
 
What You've found is only the product summary.

The whole Datasheet you can find at the ATMEL Pages http://www.atmel.com .
The Product line is 8Bit AVR Controller

The direct URL to your Datasheet is: https://www.electro-tech-online.com/custompdfs/2012/03/doc8272-6.pdf
There is a USART Section that starts on Page 174.

The whole Datasheet has 584 Pages!

MAX 232:
The Controller only give out voltages of 0V and +5V on it's USART Output.
For a regular RS232 interface you have to use -12..15V and +12..15V.
A MAX232 has 2 Charge Pumps, 2 Outgoing Level Shifters and 2 Incoming Level Shifters.
In Most Applications only one Outgoing Level Shifter is used for TxD of the Controller and one Incoming Level Shifter was used for RxD.
Thats enough to built a Connection between the PC and Your Microcontoller circuit.
Sometimes the other 2 Level Shifters were used for the RTS and CTS.

FT232Rx:
The FT232RL is a USB Bridge from FTDI. There are 2 Drivers for such Chips availible.
The D2xx Driver that give full access to the chip and the VCP ( Virtual Com Port ) Driver.
You should use the VCP Driver. When that driver is installed on your computer every connected FT232R was indicated as serial Interface.
You can Handly it with many Terminal Programms like Hyper Terminal and so on.
At the Output to the Microcontroller it has 0V, 5V Level. That fits to your Microcontroller.
I wouls suggest you to prefer that solution, because the normal serial Interfaces were not longer supported by most Motherboard manufactors.
Additional you should decouple the FT232Rx Part from the Rest of your Circuit by Using Opto Couplers.

How to do that you can see here:
**broken link removed**
The FT232Rx Part is on the right Bottom of the Schematic.

Near at the Bottom of the Page are Schematics and Layout for the PCB Program "EAGLE"
**broken link removed**
**broken link removed**

Settings:
In what Operation Mode the Controller should work syncronos/ asynchronos?
What speed you want to use 9600bps or 38400bps?
How many Stop bits you want to use 1 or 2?
Do you want to use a parity bit, when yes with sum, even or odd?
Do you want a interrupt driven transmission and receiving?
All that settings must be done in the initialisation section of your Controller program.
When that's be done and the USART is interfaced to your Computer, by Level Shifter or USB Bridge, you can write a Input and Output Routine for the comunication between your Microcontroller and the PC.
 
Last edited:
nd wht kinda settings u meant.??m sorry if i sound lyk a stupid..
Actually if you could stop writing like a stupid it would be much appreciated. If you can´t bother to write a few more letters, why should anyone bother reading it and helping you?
 
thank you.
settings :
1.Asynchronous
2.9600 baud per second
3.stop bit = 1
4.prity bit= none
5.I think interrupt is needed for our project..
 
Ok, some source Code for the ATMEGA 128:
Code:
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.3 Standard
Automatic Program Generator

Project : 
Version : 
Date    : 05.03.2012
Author  : 
Company : 
Comments: 


Chip type           : ATmega128
Program type        : Application
Clock frequency     : 8,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 1024
*****************************************************/

#include <mega128.h>
#include <string.h>

#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART0 Receiver buffer
#define RX_BUFFER_SIZE0 64
char rx_buffer0[RX_BUFFER_SIZE0];

#if RX_BUFFER_SIZE0<256
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
#else
unsigned int rx_wr_index0,rx_rd_index0,rx_counter0;
#endif

// This flag is set on USART0 Receiver buffer overflow
bit rx_buffer_overflow0;

// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer0[rx_wr_index0]=data;
   if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
   if (++rx_counter0 == RX_BUFFER_SIZE0)
      {
      rx_counter0=0;
      rx_buffer_overflow0=1;
      };
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART0 Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0];
if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
#asm("cli")
--rx_counter0;
#asm("sei")
return data;
}
#pragma used-
#endif

// USART0 Transmitter buffer
#define TX_BUFFER_SIZE0 64
char tx_buffer0[TX_BUFFER_SIZE0];

#if TX_BUFFER_SIZE0<256
unsigned char tx_wr_index0,tx_rd_index0,tx_counter0;
#else
unsigned int tx_wr_index0,tx_rd_index0,tx_counter0;
#endif

// USART0 Transmitter interrupt service routine
interrupt [USART0_TXC] void usart0_tx_isr(void)
{
if (tx_counter0)
   {
   --tx_counter0;
   UDR0=tx_buffer0[tx_rd_index0];
   if (++tx_rd_index0 == TX_BUFFER_SIZE0) tx_rd_index0=0;
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART0 Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter0 == TX_BUFFER_SIZE0);
#asm("cli")
if (tx_counter0 || ((UCSR0A & DATA_REGISTER_EMPTY)==0))
   {
   tx_buffer0[tx_wr_index0]=c;
   if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0;
   ++tx_counter0;
   }
else
   UDR0=c;
#asm("sei")
}
#pragma used-
#endif

// Standard Input/Output functions
#include <stdio.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here
unsigned char string[56],uc_i=0;
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Port E initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTE=0x00;
DDRE=0x00;

// Port F initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTF=0x00;
DDRF=0x00;

// Port G initialization
// Func4=In Func3=In Func2=In Func1=In Func0=In 
// State4=T State3=T State2=T State1=T State0=T 
PORTG=0x00;
DDRG=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer 3 Stopped
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Timer 3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=0x00;
EICRB=0x00;
EIMSK=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
ETIMSK=0x00;

// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud rate: 9600
UCSR0A=0x00;
UCSR0B=0xD8;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x33;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// Global enable interrupts
#asm("sei")

while (1)
      {
      
      strcpyf(string,"Hello World");
      for(uc_i=0;uc_i<strlen(string);uc_i++)
        {
        putchar(string[uc_i]);
        }
        // Place your code here
      };
}
Description of Usage is here:
It allows you to specify the following communication modes:
· Asynchronous
· Synchronous Master, with the UCSRC register's UCPOL bit set to 0
· Synchronous Master, with the UCSRC register's UCPOL bit set to 1
· Synchronous Slave, with the UCSRC register's UCPOL bit set to 0
· Synchronous Slave, with the UCSRC register's UCPOL bit set to 1.

The serial communication is realized using the Standard Input/Output Functions getchar, gets, scanf, putchar, puts and printf.

For interrupt driven serial communication, CodeWizardAVR automatically redefines the basic getchar and putchar functions.

The receiver buffer is implemented using the global array rx_buffer.

The global variable rx_wr_index is the rx_buffer array index used for writing received characters in the buffer.

The global variable rx_rd_index is the rx_buffer array index used for reading received characters from the buffer by the getchar function.

The global variable rx_counter contains the number of characters received in rx_buffer and not yet read by the getchar function.
If the receiver buffers overflows the rx_buffer_overflow global bit variable will be set.

The transmitter buffer is implemented using the global array tx_buffer.

The global variable tx_wr_index is the tx_buffer array index used for writing in the buffer the characters to be transmitted.

The global variable tx_rd_index is the tx_buffer array index used for reading from the buffer the characters to be transmitted by the putchar function.

The global variable tx_counter contains the number of characters from tx_buffer not yet transmitted by the interrupt system.

For devices with 2 UARTs, respectively 2 USARTs, there will be two tabs present: UART0 and UART1, respectively USART0 and USART1.

The functions of configuration check and list boxes will be the same as described above.

The UART0 (USART0) will use the normal putchar and getchar functions.

In case of interrupt driven buffered communication, UART0 (USART0) will use the following variables:

rx_buffer0, rx_wr_index0, rx_rd_index0, rx_counter0, rx_buffer_overflow0,

tx_buffer0, tx_wr_index0, tx_rd_index0, tx_counter0.

The UART1 (USART1) will use the putchar1 and getchar1 functions.

In case of interrupt driven buffered communication, UART1 (USART1) will use the following variables:

rx_buffer1, rx_wr_index1, rx_rd_index1, rx_counter1, rx_buffer_overflow1,

tx_buffer1, tx_wr_index1, tx_rd_index1, tx_counter1.

All serial I/O using functions declared in stdio.h, will be done using UART0 (USART0).

It's a Interrupt driven transmit and receive routine.
To write a Byte to the serial port You have to use putchar(byte).
For writing complete Strings you have to split it in single characters.

unsigned byte string[56], uc_i=0; //Variable decralation
strcpyf(string,"Hello World"); //Copy string
//Transmit loop
for(uc_i=0;uc_i<strlen(string);uc_i++)
{
putchar(string[uc_i]);
}
It's done with CodeVision AVR
 
I didnt understand the last bit...will you please explain it to me..??thanks
The last Bit only could 0 or 1 ;)

What exact you don't understand?
Please insert the term.

The ATMEGA 1284 is not in my Controller list.
But I can do it for a ATMEGA 644.
 
For writing complete Strings you have to split it in single characters.

unsigned byte string[56], uc_i=0; //Variable decralation
strcpyf(string,"Hello World"); //Copy string
//Transmit loop
for(uc_i=0;uc_i<strlen(string);uc_i++)
{
putchar(string[uc_i]);
}


ow..so do you think it will work for my micro controller ? just asking;)
thanks.
 
That's a little code example.
printf("Hello World"); wouldn't work with an interrupt driven serial Port.

I'm not shure if the code will work proper on a ATMEGA1284.
To check this out You have to compare the USART datasheet section of both controllers.

I would try it. When working its fine, when not you can take a look into the configuration of the USART of the ATMEGA1284.
 
in terms of interrupt i think we need interrupt driven serial port as i have said before ...bt i dont think there would be much difference if we use polling rather than using interrupt...what do i have to change in the code to make it interrupt.?...thank you very much..so kind of you...i will have a look in the configuration..
 
what do i have to change in the code to make it interrupt.?
That is the Interrupt driven one.
With putchar you give Bytes to the Transmitter Buffer.
The transmitter Buffer will be given out byte by byte via the interupt routine, without anything to do for you.
When using a non interrupt driven one the controller is blocked until the last byte of the buffer is transmitted.
 
sorry to disturb you.Can you please tell me if the following program(usart initialization) makes sense or not..



# include <avr /io.h>
# define USART_BAUDRATE 9600
# define BAUD_PRESCALE ((( F_CPU / ( USART_BAUDRATE * 16 UL))) - 1)

int main ( void )
{

char ReceivedByte ;

UCSR1B |= (1 << RXCIE1 ) | (1 << TXCIE1 ); // Turn on the transmission and reception circuitry
UCSR1C |= (1 << UCSZ10 ) | (1 << UCSZ11 ); // Use 8- bit character sizes - URSEL
bit set to select the UCRSC register

UBRR1H = ( BAUD_PRESCALE >> 8);// Load upper 8- bits of the baud rate value into the high byte of
the UBRR register
UBRR1L = BAUD_PRESCALE ; // Load lower 8- bits of the baud rate value into the low byte of the
UBRR register

for (;;) // Loop forever


{


while (( UCSR1A & (1 << RXC1 )) == 0) {}; // Do nothing until data have been received and is ready
to be read from UDR
ReceivedByte = UDR1 ; // Fetch the received byte value into the variable " ReceivedByte "

while (( UCSR1A & (1 << UDRE )) == 0) {}; // Do nothing until UDR is ready for more data to be
written to it
UDR = ReceivedByte ; // Echo back the received byte back to the computer
}

}
 
UBRR1H = ( BAUD_PRESCALE >> 8);// Load upper 8- bits of the baud rate value into the high byte of
the UBRR register
I think thats OK
UBRR1L = BAUD_PRESCALE ; // Load lower 8- bits of the baud rate value into the low byte of the
UBRR register
BAUD_PRESCALE is a 16Bit Variable, UBRR1L is a 8Bit Variable.
I think it's better to use:
UBRR1L=(BAUD_PRESCALE&0xFF);

Be Aware there is a U2X Bit in the Configuration Register of the USART.
That Changes the Formula to:
# define BAUD_PRESCALE ((( F_CPU / ( USART_BAUDRATE * 8 UL))) - 1)

Sometimes it's better to use this to set the Baud Rate closer to the needed Speed.
 
Hi, I have tried all the codes from code vision avr...and tried in proteus with the visual emulator but my hyper terminal are not getting any data. In proteus it shows that its transmitting data but it dosent show up ion the hyper terminal....i have tried more or less all the codes..can there be any other technical problem.??
 
There can be some technical problems.
First try to make a loop on your interface Chip ( FT232RL or MAX232 ).
Disconnect RxD and TxD from your ATMEGA an make a connection between RxD and TxD at your interface Chip.

When all is correct your Hyper Terminal should receive the sent Characters.
When that doesn't work you have a Problem with your Hardware or the Settings of Hyper Terminal. Is Handshake set to "none"?

When that will work there must be a Problem in your programm code.

Let the Controller send a repeated 0xAA and look at the TxD Pin of the Chip, with an Oscilloscope, what happens. Is there any Data? Is the Speed correct?
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top