marlin中Arduino主程序架构
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);
}
}
}