📄 newmain.c
字号:
#include <macros.h>
#include <iom128v.h>
#include <eeprom.h>
#include <string.h>
#define SPM_PAGESIZE 256 //M128的一个Flash页为256字节(128字)
#define DATA_BUFFER_SIZE SPM_PAGESIZE
//定义at45db161 控制I/O
#define CS 4 //PB4 at45db161 片选
#define BUSY 5 //PB5 at45db161 忙
#define WP 6 //PB6 at45db161 写
#define RESET 7 //PB7 at45db161 复位
//定义全局变量
char data[DATA_BUFFER_SIZE];
unsigned char Senddata[30];
long Filelength;
long address = 0;
unsigned int page_counter_rd;
unsigned int page_offset_rd;
unsigned char lengthbak1,lengthbak2;
int timenum;
int length;length1;
unsigned char ROK_flag,Num;
//延时
void delay_us(int time)
{
do
{
time--;
}
while (time!=0);
}
//擦除(code=0x03)和写入(code=0x05)一个Flash页
void boot_page_ew(long p_address,char code)
{
asm("mov r30,r16\n"
"mov r31,r17\n"
"out 0x3b,r18\n"); //将页地址放入Z寄存器和RAMPZ的Bit0中
SPMCSR = code; //寄存器SPMCSR中为操作码
asm("spm\n"); //对指定Flash页进行操作
}
//填充Flash缓冲页中的一个字
void boot_page_fill(unsigned int address,int data)
{
asm("mov r30,r16\n"
"mov r31,r17\n" //Z寄存器中为填冲页内地址
"mov r0,r18\n"
"mov r1,r19\n"); //R0R1中为一个指令字
SPMCSR = 0x01;
asm("spm\n");
}
//等待一个Flash页的写完成
void wait_page_rw_ok(void)
{
while(SPMCSR & 0x40)
{
while(SPMCSR & 0x01);
SPMCSR = 0x11;
asm("spm\n");
}
}
//更新一个Flash页的完整处理
void write_one_page(void)
{
int i;
boot_page_ew(address,0x03); //擦除一个Flash页
wait_page_rw_ok(); //等待擦除完成
for(i=0;i<SPM_PAGESIZE;i+=2) //jia
{
boot_page_fill(i, data[i]+(data[i+1]<<8));
}
boot_page_ew(address,0x05); //将缓冲页数据写入一个Flash页
wait_page_rw_ok(); //等待写入完成
}
//退出Bootloader程序,从0x0000处执行应用程序
void quit(void)
{
MCUCR = 0x01;
MCUCR = 0x00; //将中断向量表迁移到应用程序区头部
RAMPZ = 0x00; //RAMPZ清零初始化
asm("jmp 0x0000\n"); //跳转到Flash的0x0000处,执行用户的应用程序
}
//初始化I/O
void Init_mag128(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0xd7;
DDRB = 0xd7;
PORTC = 0xff; //m103 output only
DDRC = 0x00;
PORTD = 0x01;
DDRD = 0xf1;
PORTE = 0x02;
DDRE = 0x02;
PORTF = 0x00;
DDRF = 0x00;
PORTG = 0x0;
DDRG = 0x0;
}
//初始化 SPI
void Init_SPI(void)
{
SPCR = 0x5e; //setup SPI
SPSR = 0x00; //setup SPI
}
/* 毫秒级延时程序 */
void delay_ms(unsigned int time)
{
while(time!=0)
{
delay_us(1850);
time--;
if(PORTD&0x01==1)PORTD=PORTD&0xfe;
else PORTD=PORTD|0x1;
}
}
void clr_dog(void)
{
if(PORTD&0x01==1)PORTD=PORTD&0xfe;
else PORTD=PORTD|0x1;
}
//spi模式3
//flash复位
void df_reset(void)
{
PORTB&=~(1<<RESET);
delay_us(500);
PORTB|=1<<RESET;
}
//主模式下发送一个字节或接收一个字节
unsigned char SPI_TranByte(unsigned char cData)
{
SPDR=cData;
while(!(SPSR&0x80));
return SPDR;
}
void Read_Testfile(char *File ,int len )
{
unsigned char i,j;
while(!(PINB&0x20));
PORTB&=~(1<<CS);//使能 at45
SPI_TranByte(0x3);
SPI_TranByte((char)(page_counter_rd>>6));//页地址PA11-PA6
SPI_TranByte((char)((page_counter_rd<<2)|(page_offset_rd>>8)));////页地址PA5-PA0
SPI_TranByte((char)page_offset_rd);
while(len)
{
SPDR=0;
while(!(SPSR&0x80));
*File=SPDR;
File++;
len--;
page_offset_rd++;
if(page_offset_rd>=528)
{
page_offset_rd=0;
page_counter_rd++;
if(page_counter_rd>=4096){quit();page_counter_rd=3849;}
}
}
PORTB|=1<<CS;
}
//UART1 initialize
// desired baud rate:57600
// actual baud rate:57599 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart1_init(void)
{
UCSR1B = 0x00; //disable while setting baud rate
UCSR1A = 0x00;
UCSR1C = 0x06;
UBRR1L = 0x0B; //set baud rate lo
UBRR1H = 0x00; //set baud rate hi
UCSR1B = 0x18;
}
/*//UART1 initialize
// desired baud rate:19200
// actual baud rate:19200 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart1_init(void)
{
UCSR1B = 0x00; //disable while setting baud rate
UCSR1A = 0x00;
UCSR1C = 0x06;
UBRR1L = 0x23; //set baud rate lo
UBRR1H = 0x00; //set baud rate hi
UCSR1B = 0x18;
}*/
unsigned char RecChar(void)
{
timenum=0;
do{
timenum++;
if(timenum>50000){timenum=0;clr_dog();}
}while(!(UCSR1A & 0x80));
return UDR1;
}
/*unsigned char RecChar(void)
{
timenum=0;
do{
timenum++;
clr_dog();
}while((!(UCSR0A & 0x80))&&(timenum<10000000));
return UDR0;
} */
/* 字符输出函数 */
void Send_ByteUART1(char ch)
{
UDR1=ch;
while (!(UCSR1A&(1<<UDRE1))); //UCSRA USART 控制状态寄存器A UDRE=TI
}
void send232(unsigned char *s,unsigned char l)
{
unsigned char i;
for(i=0;i<l;i++)
Send_ByteUART1(*(s+i));
}
void sendok(void)
{
unsigned char i=0;
Senddata[0]='!';
Senddata[5]=1;
Senddata[6]=0xd;
Senddata[7]=0xa;
send232(Senddata,8);
}
void senderror(void)
{
unsigned char i=0;
Senddata[0]='!';
Senddata[5]=0;
Senddata[6]=0xd;
Senddata[7]=0xa;
send232(Senddata,8);
}
void uart0_rx(void)
{
char flag,jym,jym1;
int i;
flag=0;
do{
if(data[0]!='!')data[0]=RecChar();
else
{
Senddata[1]=RecChar();
Senddata[2]=RecChar();
Senddata[3]=RecChar();
Senddata[4]=RecChar();
for(i=0;i<256;i++)
data[i]=RecChar();
jym=RecChar();
jym1=0;
for(i=0;i<256;i++)jym1=jym1^data[i];
if(jym!=jym1)
senderror();
else if((lengthbak1==Senddata[3])&&(lengthbak2==Senddata[4]))sendok();
else if((Senddata[1]==Senddata[3])&&(Senddata[2]==Senddata[4]))
{
ROK_flag=1;
flag=1;
}
else {lengthbak1=Senddata[3];lengthbak2=Senddata[4];flag=1;}
}
// else senderror();
}while(flag==0);
}
//主程序
void main(void)
{
unsigned char BootFlag,i;
int page_num,byte_num;
Init_mag128();
uart1_init();
//PORTD&=~(1<<7);//GSM关机
PORTD|=(1<<7);
Init_SPI();
df_reset();
delay_ms(1000);
EEPROM_READ(0x7ff,BootFlag);
delay_ms(2);
if(BootFlag==0)quit();
else if(BootFlag!=1)
{
for(i=0;i<12;i++)
data[i]=RecChar();
if((data[0]=='B')&&(data[1]=='o'))
{
delay_ms(200);
sendok();
do{
uart0_rx();
write_one_page(); //收到256字节写入一页Flash中
address += SPM_PAGESIZE; //Flash页加1
sendok();
delay_ms(1);
}while(ROK_flag==0);
delay_ms(20);
BootFlag=0;
EEPROM_WRITE(0x7ff,BootFlag);
delay_ms(2000);
quit();
}
else quit();
}
else
{
page_counter_rd=3849;//128k;
page_offset_rd=0;
delay_ms(2);
Read_Testfile(data ,4 );
delay_ms(2);
Filelength=0;
Filelength=data[2];
Filelength=Filelength*0x100+data[3];
delay_ms(1000);
address=0;
while (Filelength>SPM_PAGESIZE)
{
delay_ms(2);
page_num=page_counter_rd;
byte_num=page_offset_rd;
memset(data,0xff,SPM_PAGESIZE);
Read_Testfile(data ,SPM_PAGESIZE );
delay_ms(10);
write_one_page(); //收到256字节写入一页Flash中
address += SPM_PAGESIZE; //Flash页加1
Filelength=Filelength-SPM_PAGESIZE;
}
if(Filelength>0)
{
delay_ms(2);
memset(data,0xff,SPM_PAGESIZE);
Read_Testfile(data ,Filelength );
write_one_page();
clr_dog();
BootFlag=0;
EEPROM_WRITE(0x7ff,BootFlag);
EEPROM_WRITE(0x600,BootFlag);
quit();
}
else
{
delay_ms(2);
BootFlag=0;
EEPROM_WRITE(0x7ff,BootFlag);
EEPROM_WRITE(0x600,BootFlag);
quit();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -