网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> 技术文库 >> 嵌入式 >> 文章正文
  mega128在线编程问题。于大家共享           ★★★ 【字体:
mega128在线编程问题。于大家共享
作者:61IC录入    文章来源:本站原创    点击数:    更新时间:2006-4-7    

领导要求MEGA128要能够在线升级程序,所以偶下载了很多程序来试,有幸两种方法尝试都成功了,其中一种就是用avrprog下载,不过这种方法下载速度实在有点太那个了,所以我就不用;现在主要是采用下面这种方法:
1,总共有以下几个文件
main.c,assemble.s90,cstartup.s90
defines.h,assemble.h,main.h
2,文件
main.c,
============================
#include "defines.h"
#include "assembly.h"

#define HIGH_CRYSTAL
//#define LOW_CRYSTAL
  
void FlashLoad(void);
void EEpromLoad(void);
void WriteEEprom(void);
char CheckEEprom(void);
void EEPROMwrite(int location, unsigned char byte);
unsigned char EEPROMread(int location);
void SendDeviceID(void);
void GetPageNumber(void);
void ExecCode(void);
char GetPage(void);
void WriteFlash(void);
char CheckFlash(void);
void LockBit(void);
unsigned char chkchar(void);
unsigned char recchar(void);
void sendchar(unsigned char ch);
char HomeNet(void);
void main(void);

unsigned char PageBuffer[PageByte];
unsigned int PageAddress;
unsigned int RealPageAddress;

/* Flash Programing Code                                                     */
void FlashLoad(void)
{
    sendchar('!');
    while (1)
    {
          GetPageNumber();

          if (RealPageAddress == 0xffff) return;

          if (GetPage())
        {
             WriteFlash();
             if (CheckFlash()) sendchar('!');
             else sendchar('@');
        }
          else sendchar('@');
    }
}

void GetPageNumber(void)
{
    unsigned char PageAddressHigh;
    unsigned char PageAddressLow;

    while(!chkchar());
    PageAddressHigh = recchar();

    while(!chkchar());
    PageAddressLow = recchar();

    RealPageAddress = (int)((PageAddressHigh << 8) + PageAddressLow);
    PageAddress = RealPageAddress << NSHIFTPAGE;

    #ifdef RAMPZ_FLAG
        if (PageAddressHigh) RAMPZ = 1;
        else RAMPZ = 0;
    #endif
}

char GetPage(void)
{
    unsigned int i;
    unsigned char LocalCheckSum = 0;
    unsigned char CheckSum = 0;

    for (i=0;i<PageByte;i++)
    {
        while(!chkchar());
        PageBuffer[i]=recchar();
        LocalCheckSum += PageBuffer[i];
       }
           
    while(!chkchar());
    CheckSum = recchar();
    if (LocalCheckSum == CheckSum) return 1;
    else return 0;
}

void WriteFlash(void)
{
    unsigned int i;
    unsigned int TempInt;

    for (i=0;i<PageByte;i+=2)
       {
           TempInt=PageBuffer[i]+(PageBuffer[i+1]<<8);
           fill_temp_buffer(TempInt,i);    //call asm routine.
       }
    
    write_page(PageAddress,0x03);       //Perform page ERASE
    write_page(PageAddress,0x05);       //Perform page write
    enableRWW();
}

char CheckFlash(void)
{
    unsigned int i;                            
    unsigned int TempInt;
    unsigned int TempInt2;

    for (i=0;i<PageByte;i+=2)
    {
        TempInt = read_program_memory(PageAddress + i,0x00);
        TempInt2 = PageBuffer[i] +(PageBuffer[i+1]<<8);
        if (TempInt != TempInt2) return 0;
    }
    return 1;
}

/* LockBit Code                                                                 */
#ifdef LOCKBIT
void LockBit(void)
{
    unsigned char Byte;
    
    sendchar('%');
    
    while(!chkchar());
    Byte = recchar();
    
    while(!chkchar());
    if (Byte == ~recchar()) write_lock_bits(~Byte);
}
#endif
/* Serial Port Code                                                             */
unsigned char chkchar(void)
{
    if(UCSRA & 0x80) return 1;
    else return 0;
}

unsigned char recchar(void)
{
    return UDR;
}

void sendchar(unsigned char ch)
{
    while(!(UCSRA & 0x20));  // wait for empty transmit buffer
    
    #ifndef RS485DDR
        UDR = ch;                   // write char
    #endif

    #ifdef RS485DDR
        RS485PORT |= RS485TXE;     // RS485 in TX mode
        UDR = ch;                   // write char
        while(!(UCSRA & 0x40));  // Wait for char to be cue off
        UCSRA |= 0x40;             // Clear flag
        RS485PORT &= ~RS485TXE;     // RS485 in RX mode
    #endif
}

/* Helpers Code                                                                 */
void delayx(unsigned int x)
{//Unit 1ms
    unsigned int i0,i1;
    for(i0=0;i0<x;i0++){
       #ifdef HIGH_CRYSTAL
        for(i1=0;i1<800;i1++)
       #endif
       #ifdef LOW_CRYSTAL
           for(i1=0;i1<1100;i1++)
       #endif
           {
            i1++;
            i1--;
        }
        //asm("wdr");
    }
}


void SendDeviceID(void)
{
    sendchar(DeviceID);
    sendchar(FlashSize);
    sendchar(BootSize);
    sendchar(PageSize);
    sendchar(EEpromSize);
    recchar();
}

void ExecCode(void)
{
    #ifdef RAMPZ_FLAG
    RAMPZ = 0;
    #endif
    #ifdef INTVECREG
     INTVECREG = 0x01;            // Enable interrupt vector select
     INTVECREG = 0x00;            // Move interrupt vector to flash
    #endif
    asm("jmp 0x0000");       // Run application code   
}
#ifdef HOMENET
char HomeNet(void)
{
    unsigned char i;
    unsigned char Exec = 0;
    unsigned char Boot = 0;
    unsigned char Address;
    
    EEAR = 0x01;
    EECR |= 0x01;                       // Set READ strobe
    Address = EEDR;                     // Return byte
    
    while(1)
    {
        while(!chkchar());

        i = recchar();
        
        if (i == '>') Exec++;
        else Exec = 0;
        
        if (i == '+') Boot++;
        else Boot = 0;
        
        if (Exec >= 3) return 1;
        if (Boot >= 5)
        {
            while(!chkchar());
               if (recchar() != Address) return 1;
               return 0;
        }
    }
    return 1;
}
#endif

void main(void)
{
    unsigned char i;
    asm("cli");                          // disable all interrupts
    PORTA = 0x00;//Initialize Port
       DDRA  = 0xFF;
       PORTB = 0x0;
       DDRB  = 0xeB;
    PORTC = 0x10;
    DDRC  = 0xEE;
    PORTD = 0xff;
    DDRD  = 0x79;
    PORTE = 0xff;
    DDRE  = 0xce;
    PORTE = 0xfb;
    PORTF = 0xFF;
    DDRF  = 0x00;
    PORTG = 0x7F;
    DDRG  = 0x0E;
    
    PULLUPPORT = PULLUPPIN;       // Pull up on RX line
    
    UCSRB = 0x00;                   //disable while setting baud rate
    UCSRA = 0x00;
    UCSRC = 0x86;                   // Asyn,NoParity,1StopBit,8Bit,
    UBRRH = 0x00;                   //set baud rate hi
    UCSRB = 0x18;                   // Rx enable Tx Enable

    #ifdef RS485DDR
        RS485DDR |= RS485TXE;          // RS485 Tranceiver switch pin as output
        RS485PORT &= ~RS485TXE;          // RS485 in Rx mode
    #endif

    for(i=0;i<6;i++){
        if(i%2)    PORTE &= 0xf7;//led on
        else     PORTE |= 0x08;//led off
        delayx(200);
    }

    // Auto-find baudrate if BAUDRATE is undefine
    #ifdef BAUDRATE
    {
        UBRRL = BAUDRATE;
    #else
    for (i = 0; i < 255; ++i)
       {
           UBRRL = i;
    #endif

    #ifdef HOMENET
        if (HomeNet()) ExecCode();
            delayx(20);
    #endif
        recchar();
        sendchar('>');
        if(i%2)    PORTE &= 0xf7;//led on
        else     PORTE |= 0x08;//led off
        delayx(20);
        if (recchar() == '<')
        {
           SendDeviceID();
           FlashLoad();
           #ifdef EEPROM
           EEpromLoad();
           #endif
           #ifdef LOCKBIT
           LockBit();
           #endif
           ExecCode();
        }
    }
    ExecCode();
}

assemble.s90,
============================
    NAME     ASSEMBLY
    PUBLIC    fill_temp_buffer
    PUBLIC    write_page
    PUBLIC    write_lock_bits
    PUBLIC  read_program_memory
    PUBLIC    enableRWW
    RSEG    CODE
        
#include    "defines.h"

;-----------------------------------------

; void write_page (unsigned int adr, unsigned char function);
; bits 8:15 adr addresses the page...(must setup RAMPZ beforehand!!!)
write_page:
    RCALL WAIT_SPMEN
    MOVW    r30, r16        ;move address to z pointer (R31 = ZH, R30 = ZL)
    STS     spm_creg, R18      ;argument 2 decides function
    ESPM                     ;perform pagewrite
    RET

;-----------------------------------------

; void fill_temp_buffer (unsigned int data, unsigned int adr);
; bits 7:1 in adr addresses the word in the page... (2=first word, 4=second word etc..)
fill_temp_buffer:
    RCALL WAIT_SPMEN
    MOVW    r30, r18        ;move adress to z pointer (R31=ZH R30=ZL)
    MOVW    r0, r16         ;move data to reg 0 and 1
    LDI     R19, 0x01
    STS     spm_creg, R19
    ESPM                     ;Store program memory
    RET      
    
;-----------------------------------------    

;unsigned int read_program_memory (unsigned int adr ,unsigned char cmd);
read_program_memory:
    MOVW    r30, r16        ;move adress to z pointer
    SBRC    R18, 0          ;read lockbits? (second argument = 0x09)
    STS     spm_creg, R18      ;if so, place second argument in SPMEN register
    ;#ifdef LARGE_MEMORY ;If large memory (>64K)
;          ELPM                ;Store program memory
    ;#else
    ;    LPM                ;Store program memory
    ;#endif
    ELPM    r16, Z+         ;read LSB
    ELPM    r17, Z          ;read MSB
    
    RET
    
;-----------------------------------------

;void write_lock_bits (unsigned char val);
write_lock_bits:
     MOV     R0, R16   
     LDI     R17, 0x09     
     STS     spm_creg, R17
     ESPM                ;write lockbits
     RET

;-----------------------------------------
        
enableRWW:
    RCALL WAIT_SPMEN
    LDI R27,0x11
    STS spm_creg,R27
    ESPM
    RET   
    
;-----------------------------------------           

WAIT_SPMEN:
    LDS     R27,spm_creg       ; load SPMCR to R27
    SBRC    R27,0           ; check SPMEN flag
    RJMP    WAIT_SPMEN  ; wait for SPMEN flag cleared        
    RET
    
;-----------------------------------------

END

cstartup.s90
============================
;    Call main
    RSEG    CODE:CODE:NOROOT(1)

    PUBLIC    ?cstartup_call_main

?cstartup_call_main:
;#if MEMORY_MODEL != LARGE_MEMORY_MODEL
;#if A90_PROC_OPTION > 1
    LDI    R16,0
    OUT    RAMPZ,R16
;#if A90_POINTER_REG_SIZE > 2
    OUT    RAMPY,R16
    OUT    RAMPX,R16
;#endif /* A90_POINTER_REG_SIZE > 2 */
;#endif /* A90_PROC_OPTION > 1 */
;#endif /* MEMORY_MODEL != LARGE_MEMORY_MODEL */

    XCALL    main
    XCALL    exit
    XJMP    _exit

    END
defines.h,
============================

assemble.h,
============================

main.h
============================

3,我采用的是IAR2。28编译,不过编译是记得在编译配置文件里加上下面的设置
/* Code memory */
-Z(CODE)INTVEC,SWITCH,CODE=1FC00-1FFFF
-Z(FARCODE)FAR_F,INITTAB=1FC00-1FFFF

4,记得好需要一个下载工具哦,如果有需求发mail:xt_xuyi@163.com
不过在用编译器的时候,记得编译里也需要适当的设置.
这个有点多于了。呵呵。。。。

               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    没有相关文章
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号