📄 main.c
字号:
/*
实验十九:
mega128 BOOT实验。
1、AVR单片机IAP实验,使用AVRISP协议及上位机软件,进行IAP升级实验。
进入IAP方法:在启动时按住S7键。
退出IAP方法:在不按S7按键的情况下复位CPU即可。
使用方法:和正常的AVRISP下载方式相同。
2、外部3.6864 M晶振。
3、进行此实验请插上LED短路块,与PC机的通信由UART0完成。
4、这个实验是一个高难度实验,同样也是一个很有意义的实验,
此实验可以移植到产品里面使用。
AVR mega128学习板
www.iccavr.com 阿发
5:18 2007-10-20
本实验代码主要参考了小松工程和马潮老师的作品。
*/
#include "init.h"
/*主函数*/
void main(void) {
unsigned char rec_data;
static unsigned int msgCounter;
init();
while (1) {
rec_data=getChar();
if (statusMachine == ST_START) {
//flag = 1;
//TCCR1B = 0x00;
if (rec_data==MESSAGE_START) { /*同步*/
statusMachine = ST_GET_SEQ_NUM;
checkSum = MESSAGE_START;
}
}
else if (statusMachine == ST_GET_SEQ_NUM) { /*序号*/
seqNumber = rec_data;
checkSum ^= rec_data;
statusMachine = ST_MSG_SIZE_1;
}
else if (statusMachine == ST_MSG_SIZE_1) { /*长度*/
msgSize = rec_data;
msgSize <<=8;
checkSum ^= rec_data;
statusMachine = ST_MSG_SIZE_2;
}
else if (statusMachine == ST_MSG_SIZE_2) { /*长度*/
msgSize |= rec_data;
checkSum ^= rec_data;
statusMachine = ST_GET_TOKEN;
}
else if (statusMachine == ST_GET_TOKEN) { /*关键字*/
if (rec_data==TOKEN) {
checkSum ^= rec_data;
statusMachine = ST_GET_DATA;
msgCounter=0;
}
else {
statusMachine = ST_START;
}
}
else if (statusMachine == ST_GET_DATA) { /*读取数据*/
msg_buffer[msgCounter++]=rec_data;
checkSum ^= rec_data;
if (msgCounter==msgSize) { /*判断是否完成*/
statusMachine = ST_GET_CHECK;
}
}
else if (statusMachine == ST_GET_CHECK) { /*数据校验*/
if (rec_data == checkSum) {
packageProcess(seqNumber);
}
statusMachine = ST_START;
}
}
}
/*数据包的处理*/
void packageProcess(unsigned char seqNum) {
unsigned char cmd;
unsigned char tmp = 0;
unsigned int i;
unsigned int num_bytes=0;
unsigned int temp16;
unsigned long start_address = address;
cmd = msg_buffer[0];
//版本信息
if (cmd==CMD_SIGN_ON) {
num_bytes = 11;
msg_buffer[0] = CMD_SIGN_ON;
msg_buffer[1] = STATUS_CMD_OK;
msg_buffer[2] = 8;
memcpy(msg_buffer+3,"STK500_2",8);
}
//参数设置
else if (cmd==CMD_SET_PARAMETER) {
num_bytes = 2;
msg_buffer[0] = CMD_SET_PARAMETER;
msg_buffer[1] = STATUS_CMD_OK;
}
//参数读取
else if (cmd==CMD_GET_PARAMETER) {
switch(msg_buffer[1]) {
/*case PARAM_BUILD_NUMBER_LOW:
tmp = CONFIG_PARAM_BUILD_NUMBER_LOW;
break;
case PARAM_BUILD_NUMBER_HIGH:
tmp = CONFIG_PARAM_BUILD_NUMBER_HIGH;
break;
case PARAM_HW_VER:
tmp = CONFIG_PARAM_HW_VER;
break;
case PARAM_SW_MAJOR:
tmp = CONFIG_PARAM_SW_MAJOR;
break;*/
case PARAM_SW_MINOR:
tmp = CONFIG_PARAM_SW_MINOR;
break;
case PARAM_RESET_POLARITY:
tmp = resetPolarity;
break;
case PARAM_VTARGET: //目标电压
tmp = 50;
break;
case PARAM_VADJUST:
tmp = 50; //参考电压
break;
/*case PARAM_TOPCARD_DETECT:
tmp = TOP_CARD_STK520;
break;
case PARAM_CONTROLLER_INIT:
tmp = paramControllerInit;
break;
case PARAM_SCK_DURATION:
tmp = clockSpeed;
break;*/
default:
tmp = CONFIG_PARAM_SW_MAJOR;
break;
}
num_bytes = 3;
msg_buffer[0] = CMD_GET_PARAMETER;
msg_buffer[1] = STATUS_CMD_OK;
msg_buffer[2] = tmp;
}
//读取时钟修正值
/*else if (cmd==CMD_OSCCAL) {
num_bytes = 2;
msg_buffer[0] = CMD_OSCCAL;
msg_buffer[1] = STATUS_CMD_OK;
}*/
//设置地址
else if (cmd==CMD_LOAD_ADDRESS) {
//address = ((unsigned long)msg_buffer[1])<<24;
address = ((unsigned long)msg_buffer[2])<<16;
address |= ((unsigned long)msg_buffer[3])<<8;
address |= ((unsigned long)msg_buffer[4]);
num_bytes = 2;
msg_buffer[0] = CMD_LOAD_ADDRESS;
msg_buffer[1] = STATUS_CMD_OK;
}
//芯片擦除
else if (cmd==CMD_CHIP_ERASE_ISP) {
num_bytes = 2;
msg_buffer[0] = CMD_CHIP_ERASE_ISP;
msg_buffer[1] = STATUS_CMD_OK;
}
//进入编程模式
else if (cmd == CMD_ENTER_PROGMODE_ISP) {
num_bytes = 2;
msg_buffer[0] = CMD_ENTER_PROGMODE_ISP;
msg_buffer[1] = STATUS_CMD_OK;
PORTB &= ~(1 << PB6);
}
//退出编程模式
else if (cmd==CMD_LEAVE_PROGMODE_ISP) {
num_bytes = 2;
msg_buffer[0] = CMD_LEAVE_PROGMODE_ISP;
msg_buffer[1] = STATUS_CMD_OK;
flag = 0;
PORTB |= (1 << PB6);
}
/*写FLASH*/
/*
M128一页容量为256字节,而AVRISP一帧数据为128字节。
为了仿止有奇数帧出现,所以必顺每一帧写入一次。
每页数据将写入两次,但是下一帧数据不能覆盖上一帧数据。
整个写入过程大概如下:
1、写上半页:擦除一页,写入上半页数据。
2、写全部页:擦除一页,写入整个页数据。
*/
else if (cmd==CMD_PROGRAM_FLASH_ISP) {
/*缓存合并处理*/
if ((address & 0xFF) == 0x00) { /*判断是否为上半页*/
boot_page_ew(address,0x03); /*擦除页*/
wait_page_rw_ok(); /*等待擦除完成 */
/*加载上半页数据*/
for (i = 0; i < SPM_PAGESIZE; i += 2) { /*加载上半页数据*/
temp16=msg_buffer[i+11];
temp16<<=8;
temp16+=msg_buffer[i+10];
boot_page_fill(i,temp16);
}
}
else {
/*写下半页时不擦除页*/
/*加载上半页数据*/
for (i = 0; i < SPM_PAGESIZE; i += 2) { /*填充在后半页,完成合并*/
temp16=msg_buffer[i+11];
temp16<<=8;
temp16+=msg_buffer[i+10];
boot_page_fill(i + 128, temp16);
}
}
boot_page_ew(address,0x05); /*将缓冲页数据写入一个Flash页 */
wait_page_rw_ok(); /*等待写入完成 */
address+=(SPM_PAGESIZE);
num_bytes = 2;
msg_buffer[0] = CMD_PROGRAM_FLASH_ISP;
msg_buffer[1] = STATUS_CMD_OK;
}
//读FLASH
else if (cmd==CMD_READ_FLASH_ISP) {
for(i=0;i<READ_BLOCK_SIZE;i++) {
msg_buffer[i+2] = read_program_memory (address+i,0x00);
}
address+=READ_BLOCK_SIZE;
num_bytes = READ_BLOCK_SIZE + 3;
msg_buffer[0] = CMD_READ_FLASH_ISP;
msg_buffer[1] = STATUS_CMD_OK;
msg_buffer[READ_BLOCK_SIZE + 2] = STATUS_CMD_OK;
}
//读熔丝位
else if (cmd==CMD_READ_FUSE_ISP) {
switch(msg_buffer[2]) {
case 0x50:
msg_buffer[2] = read_program_memory(0x0000,1); //读熔丝位
break;
case 0x58:
msg_buffer[2] = read_program_memory(0x0003,1); //读高熔丝位
break;
default:
break;
}
num_bytes = 4;
msg_buffer[0] = CMD_READ_FUSE_ISP;
msg_buffer[1] = STATUS_CMD_OK;
msg_buffer[3] = STATUS_CMD_OK;
}
//写锁定位
else if (cmd==CMD_PROGRAM_LOCK_ISP) {
//write_lock_bits (msg_buffer[4]|0xC0);
num_bytes = 3;
msg_buffer[0] = CMD_PROGRAM_LOCK_ISP;
msg_buffer[1] = STATUS_CMD_OK;
msg_buffer[2] = STATUS_CMD_OK;
}
//读锁定位
else if (cmd==CMD_READ_LOCK_ISP) {
msg_buffer[2] = read_program_memory(0x0001,1);
num_bytes = 4;
msg_buffer[0] = CMD_READ_LOCK_ISP;
msg_buffer[1] = STATUS_CMD_OK;
msg_buffer[3] = STATUS_CMD_OK;
}
//传送缓冲区数据
if (num_bytes>0) {
putChar(MESSAGE_START);
checkSum=MESSAGE_START;
putChar(seqNum);
checkSum^=seqNum;
tmp=(num_bytes&0xFF00)>>8;
putChar(tmp);
checkSum^=tmp;
tmp=num_bytes&0x00FF;
putChar(tmp);
checkSum^=tmp;
putChar(TOKEN);
checkSum^=TOKEN;
for(i = 0; i < num_bytes; i++) {
putChar(msg_buffer[i]);
checkSum^=msg_buffer[i];
}
putChar(checkSum);
checkSum=0x00;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -