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(); } |