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:
I found that convertors that use the FT232RL chip work the best *NOTE the R*

Cheers Ian
 
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.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…