⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 demo.c

📁 《AVR单片机GCC程序设计》
💻 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 + -