小智打印机第十二节:打印处理
1. 数据发送与锁存 (send_one_line_data)
- 原理:热敏打印头通常包含一行384个加热像素点(Dot)。代码中通过 spiCommand(data, TPH_DI_LEN) 将一行数据(48字节,即 48 * 8 = 384位)通过SPI接口移入打印头的移位寄存器中。
- 锁存(LAT):数据传输完毕后,digitalWrite(PIN_LAT, LOW) 产生一个低电平脉冲。这个脉冲的作用是将移位寄存器中的数据“锁存”到内部的锁存器中,准备进行加热。
- 动态加热时间计算:代码中有一个巧妙的算法:
float tmpAddTime = 0; clearAddTime(); for (uint8_t i = 0; i < 6; ++i) { for (uint8_t j = 0; j < 8; ++j) { addTime[i] += data[i * 8 + j]; // 统计这一组64个点中有多少个“黑点” } tmpAddTime = addTime[i] * addTime[i]; addTime[i] = kAddTime * tmpAddTime;// 计算补偿时间 } spiCommand(data, TPH_DI_LEN);
因为同时加热的点越多,电源负载越大,单点的实际加热功率会下降。这段代码通过统计黑点数量,动态增加加热时间(
addTime),以保证打印浓度一致。
2. 通道选通与加热 (run_stb)
- 原理:384个加热点被分成了6组(STB1 ~ STB6),每组控制64个点。run_stb 函数通过 switch 语句依次拉高对应的 STB 引脚。
- 加热控制:digitalWrite(PIN_STBx, 1) 拉高引脚,对应的64个加热电阻开始通电发热。加热时长由 us_delay 决定,计算公式为:(基础时间 + 动态补偿时间 + 偏移修正) * (热密度 / 100)。加热结束后拉低引脚,并等待 PRINT_END_TIME 让电阻冷却,防止过热或拖影。
switch (now_stb_num) { case 0: digitalWrite(PIN_STB1, 1); us_delay((PRINT_TIME + addTime[0] + STB1_ADDTIME) * ((double)heat_density / 100)); digitalWrite(PIN_STB1, 0); us_delay(PRINT_END_TIME); break;
3. 走纸与打印协同 (move_and_start_std)
- 原理:打印是逐行进行的,每打印完一行,电机需要带动纸张移动到下一行的位置。
- 时间片优化:代码中有一个非常优秀的细节:
// 4step一行 motor_run(); if (stbnum == ALL_STB_NUM) { // 所有通道打印 for (uint8_t index = 0; index < 6; index++) { run_stb(index); // 把电机运行信号插入通道加热中,减少打印卡顿和耗时 if (index == 1 || index == 3 || index == 5) { motor_run(); } } // motor_run_step(3); } else { // 单通道打印 run_stb(stbnum); motor_run_step(3); }
4. 主打印流程 (start_printing / start_printing_by_queuebuf)
- 流程闭环:
-
- 初始化 (init_printing):开启高压电源 (VH_EN),复位 STB 和 LAT 引脚,开启超时看门狗。
- 循环打印:通过 while(1) 循环,不断从缓冲区提取一行数据,调用 send_one_line_data 发送,再调用 move_and_start_std 执行物理加热和走纸。
- 异常检测 (printing_error_check):在循环中实时检查打印超时、缺纸、温度过高(>65℃)等状态。一旦出现异常,立即停止打印并触发蜂鸣器/LED报警,保护设备安全。
- 收尾 (stop_printing):打印完成后,关闭高压电源,停止电机,并多走几步(motor_run_step)防止纸张卡在加热头下。
void start_printing_by_queuebuf()
{
uint8_t *pdata = NULL;
uint32_t printer_count = 0;
init_printing();
while (1)
{
if (get_ble_rx_leftline() > 0)
{
pdata = read_to_printer();
if (pdata != NULL)
{
printer_count++;
send_one_line_data(pdata);
if (move_and_start_std(false, ALL_STB_NUM))
break;
}
}
else
{
if (move_and_start_std(true, ALL_STB_NUM))
break;
}
if (get_printer_timeout_status())
break;
if (printing_error_check(true))
break;
}
motor_run_step(140);
motor_stop();
clean_blepack_count();
printf("printer finish !!! read=%d printer:%d\n", get_blepack_count(), printer_count);
}
更多推荐




所有评论(0)