吹塑塑料瓶工位检测

发布时间:2026/6/28 2:53:27
吹塑塑料瓶工位检测 该代码是基于STC单片机的双工位塑料瓶检测系统程序主要功能包括采用12864液晶显示工位A和B的工作状态与计时数据通过4个独立按键实现两个工位时间参数的加减设置0-999可调具有EEPROM存储功能可保存设定的时间参数包含两个工位的独立检测控制逻辑通过外部中断检测启动信号定时器0中断实现精确计时超时报警功能蜂鸣器指示灯采用硬件消抖算法处理按键和传感器信号系统通过IAP方式读写内部EEPROM实现工作参数的掉电保存并具有完善的异常处理机制。程序结构包含初始化、显示驱动、按键处理、中断服务和主控制循环等模块实现了双工位的独立控制和状态监测功能。/*塑料瓶检测2021 11 2 **//*****L609 CODE2211 **//*****-------------------***********//*****| 工位A 000 |**********//*****| 工位B 000 |**********//*****| |**********//*****| |**********//*****-------------------***********//***********************************/#include REG52.H#include intrins.H#define uint unsigned int#define uchar unsigned charuchar code disdt[11]{0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xa3}; //uchar code disds[10]{0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //#define IAP_ADDRESS 0x0800 //EEPROM首地址typedef unsigned char BYTE;typedef unsigned int WORD;#define CMD_IDLE 0 //空闲模式#define CMD_READ 1 //IAP字节读命令#define CMD_PROGRAM 2 //IAP字节编程命令#define CMD_ERASE 3 //IAP扇区擦除命令#define ENABLE_IAP 0x82 //if SYSCLK20MHzsfr INT_CLKO0x8f; //外部中断与时钟输出控制寄存器uint val1,val2,val3,vala,valb; /**/sbit BpP2^3; //Bpsbit CSP2^6; //12864PIN4 vala显示缓冲valb加减时间处理缓冲sbit SIDP2^7; //12864PIN5sbit SCLKP1^0; //12864PIN6sbit A_UpP3^2; // A工位加按键sbit A_DownP3^3; // A工位减按键sbit B_UpP1^3; // B工位加按键sbit B_DownP1^2; // B工位减按键uchar kcounter,kstatus; //按键计数标志 按键状态标志bit Sign; /*低电平标志01*/bit Flag_A,Flag_B; //AB工位运行标志sbit IntPut1P3^6;sbit IntPut2P3^7;sbit IntPut3P2^0;sbit IntPut4P2^1;sbit OUT1P3^0;sbit OUT2P3^1;sbit OUT3P3^4;// sbit OUT4P3^5;sbit OUT5P3^5;uint l,m,n,k; /****个十百代码缓冲**/uint aa0; /****RUN FLAG****//*------------------延时子程序------------------------*/void delay_1ms(uint x){int i, j;for(i0;ix;i)for(j0;j1500;j);}/*----关闭IAP----------------------------*/void IapIdle(){IAP_CONTR0; //关闭IAP功能IAP_CMD0; //清除命令寄存器IAP_TRIG0; //清除触发寄存器IAP_ADDRH0x80; //将地址设置到非IAP区域IAP_ADDRL0;}/*-从ISP/IAP/EEPROM区域读取一字节-*/BYTE IapReadByte(WORD addr){BYTE dat; //数据缓冲区IAP_CONTRENABLE_IAP; //使能IAPIAP_CMDCMD_READ; //设置IAP命令IAP_ADDRLaddr; //设置IAP低地址IAP_ADDRHaddr8; //设置IAP高地址IAP_TRIG0x5a; //写触发命令(0x5a)IAP_TRIG0xa5; //写触发命令(0xa5)_nop_(); //等待ISP/IAP/EEPROM操作完成datIAP_DATA; //读ISP/IAP/EEPROM数据IapIdle(); //关闭IAP功能return dat; //返回}/*-写一字节数据到ISP/IAP/EEPROM区域-*/void IapProgramByte(WORD addr, BYTE dat){IAP_CONTRENABLE_IAP; //使能IAPIAP_CMDCMD_PROGRAM; //设置IAP命令IAP_ADDRLaddr; //设置IAP低地址IAP_ADDRHaddr8; //设置IAP高地址IAP_DATAdat; //写ISP/IAP/EEPROM数据IAP_TRIG0x5a; //写触发命令(0x5a)IAP_TRIG0xa5; //写触发命令(0xa5)_nop_(); //等待ISP/IAP/EEPROM操作完成IapIdle();}/*---扇区擦除---------------*/void IapEraseSector(WORD addr){IAP_CONTRENABLE_IAP; //使能IAP valIapReadByte(IAP_ADDRESS1);IAP_CMDCMD_ERASE; //设置IAP命令IAP_ADDRLaddr; //设置IAP低地址IAP_ADDRHaddr8; //设置IAP高地址IAP_TRIG0x5a; //写触发命令(0x5a)IAP_TRIG0xa5; //写触发命令(0xa5)_nop_(); //等待ISP/IAP/EEPROM操作完成IapIdle();}/*******************************************/void write_eeprom(void){IapEraseSector(IAP_ADDRESS); //扇区擦除lvala/100;m(vala-l*100)/10;nvala-l*100-m*10;IapProgramByte(IAP_ADDRESS1,l); //百位IapProgramByte(IAP_ADDRESS2,m); //十位IapProgramByte(IAP_ADDRESS3,n); //个位lvalb/100;m(valb-l*100)/10;nvalb-l*100-m*10;IapProgramByte(IAP_ADDRESS4,l);//百位IapProgramByte(IAP_ADDRESS5,m);//十位IapProgramByte(IAP_ADDRESS6,n);//个位}/*******************************************/void red_eeprom(void){lIapReadByte(IAP_ADDRESS1); //mIapReadByte(IAP_ADDRESS2); //nIapReadByte(IAP_ADDRESS3); //valal*100m*10n; //A工位时间lIapReadByte(IAP_ADDRESS4); //mIapReadByte(IAP_ADDRESS5); //nIapReadByte(IAP_ADDRESS6); //valbl*100m*10n; //B工位时间}/****************按键计数器状态寄存器归零*************/void RstKey(){kcounter0; //按键计数器归零kstatus0; //状态寄存器归零}/*****************按键低电平检测函数*****************/void LowVoltKey(void) //按键计数器状态标志加一{kcounter;kstatus;}/*****************按键高电平检测函数*****************/void HighVoltKey(void) //按键计数器加一 状态标志归零{kcounter; //按键计数器加一kstatus0; //按键状态标志归零}/*------------------写命令到LCD-----------------------*/void write_com(unsigned char cmdcode){uchar i;uchar i_data,temp_data1,temp_data2;EA0;i_data0xf8;delay_1ms(10);CS1;SCLK0;for(i0;i8;i){SID(bit)(i_data0x80);SCLK0;SCLK1;i_datai_data1;}i_datacmdcode;i_data0xf0;for(i0;i8;i){SID(bit)(i_data0x80);SCLK0;SCLK1;i_datai_data1;}i_datacmdcode;temp_data1i_data0xf0;temp_data2i_data0x0f;temp_data14;temp_data24;i_datatemp_data1|temp_data2;i_data0xf0;for(i0;i8;i){SID(bit)(i_data0x80);SCLK0;SCLK1;i_datai_data1;}CS0;EA1;}/*-------------------写数据到LCD----------------------*/void write_data(unsigned char Dispdata){uchar i;uchar i_data,temp_data1,temp_data2;EA0;i_data0xfa;delay_1ms(10);CS1;for(i0;i8;i){SID(bit)(i_data0x80);SCLK0;SCLK1;i_datai_data1;}i_dataDispdata;i_data0xf0;for(i0;i8;i){SID(bit)(i_data0x80);SCLK0;SCLK1;i_datai_data1;}i_dataDispdata;temp_data1i_data0xf0;temp_data2i_data0x0f;temp_data14;temp_data24;i_datatemp_data1|temp_data2;i_data0xf0;for(i0;i8;i){SID(bit)(i_data0x80);SCLK0;SCLK1;i_datai_data1;}CS0;EA1;}/*------------------初始化LCD屏-----------------------*/void lcd_init(){uchar comdata;delay_1ms(100);comdata0x30;write_com(comdata); /*功能设置:一次送8位数据,基本指令集*/comdata0x04;write_com(comdata); /*点设定:显示字符/光标从左到右移位,DDRAM地址加1*/comdata0x0f;write_com(comdata); /*显示设定:开显示,显示光标,当前显示位反白闪动*/comdata0x01;write_com(comdata); /*清DDRAM*/comdata0x02;write_com(comdata); /*DDRAM地址归位*/comdata0x80;write_com(comdata); /*把显示地址设为0X80即为第一行的首位*/}/*--------------X位置数据显示------------------------*/void Dis_Xdata() //A3B0{lvala/100; /**/m(vala-l*100)/10; /*减t1x1000再减t2X100*/nvala-l*100-10*m; /*分离千 百 十 个三位*/write_com(0x84);write_data(0xA3); /*半个字符*/write_data(disds[l]); /*百位半个字符*/write_com(0x85);write_data(0xA3); /*半个字符*/write_data(disds[m]); /*十位半个字符*/write_com(0x86);write_data(0xA3); /*半个字符*/write_data(disds[n]); /*个位半个字符*/}/*--------------Y位置数据显示------------------------*/void Dis_Ydata(){lvalb/100; /**/m(valb-l*100)/10; /*减t1x1000再减t2X100*/nvalb-l*100-10*m; /*分离千 百 十 个三位*/write_com(0x94);write_data(0xA3); /*半个字符*/write_data(disds[l]); /*百位半个字符*/write_com(0x95);write_data(0xA3); /*半个字符*/write_data(disds[m]); /*十位半个字符*/write_com(0x96);write_data(0xA3); /*半个字符*/write_data(disds[n]); /*个位半个字符*/}/*--------------X位置数据显示------------------------*/void Dis_XTime(uint val) //A3B0{lval/100; /**/m(val-l*100)/10; /*减t1x1000再减t2X100*/nval-l*100-10*m; /*分离千 百 十 个三位*/write_com(0x88);write_data(0xA3); /*半个字符*/write_data(disds[l]); /*百位半个字符*/write_com(0x89);write_data(0xA3); /*半个字符*/write_data(disds[m]); /*十位半个字符*/write_com(0x8A);write_data(0xA3); /*半个字符*/write_data(disds[n]); /*个位半个字符*/}/*--------------Y位置数据显示------------------------*/void Dis_YTime(uint val){lval/100; /**/m(val-l*100)/10; /*减t1x1000再减t2X100*/nval-l*100-10*m; /*分离千 百 十 个三位*/write_com(0x98);write_data(0xA3); /*半个字符*/write_data(disds[l]); /*百位半个字符*/write_com(0x99);write_data(0xA3); /*半个字符*/write_data(disds[m]); /*十位半个字符*/write_com(0x9A);write_data(0xA3); /*半个字符*/write_data(disds[n]); /*个位半个字符*/}/*------------------开机广告-----------------------*/void displayAdvertising() //B9 A4 CEBB A6AA A6AB{write_com(0x80); /*--工---*/write_data(0xB9);write_data(0xA4);write_com(0x81); /*--位---*/write_data(0xCE);write_data(0xBB);write_com(0x82);write_data(0xA3);write_data(0xC1); /*--A----*/write_com(0x90); /*--工---*/write_data(0xB9);write_data(0xA4);write_com(0x91); /*--位---*/write_data(0xCE);write_data(0xBB);write_com(0x92);write_data(0xA3);write_data(0xC2); /*--B----*/}/**************定时中断*************************/void timer0() interrupt 1{aaaa1;TH00X53;TL00X32;if(aa2){OUT5!OUT5,aa0;if(Flag_A1) //气缸下位开关未到位val1; //标志未复位工位A计时if(Flag_B1) //气缸下位开关未到位val2; //标志未复位工位B计时}}//中断服务程序 P3.6void exint2() interrupt 10 //INT2中断入口{RstKey();if(!IntPut1Flag_A0) //启动信号键{for(;kcounter3;) //按键循环5次{if(!IntPut1) //按键低电平{LowVoltKey();}else if(~!IntPut1) //按键高电平{HighVoltKey();}}if(kstatus2) /*按键状态标志大于等于3为有效值*/{ /*循环检测 */Flag_A1; //启动气缸A计数OUT10; //A工位启动指示}}}//中断服务程序 P3.7void exint3() interrupt 11 //INT3中断入口{RstKey(); /*开始kcounter,kstatus*/if(!IntPut2Flag_B0) //启动信号键{for(;kcounter3;) //按键循环5次{if(!IntPut2) //按键低电平{LowVoltKey();}else if(~!IntPut2) //按键高电平{HighVoltKey();}}if(kstatus2) /*按键状态标志大于等于3为有效值*/{ /*循环检测 */Flag_B1; //启动气缸B计数OUT20; //B工位启动指示}}}/*------------------主循环程序----------------*/void main( ) /*主程序开始*/{Flag_A0;Flag_B0;lcd_init() ; /*液晶复位*/k0;AUXR0X80; //STC系列的1T 设置TMOD0X01;TH00X53;TL00X32;INT_CLKO|0x10; //(EX2 1)使能INT2中断INT_CLKO|0x20; //(EX3 1)使能INT3中断ET01;TR01;displayAdvertising(); /*开机广告*/OUT50;red_eeprom(); /*读EEPROM数据*/Dis_Xdata();Dis_Ydata();EA1;while(1) /*主函数循环*/{RstKey(); /*开始kcounter,kstatus*/if(!A_Up) //启动信号键{for(;kcounter5;) //按键循环5次{if(!A_Up) //按键低电平{LowVoltKey();}else if(~!A_Up) //按键高电平{HighVoltKey();}}if(kstatus4) /*按键状态标志大于等于3为有效值*/{ /*循环检测 */valavala1; /**加一**/if(vala999)vala0; /*大于999归零*/Dis_Xdata();write_eeprom();}}/************************************/RstKey(); /*开始kcounter,kstatus*/if(!A_Down) //启动信号键{for(;kcounter5;) //按键循环5次{if(!A_Down) //按键低电平{LowVoltKey();}else if(~!A_Down) //按键高电平{HighVoltKey();}}if(kstatus4) /*按键状态标志大于等于3为有效值*/{ /*循环检测 */valavala-1; /**减一**/if(vala0)vala999; /*等于零赋值999*/Dis_Xdata();write_eeprom();}}/************************************/RstKey(); /*开始kcounter,kstatus*/if(!B_Up) //启动信号键{for(;kcounter5;) //按键循环5次{if(!B_Up) //按键低电平{LowVoltKey();}else if(~!B_Up) //按键高电平{HighVoltKey();}}if(kstatus4) /*按键状态标志大于等于3为有效值*/{ /*循环检测 */valbvalb1; /**加一**/if(valb999)valb0; /*大于999归零*/Dis_Ydata();write_eeprom();}}/************************************/RstKey(); /*开始kcounter,kstatus*/if(!B_Down) //启动信号键{for(;kcounter5;) //按键循环5次{if(!B_Down) //按键低电平{LowVoltKey();}else if(~!B_Down) //按键高电平{HighVoltKey();}}if(kstatus4) /*按键状态标志大于等于3为有效值*/{ /*循环检测 */valbvalb-1; /**减一**/if(valb0)valb999; /*等于零赋值999*/Dis_Ydata();write_eeprom();}}/****************工位A检测********************/RstKey(); /*开始kcounter,kstatus*/if(!IntPut3) //启动信号键{for(;kcounter5;) //按键循环5次{if(!IntPut3) //按键低电平{LowVoltKey();}else if(~!IntPut3) //按键高电平{HighVoltKey();}}if(kstatus4) /*按键状态标志大于等于3为有效值*/{ /*循环检测 */Flag_A0; //关工位A运行标志val10; //关工位A定时器计数OUT11; //关闭A工位指示}}/****************工位B检测********************/RstKey(); /*开始kcounter,kstatus*/if(!IntPut4) //启动信号键{for(;kcounter5;) //按键循环5次{if(!IntPut4) //按键低电平{LowVoltKey();}else if(~!IntPut4) //按键高电平{HighVoltKey();}}if(kstatus4) /*按键状态标志大于等于3为有效值*/{ /*循环检测 */Flag_B0; //关工位B运行标志val20; //关工位B定时器计数OUT21; //关闭B工位指示}}Dis_XTime(val1); //工位A计时显示Dis_YTime(val2); //工位B计时显示if(val1vala){EA0;Bp0;OUT30;delay_1ms(100);Bp1;delay_1ms(100);Bp0;delay_1ms(100);Bp1;delay_1ms(100);Bp0;delay_1ms(100);Bp1;val10;Flag_A0;OUT31;EA1;}if(val2valb){EA0;Bp0;OUT30;delay_1ms(100);Bp1;delay_1ms(100);Bp0;delay_1ms(100);Bp1;delay_1ms(100);Bp0;delay_1ms(100);Bp1;val20;Flag_B0;OUT31;EA1;}} //} //L609 CODE2211