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)

  • 流程闭环:
    1. 初始化 (init_printing):开启高压电源 (VH_EN),复位 STB 和 LAT 引脚,开启超时看门狗。
    2. 循环打印:通过 while(1) 循环,不断从缓冲区提取一行数据,调用 send_one_line_data 发送,再调用 move_and_start_std 执行物理加热和走纸。
    3. 异常检测 (printing_error_check):在循环中实时检查打印超时、缺纸、温度过高(>65℃)等状态。一旦出现异常,立即停止打印并触发蜂鸣器/LED报警,保护设备安全。
    4. 收尾 (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);
}
 

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐