}
//从RS232发送一个字节
void UART_putchar(char c)
{
while(!(UCSR0A & 0x20));
UDR0 = c;
}
//从RS232接收一个字节
int uart_getchar(void)
{
unsigned char status,res;
if(!(UCSR0A & 0x80)) return -1; //no data to be received
status = UCSR0A;
res = UDR0;
if (status & 0x1c) return -1; // If error, return -1
return res;
}
//等待从RS232接收一个有效的字节
char uart_waitchar(void)
{
int c;
while((c=uart_getchar())==-1);
return (char)c;
}
//计算CRC
int calcrc(char *ptr, int count)
{
int crc = 0;
char i;
while (--count >= 0)
{
crc = crc ^ (int) *ptr++ << 8;
i = 8;
do
{
if (crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
} while(--i);
}
return (crc);
}
//退出Bootloader程序,从0x0000处执行应用程序
void quit(void)
{
uart_putchar('O');uart_putchar('K');
uart_putchar(0x0d);uart_putchar(0x0a);
while(!(UCSR0A & 0x20)); //等待结束提示信息回送完成
MCUCR = 0x01;
MCUCR = 0x00; //将中断向量表迁移到应用程序区头部
RAMPZ = 0x00; //RAMPZ清零初始化
asm("jmp 0x0000\n"); //跳转到Flash的0x0000处,执行用户的应用程序
}
//主程序
void main(void)
{
int i = 0;
unsigned char timercount = 0;
unsigned char packNO = 1;
int bufferPoint = 0;
unsigned int crc;
//初始化M128的USART0
UBRR0H = BAUD_H;
UBRR0L = BAUD_L; //Set baud rate
UCSR0B = 0x18; //Enable Receiver and Transmitter
UCSR0C = 0x0E; //Set frame format: 8data, 2stop bit
//初始化M128的T/C0,15ms自动重载
OCR0 = 0xEA;
TCCR0 = 0x0F;
//向PC机发送开始提示信息
while(startupString[i]!='\0')
{
uart_putchar(startupString[i]);
i++;
}
//3秒种等待PC下发“d”,否则退出Bootloader程序,从0x0000处执行应用程序
while(1)
{
if(uart_getchar()== 'd') break;
if (TIFR & 0x02) //timer0 over flow
{
if (++timercount > 200) quit(); //200*15ms = 3s
TIFR = TIFR|0x02;
}
}
//每秒向PC机发送一个控制字符“C”,等待控制字〈soh〉
while(uart_getchar()!=XMODEM_SOH) //receive the start of Xmodem
{
if(TIFR & 0x02) //timer0 over flow
{
if(++timercount > 67) //wait about 1 second
{
uart_putchar(XMODEM_RECIEVING_WAIT_CHAR); //send a "C"
timercount=0;
}
TIFR=TIFR | 0x02;
}
}
//开始接收数据块
do
{
if ((packNO == uart_waitchar()) && (packNO ==(~uart_waitchar())))
{ //核对数据块编号正确
for(i=0;i<128;i++) //接收128个字节数据
{
data[bufferPoint]= uart_waitchar();
bufferPoint++;
}
crc = (uart_waitchar()<<8);
crc += uart_waitchar(); //接收2个字节的CRC效验字
if(calcrc(&data[bufferPoint-128],128)==crc) //CRC校验验证
{ //正确接收128个字节数据
while(bufferPoint >= SPM_PAGESIZE)
{ //正确接受256个字节的数据
write_one_page(); //收到256字节写入一页Flash中
上一页 [1] [2] [3] 下一页
本文关键字:程序 用户 AVR单片机,单片机-工控设备 - AVR单片机