该代码是基于STC单片机的自动化控制系统程序,主要用于控制工业设备中的电机、夹具、切割机等执行机构。程序实现了IAP/EEPROM读写、串口通信、定时器中断等功能模块,支持手动/自动模式切换,通过触摸屏进行参数设置和数据交互。系统具有延时切割时间设定、产量计数、状态指示等功能,通过检测输入信号触发相应的控制逻辑,并实时更新设备运行状态到触摸屏界面。程序采用模块化设计,包含初始化、IAP操作、延时控制、串口通信等子函数,实现了工业设备的自动化控制流程。
#include <REG52.H> //
#include <intrins.h> //
#include <string.h> //
#include "stdio.h" //
#define uint unsigned int //
#define uchar unsigned char //
#define CMD_IDLE 0 //空闲模式
#define CMD_READ 1 //IAP字节读命令
#define CMD_PROGRAM 2 //IAP字节编程命令
#define CMD_ERASE 3 //IAP扇区擦除命令
#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
#define IAP_ADDRESS 0x0000 //时间 EEPROM首地址
typedef unsigned char BYTE; //Catch_Up接上Catch_Dwon接下
typedef unsigned int WORD;
bit Signauto=0; /*退出循环检测*/
bit Rst_Bit=0; /**/
sbit Motor=P2^6; //电机
sbit Clamp=P2^7; //夹具
sbit Cutting_dwon=P1^0; //切割机下降
sbit Flap_Open=P1^1; //翻板开
sbit Catch_Up=P1^2; //接上
sbit Table=P1^3; //台板
sbit OUTA=P1^4;
sbit OUTB=P1^5;
sbit OUT0=P1^6; //
sbit OUT1=P1^7; //
sbit Manual=P5^4; //手动指示
sbit Automatic=P5^5; //自动指示
sbit INTPUT1=P3^2; //自动
sbit INTPUT2=P3^3; //手动
sbit INTPUT3=P3^4; //启动信号
uint Ad_data;
uint DELAY_A; //切割延时
uint aa=0; /****RUN FLAG****/
uint a[10]; //定义数组a
uchar i; //串口接收计数器
uchar k; //信号输入高电平计数器
uint counter; //产量计数器
bit Receive_Flag; //串口接收标志
bit Run_Flag; //自动运行标志
uint FLAG_S; //触摸屏显示标志
uint FLAG_M;
uchar kcounter,kstatus; //按键计数标志 按键状态标志
/*----关闭IAP----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
/*-从ISP/IAP/EEPROM区域读取一字节-*/
BYTE IapReadByte(WORD addr)
{
BYTE dat; //数据缓冲区
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
nop(); //等待ISP/IAP/EEPROM操作完成
dat = IAP_DATA; //读ISP/IAP/EEPROM数据
IapIdle(); //关闭IAP功能
return dat; //返回
}
/*-写一字节数据到ISP/IAP/EEPROM区域-*/
void IapProgramByte(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写ISP/IAP/EEPROM数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
nop(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*---扇区擦除---------------*/
void IapEraseSector(WORD addr)
{
IAP_CONTR = ENABLE_IAP; //使能IAP val=IapReadByte(IAP_ADDRESS+1);
IAP_CMD = CMD_ERASE; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
nop(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*------------------------------------------*/
void delay(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<1000;j++);
}
/*-----------(1)延时子程序12MHz 加千百十个显示--------*/
void Delay100ms(uint x) //
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<11000;j++);
}
/********************************************/
void resrt_io()
{
FLAG_S=7; //1待 机2夹 紧3切 割4翻 转5回 转6复 位7手 动8自 动9切 退 10夹 退11接 上12接 下
printf("va0.val=%d\xff\xff\xff",FLAG_S); //
Motor=1; //电机关
Clamp=1; //夹紧
Cutting_dwon=1; //切割机下降
Flap_Open=1; //翻板开
Table=1; //台板
Catch_Up=1; //接上
OUTA=1; //
OUTB=1; //
Manual=0; //手动指示
Automatic=1; //自动指示
FLAG_M=0; //运行标志
printf("n2.val=%d\xff\xff\xff",FLAG_M);//
}
/****************按键计数器状态寄存器归零*************/
void RstKey()
{
kcounter=0; //按键计数器归零
kstatus=0; //状态寄存器归零
}
/*****************按键低电平检测函数*****************/
void LowVoltKey(void) //按键计数器状态标志加一
{
kcounter++;
kstatus++;
}
/*****************按键高电平检测函数*****************/
void HighVoltKey(void) //按键计数器加一 状态标志归零
{
kcounter++; //按键计数器加一
kstatus=0; //按键状态标志归零
}
/******************************************/
void red_eeprom(void)
{
uint m,n;
m=IapReadByte(IAP_ADDRESS); //时间前八位
n=IapReadByte(IAP_ADDRESS+1); //时间后八位
DELAY_A=m*256+n; //排气一段延时时间
}
/******************************************/
void Write_EepromTime()
{
IapEraseSector(IAP_ADDRESS); //扇区擦除
IapProgramByte(IAP_ADDRESS,DELAY_A/256); // 排气一段延时时间高位
IapProgramByte(IAP_ADDRESS+1,DELAY_A%256); // 排气一段延时时间低位
}
/*****************************************/
void start()
{
//EX0=0; //关INT0中断
FLAG_S=1; //1待 机2夹 紧3切 割4翻 转5回 转6复 位7手 动8自 动 9切 退 10夹 退11接 上12接 下
printf("va0.val=%d\xff\xff\xff",FLAG_S); //
Delay100ms(2);
/*一:启动无输入为1,永久循环*/
do
{ //INTPUT3 启动信号
}
while(Run_Flag);
}
/*------------初始化串口---------------------*/
void InitUart()
{
SCON=0X50; //8位数据,可变波特率
AUXR|=0x01; //串口1选择定时器2为波特率发生器
AUXR|=0X04; //定时器2时钟为Fosc,即1T
T2L=0XE0; //设置定时器处置 110592》9600
T2H=0XFE; //设置定时器处置 110592》9600
AUXR|=0X10; //启动定时器2
TI=1;
ES=1; //
EA=1;
}
/*×--------UART 中断服务程序-------------------**/
/**×**把接收到的数据存进数组a[i]**i开机初始化****/
/***×*接收到触摸屏结束码Receive_Flag标志位置1****/
void Uart() interrupt 4 using 1
{
if(RI)
{
if(SBUF==0XFA) //触摸屏结束码
{
Receive_Flag=1; //接收数据标志置一
RI=0; //
i=0; //数组计数器归零
}
else
{
a[i]=SBUF; //数组下标位置的数据等于SBUF
RI=0; //
i++;
}
}
}
/**************定时中断*************************/
void timer0() interrupt 1
{
TH0=0X53;
TL0=0X32;
aa++;
if(aa>=300)
{
OUT1=~OUT1;
aa=0;
}
}
/*************************************************/
void main( ) /*主程序开始*/
{
AUXR=0X80; //STC系列的1T 设置
TMOD=0X01;
TH0=0X53;
TL0=0X32;
ET0=1;
TR0=1;
P_SW1=0x00; //RXD/P3.0, TXD/P3.1
Receive_Flag=0;
InitUart(); //初始化串口
resrt_io();
Delay100ms(20);
red_eeprom(); //
printf("XFF,XFF,XFF");
i=0; //数据接收计数器等于0
Run_Flag=0; //自动标志等于0
counter=0; //产量归零
printf("n0.val=%d\xff\xff\xff",DELAY_A); // 延时切割时间
printf("n0.val=%d\xff\xff\xff",DELAY_A); // 延时切割时间
printf("n1.val=%d\xff\xff\xff",counter); // 产量计数
while(1)
{
OUT0=~OUT0; //手动循环信号指示
Delay100ms(20);
////////////////////////////////
RstKey(); //按键复位
for(;kcounter<5;) //按键循环5次
{
if(!INTPUT1) //按键低电平
{
LowVoltKey();
}
else if(~!INTPUT1) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
Run_Flag=1; //自动运行标志
}
////////////////////////////////
if(Receive_Flag==1) //串口数据更新标志
{
Receive_Flag=0;
if(a[0]==0XE0) //EEPROM参数存储
{
OUT0=0; //写EEPROM指示
if(a[1]==0X00)
{
DELAY_A=a[3]*256+a[2]; //延时切割时间
}
Write_EepromTime();
delay(20);
OUT0=1; //写EEPROM指示
red_eeprom();
printf("n2.val=%d\xff\xff\xff",DELAY_A);//延时切割时间 校对
delay(20);
OUT0=0;
delay(20);
OUT0=0;
}
else if(a[0]==0XB0) //B0 00发送主画面 内容
{
if(a[1]==0X00) //
{
red_eeprom();
printf("n0.val=%d\xff\xff\xff",DELAY_A); //延时切割时间
}
}
}
if(Run_Flag==1) //自动运行标志
{
Manual=1; //手动指示
Automatic=0; //自动指示
FLAG_S=8; //1待 机2夹 紧3切 割4翻 转5回 转6复 位7手 动8自 动9切 退10夹 退
printf("va0.val=%d\xff\xff\xff",FLAG_S); //
Delay100ms(5);
printf("va0.val=%d\xff\xff\xff",FLAG_S); //
Delay100ms(5);
FLAG_M=1;
printf("n2.val=%d\xff\xff\xff",FLAG_M);//
Delay100ms(5);
FLAG_M=1;
printf("n2.val=%d\xff\xff\xff",FLAG_M);//
Delay100ms(5);
start(); //自动运行循环子程序
}
}
} //L311