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

📄 main.c

📁 AVR16源代码 ICC编译器
💻 C
字号:
#include	<iom128v.h>
#include	"Eeprom128.h"
#include	"Rtc8025.h"
#include	"Uart.h"
#include	"Crc.h"

#define		BOOT_TEST	0

//============================================================
//无线错误下载设置错误代码定义
#define		ERR_CONNECT	0x10//表示握手信号接收不对;
#define		ERR_COMMANDCRC	0x11//表示接收命令校验错误;
#define		ERR_DATACRC	0x12//表示接收数据不正确,要求丛发数据;
#define		ERR_OVERTIME	0x13//表示接收数据超时;
#define		ERR_NOCOMMAND	0x14//没有该指令;
#define		ERR_SETTING	0x15//设置参数失败;
#define		ERR_READTIME	0x16//读取系统时钟失败;

//============================================================
//定义写Flash一页的长度,同时声明数据Buffer
#define   	SPM_PAGESIZE 	256
unsigned char	SendData[100];       
unsigned char 	SendBuf[100];
unsigned char 	ReceiveBuf[150];
unsigned char 	data[SPM_PAGESIZE];

//============================================================ 
//定义接收数据的起点和写FLASH的起始地址
unsigned int 	bPiont = 0;
unsigned long 	address= 0x0000;

//============================================================
//函	数:void boot_page_ew(long p_address,char code) 
//功	能:读写FLASH数据
//入口参数:地址,命令字03擦除,05写入
//返 回 值:无
//设 计 者:覃道堂
//创作时间:2006-03-16
//修改时间:
//修改目的:
//============================================================ 
void boot_page_ew(long p_address,char code) 
{ 
    	asm("mov r30,r16\n" 
        "mov r31,r17\n" 
        "out 0x3b,r18\n");            	//将页地址放入Z寄存器和RAMPZ的Bit0中 
    	SPMCSR = code;                	//寄存器SPMCSR中为操作码 
    	asm("spm\n");                   //对指定Flash页进行操作 
} 
//============================================================
//函	数:void boot_page_fill(unsigned int address,int data) 
//功	能:填充Flash缓冲页中的一个字 
//入口参数:地址和数据
//返 回 值:无
//设 计 者:覃道堂 
//创作时间:2006-03-16
//修改时间:
//修改目的:
//============================================================        
void boot_page_fill(unsigned int address,int data) 
{ 
    	asm("mov r30,r16\n" 
        "mov r31,r17\n"             //Z寄存器中为填冲页内地址 
        "mov r0,r18\n" 
        "mov r1,r19\n");            //R0R1中为一个指令字 
    	SPMCSR = 0x01; 
   	asm("spm\n"); 
} 
//============================================================
//函	数:void wait_page_rw_ok(void)
//功	能:等待一个Flash页的写完成
//入口参数:无
//返 回 值:无
//设 计 者:覃道堂 
//创作时间:2006-03-16
//修改时间:
//修改目的:
//============================================================
void wait_page_rw_ok(void) 
{ 
      	while(SPMCSR & 0x40) 
     	{ 
         	while(SPMCSR & 0x01); 
         	SPMCSR = 0x11; 
         	asm("spm\n"); 
     	} 
} 
//============================================================
//函	数:void write_one_page(void)
//功	能:一页处理完成
//入口参数:无
//返 回 值:无
//设 计 者:覃道堂 
//创作时间:2006-03-16
//修改时间:
//修改目的:
//============================================================
void write_one_page(void) 
{ 
    	int 	i; 
    	boot_page_ew(address,0x03);                 //擦除一个Flash页 
    	wait_page_rw_ok();                          //等待擦除完成 
    	for(i = 0;i < SPM_PAGESIZE;i += 2)                //将数据填入Flash缓冲页中 
    	{ 
        	boot_page_fill(i, data[i]+(data[i+1]<<8)); 
    	} 
    	boot_page_ew(address,0x05);                  //将缓冲页数据写入一个Flash页 
    	wait_page_rw_ok();                           //等待写入完成 
}  

//============================================================
//函	数:void quit(void)
//功	能:跳转程序运行
//入口参数:无
//返 回 值:无
//设 计 者:覃道堂 
//创作时间:2006-03-16
//修改时间:
//修改目的:
//============================================================
void quit(void)
{
	MCUCR = 0x01;
	MCUCR = 0x00;
	RAMPZ = 0x00;
	asm("jmp 0x0000\n");
}

//============================================================
//函	数:unsigned char Flow_Control(void)
//功	能:下载函数控制
//入口参数:ReceiveBuf接收数据,data写入Flash数据
//返 回 值:0成功,否则失败
//设 计 者:覃道堂 
//创作时间:2006-03-16
//修改时间:
//修改目的:
//============================================================
unsigned char Flow_Control(void)
{
	int		bPiont = 0;
	unsigned char 	Rec_Len;  
	unsigned char 	Wrong_Cnt = 0;
	unsigned short 	CRC_Value;
	    	
	while(Wrong_Cnt < 3)
	{
		Rec_Len = Uart_Receive_Frame(ReceiveBuf, 10);
		if(Rec_Len)//收到数据吗?没有等待数据	    
	 	{  
	 		if((ReceiveBuf[3] == 'E')&&(ReceiveBuf[4] == 'N')&&(ReceiveBuf[5] == 'D'))
	      		{
	       			break;		//如果收到END终止
	       		}
        		else
			{  
				CRC_Value = Verify_Command(ReceiveBuf,Rec_Len);
		          	if(CRC_Value == 0)
		            	{
		            		if(bPiont == 0)
		            		{
		            			for(bPiont = 0; bPiont < 128; bPiont ++)
				        		data[bPiont] = ReceiveBuf[bPiont+5];
		            		}
		            		else
		            		{
		            			for(bPiont = 128; bPiont < 256; bPiont ++)
				        		data[bPiont] = ReceiveBuf[bPiont-128+5];
				        	write_one_page();
				        	address += SPM_PAGESIZE;
				        	bPiont = 0;
		            		}
		             		PC_Send_Ok(SendData,0x00,SendBuf,0);	//请求下一包命令				
	          		}
            			else
	          		{
	          			Wrong_Cnt++;
	          			if(Wrong_Cnt == 3)
	           				return ERR_OVERTIME;
	          			PC_Send_Err(ERR_DATACRC,SendBuf);	//接收数据错误,需重发
	          		}
	          	}
		}
    	}
	if(bPiont)
		write_one_page();
	PC_Send_Ok(SendData,0x00,SendBuf,0);	//向上位机发送下载成功命令
	
	return 0x00;
}

//============================================================
//函	数:void Setting_Param(unsigned char *ReceiveBuf)
//功	能:设置参数
//入口参数:接收到的数据
//返 回 值:执行结果
//设 计 者:覃道堂 
//创作时间:2006-03-16
//修改时间:
//修改目的:
//============================================================
unsigned char Setting_Param(unsigned char *ReceiveBuf)
{
	Write_EEPROM(&ReceiveBuf[5],2,EE_WT_ID);//设置节点地址
	
	Write_EEPROM(&ReceiveBuf[7],1,EE_WT_GD);//设置组地址
	
	if(Write_Time_Data(&ReceiveBuf[8],Time_Address,7))//设置系统时钟
		PC_Send_Err(ERR_SETTING,SendBuf);
	else
		PC_Send_Ok(SendData,0x00,SendBuf,0);	//向上位机发送设置表具信息结果
	
	return 0;
}

//============================================================
//函	数:unsigned char Read_Param(unsigned char *SendData)
//功	能:读取参数
//入口参数:读取存放的地址
//返 回 值:执行结果
//设 计 者:覃道堂 
//创作时间:2006-03-16
//修改时间:
//修改目的:
//============================================================
unsigned char Read_Param(unsigned char *SendData)
{
	Read_EEPROM(SendData,2,EE_WT_ID);	//读取节点地址
	
	Read_EEPROM(&SendData[2],1,EE_WT_GD);	//读取组地址
	
	PC_Send_Ok(SendData,0,SendBuf,3);	//向上位机发送读取表具信息结果
	
	return 0;
}

//============================================================
//函	数:unsigned char Read_SystemTime(unsigned char *SendData)
//功	能:读取参数
//入口参数:读取存放的地址
//返 回 值:执行结果
//设 计 者:覃道堂 
//创作时间:2006-03-16
//修改时间:
//修改目的:
//============================================================
unsigned char Read_SystemTime(unsigned char *SendData)
{
	if(Read_Time_Data(SendData,Time_Address,7))
		PC_Send_Err(ERR_READTIME,SendBuf);
	else
		PC_Send_Ok(SendData,0,SendBuf,7);	//向上位机发送读取表具信息结果
	
	return 0;
}

//============================================================
//函	数:void main(void)
//功	能:主函数
//入口参数:无
//返 回 值:无
//设 计 者:覃道堂 
//创作时间:2006-03-16
//修改时间:
//修改目的:
//============================================================
void main(void)
{
	int		Rec_Len = 0;
	unsigned char 	Ret_Value = 0;
	unsigned short 	Crc_Value;

	Init_Com();
	Reset_R8025();
	
	PC_Send_Ok(SendData,0x00,SendBuf,1);				//向PC 发送接收握手信号

	Rec_Len = Uart_Receive_Frame(ReceiveBuf, 100);	//等待接收握手信号
	if(Rec_Len)  					//如果没收到数据,跳到0x00处运行程序
  	{
   		if(Verify_Command(ReceiveBuf,Rec_Len))
	 	{
	 		PC_Send_Err(ERR_COMMANDCRC,SendBuf);	//命令CRC校验错误
	  		quit();
	  	} 	
		if((ReceiveBuf[2] != 0x00))		//不是联机命令
		{		
			PC_Send_Err(ERR_CONNECT,SendBuf);					
			quit();  	    		//验证错误		
		}
	}
	else
		quit(); 

	while(1) 
     	{
     		Rec_Len = 0;
     		Rec_Len = Uart_Receive_Frame(ReceiveBuf,10);
        	if(Rec_Len)//接收命令信号
		{
		    	if(Verify_Command(ReceiveBuf,Rec_Len))
	            		Ret_Value = ERR_COMMANDCRC;				
	        	else
			{
			   	switch(ReceiveBuf[2])	//根据不同指令执行不同的操作
	                 	{
		              		case 0x01:	//程序下载
			              		Ret_Value = Flow_Control(); 
						break;
                    			case 0x02:  	//设置组地址,接点地址					     	//Read_Eeprom(POINT,data,14);
						Ret_Value = Setting_Param(ReceiveBuf);
						break;
                      			case 0x03:	//上传表具信息
					     	Ret_Value = Read_Param(SendData);
						break;
					case 0x04: 	//硬件检测
						SendData[0] = 'R';
						SendData[1] = 'T';
						SendData[2] = 'C';
						SendData[3] = 'O';
						SendData[4] = 'K';
						PC_Send_Ok(SendData,0x00,SendBuf,5);	//向上位机发送硬件检测情况       
					        break;	
                      			case 0x05: 	//复位命令   
                      				PC_Send_Ok(SendData,0x00,SendBuf,0);	//向上位机发送复位成功命令 
					        quit();      
					        break;
					case 0x06:	//读取系统时钟
						Ret_Value = Read_SystemTime(SendData);
						break;   
                      			default:	//没有找到相应的指令,返回指令错误
					        Ret_Value = ERR_NOCOMMAND;
			               	        break;
				}
			}
	        	if(Ret_Value)			//执行的子程返回0时表示,成功执行命令
		        	PC_Send_Err(Ret_Value,SendBuf); 
		}
	}
}

⌨️ 快捷键说明

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