📄 demo.c
字号:
/*
LuckyProg2004 Mega8 BootLoader 引导程序
文件名 : demo.c
作 者: 芯 艺
更新时间: 2004-11-16
CPU : ATMEGA8
时 钟: 外部4MHz
编 译: WinAVR-20040720
E-mail : changfutong@sina.com
MSN : changfutong@hotmail.com
OICQ : 27796915
欢迎访问: http://bitfu.zj.com http://BitFu.yeah.net
注:本程序在CA-M8实验板上调试通过,
与计算机程序LuckyProg2004 配合使用。
*/
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/boot.h>
#include "lp2004.h"
#define uchar unsigned char
#define uint unsigned int
#define FREQ 4
//数据包长度设置成M8页长度(按字节)
//PAGE_SIZE == LP_PACKET_SIZE
#define PAGE_SIZE 64
#define DEVICE_ID 8
#define MAX_PAGE_COUNT 96
#define SET_RED_LED PORTB&=~_BV(PB1)
#define CLR_RED_LED PORTB|=_BV(PB1)
#define SET_YEL_LED PORTB&=~_BV(PB0)
#define CLR_YEL_LED PORTB|=_BV(PB0)
uint g_wPageIndex=0; //读或写例程中用于索引页
uchar g_aPageTemp[PAGE_SIZE]; //数据包缓冲区
uchar g_aCommand[5]; //命令缓冲区
void (*reset)(void)=0x0000;
void uart_putc(uchar c)
{
while( !(UCSRA & (1<<UDRE)) );
UDR=c;
}
uchar uart_getc(void)
{
while( !(UCSRA & (1<<RXC)) );
return UDR;
}
//写flash
void WriteFlash(void)
{
uchar i;
uint PageCount=g_aCommand[2];
PageCount<<=8;
PageCount+=g_aCommand[1];
for(g_wPageIndex=0;g_wPageIndex<PageCount;g_wPageIndex++)
{
uart_putc(LP_ACK);
// 接收当前页面数据
for(i=0;i<PAGE_SIZE;i++)
g_aPageTemp[i]=uart_getc();
//6K以上的不写
if(g_wPageIndex<MAX_PAGE_COUNT)
{
// 页擦除操作
boot_page_erase(g_wPageIndex<<6);
while(boot_rww_busy())
boot_rww_enable();
// 填充缓冲页
for(i = 0; i < PAGE_SIZE; i += 2)
boot_page_fill((unsigned long)i,*((uint *)(g_aPageTemp +i)));
// 页写入操作
boot_page_write(g_wPageIndex<<6);
while(boot_rww_busy())
boot_rww_enable();
}
}
uart_putc(LP_ACK);
}
//读flash
void ReadFlash(void)
{
uchar i;
uint PageCount=g_aCommand[2];
PageCount<<=8;
PageCount+=g_aCommand[1];
uart_putc(LP_ACK);
for( g_wPageIndex=0;g_wPageIndex<PageCount;g_wPageIndex++)
{
uart_getc();
if(g_wPageIndex<MAX_PAGE_COUNT)
{
for(i=0;i<PAGE_SIZE;i++)
uart_putc(pgm_read_byte(i+(g_wPageIndex*PAGE_SIZE)));
}
else//6K以上的页面
{
for(i=0;i<PAGE_SIZE;i++)
uart_putc(0xff);
}
}
}
//写eeprom
void WriteEeprom(void)
{
uchar i;
uint PageCount=g_aCommand[2];
PageCount<<=8;
PageCount+=g_aCommand[1];
for(g_wPageIndex=0;g_wPageIndex<PageCount;g_wPageIndex++)
{
uart_putc(LP_ACK);
// 接收页面数据
for(i=0;i<PAGE_SIZE;i++)
g_aPageTemp[i]=uart_getc();
eeprom_write_block (g_aPageTemp,PAGE_SIZE *g_wPageIndex, PAGE_SIZE);
}
uart_putc(LP_ACK);
}
//读eeprom
void ReadEeprom(void)
{
uchar i;
uint PageCount=g_aCommand[2];
PageCount<<=8;
PageCount+=g_aCommand[1];
uart_putc(LP_ACK);
for( g_wPageIndex=0;g_wPageIndex<PageCount;g_wPageIndex++)
{
uart_getc();
for(i=0;i<PAGE_SIZE;i++)
uart_putc(eeprom_read_byte(i+(g_wPageIndex*PAGE_SIZE)));
}
}
int main(void)
{
uchar tmp;
DDRB=_BV(PB0)|_BV(PB1);
PORTB=0X03;
//uart 初始化
UBRRH=0;
UBRRL=25;//9600 baud 4MHz:25
UCSRB=_BV(RXEN)|_BV(TXEN);
while(1)
{
SET_YEL_LED;
CLR_RED_LED;
tmp=uart_getc();
if(tmp==LP_ACK)
{
uart_putc(LP_ACK);
continue;
}
else if(tmp!=DEVICE_ID)
continue;
uart_putc(LP_ACK);
SET_RED_LED;
CLR_YEL_LED;
for(tmp=0;tmp<5;tmp++)
g_aCommand[tmp]=uart_getc();
switch(g_aCommand[0])
{
case LP_WRITE_FLASH :
WriteFlash();
break;
case LP_READ_FLASH :
ReadFlash();
break;
case LP_WRITE_EEPROM:
WriteEeprom();
break;
case LP_READ_EEPROM:
ReadEeprom();
break;
case LP_ERASE_DEVICE:
uart_putc(LP_ACK);
break;
case LP_WRITE_BITS:
break;
case LP_READ_BITS:
break;
case LP_SCAN_HARDWAR:
break;
case LP_RESET_DEVICE:
uart_putc(LP_ACK);
reset();
break;
default:
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -