marlin固件函数解析

setup()

setup()一般作为初始化的动作

void setup()
{
	setup_killpin();
	setup_powerhold();
	MYSERIAL.begin(BAUDRATE);
	SERIAL_PROTOCOLLNPGM("start");
	SERIAL_ECHO_START;
	//代码段1
	{
	byte mcu = MCUSR;
	if(mcu&1) SERIAL_ECHOLNPGM(MSG_POWERUP);
	if(mcu&2) SERIAL_ECHOLNPGM(MSG_EXTERNAL_RESET);
	if(mcu&4) SERIAL_ECHOLNPGM(MSG_BROWNOUT_RESET);
	if(mcu&8) SERIAL_ECHOLNPGM(MSG_WATCHDOG_RESET);
	if(mcu&32) SERIAL_ECHOLNPGM(MSG_SOFTWARE_RESET);
	MCUSR = 0;
	}
# ifdef STRING_VERSION_CONFIG_H
//代码段2
{
 	#ifdef STRING_CONFIG_H_AUTHOR
SERIAL_ECHO_START;
SERIAL_ECHOPGM(MSG_CONFIGURATION_VER);
SERIAL_ECHOPGM(STRING_VERSION_CONFIG_H);
SERIAL_ECHOPGM(MSG_AUTHOR);
SERIAL_ECHOLNPGM(STRING_CONFIG_H_AUTHOR);
SERIAL_ECHOPGM("Compiled:");
SERIAL_ECHOLNPGM(_DATE_);
 	#endif
}
#endif
//代码段3
{
SERIAL_ECHO_START;
SERIAL_ECHOPGM(MSG_FREE_MEMORY);
SERIAL_ECHO(freeMemory());
SERIAL_ECHOPGM(MSG_PLANNER_BUFFER_BYTES);
SERIAL_ECHOLN((int) sizeof(block_t)*BLOCK_BUFFER_SIZE);
......
Config_RetrieveSettings();//从EEROM载入系统参数
tp_init();//温度设定的初始化
plan_init();//路径规划初始化
watchdog_init();//看门狗初始化
st_init;/步进马达的初始化
setup_photpin();//佳能遥控器控制初始化
servo_init();//RC servo 的初始化
lcd_init();//lcd初始化
_delay_ms(1000);
#if defined((CONTROLLERFAN_PIN)&&CONTROLLERFAN_PIN>-1) //设定CONTROLLERFAN_PIN
#endif
}
}

其中setup_killpin():kill pin设high时会disable失能各个功能,包括步进电机,加热器。
setup_powerhold():在有定义PS_ON的情况下,会依ATX power或是X-Box 360203W设定PS_ON。
其中代码段1是检查startup是否成功
检测reset flag MCUSR的值。
代码段2:marlin的版本信息
代码段3:系统剩下多少memory,以及block的size。

Loop()

Loop()作为执行的主程序

void Loop()
{
//如果cmdbuffer有空间,则读取G-code指令
//读取G-code的buffer为cmdbuffer[BUFSIZE][MAX_CMD_SIZE],BUFSIZE为4,
//最多存4条指令。MAX_CMD_SIZE为96,一条指令最多存96个字元。
	if(buflen<(BUFSIZE -1))
	 get_command();
	 #ifdef SDSUPPORT
	 card.checkautostart(false);
	 #endif
	 if(buflen)
	 {
	 	#ifdef SDSUPPORT
	 	if(card.saving)//当SD卡开启档案作为写入M28时,card.saving会设true,会将cmdbuffer的内容复制到SD卡
	 	{
	 		if(strstr_P(cmdbuffer[bufindr],PSTR("M29"))== null)//如果cmdbuffer读取到M29的指令,则结束复制动作。
	 		card.write_command(cmdbuffer[bufindr]);
	 		if(card.logging)
	 		{
	 			process_commands();//解释并执行G-code的动作
	 		}
	 		else
	 		{
	 	SERIAL_PROTOCOLLNPGM(MSG_OK);
	 		}
	 	}
	 	else
	 	{
	 		SERIAL_PROTOCOLLNPGM(MSG_OK);
	 	}
	 	else 
	 	{
	 		card.closefile();
	 		SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED);
	 		
	 	}
	 }
	 else
	 {
	 process_commands();
	 }
	 #else
	 process_commands();
	 #endif
	 buflen= (buflen-1);//载入cmdbuffer下一个命令
	 bufindr= (bufindr+1)%BUFSIZE;
	 manage_heater();//加热温度控制函数
	 manage_inactivity();//检查系统是否有异常的状况
	 checkHitEndstops();//检查endstop的状态
	 lcd_updata();//更新LCD的讯息
}

manage_heater():温度控制函数

void manage_heater()
{	
	float pid_input;
	float pid_output;
if(temp_meas_ready!=true)//检查是否需要更新,否则结束。
//依据进中断的累积次数是否达到128次(128ms),决定是否要跟新目前的温度。
//在中断中,累积次数达到128次(128ms),会跟新soft-PWM
return;
updataTemperaturesFromRawValues();//跟新每个挤出头及加热板目前的温度,由analog值转换成温度。
for((int e=0;e<EXTRUDERS;e++)
{
	#ifdef PIDTEMP
	kp=22.2,Ki=0.14155776,Kd=869,75,K1=0.95,K2=0.05;
	pid_input = current_temperature[e];//取得目前温度
	#ifdef PID_OPENLOOP//对每个挤出头及加热板做soft_pwm的计算
	//计算每个挤出头及加热板需要加热的时间
	//此计算采用PID控制
	pid_error[e] = target_tenperature[e]-pid_input;
	if(pid_error[e]>PID_FUNCTIONAL_RANGE)
	{
		pid_output = BANG_MAX;
		pid_reset[e] = ture;
		
	}
	else {
	if(pid_reset[e]==true){
		temp_iState[e] = 0.0;
		pid_reset[e] = false;
	}
	pTerm[e] = Kp*pid_error[e];//计算P项
	//计算I项
	{
	temp_iState[e]+=pid_error[e];
	temp_iState[e]=constrain(temp_iState[e],temp_iState_min[e],temp_iState_max[e]);
	iTerm[e] = Ki*temp_iState[e];
	}
	//计算d项
	dTemp[e] = (Kd*(pid_input-temp_dState[e]))*K2+(K1*dTerm[e]);
	temp_dState[e] = pid_input;
	//跟新soft_pwm
	pid_output = constrain(pTerm[e]+iTerm[e]-dTerm[e],0,PID_MAX);
	}
}
}

猜你喜欢

转载自blog.csdn.net/qq_37272520/article/details/82939707