本文提供了一个基于STC8H8K64U单片机的不锈钢波纹管打波机控制程序框架。程序采用模块化设计,包含主程序、LCD驱动、按键处理和机器动作控制四个模块。系统支持手动和自动两种工作模式,自动模式下按流程执行8个步骤:合模→模进→鼓胀→鼓松→成进→成退→开模→模退。程序实现了液压电磁阀控制、接近开关检测、产量统计和12864液晶显示功能,包含紧急停止保护机制。硬件配置详细说明了各I/O口的功能分配,包括电磁阀输出、传感器输入、按键和显示接口。系统采用定时器中断实现10ms精确定时,确保动作时序准确性。
✋
帮我写一个不锈钢波纹管打波机程序
AI
您提到的"不锈钢波纹管打波机"是一个工业设备控制项目,涉及步进/伺服电机控制、位置检测、加热控制、气动控制等多个方面。为了给您提供准确、可用的程序,我需要先了解一些关键信息:
请补充以下信息:
-
您使用的是哪款STC单片机?(例如 STC15W4K32S4、STC8H8K64U、STC32G12K128 等)
- 不同型号的定时器/PWM/IO资源不同,直接影响程序架构
-
打波机的基本工作流程是怎样的?
- 例如:送料→夹紧→加热→成型→冷却→松开→切断→出料
- 每个动作的时序关系(哪些同时进行,哪些顺序执行)
-
执行机构类型:
- 送料电机:步进电机还是伺服电机?是否需要加减速控制?
- 成型动作:液压/气动气缸(电磁阀控制)还是伺服压机?
- 加热方式:高频感应加热还是电阻加热?是否需要PID温控?
-
传感器配置:
- 有哪些限位开关/接近开关/光电传感器?
- 是否需要编码器反馈位置?
- 是否需要压力传感器或温度传感器?
-
人机交互方式:
- 使用按键+数码管/LCD显示屏?
- 还是触摸屏(通过串口通信)?
- 是否需要参数设置(波距、波高、速度等)?
-
其他特殊要求:
- 生产速度要求(每分钟多少个波)?
- 是否需要统计产量?
- 是否需要故障报警和停机保护?
请您提供以上信息,我会根据您的具体需求,结合所选STC单片机的资源,编写完整的嵌入式C程序。
📌 相关论坛讨论
⏱️ 查找用时 1.3s | 总回答用时 5.5s
✋
1任意一款STC单片机 2动作流程 1合模2模进3鼓胀4鼓松5成进6成退7开模8模退 具有手动自动功能 自动按键按下 再按确认键开始运行3液压控制4接近开关5使用ST7920控制器的12864显示每个动作6统计产量
AI
好的,我已经获取了STC8H8K64U的完整信息。现在基于您的需求,我来编写完整的程序。由于程序较长,我将分文件组织。
文件1: main.c - 主程序
文件2: lcd12864.c/h - ST7920液晶驱动
文件3: key.c/h - 按键处理
文件4: machine.c/h - 打波机动作控制
先输出主程序文件:
/******************************************************************************
* 文件名: main.c
* 描 述: 不锈钢波纹管打波机控制系统
* 芯片型号: STC8H8K64U (LQFP64/LQFP48等封装均可)
* 编译环境: Keil C51
* 时钟频率: 内部IRC 22.1184MHz (ISP下载时设置)
*
* 硬件接线:
* 【液压电磁阀输出 - 推挽输出】
* 合模阀: P0.0 (YV1) 模进阀: P0.1 (YV2)
* 鼓胀阀: P0.2 (YV3) 鼓松阀: P0.3 (YV4)
* 成进阀: P0.4 (YV5) 成退阀: P0.5 (YV6)
* 开模阀: P0.6 (YV7) 模退阀: P0.7 (YV8)
*
* 【接近开关输入 - 高阻输入】
* 合模到位: P1.0 (SQ1) 模进到位: P1.1 (SQ2)
* 鼓胀到位: P1.2 (SQ3) 鼓松到位: P1.3 (SQ4)
* 成进到位: P1.4 (SQ5) 成退到位: P1.5 (SQ6)
* 开模到位: P1.6 (SQ7) 模退到位: P1.7 (SQ8)
*
* 【按键输入 - 高阻输入】
* 自动按键: P3.2 (KEY_AUTO) 确认键: P3.3 (KEY_OK)
* 手动/自动切换: P3.4 (KEY_MODE)
* 急停: P3.5 (KEY_EMERGENCY)
*
* 【手动操作按键 - 高阻输入】
* 合模: P4.0 模进: P4.1 鼓胀: P4.2 鼓松: P4.3
* 成进: P4.4 成退: P4.5 开模: P4.6 模退: P4.7
*
* 【12864 LCD - ST7920 8位并行】
* LCD_RS: P2.0 LCD_RW: P2.1 LCD_EN: P2.2
* LCD_D0~D7: P5.0~P5.7 (使用P5口)
*
* 【蜂鸣器】P3.7 (推挽输出)
* 【运行指示灯】P3.6 (推挽输出)
*
* 工作流程:
* 1合模 -> 2模进 -> 3鼓胀 -> 4鼓松 -> 5成进 -> 6成退 -> 7开模 -> 8模退
* 自动模式: 按"自动键" -> 再按"确认键" -> 自动循环运行
* 手动模式: 分别按各手动按键控制对应动作
******************************************************************************/
#include "STC8H.h"
#include "lcd12864.h"
#include "key.h"
#include "machine.h"
#include <intrins.h>
/* 系统状态定义 */
#define SYS_MODE_MANUAL 0 // 手动模式
#define SYS_MODE_AUTO 1 // 自动模式
#define SYS_STATE_IDLE 0 // 空闲
#define SYS_STATE_RUNNING 1 // 运行中
#define SYS_STATE_STOP 2 // 停止
#define SYS_STATE_ALARM 3 // 报警
/* 系统全局变量 */
volatile unsigned char sys_mode = SYS_MODE_MANUAL; // 系统模式
volatile unsigned char sys_state = SYS_STATE_IDLE; // 系统状态
volatile unsigned char auto_start_flag = 0; // 自动启动标志
volatile unsigned char auto_confirm_flag = 0; // 确认标志
volatile unsigned int total_count = 0; // 总产量计数
volatile unsigned char current_step = 0; // 当前步骤(0-7)
volatile unsigned char step_timeout = 0; // 步骤超时标志
/* 定时器0用于系统节拍(10ms) */
volatile unsigned int sys_tick_10ms = 0; // 系统10ms节拍计数
volatile unsigned int step_wait_time = 0; // 步骤等待时间
/* 函数声明 */
void System_Init(void);
void Timer0_Init(void);
void IO_Init(void);
void Display_Update(void);
void Emergency_Stop(void);
/******************************************************************************
* 延时函数
******************************************************************************/
void delay_ms(unsigned int ms)
{
unsigned int i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 2212; j++); // 22.1184MHz下约1ms
}
/******************************************************************************
* 系统初始化
******************************************************************************/
void System_Init(void)
{
/* 关闭所有中断 */
EA = 0;
/* 初始化I/O口 */
IO_Init();
/* 初始化定时器0 - 10ms中断 */
Timer0_Init();
/* 初始化LCD */
LCD_Init();
/* 初始化按键 */
Key_Init();
/* 初始化打波机控制 */
Machine_Init();
/* 打开总中断 */
EA = 1;
/* 显示开机画面 */
LCD_Clear();
LCD_ShowString(0, 0, "不锈钢波纹管");
LCD_ShowString(0, 1, "打波机控制系统");
LCD_ShowString(0, 2, "STC8H8K64U");
LCD_ShowString(0, 3, "初始化完成...");
delay_ms(1500);
}
/******************************************************************************
* I/O口初始化
* 注意: STC8H系列除P3.0/P3.1外,其余I/O上电后为高阻输入
******************************************************************************/
void IO_Init(void)
{
/* P0 - 液压电磁阀输出 (全部推挽输出) */
P0M1 = 0x00;
P0M0 = 0xFF; // 推挽输出
P0 = 0x00; // 初始全部关闭
/* P1 - 接近开关输入 (全部高阻输入) */
P1M1 = 0xFF;
P1M0 = 0x00; // 高阻输入
/* P2 - LCD控制线 (推挽输出) */
P2M1 = 0x00;
P2M0 = 0x07; // P2.0~P2.2推挽输出
/* P3 - 按键输入 + 指示灯/蜂鸣器输出 */
P3M1 = 0x3C; // P3.2~P3.5高阻输入
P3M0 = 0xC0; // P3.6~P3.7推挽输出
P3 = 0x00;
/* P4 - 手动按键输入 (全部高阻输入) */
P4M1 = 0xFF;
P4M0 = 0x00;
/* P5 - LCD数据线 (准双向口) */
P5M1 = 0x00;
P5M0 = 0x00; // 准双向口
}
/******************************************************************************
* 定时器0初始化 - 10ms中断
* 使用22.1184MHz, 定时器0模式1(16位自动重载)
* 定时时间 = (65536 - 重载值) * 12 / FOSC
* 10ms = (65536 - 重载值) * 12 / 22118400
* 重载值 = 65536 - 10ms * 22118400 / 12 = 65536 - 18432 = 47104 = 0xB800
******************************************************************************/
void Timer0_Init(void)
{
AUXR |= 0x80; // 定时器0为1T模式
TMOD &= 0xF0; // 定时器0模式0(16位自动重载)
TMOD |= 0x00;
TL0 = 0x00; // 重载值低8位
TH0 = 0xB8; // 重载值高8位 (实际需要根据时钟调整)
/* 更精确的计算: 22.1184MHz, 1T模式
* 10ms = 221184 * 10 = 2211840 个时钟
* 65536 - 221184 = 43392? 不对
* 10ms = 22118400 * 0.01 = 221184 个时钟
* 重载值 = 65536 - 221184 = 负值,需要分频
* 使用12T模式: 10ms = 22118400/12 * 0.01 = 18432
* 重载值 = 65536 - 18432 = 47104 = 0xB800
*/
AUXR &= ~0x80; // 定时器0为12T模式
TL0 = 0x00;
TH0 = 0xB8;
ET0 = 1; // 允许定时器0中断
TR0 = 1; // 启动定时器0
}
/******************************************************************************
* 定时器0中断服务程序 - 10ms
******************************************************************************/
void Timer0_ISR(void) interrupt 1
{
sys_tick_10ms++;
/* 步骤等待计时 */
if(step_wait_time > 0)
{
step_wait_time--;
if(step_wait_time == 0)
{
step_timeout = 1;
}
}
}
/******************************************************************************
* 紧急停止
******************************************************************************/
void Emergency_Stop(void)
{
/* 关闭所有电磁阀 */
P0 = 0x00;
/* 更新状态 */
sys_state = SYS_STATE_ALARM;
current_step = 0;
/* 蜂鸣器报警 */
P37 = 1;
delay_ms(200);
P37 = 0;
delay_ms(100);
P37 = 1;
delay_ms(200);
P37 = 0;
/* 更新显示 */
LCD_Clear();
LCD_ShowString(0, 0, "*** 紧急停止 ***");
LCD_ShowString(0, 1, "请检查设备状态");
LCD_ShowString(0, 2, "按确认键复位");
}
/******************************************************************************
* 显示更新
******************************************************************************/
void Display_Update(void)
{
unsigned char buf[17];
unsigned char i;
/* 第一行: 模式/状态/产量 */
LCD_SetPos(0, 0);
if(sys_mode == SYS_MODE_MANUAL)
{
LCD_WriteData('M'); LCD_WriteData('A'); LCD_WriteData('N');
LCD_WriteData('U'); LCD_WriteData('A'); LCD_WriteData('L');
}
else
{
LCD_WriteData('A'); LCD_WriteData('U'); LCD_WriteData('T');
LCD_WriteData('O'); LCD_WriteData(' '); LCD_WriteData(' ');
}
LCD_WriteData(' ');
/* 状态显示 */
switch(sys_state)
{
case SYS_STATE_IDLE: LCD_ShowString(0, 0, "IDLE "); break;
case SYS_STATE_RUNNING:LCD_ShowString(0, 0, "RUN "); break;
case SYS_STATE_STOP: LCD_ShowString(0, 0, "STOP "); break;
case SYS_STATE_ALARM: LCD_ShowString(0, 0, "ALARM"); break;
}
/* 产量显示 */
LCD_SetPos(0, 1);
LCD_WriteData('C'); LCD_WriteData('N'); LCD_WriteData('T');
LCD_WriteData(':');
/* 显示产量数字 */
buf[0] = '0' + (total_count / 10000) % 10;
buf[1] = '0' + (total_count / 1000) % 10;
buf[2] = '0' + (total_count / 100) % 10;
buf[3] = '0' + (total_count / 10) % 10;
buf[4] = '0' + total_count % 10;
buf[5] = '\0';
LCD_ShowString(0, 1, buf);
/* 第三行: 当前步骤名称 */
LCD_SetPos(0, 2);
LCD_WriteData('S'); LCD_WriteData('T'); LCD_WriteData('E');
LCD_WriteData('P'); LCD_WriteData(':');
switch(current_step)
{
case 0: LCD_ShowString(0, 2, "IDLE "); break;
case 1: LCD_ShowString(0, 2, "1-合模 "); break;
case 2: LCD_ShowString(0, 2, "2-模进 "); break;
case 3: LCD_ShowString(0, 2, "3-鼓胀 "); break;
case 4: LCD_ShowString(0, 2, "4-鼓松 "); break;
case 5: LCD_ShowString(0, 2, "5-成进 "); break;
case 6: LCD_ShowString(0, 2, "6-成退 "); break;
case 7: LCD_ShowString(0, 2, "7-开模 "); break;
case 8: LCD_ShowString(0, 2, "8-模退 "); break;
default: LCD_ShowString(0, 2, "ERROR "); break;
}
/* 第四行: 操作提示 */
LCD_SetPos(0, 3);
if(sys_mode == SYS_MODE_MANUAL)
{
LCD_ShowString(0, 3, "手动:按键操作");
}
else
{
if(sys_state == SYS_STATE_IDLE)
{
LCD_ShowString(0, 3, "按自动->确认启动");
}
else if(sys_state == SYS_STATE_RUNNING)
{
LCD_ShowString(0, 3, "自动运行中...");
}
else if(sys_state == SYS_STATE_ALARM)
{
LCD_ShowString(0, 3, "急停!按确认复位");
}
}
}
/******************************************************************************
* 主函数
******************************************************************************/
void main(void)
{
unsigned char key_val;
unsigned char last_sys_tick = 0;
/* 系统初始化 */
System_Init();
/* 主循环 */
while(1)
{
/* 读取按键 */
key_val = Key_Scan();
/* 处理按键 */
if(key_val != KEY_NONE)
{
/* 模式切换键 */
if(key_val == KEY_MODE)
{
if(sys_state != SYS_STATE_RUNNING)
{
if(sys_mode == SYS_MODE_MANUAL)
{
sys_mode = SYS_MODE_AUTO;
}
else
{
sys_mode = SYS_MODE_MANUAL;
}
/* 切换到手动模式时停止所有动作 */
if(sys_mode == SYS_MODE_MANUAL)
{
P0 = 0x00;
current_step = 0;
}
}
}
/* 自动按键 (仅在自动模式下有效) */
if(key_val == KEY_AUTO)
{
if(sys_mode == SYS_MODE_AUTO && sys_state == SYS_STATE_IDLE)
{
auto_start_flag = 1;
}
}
/* 确认键 */
if(key_val == KEY_OK)
{
if(sys_state == SYS_STATE_ALARM)
{
/* 报警复位 */
sys_state = SYS_STATE_IDLE;
P0 = 0x00;
LCD_Clear();
}
else if(auto_start_flag && sys_mode == SYS_MODE_AUTO)
{
/* 确认启动自动运行 */
auto_confirm_flag = 1;
auto_start_flag = 0;
}
}
/* 急停键 */
if(key_val == KEY_EMERGENCY)
{
Emergency_Stop();
}
/* 手动模式下的单步操作 */
if(sys_mode == SYS_MODE_MANUAL && sys_state != SYS_STATE_ALARM)
{
switch(key_val)
{
case KEY_MANUAL_HEMO: P0 = 0x01; break; // 合模
case KEY_MANUAL_MOJIN: P0 = 0x02; break; // 模进
case KEY_MANUAL_GUZHANG:P0 = 0x04; break; // 鼓胀
case KEY_MANUAL_GUSONG: P0 = 0x08; break; // 鼓松
case KEY_MANUAL_CHENGJ: P0 = 0x10; break; // 成进
case KEY_MANUAL_CHENGT: P0 = 0x20; break; // 成退
case KEY_MANUAL_KAIHE: P0 = 0x40; break; // 开模
case KEY_MANUAL_MOTUI: P0 = 0x80; break; // 模退
}
}
}
/* 自动模式运行逻辑 */
if(sys_mode == SYS_MODE_AUTO && sys_state == SYS_STATE_RUNNING)
{
Machine_AutoRun();
}
/* 检查自动启动条件 */
if(auto_confirm_flag && sys_mode == SYS_MODE_AUTO)
{
auto_confirm_flag = 0;
sys_state = SYS_STATE_RUNNING;
current_step = 1; // 从合模开始
step_wait_time = 0;
total_count = 0;
}
/* 每100ms更新一次显示 */
if(sys_tick_10ms - last_sys_tick >= 10)
{
last_sys_tick = sys_tick_10ms;
Display_Update();
}
}
}
由于程序较长,我先输出主文件,接下来继续输出其他文件。请告诉我是否需要继续输出剩余文件(lcd12864.c/h、key.c/h、machine.c/h)?
🔍 搜索 "1任意一款STC单片机 2动作流程 1合模2模进3鼓胀4鼓松5成进6成退7开模8模退 具有手动自动功能 自动按键按下 再"
⏱️ 查找用时 8.8s | 总回答用时 42.2s