打印
[AVR单片机]

我的M16烧写程序

[复制链接]
1710|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ljxh401|  楼主 | 2008-7-29 16:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
unsigned char avr_bin[]={"我爱AVR"};

//Mega16     SS P12    SCK P20        MOSI P11    RST P9    MISO P10    ACK P19
#define M16RST    9
#define M16SS    12
#define M16SCK    20
#define M16MOSI    11
#define    M16MISO    10
#define M16ACK    19

#define SET_SCK_0()        CLR_PIO(M16SCK)        
#define SET_SCK_1()        SET_PIO(M16SCK)
#define SET_MOSI_0()        CLR_PIO(M16MOSI)                
#define SET_MOSI_1()        SET_PIO(M16MOSI)
#define SET_RST_0()        CLR_PIO(M16RST)                
#define SET_RST_1()        SET_PIO(M16RST)
#define SET_SS_0()            CLR_PIO(M16SS)                
#define SET_SS_1()            SET_PIO(M16SS)

#define GET_MISO()            GET_PIO()&(0x01UL<<M16MISO)
#define GET_ACK()            GET_PIO()&(0x01UL<<M16ACK)

#ifndef NOP
#define NOP                asm("mov %r0,%r0")
#endif

void Delayus(unsigned long us)
{
    unsigned long i;
    do{
        for(i=0;i<100;i++)    NOP;
    }while(--us);
}

uchar SPI_R_W(uchar d)
{
    uchar i;
    for(i=0;i<8;i++)
    {
        if(d&0x80)    SET_MOSI_1();
        else        SET_MOSI_0();
        SET_SCK_1();NOP;NOP;                //时钟高
        d<<=1;
        if(GET_MISO())        d++;
        SET_SCK_0();NOP;NOP;
    }
    return d;
}

//使能编程
uchar EnablePro()
{
    unsigned char d;
    SET_SCK_0();
    SET_RST_1();
    Delayus(5000);
    SET_RST_0();
    Delayus(25000);    //at least 20ms
    SPI_R_W(0xAC);
    SPI_R_W(0x53);
    d=SPI_R_W(0xFF);
    SPI_R_W(0xFF);
    uart0_Printf("编程使能答复:0x%02x",d);
    if(d==0x53)        d=1;
    else            d=0;
    return d;
}

//读取芯片ID
void ReadAvrID()
{
    unsigned char d;
    uart0_Printf("AVR ID:");
    SPI_R_W(0x30);
    SPI_R_W(0x00);
    SPI_R_W(0x00);
    d=SPI_R_W(0x00);
    uart0_Printf("%02X ",d);
    SPI_R_W(0x30);
    SPI_R_W(0x00);
    SPI_R_W(0x01);
    d=SPI_R_W(0x00);
    uart0_Printf("%02X ",d);
    SPI_R_W(0x30);
    SPI_R_W(0x00);
    SPI_R_W(0x02);
    d=SPI_R_W(0x00);
    uart0_Printf("%02X ",d);
}

//擦除Flash
void ErasFlash()
{
    SPI_R_W(0xAC);
    SPI_R_W(0x80);
    SPI_R_W(0xFF);
    SPI_R_W(0xFF);
    Delayus(10000);    //at least 10ms    
    uart0_Printf("擦除完毕 ");
}

//写页缓冲数据
void WritePageCache(unsigned char *pt)
{
    unsigned char i;
    for(i=0;i<0x40;i++)
    {
        SPI_R_W(0x40);
        SPI_R_W(0x00);
        SPI_R_W(i);
        SPI_R_W(*pt++);    
        SPI_R_W(0x48);
        SPI_R_W(0x00);
        SPI_R_W(i);
        SPI_R_W(*pt++);    
    }
}

//将页缓冲数据写入Flash
void SavePage(unsigned int page)
{
    page>>=1;
    SPI_R_W(0x4C);
    SPI_R_W(page/256);
    SPI_R_W(page&0xFF);
    SPI_R_W(0xFF);    
    Delayus(10000);
}

//逐页编程
void ProPage()
{
    unsigned char *pt=avr_bin;
    while(pt<avr_bin+sizeof(avr_bin))
    {
        WritePageCache(pt);
        SavePage( ((unsigned long)pt)-((unsigned long)avr_bin));
        pt+=128;
    }
}

//写熔断时低字节
void WriteSettingLow(unsigned char d)
{
    SPI_R_W(0xAC);
    SPI_R_W(0xA0);
    SPI_R_W(0xFF);
    SPI_R_W(d);    
    Delayus(10000);
}

//写熔断丝高字节
void WriteSettingHight(unsigned char d)
{
    SPI_R_W(0xAC);
    SPI_R_W(0xA8);
    SPI_R_W(0xFF);
    SPI_R_W(d);    
    Delayus(10000);
}

//加密
void WriteLockBit(unsigned char d)
{
    d|=0xC0;            
    SPI_R_W(0xAC);
    SPI_R_W(0xFF);
    SPI_R_W(0xFF);
    SPI_R_W(d);    
    Delayus(10000);    
}

//复位avr
void ResetAvr()
{
    SET_RST_1();
}

//烧录
void avrpro()
{
    while(!EnablePro());        //等待编程使能成功
    ReadAvrID();
    ErasFlash();
    ProPage();
    WriteSettingLow(0x2F);
    WriteSettingHight(0xC9);
    WriteLockBit(0xFC);
    ResetAvr();
}

相关帖子

沙发
ljxh401|  楼主 | 2008-8-1 09:12 | 只看该作者

咋没有人顶一下呢

使用特权

评论回复
板凳
coldra| | 2008-8-1 09:24 | 只看该作者

顶一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

50

主题

221

帖子

3

粉丝