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.

Question:Programming ATMEGA16/8/32 by serial port

Status
Not open for further replies.

Deadly Arrow

New Member
Hello All


I've seen one of my seniors has made a very simple circuit that allowed him to programme the Atmega ucontroller by his serial port ( his laptop has a serial port )

but , my laptop hasn't a serial port , So the question is , if i use an USB to serial converter does't work to programme Atmega (i.e. does the USB 2 serial provides exactly a serial port ?) .. , If not is there any circuit can be used to programme atmega via serial port ?

Regarads ..
 
USB to serial converter should work, but I have seen some cheap converters that does not work.
Valid RS232 signals are plus or minus 5 to 15 volts. I guess that (cheap) USB to serial converter uses plus minus 5 volts and your friends laptop rs232 may have something else. You may need to modify the programmer depending on its design.

I recommend you buy the AVRISP mkII programmer from Atmel (~34 USD): Atmel Products - Atmel AVR 8- and 32-bit - megaAVR - AVRISP mkII
 
Last edited:
Last edited:
At my last unit with an ATMEGA 644, i've included a Boot Loader. The Boot Loader must be played in by a normal ISP Interface.
Further programming is possible by a normal serial interface without any additional Parts.
I've used the CV Megaload Bootloader.
In my Board is included a FT232RL, so you can connect the Unit direct to USB to programm it.
Here ist the cvmegaload.c file
Code:
//uncomment to use UART1
//#define UART1

#pragma promotechar+
#pragma uchar+
#pragma regalloc-
#pragma optsize+

#ifdef UART1
#include <cvmegaloaduart1.h> //contains defines for DeviceID FlashSize BootSize PageSize AddressLshift
#else
#include <cvmegaload.h> //contains defines for DeviceID FlashSize BootSize PageSize AddressLshift
#endif

#include <stdio.h>
#include <delay.h>

#define BAUDRATE 38400
register unsigned int Pagedata @2; //program data to be written from this and read back for checking
register unsigned int PageAddress @4; //address of the page
register unsigned int CurrentAddress @6; //address of the current data -  PageAddress + loop counter
register char inchar @8; //data received from RS232 
register char spmcrval @10; //value to write to SPM control register 
register unsigned int i @11;   //loop counter
register unsigned int j @13;  //13 loop counter  
unsigned int ubbr;
unsigned int Checkdata ; //compared with Pagedata for checking
char PageBuffer[PageByte]; //buffer for data to be written   

#ifdef UART1

#define getchar getchar1
#define putchar putchar1

// Get a character from the USART1 Receiver
#pragma used+
char getchar(void)
{
char status,data;
while (1)
      {
      while (((status=UCSRA) & 128)==0);
      data=UDR1;
      if ((status & (28))==0)
         return data;
      };
}
#pragma used-

// Write a character to the USART1 Transmitter
#pragma used+
void putchar(char c)
{
while ((UCSRA & 32)==0);
UDR1=c;
}
#pragma used-

#endif

char GetPage(void)
{
char LocalCheckSum = 0;
char CheckSum = 0;
// The programming software generates a simple checksum in the 
// same fashion as below to check for data transmission errors
for (j=0;j<PageByte;j++)
    {
    PageBuffer[j]=getchar();
    LocalCheckSum += PageBuffer[j];
    }
CheckSum = getchar();  
if (LocalCheckSum == CheckSum) return 1;
else return 0;
}

char CheckFlash(void)
{
//After the data has been written to flash it is read back and compared to the original
for (j=0;j<PageByte;j+=2)
    {
    CurrentAddress=PageAddress+j; 
    #if defined _CHIP_ATMEGA128_ 
    #asm
    movw r30, r6       ;//move  CurrentAddress to Z pointer  
    elpm r2, Z+         ;//read LSB
    elpm r3, Z           ;//read MSB    
    #endasm    
    #else
    #asm
    movw r30, r6       ;//move  CurrentAddress to Z pointer  
    lpm r2, Z+          ;//read LSB
    lpm r3, Z            ;//read MSB
    #endasm    
    #endif
    Checkdata = PageBuffer[j] +(PageBuffer[j+1]<<8);
    if (Pagedata != Checkdata) return 0;
    }
return 1;
}  

void ExecCode(void)
{
#if defined _CHIP_ATMEGA128_
RAMPZ =  0;  
#endif
MCUCR = 0x01;	       // Enable interrupt vector select
MCUCR = 0x00;	       // Move interrupt vector to flash
#asm("jmp 0x00"); // Run application code   
}

void BootLoad(void)
{ 
// Send chip data to the programming software so that it knows
// how to format transmissions
putchar(DeviceID); 
putchar(FlashSize);
putchar(BootSize);
putchar(PageSize);  
// "!" means all ok and send the next data if there is more
putchar('!');
while(1)
{
PageAddress = (unsigned int)getchar() << 8;  // Receive PageAddress high byte
PageAddress += getchar();   // Add PageAddress low byte
if (PageAddress == 0xffff) ExecCode(); // The windows program sends this value when finished  
#if defined _CHIP_ATMEGA128_  
if (PageAddress >> 8) RAMPZ =  1;
else RAMPZ=0;  
#endif
PageAddress = PageAddress << AddressLshift; //essentially the same as multiply by PageSize
if (GetPage()) //receive one page of data followed by a checksum byte and verify data
{
    for (i=0;i<PageByte;i+=2) //fill temporary buffer in 2 byte chunks from PageBuffer       
    
        {
        Pagedata=PageBuffer[i]+(PageBuffer[i+1]<<8);
        while (SPMCR&1); //wait for spm complete
        CurrentAddress=PageAddress+i; 
        spmcrval=1;
        #asm 
        movw r30, r6    ;//move CurrentAddress to Z pointer   
        mov r1, r3        ;//move Pagedata MSB reg 1
        mov r0, r2        ;//move Pagedata LSB reg 1  
        sts SpmcrAddr, r10   ;//move spmcrval to SPM control register
        spm                ;//store program memory
        #endasm
        }    
   
    while (SPMCR&1);  //wait for spm complete
    spmcrval=3;        //erase page
    #asm 
    movw r30, r4       ;//move PageAddress to Z pointer
    sts SpmcrAddr, r10    ;//move spmcrval to SPM control register              
    spm                 ;//erase page
    #endasm
      
    while (SPMCR&1); //wait for spm complete
    spmcrval=5;        //write page
    #asm 
    movw r30, r4       ;//move PageAddress to Z pointer
    sts SpmcrAddr, r10    ;//move spmcrval to SPM control register              
    spm                 ;//write page
    #endasm

    while (SPMCR&1);  //wait for spm complete
    spmcrval=0x11;   //enableRWW  see mega8 datasheet for explanation
     // P. 212 Section "Prevent reading the RWW section
     // during self-programming
    #asm 
    sts SpmcrAddr, r10   ;//move spmcrval to SPMCR              
    spm   
    #endasm
     if (CheckFlash()) putchar('!');  //all ok, send next page
     else putchar('@'); //there was an error, resend page
     }  //end if (GetPage()) 
  else putchar('@');  //there was an error ,resend page
  }
  }

void main(void)
{    
//Set Pullup on PortA.5 to give power to the Tast
PORTA=0b00100000;
DDRA=0b00000000;
//When PortA.5 ist set to High ( Tast Open ) start Application Else start Bootloader
delay_ms(100);

//Read in Tast
if((PINA&0b00100000)>0)
{
ExecCode(); //Start Programm, when Tast is open - works to GND
}

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
//UBRRH=0x00;
//UBRRL=0x2F;   

//Calculate Baud Rate
ubbr = (unsigned long int)_MCU_CLOCK_FREQUENCY_ / (BAUDRATE * 16) - 1;
UBRRH=ubbr >> 8;
UBRRL = ubbr;

putchar('>'); //I'm here, talk to me


while ( (! (UCSRA&128)) &&( i < 32000) ) i++; //wait for data in or timeout 
if (i < 32000)  inchar= getchar(); 

if (inchar == '<') BootLoad(); // I'm here too, go ahead and load the program to flash 
#asm("jmp 0x7C00"); //Start Bootloader again for ATMEGA 644!
//while(1);
//ExecCode();  // set up and jump to application
}

And the according .h file
Code:
//#define  BootSize    'c'    // 512 Words
#define	 BootSize	 'd'    // 1024 Words
//#define  BootSize    'e'    // 2048 Words
//#define  BootSize    'f'    // 4096 Words
#if defined _CHIP_ATMEGA8_
#define	 DeviceID  	 'A'	// Mega8		
#define	 FlashSize	 'l'    // Flash 8k
#define	 PageSize	 'R'    // 64 Bytes
#define  PageByte 	 64     // 64 Bytes
#define  AddressLshift    6 
#asm(".EQU SpmcrAddr=0x57")
#include <mega8.h>

#elif defined _CHIP_ATMEGA16_
#define	 DeviceID  	 'B'	// Mega16	
#define	 FlashSize	 'm'    // Flash 16k
#define	 PageSize	 'S'    // 128 Bytes
#define  PageByte 	 128     // 128 Bytes
#define  AddressLshift    7
#asm(".EQU SpmcrAddr=0x57")
#include <mega16.h>

#elif defined _CHIP_ATMEGA32_
#define  DeviceID	 'E'	// Mega32
#define	 FlashSize	 'n'    // Flash 32k
#define	 PageSize	 'S'    // 128 Bytes
#define  PageByte 	 128     // 128 Bytes
#define  AddressLshift    7
#asm(".EQU SpmcrAddr=0x57")
#include <mega32.h>

#elif defined _CHIP_ATMEGA8515_
#define	 DeviceID  	 'H'	// Mega8515
#define	 FlashSize	 'l'    // Flash 8k
#define	 PageSize	 'R'    // 64 Bytes
#define  PageByte 	 64     // 64 Bytes
#define  AddressLshift    6
#asm(".EQU SpmcrAddr=0x57")
#include <mega8515.h>

#elif defined _CHIP_ATMEGA8535_
#define	 DeviceID  	 'I'	// Mega8535
#define	 FlashSize	 'l'    // Flash 8k
#define	 PageSize	 'R'    // 64 Bytes
#define  PageByte 	 64     // 64 Bytes
#define  AddressLshift    6
#asm(".EQU SpmcrAddr=0x57")
#include <mega8535.h>

#elif defined _CHIP_ATMEGA88_
#define	 DeviceID  	 'M'	// Mega88
#define	 FlashSize	 'l'    // Flash 8k
#define	 PageSize	 'R'    // 64 Bytes
#define  PageByte 	 64     // 64 Bytes
#define  AddressLshift    6
#asm(".EQU SpmcrAddr=0x57")
#include <mega88.h>

#elif defined _CHIP_ATMEGA168_
#define	 DeviceID  	 'N'	// Mega168
#define	 FlashSize	 'm'    // Flash 16k
#define	 PageSize	 'R'    // 64 Bytes
#define  PageByte 	 64     // 64 Bytes
#define  AddressLshift    6
#asm(".EQU SpmcrAddr=0x57")
#include <mega168.h>   

#elif defined _CHIP_ATMEGA64_
#define	 DeviceID  	 'C'	// Mega64	
#define	 FlashSize	 'o'    // Flash 64k
#define	 PageSize	 'T'    // 256 Bytes		
#define  PageByte 	 256     // 256 Bytes
#define  AddressLshift    8
#define SPMCR SPMCSR
#define UCSRA UCSR0A
#define UCSRB UCSR0B 
#define UCSRC UCSR0C
#define UBRRH UBRR0H
#define UBRRL UBRR0L
#asm(".EQU SpmcrAddr=0x68")
#include <mega64.h>

#elif defined _CHIP_ATMEGA644_
#define	 DeviceID  	 'A'	// Mega644 Mega8
#define	 FlashSize	 'o'    // Flash 64k
#define	 PageSize	 'T'    // 256 Bytes
#define  PageByte 	 256     // 256 Bytes
#define  AddressLshift    8
#define UCSRA UCSR0A
#define UCSRB UCSR0B 
#define UCSRC UCSR0C
#define UBRRH UBRR0H
#define UBRRL UBRR0L
#define SPMCR SPMCSR
#asm(".EQU SpmcrAddr=0x57")
#include <mega644.h>

#elif defined _CHIP_ATMEGA128_
#define	 DeviceID  	 'D'	// Mega128	
#define	 FlashSize	 'p'    // Flash 128k
#define	 PageSize	 'T'    // 256 Bytes
#define  PageByte 	 256     // 256 Bytes
#define  AddressLshift    8
#define UCSRA UCSR0A
#define UCSRB UCSR0B 
#define UCSRC UCSR0C
#define UBRRH UBRR0H
#define UBRRL UBRR0L
#define SPMCR SPMCSR
#asm(".EQU SpmcrAddr=0x68")
#include <mega128.h>

#elif defined _CHIP_ATMEGA169_
#define	 DeviceID  	 'G'	// Mega169
#define	 FlashSize	 'm'    // Flash 16k
#define	 PageSize	 'S'    // 128 Bytes
#define  PageByte 	 128     // 128 Bytes
#define  AddressLshift    7
#define SPMCR SPMCSR
#define UCSRA UCSR0A
#define UCSRB UCSR0B 
#define UCSRC UCSR0C
#define UBRRH UBRR0H
#define UBRRL UBRR0L
#asm(".EQU SpmcrAddr=0x57")
#include <mega169.h>

#elif defined _CHIP_ATMEGA162_
#define	 DeviceID  	 'F'	// Mega162
#define	 FlashSize	 'm'    // Flash 16k
#define	 PageSize	 'S'    // 128 Bytes
#define  PageByte 	 128     // 128 Bytes
#define  AddressLshift    7
#define UCSRA UCSR0A
#define UCSRB UCSR0B 
#define UCSRC UCSR0C
#define UBRRH UBRR0H
#define UBRRL UBRR0L
#asm(".EQU SpmcrAddr=0x57")
#include <mega162.h>

#endif
To Start the Bootloader you must press a button, while powering up the Unit.

Be aware, the Bootloader must! played into Controller via a normal ISP or an other Programm Interface.
Then you can use him.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top