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

📄 main.c

📁 AVR单片机DIY编程器!源代码及原理图都有!
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
  Copyright (C), 1988-2005, ilan2003 
  File name:      Main.c
  Author: ilan2003     Version:1.1        Date: 2005-12-25
  Description:    
  	MCU Name   	:	Atmega16L
  	Frequency  	:	7.3728MHZ
  	Baudrate   	:	1152000 bit/s
  	IDE	   		:	ICCAVR6.31
  	ProjectName :	High Voltage programmer 	 			
  	ModuleName	:	Main function and some interrupt function		
  Others:  
  Function List:	
  	1. void main(void);	
  	2. void uart0_rx_isr(void);
  	3. void packageProcess(uint08 seqNum);
小松工程(ilan2003)出品    
 2006-1-31
 串口中断实现数据接受
 支持ISP PP模式烧写
 仅支持页写模式
 2006-3-14 	增加bld调线引脚		PA4 
 			输出可控频率		PD4

文件说明:
main.c				//主函数,串口命令处理函数,中断函数
eeprom_my.c			//自定义的eeprom读写函数
delay.c				//软件延时函数
hvprog.c			//并行编程函数
initial.c			//硬件初始化函数
uart.c				//串口驱动函数

command.h			//STK500_2协议头文件
define.h			//一些常用的宏定义
eeprom_add.h		//EEPROM参数地址分别表	
exterPara.h			//参数外部声明头文件
function.h			//函数声明头文件	
hvprog.h			//并行编程有关的宏定义
para.h				//参数声明头文件
		
********************************************************************************/
#include <iom16v.h>
#include <macros.h>
#include <stdlib.h>
#include <string.h>
#include <eeprom.h>
#include "command.h"
#include "define.h"
#include "function.h"
#include "para.h"
#include "Hvprog.h"
#include "eeprom_add.h"


/**********************************************************************
functionName:void uart0_rx_isr(void)
description:串口接收中断
**********************************************************************/
#pragma interrupt_handler uart0_rx_isr:iv_USART_RX
void uart0_rx_isr(void)
{
 	uint08 uartData;				//串口数据
	static uint16 msgCounter=0;
	uartData=UDR;					//读缓冲区数据
	if(statusMachine == ST_START)
	{
		if(uartData==MESSAGE_START)
		{
			statusMachine = ST_GET_SEQ_NUM;	
			checkSum = MESSAGE_START;
		}
	}
	else if(statusMachine == ST_GET_SEQ_NUM)
	{
		seqNumber = uartData;
		checkSum ^= uartData; 
		statusMachine = ST_MSG_SIZE_1;
	}
	else if(statusMachine == ST_MSG_SIZE_1)
	{
		msgSize = uartData;
		msgSize <<=8;
		checkSum ^= uartData;
		statusMachine = ST_MSG_SIZE_2;	
	}
	else if(statusMachine == ST_MSG_SIZE_2)
	{
		msgSize |= uartData;
		checkSum ^= uartData;
		statusMachine = ST_GET_TOKEN;	
	}
	else if(statusMachine == ST_GET_TOKEN)
	{
		if(uartData==TOKEN)
		{
			checkSum ^= uartData;
			statusMachine = ST_GET_DATA;
			msgCounter=0;
		}
		else
		{
			statusMachine = ST_START;
		}
	}
	else if(statusMachine == ST_GET_DATA)
	{
		msg_buffer[msgCounter++]=uartData;
		checkSum ^= uartData;
		if(msgCounter==msgSize)
		{
			statusMachine = ST_GET_CHECK;
		}
	}
	else if(statusMachine == ST_GET_CHECK)
	{
		if(uartData == checkSum)
		{
			mssageEndFlag=1;
		}	
		statusMachine = ST_START;	
	}
}

/**********************************************************************
functionName:void if_upgrade(void)
description:判断升级程序
**********************************************************************/
void if_upgrade(void)
{
	if(!(PINA&BIT(PA4)))
	{
		asm("jmp 0x37ff");
	}
}

/**********************************************************************
functionName:void main(void)
description:主函数
**********************************************************************/
void main(void)
{ 
 	allInit();
 	if_upgrade();
	while(1)
	{	
		if(mssageEndFlag)
		{
			mssageEndFlag=0;
			packageProcess(seqNumber);
		}
	}
}




/**********************************************************************
functionName:void packageProcess(uint08 seqNum)
description:数据包的处理过程
**********************************************************************/		
void packageProcess(uint08 seqNum)
{
	uint08 cmd;
	uint08 tmp=0;
	uint08 tmp2=0;
	uint08 tmp3=0;
	uint08 mode;
	uint16 block_size;
	uint16 i;
	uint16 tmp16;
	uint16 num_bytes=0;
	uint32 polling_address=0;
	uint32 start_address;
	cmd = msg_buffer[0];
	
	//命令CMD_SIGN_ON
	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);
	}
	//命令CMD_SET_PARAMETER
	else if(cmd==CMD_SET_PARAMETER)
	{
		switch(msg_buffer[1])
		{
			case PARAM_SCK_DURATION:
				if((msg_buffer[2]) >= 1  ) clockSpeed=SPI_SPEED_2MHZ;
				if((msg_buffer[2]) >= 2  ) clockSpeed=SPI_SPEED_1MHZ;
				if((msg_buffer[2]) >= 4  ) clockSpeed=SPI_SPEED_500KHZ;
				if((msg_buffer[2]) >= 8  ) clockSpeed=SPI_SPEED_250KHZ;
				if((msg_buffer[2]) >= 16 ) clockSpeed=SPI_SPEED_125KHZ;
				if((msg_buffer[2]) >= 32 ) clockSpeed=SPI_SPEED_62KHZ;
				if(EEPROMread(EEP_SCK_DURATION)!=clockSpeed) 
				EEPROMwrite(EEP_SCK_DURATION,clockSpeed);
				//spi_set_speed(clock_speed);		//因为我这里不是SPI方式编成的
				break;
			case PARAM_RESET_POLARITY:			//区分51和AVR用的
				resetPolarity = msg_buffer[2];
				break;
			case PARAM_CONTROLLER_INIT:
				paramControllerInit = msg_buffer[2];
				break;
			case PARAM_VADJUST:
				vAdjust = msg_buffer[2];
				EEPROMwrite(EEP_VOL_ADJUST,vAdjust);
				break;
			case PARAM_VTARGET:
				vTarget = msg_buffer[2]; 
				EEPROMwrite(EEP_VOL_TARGET,vTarget);
				break;	
			case PARAM_OSC_PSCALE:
				ocsPscale=msg_buffer[2];					
				TCCR1B = ocsPscale&0x07;
				EEPROMwrite(EEP_OCS_PSCALE,ocsPscale);
				break;	
			case PARAM_OSC_CMATCH:
				ocsCmatch=msg_buffer[2];
				OCR1BH=0x00;
				OCR1BL=ocsCmatch;	
				EEPROMwrite(EEP_VOL_CMATCH,ocsCmatch);
				break;
			default:break; 		
		}
		num_bytes = 2;
		msg_buffer[0] = CMD_SET_PARAMETER;
		msg_buffer[1] = STATUS_CMD_OK;
	}
	//命令CMD_GET_PARAMETER
	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_SCK_DURATION:
				tmp = clockSpeed;
				break;
			case PARAM_RESET_POLARITY:
				tmp = resetPolarity;
				break;
			case PARAM_CONTROLLER_INIT:
				tmp = paramControllerInit;
				break;
			case PARAM_VTARGET:				//目标电压
				tmp = vTarget;
				break;	
			case PARAM_VADJUST:
				tmp = vAdjust;				//参考电压
				break;
			case PARAM_TOPCARD_DETECT:
				tmp = TOP_CARD_STK520;
			case PARAM_OSC_PSCALE:
				tmp=ocsPscale;				
				break;	
			case PARAM_OSC_CMATCH:
				tmp=ocsCmatch;
				break;	
			default:break;		
		}
		num_bytes = 3;
		msg_buffer[0] = CMD_GET_PARAMETER;
		msg_buffer[1] = STATUS_CMD_OK;
		msg_buffer[2] = tmp;
	}
	
	//命令CMD_OSCCAL
	else if(cmd==CMD_OSCCAL)
	{
		num_bytes = 2;
		msg_buffer[0] = CMD_OSCCAL;
		msg_buffer[1] = STATUS_CMD_OK;
	}
	
	//命令CMD_LOAD_ADDRESS
	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;
	}
	
	//命令CMD_FIRMWARE_UPGRADE
	else if(cmd==CMD_FIRMWARE_UPGRADE)
	{
		num_bytes = 2;
		msg_buffer[0] = CMD_FIRMWARE_UPGRADE;
		//msg_buffer[1] = STATUS_CMD_OK;
		msg_buffer[1] = STATUS_CMD_FAILED;
		//进入Firmware upgrade模式
	}
	
	//命令CMD_ENTER_PROGMODE_PP
	else if(cmd==CMD_ENTER_PROGMODE_PP)
	{
		uint08 i;
		portInit();			//每次进入编程模式对引脚初始化
		LED_ON_3;
		msDelay(msg_buffer[1]);
		CLR_XTAL;
		CLR_RESET;
		msDelay(msg_buffer[2]);
		for(i=0;i<msg_buffer[3];i++)
		{
			SET_XTAL;
			usDelay(1);
			CLR_XTAL;
			usDelay(1);
		}
		CLR_BS1;	
		CLR_XA0;
		CLR_XA1;
		CLR_PAGEL;
		usDelay(DELAY_PULSE);		//要求等待100ns
		SET_RESET;
		usDelay(DELAY_PULSE);		//要求等待100ns
		num_bytes = 2;
		msg_buffer[0] = CMD_ENTER_PROGMODE_PP;
		msg_buffer[1] = STATUS_CMD_OK;
	}
	
	//命令CMD_LEAVE_PROGMODE_PP
	else if(cmd==CMD_LEAVE_PROGMODE_PP)
	{
		exitProgMode();
		num_bytes = 2;
		msg_buffer[0] = CMD_LEAVE_PROGMODE_PP;
		msg_buffer[1] = STATUS_CMD_OK;
	}
	
	//命令CMD_CHIP_ERASE_PP
	else if(cmd==CMD_CHIP_ERASE_PP)
	{
		uint08 temp; 
		tmp=eraseChip();
		num_bytes = 2;
		msg_buffer[0] = CMD_CHIP_ERASE_PP;
		if(tmp)
		msg_buffer[1] = STATUS_CMD_OK;
		else
		msg_buffer[1] = STATUS_RDY_BSY_TOUT;
	}
	
	/*
	loadCMD(CMD_LOAD_WRITE_FLASH);
			start_address=address;
			for(i=0;i<block_size;i+=2)
			{
				tmp = address&0x00ff;
				flashDataLoad(tmp,msg_buffer[i+11],msg_buffer[i+10]);
				address++;
			}
			if(mode&0x80)	//如果页写
			{
				tmp = (start_address>>8)&0x00ff;
				loadAddH(tmp);
				if(pageProg())
				{
					msg_buffer[1] = STATUS_CMD_OK;
				}
				else 
				{
					msg_buffer[1] = STATUS_RDY_BSY_TOUT;
				}
			}	
			LED_FLASH_2;
	*/
	
	//命令CMD_PROGRAM_FLASH_PP
	else if(cmd==CMD_PROGRAM_FLASH_PP)
	{
		uint16 page_size; 
		block_size = ((unsigned int)msg_buffer[1])<<8;
		block_size |= msg_buffer[2];
		
		tmp=msg_buffer[3]&0b00001110;	//计算pagesize大小,字节数
		tmp>>=1;
		if(tmp==0)
		page_size=0x100;
		else
		page_size=1<<tmp;
		
		if(msg_buffer[3]&0x01)							//page Mode
		{
			if(block_size>=page_size)
			{	
				tmp=block_size/page_size;
				for(tmp2=0;tmp2<tmp;tmp2++)				//页写数次
				{
					start_address=address;
					loadCMD(CMD_LOAD_WRITE_FLASH);
					for(i=0;i<page_size;i+=2)
					{
						tmp3 = address&0x00ff;
						flashDataLoad(tmp3,msg_buffer[i+6+tmp2*page_size],msg_buffer[i+5+tmp2*page_size]);
						address++;
					}
					tmp3 = (start_address>>8)&0x00ff;
					loadAddH(tmp3);
					pageProg();		
				}
			}
			else
			{
				if(msg_buffer[3]&0b10000000)			//需要页写
				{
					;	
				}
			}
		}
		else											//byte Mode
		{
			;
		}
		if(msg_buffer[3]&0b01000000)					//页写结束
		{
			pageProgEnd();
		}
		LED_FLASH_2;
		num_bytes = 2;
		msg_buffer[0] = CMD_PROGRAM_FLASH_PP;
		msg_buffer[1] = STATUS_CMD_OK;
	}
	
	//命令CMD_READ_FLASH_PP
	else if(cmd==CMD_READ_FLASH_PP)
	{
		block_size = ((unsigned int)msg_buffer[1])<<8;
		block_size |= msg_buffer[2];
		for(i=0;i<block_size;i+=2)
		{
			tmp16=flashDataRead2(address);
			tmp  = tmp16&0x00ff;
			tmp2 = (tmp16>>8)&0x00ff;
			msg_buffer[i+2] = tmp;
			msg_buffer[i+3] = tmp2;
			address++;
		}
		num_bytes = 3+block_size;
		msg_buffer[0] = CMD_READ_FLASH_PP;
		msg_buffer[1] = STATUS_CMD_OK;
		msg_buffer[2+block_size] = STATUS_CMD_OK;
		LED_FLASH_2;
	}
	
	//命令CMD_PROGRAM_EEPROM_PP
	else if(cmd==CMD_PROGRAM_EEPROM_PP)
	{
		uint16 page_size; 
		block_size = ((unsigned int)msg_buffer[1])<<8;
		block_size |= msg_buffer[2];
		
		tmp=msg_buffer[3]&0b00001110;					//计算pagesize大小,字节数
		tmp>>=1;
		if(tmp==0)
		page_size=0x100;
		else
		page_size=1<<tmp;
		if(msg_buffer[3]&0x01)							//page Mode
		{
			if(block_size>=page_size)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -