STC15F204EA单片机旋转编码器版白光T12控制器代码(开发固件)(by金向维)
基于STC15F200单片机的控温式手枪自给电烙铁
摘要:基于stc15f200单片机的控温式手枪自给电烙铁与传统的电烙铁在结构上进行了极大的改进,其采用了手枪式的结构,便于操作;自动进给焊丝的功能避免的操作的不当;基于单片机的控温系统保证了焊接的质量。
关键词:电烙铁;手枪式;控温;单片机0 引言众所周知,电烙铁在电子、金属焊接、机械制造等各行业中得到十分广泛的应用。
据了解,普通电烙铁在实际使用过程中存在以下不足:(1)普通电烙铁操作难度系数高,新手难于掌握。
电烙铁在进行焊接操作时需要操作者双手配合工作,但焊接时双手由于长期处于紧张状态而易疲劳,从而造成注意力不能集中。
同时由于左右手配合需要一定的熟练程度,在操作时其焊接的质量和精度很难保证。
(2)普通电烙铁的温度不能准确控制。
在使用过程中当焊接比较大的区域或者焊接比较大的连接件时就需要比较高的焊接温度,若温度低则无法进行焊接;但是当焊接集成电路的引脚时就需要比较低的温度,若温度太高则极易烧毁集成电路或电子元件。
(3)普通电烙铁采用的是直线型,未能结合人机工程的特点。
现有的普通电烙铁,外观轮廓一般是直线型的,没有过多考虑人手的生理结构和操作的手势,在焊接操作时加剧了受到疲劳感,不便使用。
基于上述原因和实践中的经验,现设计了一种新型的单片机控温的手枪式进给电烙铁。
1 手枪式电烙铁机械结构的初步改进本电烙铁的设计主要由烙铁部分、夹持部分和自动进给三部分组成,如图一所示。
烙铁部分由焊枪架体(18)、加热部分(2)、压线板(17)、十字槽盘头螺钉(10)组成,其构成同普通电烙铁;夹持部分由前置卡紧弹簧(4)、前置卡紧滑块(5)、后置卡紧弹簧固定塞(6)、后置卡紧弹簧(7)、反向进给滑块(8)、后置卡紧滑块(9)组成;自动进给部分由焊丝盘安装座(11)、复位弹簧(12)、焊丝盘(13)、封闭板(14)、扳机(15)、换向齿轮(16)组成。
其中,扳机安装在焊枪架体内部,换向齿轮与扳机相连,复位弹簧一端固定在焊枪架体内部,另一端与扳机相连,压线板安装在焊枪架体上,封闭板安装在扳机的上部,封闭板的右侧安装有反向进给滑块,反向进给滑块的内部安装有后置卡紧弹簧,后置卡紧弹簧左端与后置卡紧弹簧固定塞相连,右端与后置卡紧滑块相连,封闭板左侧安装有前置卡紧滑块,前置卡紧弹簧一端与前置卡紧滑块相连,另一端与前置卡紧弹簧固定塞相连,导向管安装在焊枪架体上,导向管的上端安装有加热部分,焊丝盘上加工有焊丝盘安装座,焊丝盘安装座通过十字槽盘头螺钉固定在焊枪架体上。
白光t12 原理图
12345678ABCD87654321DC B ATitle NumberRevisionSize A2Date:5-May-2012 Sheet of File:D:\电路开发\工程\T12控制器\New_Pcb\T12控制器.ddbDrawn By:P2.61P2.72ADC0/P1.03ADC1/P1.14ADC2/P1.25ADC3/P1.36ADC4/P1.47ADC5/P1.58ADC6/P1.69ADC7/P1.710IRC_CLKO/RST/P0.011Vcc 12P0.113Gnd 14P3.0/LOW INT415P3.116P3.2/INT017P3.3/INT118P3.4/T0/CLKOUT119P3.5/T1/CLKOUT020P3.6/LOW INT221P3.7/LOW INT322P2.0/RSTOUT_LOW 23P2.124P2.225P2.326P2.427P2.528STC15F200U1STC15F200-28PIN_A+5C2100nf+C110uf上电后输出低电平,在复位期间也是输出低电平.T12_CTRL 123J1UART更新与调试TTL 串口RxD TxDRxDTxD T12_ADC 618D1TL431R191KTL431_ADCTL431 2.49V 基准+5TL431_ADC NTC_ADC DPY_BDPY_A DPY_C DPY_D DPY_E DPY_F DPY_G DPY_DP DPY_DIG3DPY_DIG2DPY_DIG1ENCODER_A ENCODER_D ENCODER_BQ2s8050R244.7kR234.7kQ1MOSFET P 9435+24T12_CTRL12J4T12_OUTD2LED RedR264.7k 加热状态指示T12_AMPR201kT12驱动48231U2ALM358R410kR211k R274.7kC3100nf56748U2BLM358VCC_OPT12_AMPR2820kR221kR3010kT12_ADCD45.1V对于936 建议预留焊0805焊盘 断开后转接936热电偶12J2936_SWITCH_A 1322_AMP12J3936_SWITCH_BR2920kR254.7k拆自3R33模块, 5.2V 左右输入端对地, 输出电压实测39mv 国产LM358D31N4148T12热电偶信号放大 936部分暂时忽略T12 0-500 0.000-16.748mv℃单片机ADC 参考电压等于VCC 约5v代码中按照放大器269倍增益计算既在500度时4505.212mv 只要放大器满足此条件可以用别的也可以改变电路A 1C 2B 3D 4E5Encoderencoder1ROTARYENCODERR110k R210k +5C410nfC510nfR310kENCODER_AENCODER_B ENCODER_D 软件消抖,可以不使用.旋转编码开关控制a b f c g d e DIG1a b c d e f g abc d e fgdpdpdp a b f c g d e DIG2dp a bf cg d e DIG3dp D I G 1D I G 1D I G 2D I G 2D I G 3D I G 3DS1DPY_7-SEG_DP_3I/O 口直接驱动LED 数码管R6470R7470R8470R9470R10470R11470R12470R13470R14470R15470R164703位共阴数码管驱动DPY_A DPY_B DPY_CDPY_DDPY_EDPY_F DPY_G DPY_DPDPY_DIG1DPY_DIG2DPY_DIG3R18NTC-MF52AT 10K 5% B 3950 %1R1710k %1C610nf基于NTC 热敏电阻 NTC-MF52AT 10K 5% B 3950 %1+5NTC_ADC滤波可省略冷端参考ON/OFF 1VIN 2GND3GND4VOUT 5ADJ 6KIS-3R33S U3KIS-3R33SD51N4004+C733uf 30V+24DC 19.5-24V需要拆除稳压二极管R510k可选? 没示波器看不到纹波情况+C833uf-100uf 25vC90.1-10uf+55V 输出修改输出电压为5V VCC_OP给LM358供电DC-DC 转换STC15F204EA 白光T12控制器 V 1.00 By GOODCODE。
单片机程序编码器
if(B_in) value++;
else value--; //value为编码器的值
P3IF=P3IF|0x04; //改上升沿触发
}
}
/************************************************************************/
* MCU: AT89S52 晶振:11.0592MHz *
* *
* 版本:V1.1 (2009/04/29) *
* *
* 3位数码管显示 *
* *
扫描编码器子函数
在编码器引脚A为低电平期间:
编码器引脚B从0到1为正转,编码器引脚B从1到0为反转。
**********************************************************/
void scan_encoder(void)
{
static bit Curr_encoder_b; //定义一个变量来储存当前B信号
对于方波信号,A,B两相相差90度相(1/4T),这样,在0度相位角,90度,180度,270度相位角,这四个位置有上升沿和下降沿,这样,实际上在1/4T方波周期就可以有角度变化的判断,这样1/4的T周期就是最小测量步距,通过电路对于这些上升沿与下降沿的判断,可以4倍于PPR读取角度的变化,这就是方波的四倍频。这种判断,也可以用逻辑来做,0代表低,1代表高,A/B两相在一个周期内变化是0 0,0 1,1 1,1 0 。这种判断不仅可以4倍频,还可以判断旋转方向。
}
if(updata)
{
updata = 0 ;
单片机编码器编程实例 -回复
单片机编码器编程实例-回复“单片机编码器编程实例”编码器是一种常用的输入设备,广泛应用于各种电子设备中。
在单片机编程中,编码器常被用于控制和监测电机运动、旋转角度的测量以及用户界面交互等方面。
本文将以编码器编程为主题,一步一步介绍如何在单片机中实现编码器的功能。
第一步:了解编码器的基本原理和工作方式编码器是一种将旋转运动转化为电信号的设备。
常见的编码器有旋转编码器和线性编码器两种。
旋转编码器通常由一对光电传感器和一个带有刻度盘的旋转轴组成。
当旋转轴旋转时,光电传感器会感知到刻度盘的变化,并将其转化为电信号输出。
线性编码器则是通过传感器感知物体的移动,并将其转化为电信号输出。
第二步:了解编码器的输出类型和工作原理编码器的输出类型有两种,一种是增量式编码器,另一种是绝对式编码器。
增量式编码器通常输出两路信号,一路表示方向(A相信号),另一路表示旋转角度(B相信号)。
绝对式编码器则输出更多的信号,可以精确表示旋转位置或线性位移。
第三步:选择合适的编码器类型和接口在单片机编程中,通常会选择增量式编码器,因为其相对简单且较为常用。
选择适合的编码器接口是编程前必须考虑的因素之一。
常见的编码器接口有两种:脉冲计数接口和磁编码接口。
对于脉冲计数接口,编码器输出的脉冲信号通过单片机的IO口进行读取;对于磁编码接口,编码器输出的信号可以通过SPI、I2C等通信协议进行读取。
第四步:编写初始化函数在进行编码器编程之前,首先需要编写初始化函数,对编码器进行初始化设置。
初始化函数主要包括设置IO口的输入输出方向、使能编码器等操作。
第五步:编写中断服务函数编码器的工作是通过中断来实现的。
当编码器发生旋转或位移时,会产生相应的中断信号,通过中断服务函数来处理这些信号。
中断服务函数主要包括读取编码器的脉冲信号、计算旋转角度或位移,以及对应的控制逻辑。
第六步:编写主程序逻辑在编写主程序逻辑时,可以根据需要选择编码器的工作模式和功能。
利用STC15F104W单片机开发的夜航灯的控制器的源代码
{ a2_key=0; //开始记录高电平的标志的初始化
flag2_key=0; //识别高低电平的标志
if(over2_key==1)//如果高电平结束
c2_key=b2_key; //把高电平持续的时间保存下来
b2_key=0; //初始化b1的值,b1是负责计算高电平持续的时间的
}
}
void main()
{
TMOD=0x11; //定时器0和定时器1开启
ET0=1;
TR0=1;//开定时器0中断
TH0=(65536-20)/256;
TL0=(65536-20)%256;
EA=1; //开总中断
while(1)
{ get_data();//数据的获取
#include<reg52.h>//沿用51的头文件了,不涉及特殊的寄存器,都可以的
#define uint unsigned int
#define uchar unsigned char
sbit key=P3^4;
sbit led=P3^3;
sbit all_led=P3^2;
uint count=0,count1=0,count2=0;
{
all_led=1;//led灯亮
}
if( c2_key<61)
{
all_led=0; //led灯灭
}
if(c2_key>59&&c2_key<75)
{
count++;
if(count==50)
over2_key=0;//高电平计算结束的标志
STC15F204EA单片机旋转编码器版白光T12控制器代码
/*************STC15F204EA单片机旋转编码器版白光T12控制器代码(开发固件)(by金向维)******************* /#include <> //单片机头文件,24MHz时钟频率#include "" //头文件unsigned char code duanma[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x73}; //共阴数码管段码数据(0,1,2,3,4,5,6, 7,8,9),倒数第二个是显示负号-的数据,倒数第一个是显示字母P的数据unsigned int code wendubiao[62]={924,959,996,1033,1071,1110,1150,1190,1232,1273,1315,1358,1401,1443 ,1487,1501,1574,1619,1663,1706,1751,1756,1776,1810,1853,1903,1958,2017,2078,2 141,2204,2266,2327,2387,2444,2500,2554,2607,2657,2706,2738,2800,2844,2889,2 931,2974,3016,3056,3098,3139,3179,3218,3257,3296,3333,3372,3408,3446,3484,3 519, 3554,3590}; //根据NTC电阻随温度变化进而引起电压变化得出的数据,用来查表计算室温(进而对热电偶冷端补偿)sbit t12=P2^0; //T12通过控制sbit bw=P3^4; //数码管百位位选为sbit sw=P3^5; //数码管十位位选为sbit gw=P3^6; //数码管个位位选为sbit tihuan=P3^7; //数码管的a段本应该用控制,由于被用来控制T12,所以要用替代sbit encoderb=P1^4; //编码器的b脚接sbit encodera=P3^2; //编码器的a脚接sbit zhendongkaiguan=P0^1; //震动开关接sbit bianmaanniu=P3^3; //编码器的按键接sbit a7=P2^7; //数码管小数点sbit a6=P2^6; //数码管g段sbit a5=P2^5; //数码管f段sbit a4=P2^4; //数码管e段sbit a3=P2^3; //数码管d段sbit a2=P2^2; //数码管c段sbit a1=P2^1; //数码管d段bit e=1, f=1; //e f 用来保存编码器上一次的状态bit huancunkaiguan=0; //用于改变设定温度后延时显示设定温度(而不是立刻显示t12温度)signed int huancun; //显示函数直接显示huancun,要显示一个数据将必须这个数据赋值给缓存(由于数码管只有三位,为了在显示三位数同时保持四位数的精度,所以实际显示的是数据除以10,并支持显示负数)signed int shiwen; //10倍实际室温,即实际室温乘以10(为了精确)(允许的室温范围为-11度至50度)signed int t12wendu; //T12烙铁头的实际温度(非热电偶的温差)(同样为10倍温度)signed int shedingwendu; //设定温度(范围200~450度)signed int wencha; //T12两个周期间的温差signed int jiareshu; //每200ms加热周期内需要加热的次数(一次等于1ms,相当于加热占空比)unsigned char zhouqijishu; //加热周期200ms计数unsigned int huancunjishu; //用于改变设定温度后延时显示设定温度(而不是立刻显示t12温度)unsigned long cankaodianya0, t12dianya, ntcdianya, dianyuandianya;/********************************1ms延时函数*************************************************/void delay_ms (unsigned int a) //24MHz时钟时的1毫秒延时函数{unsigned int b;while(a--){for(b=0;b<1200;b++);}}/********************************10us延时函数************************************************/void delay_10us (unsigned int a) //24MHz时钟时的10微秒延时函数{unsigned int b;while(a--){for(b=0;b<12;b++);}}/********************************数码管延时关断函数******************************************/ void guanduan (void) //用于关断数码管的位选{delay_ms(1); //延时bw=1; //关断百位sw=1; //关断十位gw=1; //关断个位}/********************************公共函数10(显示)********************************************/ void gonggonghanshu10(unsigned char a){a7=a&0x80; //小数点a6=a&0x40; //ga5=a&0x20; //fa4=a&0x10; //ea3=a&0x08; //da2=a&0x04; //ca1=a&0x02; //btihuan=a&0x01; //a}/********************************显示函数****************************************************/ void display(signed int a) //显示函数(显示实际数据除以10,支持显示负数){unsigned char baiwei, shiwei, gewei, d; //定义百位,十位,个位,每次显示帧数signed int c; //用于处理数字aif(a<0) //如果a是负数c=-a; //取a的相反数else //否则c=a; //就直接取ac=c/10;baiwei=c/100; //计算百位c=c%100;shiwei=c/10; //计算十位c=c%10;gewei=c; //计算个位for(d=0;d<20;d++) //显示部分,每次显示20个循环(20帧){if(a<0) //如果a是负数,则百位显示负号gonggonghanshu10(duanma[10]);else //否则直接显示百位gonggonghanshu10(duanma[baiwei]); //显示百位bw=0; //打开百位guanduan(); //延时关断百位gonggonghanshu10(duanma[shiwei]); //显示十位sw=0; //打开十位guanduan(); //延时关断十位gonggonghanshu10(duanma[gewei]); //显示个位gw=0; //打开个位guanduan(); //延时关断个位}}/********************************ADC公共函数**************************************************/ void gonggonghanshu2(void) //此函数测量单片机电源电压{ADC_CONTR=0x88; //ADC_POWER, SPEED1, SPEED0, ADC_FLAG---ADC_START, CHS2, CHS1, CHS0 delay_10us(2); //延时等待转换结束ADC_RESL=ADC_RESL&0x03; //取转换结果低八位中的低二位cankaodianya0=(ADC_RES*4+ADC_RESL); //把结果转换成十进制数据(10位ADC,最大值1024)dianyuandianya=2549760/cankaodianya0; //计算电源电压,单位mV}/********************************ADC测电压函数************************************************/void adc (void) //ADC函数,用于测量和计算各种电压{signed char a; //查NTC表用gonggonghanshu2(); //公共函数2(此函数功能是测量电源电压,单位mV)ADC_CONTR=0x89; //ADC控制寄存器设置,转换采用最低速度速,低速更精确(测量t12电压务必使用最低速度AD转换,实测高速误差大) delay_10us(2);ADC_RESL=ADC_RESL&0x03;t12dianya=(ADC_RES*4+ADC_RESL);t12dianya=2490*t12dianya/cankaodianya0; //计算t12电压,单位mVADC_CONTR=0x8a; //ADC控制寄存器设置delay_10us(2);ADC_RESL=ADC_RESL&0x03;ntcdianya=(ADC_RES*4+ADC_RESL);ntcdianya=2490*ntcdianya/cankaodianya0; //计算ntc电压,单位mVfor(a=0;wendubiao[a]<ntcdianya;a++) //查表计算室温{if(a>=61) //如果超出表的范围就取允许的最高温度(50度) break; //并且退出查表}shiwen=(a-11)*10; //得出室温(实际室温乘以10)t12wendu=(t12dianya-100)*43*10/260+shiwen; //计算t12的实际温度,其中260为运放增益if(t12wendu<shiwen) //如果t12温度小于室温t12wendu=shiwen; //就取室温if(t12wendu>5000) //如果得出的温度超过500度,说明没有插入烙铁头或参数错误(因为烙铁头的温度不可能超过500度)t12wendu=5000; //显示500作为错误指示(注意显示函数显示的是1/10,所以要显示500,需要赋值5000)if(huancunkaiguan==1) //如果缓存开关开,说明刚刚改变了设定温度huancun=shedingwendu; //于是显示设定温度(而不是t12温度) elsehuancun=t12wendu; //否则直接显示t12温度}/********************************定时器0初始化函数*******************************************/ void timer0init (void) //定时器0初始化程序,24MHz频率下,每1ms中断一次{TMOD=0x00; //定时模式,16位自动重装TH0=0xf8; //计时1msTL0=0x2f;ET0=1; //开启定时器0中断TR0=1; //启动定时器0}/********************************公共函数6(记录编码器状态)**********************************/ void gonggonghanshu6(void){e=encodera; //记录编码器a脚此次状态f=encoderb; //记录编码器b脚此次状态}/********************************编码器函数(正常加热模式调用)********************************/ void bianmaqi(void){if(e==1&&f==1&&encodera==1&&encoderb==0) //和前一次状态比较确定为右旋{shedingwendu=shedingwendu+100; //步进if(shedingwendu>4500) //最高允许450度shedingwendu=4500;huancun=shedingwendu; //显示改变后的设定温度huancunkaiguan=1; //打开缓存开关(用于延时显示设定温度秒)huancunjishu=0; //重新开始缓存计数}if(e==1&&f==1&&encodera==0&&encoderb==1) //和前一次状态比较确定为左旋{shedingwendu=shedingwendu-100; //步进if(shedingwendu<2000) //最低允许200度shedingwendu=2000;huancun=shedingwendu; //显示改变后的设定温度huancunkaiguan=1; //打开缓存开关(用于延时显示设定温度秒)huancunjishu=0; //重新开始缓存计数}gonggonghanshu6(); //记录编码器状态}/********************************定时器0中断函数********************************************/void timer0(void) interrupt 1 //定时器0中断函数,检测编码器,掉电存储等操作(仅用于正常工作模式){unsigned char buchang;bianmaqi(); //调用编码器函数if(huancunkaiguan==1) //延时显示计数huancunjishu++;zhouqijishu++; //加热周期计数if(jiareshu>190) //最多加热190msjiareshu=190;if(zhouqijishu<=jiareshu) //如果当前计数小于等于加热数t12=1; //就加热else //否则t12=0; //不加热if(t12wendu==5000) //如果t12温度为500,说明没有插入烙铁头或参数严重错误t12=0; //停止加热if(huancunjishu==1500) //如果达到了设定温度延时显示的秒{huancunkaiguan=0; //关闭缓存开关huancunjishu=0; //停止缓存计数huancun=t12wendu; //由显示设定温度改为显示t12温度}if(zhouqijishu==200) //t12停止加热后2ms再检测温度(给电容留出放电时间,防止检测的温度偏高){adc(); //检测电压,计算温度zhouqijishu=0; //重新开始加热周期计数////////////////////以下为加热算法(请自行理解,不作注释)//// /////////////if(t12wendu>shedingwendu){if(t12wendu-shedingwendu<=20)jiareshu=(shedingwendu-1500)/160;elsejiareshu=0;}if(t12wendu<=shedingwendu){wencha=shedingwendu-t12wendu;if(wencha>20){buchang++;if(buchang>150)buchang=150;}elsebuchang=0;if(shedingwendu-t12wendu>=300)jiareshu=198;else if(shedingwendu-t12wendu>=200)jiareshu=160;else if(shedingwendu-t12wendu>=150)jiareshu=130;else if(shedingwendu-t12wendu>=100)jiareshu=90+wencha/2+buchang;else if(shedingwendu-t12wendu>=50)jiareshu=50+buchang*2;elsejiareshu=(shedingwendu-1000)/80+wencha*2/3+buchang;}}}/********************************主函数*****************************************************/ void main (void) //主函数{P1M0=0x00; //P1除,,为输入模式外均为正常模式P1M1=0x07;P1ASF=0x07; //设置P1相应ADC转换的I/O口为ADC输入模式P2M0=0xff; //P2都是推挽模式P2M1=0x00;P3M0=0xf0; //,,,为推挽模式,,为输入模式,P3M1=0x06; //其余正常模式ADC_CONTR=0xe0; //打开ADC电源shedingwendu=3000; //设为300度IE=0x88; //打开定时器0中断,关闭定时器1中断timer0init(); //初始化定时器0while(1){display(huancun); //数码管显示数据}}。
OTIS奥的斯元件代码表(完全版)
OTIS奥的斯元件代码表(完全版)OTIS 元件代码表AACS 自动防犯罪服务继电器AB 警铃ACB 自动断路器ACB-1 电流断路器(主变压器)ACB-2 电流断路器(门驱动电路)ACD 紧急制动器ACL 电抗器ACSC 防犯罪服务开关ADO 提前开门ALARB 警铃ALB 报警按钮ALC 报警信号电路ANS 防捣乱ANSS 10%负载开关APD 电磁干扰滤波器APKS 自动驻停—自动驻停开关继电器ARD 轿厢自动返层装置(返基站)ARD-1 轿厢自动返层装置(返基站)ARED 自动救援装置AREEA 应急电源ARO 自动返回基站ARR 紧急电源操作继电器ARS1.2 轿顶防护栏开关ASCB 速度检测板AT120 AT120门机ATK 司机开关ATT, ATT-2 司机服务功能ATTD 司机操作下行超动按钮ATTU 司机操作上行走动按钮B 制动器,抱闸B1 降压电阻B1,B2 抱闸电阻B2 泄能电阻,抱闸单元BDS-1 制动软降噪BFL 盲层BFS 油压缓冲器开关BID 断带、断绳检测装置BIT 寄存单元BK 变频器制动单元BLF 首层感应器BLTS 应急灯检测开关BOD 自救服务继电器BR 抱闸继电器BRM 制动单元BS1,BS2 抱闸开关BSM 地下室服务BUZ 蜂鸣器BV 压敏电阻BY 抱闸继电器C 检修控制按钮C1,2,3 电容C3R3 阻容滤波CAB 轿厢报警蜂鸣器CAP 电容CB0,CB1,CBN 轿厢楼层按钮CBM 机械式轿厢选层按钮CBT 双操纵盘CCBFS 主缓冲器CCBL 轿厢呼叫到底层CCM 轿厢到站钟CCT 自动外呼内选切除继电器CCTL 轿厢呼叫到顶层CDD(LRD)、CDD-LRD 轿厢门保护(光幕),轿门检测器,光幕-LRDCDD-IRC2D 光幕2DCDD-IRC3D 光幕3DCDDL 轿厢下方向灯CF 轿厢风扇CFL 轿厢照明灯CFL-1 可控的轿厢照明CFL-2 永久轿厢照明CFR 电梯故障继电器CFS 电梯故障信号CHCS 外呼取消开关CHF 电流滤波器CHT-4、 CHT4 独立的轿厢呼叫和大厅呼叫门时间CIS 机房检修开关CL 轿厢灯CL1,2 到站灯CMS,CMR 监控,远程监控CNT 紧急电源供电电梯正常使用继电器CODL 下行方向指示灯COP 内呼按钮,按钮灯,操纵盘CP1,2,3 小空气开关CPB(X) 空气开关CPI 轿厢位置指示器,轿厢显示CPI17, CPI-17 轿厢位置显示器(16段数码管)CPIC 轿内选切除开关CPIH 外呼切除开关CPI-K1 轿厢位置显示-K1CPI-K2 轿厢位置显示-K2CSAC 进入密码操作开关CT,CNT 计数器CTTL 轿厢呼叫登记灯CTTL1 大厅呼叫登记灯CUDL 上方向灯CUR 控制柜插件CWS-1 对重安全钳,对重限速器张紧接点D 下行按钮,下方向继电器DA 安全电源插座DBD 楼层误差反馈信号DBP 门旁路继电器DBR 泄能电阻DBS1,DBS2,DBS3,DBS4 紧急电动运行开关DCB 关门按钮DCB-1、 DCB1 关门按钮DCBL 关门按钮灯DCL 关门DCLR 关门到位继电器DCSS5 DCSS5门机DDB 紧急电动运行下行按钮DDOS 门操作无效开关DDP 位移检测盘,拖动保护延迟DDP 延迟驱动保护DFC 安全门锁继电器DHB、 DCH-1 门保持按钮DHBL 门保持灯DHBn 大厅下行呼叫按钮DHL 下行到站灯DIS 门区下行限位开关DISS 相接反转开关DOB,DOB-1、 DOB1 开门按钮DOBF 快速开门反应DOCB 门控制箱DOL 开门DOLR 开门到位继电器DOS 开门开关DS 厅门DS1,DSn 厅门触点DSBD 厅门门锁短接装置DTG-2 数字式旋转编码器(双通道)DTG-4、 DTG4 增量式编码器(双通道+校正脉冲)DTG-X 编码器DTL 下检修终端开关DTP 门时间保护DTTL2 下行记忆灯DXT-1 附加的门时间DZI 门区指示灯E 警铃电池EAR 紧急自动援救装置ECA,ECG 层站指示ECB 轿厢应急电源盒ECL 轿厢应急灯ECM1,ECM-N 井道照明灯ECR 紧急呼叫继电器ECU2 轿顶紧急照明装置ECZ 超载报警灯ED1,ED9 内指令应答灯EDM 轿厢照明灯EEC 轿顶紧急出口EEM 应急照明灯EES,EEC 安全窗EFO,EFO-1, EFO1 紧急消防员操作EFOB 转换开关装置EFS, EFS-1 紧急消防员服务(自动)EH1,EH9 上呼梯应答灯EHS 内选快速服务开关EHZ 司机开关指示EJX 检修开关指示EKM 底坑照明灯ELEVOA 消防合成单元ELTU 应急灯EM 轿内照明灯EMA 安全照明灯EMERG 轿厢因急停而处于减速EPA 自动紧急电源操作继电器EPOA 紧急电源操作EPOAUTO 自动紧急电源操作EPOMANUAL 手动紧急电源操作EPOS 紧急电源操作开关EPSS 紧急电源服务开关EQ0102,BC1 地震操作EQO 正在地震管制运行中EQRS 地震复位继电器EQS 地震操作开关ERO-1,ERO-2 紧急电动运行EROB(ERO,UDB.DDB) 转换开关ES 紧急停止开关ES-EX 方向指示ESS 急停开关ESS-1 急停ET1,ET2,ET(N) 下呼梯应答灯ETSC,SC,FSO 紧急端站超速,速度保护和开关门检测继电器EXDE 平层门区继电器EXDZ 首层,消除平层误差EZ1 底坑控制指示,轿顶急停指示EZ2 底坑控制指示,轿顶急停指示EZ3 厅门连锁指示EZ4 轿门连锁指示F1C,F2C,F6C,F8C 断路器,空气开关F8L 熔断器FAIL 结构5次救援操作FAN、 FAN1 风扇FAN-1 轿厢风扇(手动)FAN-2 轿厢风扇(自动)FHPI 大厅位置显示器FHUDL 闪烁上方向灯FLS-1 上/下端站极限开关7LS/8LSFLS-2 终端限位开关FR 热继电器FS 风扇开关FSK1,FSK2 断路器,空气开关FSL 应急操作灯(消防员)FSL 风扇开关FSO 前门安全继电器FULL 闪烁满载灯G5-PCB 变频器曲线卡GCS 对重限速器超速开关GDCB 运动控制板GS 轿门门锁GSS 底坑断绳开关GTC 限速器张紧动作触点HBM 机械式大厅呼叫按钮HCOP 残疾人操纵盘HDI-3 大厅方向显示器(按钮盒内)HL 汇流条HPI,PKS 调频率抑制电路,综合动力电路HPI17, HPI-17 大厅位置显示器HPI-K2、HPI-K1 位置显示器HSD 手动应急疏散装置HTTL 大厅呼叫登记灯ICB 检修盒ICU、 ICU1 通信单元(对讲机)IDIZ,ODZ,IDZ2 门区平层感应器INS 检修开关INT 对讲INV 变频器IPS 对讲电源ISC-1、 ISC1 独立服务ISD 司机下行ISS 独立服务功能ISU 司机上行J 相序继电器J2 相序保护继电器JX 轿内检修开关KBZ(1,2) 抱闸接触器KCMD 底坑井道照明开关KCMJ 机房井道照明开关KCZ 超载开关KDF 厅外电锁继电器KDY1,2,3 电源总控继电器KFX 封星接触器KGM 关门接触器KJC 快加接触器KJT 急停继电器KKC 快车接触器KKM 开门接触器KMB 门连锁继电器KMC 慢车接触器KMJ 轿门开关KMQ 门区继电器KS 上行接触器KSD 上端站接触器KTM 热敏电阻监视器KX 下行接触器KXD 下端站接触器KXF 消防继电器KXJ 下极限开关KXX 相序继电器KZD 制动接触器LAMBDA950 门保护装置LB 抱闸线圈LIH1,LIHn 井道照明LIHS-M 井道照明开关-机房LIHS-P 井道照明开关-底坑LNS 满载直驶LPT 到站通过钟LR 轿厢风扇/照明继电器LRD 光幕LRU 电子门LRU 光幕光电保护开关LRV 等待开关LS1 灯开关LT*C 轿厢侧线终端LT*H 大厅侧线终端LW-11 绳头称量装置LW110 110%超载开关LW30,LW50 30%,50%负载开关LW-6 轿底称量装置LW80 满载直驶开关LWB 称重板LWL 超载灯LWS 100%超载开关LW-S 轿底微动开关称量装置LZ 电磁闸LZK 抱闸继电器M1,M2,M3 主,风机,门电机MBDS 门机MCB 运行控制板MCB3x 运行控制板MES2 机房急停开关MIP 丢失IP,MIP3门状态MO 电动机MP,PG 光电码盘或者旋转编码器MRO 手动救援操作MTS 马达温度检测MZH 贯通门转换开关NDG 强迫关门NF 滤波器NF1,2,3 噪声滤波器NFBC,NFBL 空气开关SA33B,SA32B NFBM 空气断路器NSB 直驶按钮,不停按钮OCB 电流过载断路器ODZ 非门区开关OIB 光电磁门板OLD 超载装置OLS 超载灯OS,OS-1 限速器超速开关OSB 电路板OSU 上行超速保护开关OUB 电锁继电器OVF20CR OTIS VF变频器OVF40CR OTIS VF变频器PA 制动电流表PAP 整流组件板PCS1,PCS2 轿顶插座PDB-II 功率驱动板PE 到汇流排(接地)PES-1、 PES1 第一底坑急停开关PES-2、 PES2 第二底坑急停开关PG 旋转编码器PH 电话PKS,PKL 驻停开关,灯PKS-1、 PKS1 轿厢驻停开关、锁梯操作1 PL 底坑照明PLC1,2,3,4 PC主机扩展PLF 电源滤波器PLS1 底坑照明开关PS1,PS2 井道插座PSR1,2 稳压电源PUR 底坑插座PV 电压表PVT 编码器PWC P 波传感器(地震)Q1 总电源接触器Q2 照明电源开关RALB 副操纵盘警铃按钮RBFS 对重缓冲器RBU-2 上行断绳保护装置,断绳单元RC1-10 灭弧器RCB 环形通信板RCB0,RCBn 副操纵盘轿厢按钮RCP1,2,3 阻容板RCPI 副操纵盘位置显示器RDCB 副操纵盘关门按钮RDHB 副操纵盘门保持按钮RDHBL 副操纵盘门保持按钮灯RDOB 副操纵盘开门按钮REC 整流桥RELB 继电器板REMP 电梯远程监控系统(就绪)R-ENC 援救编码器RESCU 正在救援运行中RF 抱闸放电电阻RF,RF1,RF2,RF3 整流(整流桥堆)RGM 关门分流电阻RHS 手动盘车轮安全开关,可移动的盘车轮开关RIB 继电器接口板RICI 阻容滤波RKM 开门分流电阻RLEV1 再平层操作1RLV 正在找平层运行中RMK 门总电阻RS14,RS*CAR*1,RS*CAR*2 远程站RS4 选层控制板RS5 远程通信板RSS 安全触板RV 电压继电器RZD 制动电阻S(1-6) 空开SA4-1 尖峰吸收SAB 防夹人开关SAF 安全接触器SAFE 安全信号SC 速度检测继电器SCB 轿厢声响按钮SCS-1、 SCS-2、 SCS-3 松绳开关SCZ 超载开关SDA 安全照明开关SDM 轿顶照明开关SDS 轿顶慢上按钮SDT 轿顶急停开关SDX 轿顶慢下按钮SF1-N 层站开关,磁感应开关SFA 风扇开关SFC 上防冲顶开关SFS 机房慢上按钮SFX 机房慢下按钮SGD 光电开关SGJ 机房检修开关SGM 关门按钮SGS1,2 左右安全触板SHC 缓冲器复位开关SHL 大厅方向信号显示SI 隔音SJM 轿内照明开关SJT 机房急停开关SKK 底坑照明开关SKL-1 轿厢照明开关1SKM 开门按钮SKS 断绳开关SKT 底坑急停开关SL 最小层间距SLS1 检修极限开关SM1,SMN 厅门开关SMC 烟雾传感器SMG 关门限位开关SMJ 轿门开关SMK 开门限位开关SMQ 门区开关SMS 轿内慢上按钮SMX 轿内慢下按钮SMZ 满载开关SN(1-N) 内指令开关SNC 安全窗开关SNQ 安全权开关SOM 群控切换模块SOR1,SOR2 群控切换继电器SOS 安全钳超速开关SP,CPI 独立轿厢位置指示器SP,HPI 独立大厅位置指示器SQ501,SQ503 开关门分流开关SS(1-N) 上呼梯按钮SS1,2 紧急端站保护开关SSD1,2 上端站开关SSDM 超声波门监控器SSH 上换速开关SSJ 司机开关SSOM×LAMBOA 光电开关SSP 上平层开关SSS 上行限速器开关SSV 上限位开关STD 底层厅外门锁STT 轿内急停SW, SW1,SW2 主接触器SX2-N 下呼梯按钮SXD1,2 下端站开关SXF 消防开关SXH 下换速开关SXP 下平层开关SXS 下行限速器开关SXV 下限位开关SYJ 应急开关SZH1,2 轿顶检修开关SZS 直驶开关T 延时继电器,轿厢报警计时器T1,T2 插件TB1,TB2,TB3,TBn 接线端子TBL1,2 控制柜端子排TC 运行计数器TC1,2 控制,照明变压器TC3 变频曲线板变压器TC3 双速电抗器TCBC 牵引控制板TCI 轿顶检修开关TCIB 轿顶检修控制按钮TCIB1 轿顶检修公共按钮TCL 轿顶照明TCR 轿顶插件TDOS 轿顶门操作开关TES 轿顶急停开关TES1,2、 TES-2 轿顶急停开关THB 电机热敏电阻保护触点TIB 轿顶检修方向按钮TOCL 轿顶检修照明灯TOCLS 轿顶检修照明开关TOCS 轿顶电源插座TRF1,TRF2 变压器TRIC、 TRIC1 电梯运行计数器TRS 灯,风扇变压器TRV 继电器操作电路的交流100V电源脱漏TZD 制动电阻热开关U 上行继电器UCM 开门动车保护-韩国UD 运行继电器UDB 紧急电动运行上行按钮UDX 上下行辅助继电器UHBn 大厅上行呼梯按钮UHL 上行到站灯UIS 门区上行限位开关URS 底坑电源插座UTL 上检修端站开关VD1,2,3 二极管WR 门电机励磁绕组XA 安全电源插座XD 轿顶照明插座XDS1,XDSn 辅助厅门触点XFC 下防冲顶开关XGS 辅助轿门门锁XK 底坑照明插座ZQF 计数器12PS DC12V电源1BFS 缓冲器开关1LS 下行减速限位开关1LV 门区开关1PES 底坑急停开关25L,50L 25%,50%负载开关2BFS 缓冲器开关2COP 副轿厢操纵盘2CPI 副轿厢位置指示器2CTTL 副内选记忆灯2DCB 副关门按钮2DCBL 副关门按钮灯2DHB 副门保持按钮2DHBL 副门保持按钮灯2DOB 副开门按钮2DOBL 副开门按钮灯2LS 上行减速限位开关2LV 门区开关2PES 底坑急停开关2SCB 副声响轿厢按钮5LS,6LS 上下方向限速开关7LS 下终端极限开关8LS 上终端极限开关。
STCCAS单片机各个模块程序代码
//**************************************************************************** //// STC12C5A60S2可编程时钟模块////// 说明:STC12C5A60S2单片机有三路可编程时钟输出CLKOUT0/T0/P3.4// CLKOUT1/T1/P3.5、CLKOUT2/P1.0//// 涉及寄存器:AUXR(辅助寄存器)、WAKE_CLKO(时钟与系统掉电唤醒控制寄存器) // BRT(独立波特率发生器定时器寄存器)//// 程序说明:// 本程序可选实现P3.4输出CLKOUT0时钟、P3.5输出CLKOUT1时钟// P1.0输出CLKOUT2时钟//////************************************************************************** **//#include <STC12C5A60S2.H>#include <intrins.h>//#define Port_BRT //如果想测试独立波特率发生器时钟输出请打开此句//若想测试CLKOUT1和CLKOUT0请注释此句#ifdef Port_BRT /*条件编译独立波特率发生器时钟输出*///*********************************//// CLKOUT2时钟初始化 ////*********************************//void CLKOUT_init(void){WAKE_CLKO = 0x04; //Bit2-BRTCLKO 允许P1.0配置为独立波特率发生器的时钟输出//BRT工作在1T模式下时的输出频率 = Sysclk/(256-BRT)/2 //BRT工作在12T模式下时输出频率 = Sysclk/12/(256-BRT)/2 AUXR = 0x14; //Bit4-BRTR 允许独立波特率发生器运行//Bit2-BRTx12 BRT工作在1T模式下BRT = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频}#else /*条件编译CLKOUT0时钟输出*///*********************************//// CLKOUT0时钟和CLKOUT1初始化 ////*********************************//void CLKOUT_init(void){WAKE_CLKO = 0x03; //允许将P3.4/T0脚配置为定时器0的时钟输出CLKOUT0//T0工作在1T模式时的输出频率 = SYSclk/(256-TH0)/2//T0工作在12T模式时的输出频率 = SYSclk/12/(256-TH0)/2 //1T指的是每1个时钟加1,是普通C51的12倍//12T指的是每12个时钟加1与普通C51一样//允许将P3.5/T1脚配置为定时器1的时钟输出CLKOUT1,只能工作在定时器模式2下//T1工作在1T模式时的输出频率 = SYSclk/(256-TH0)/2//T1工作在12T模式时的输出频率 = SYSclk/12/(256-TH0)/2 //1T指的是每1个时钟加1,是普通C51的12倍//12T指的是每12个时钟加1与普通C51一样AUXR = 0xc0; //T0定时器速度是普通8051的12倍,即工作在1T模式下//T1定时器速度是普通8051的12倍,即工作在1T模式下TMOD = 0x22; //定时器0工作模式为方式2,自动装载时间常数//定时器1工作模式为方式2,自动装载时间常数TH0 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频TL0 = 0xff;TH1 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频TL1 = 0xff;TR1 = 1;TR0 = 1;}#endif//**********************************//// 主程序////**********************************//void main(){CLKOUT_init();while(1);}//**************************************************************************** //// STC12C5A60S2系统时钟模块////// 说明: STC12C5A60S2单片机有两个时钟源,内部R/C振荡时钟和外部晶体时钟// 出厂标准配置是使用外部晶体或时钟////// 涉及寄存器:CLK_DIV(时钟分频寄存器)// 由该寄存器的Bit0-2组合可实现对时钟源进行0、2、4、8、16 // 32、64、128分频// //// 程序说明:// 对外部时钟进行分频得到Sysclk,然后经过P1.0的独立波特率// 时钟输出功能Sysclk/2输出时钟频率//**************************************************************************** //#include <STC12C5A60S2.h>#include <intrins.h>#define Bus_clk 12 //若要修改系统时钟直接在此处修改//12 为 12M 的sysclk//6 为 6M 的sysclk//3 为 3M 的sysclk//1500 为 1.5M 的sysclk//750 为 750kHz 的sysclk//375 为 375kHz 的sysclk//187500 为 187.5kHz 的sysclk//93750 为 93.75kHz 的sysclk//*********************************************//// 系统时钟初始化 ////*********************************************//void Sysclk_init(void){WAKE_CLKO = 0x04; //配置P1.0口为频率输出AUXR = 0x14; //允许波特率时钟工作//工作模式为1TBRT = 0xff;#if( Bus_clk == 12 )CLK_DIV = 0x00;#elif( Bus_clk == 6 )CLK_DIV = 0x01;#elif( Bus_clk == 3 )CLK_DIV = 0x02;#elif( Bus_clk == 1500 )CLK_DIV = 0x03;#elif( Bus_clk == 750 )CLK_DIV = 0x04;#elif( Bus_clk == 375 )CLK_DIV = 0x05;#elif( Bus_clk == 187500 )CLK_DIV = 0x06;#elif( Bus_clk == 93750 )CLK_DIV = 0x07;#endif}//**********************************************//// 主程序////**********************************************//void main(){Sysclk_init();while(1);}//**************************************************************************** //// STC12C5A60S2系统省电模块////// 说明: STC12C5A60S2单片机有三种省电模式以降低功耗.空闲模式,低速模式// 掉电模式////// 涉及寄存器:PCON(电源控制寄存器)// Bit0 - IDL 控制单片机进入IDLE空闲模式// Bit1 - PD 控制单片机进入掉电模式// //// 程序说明:程序实现让单片机先工作一阵子(通过P0^3指示灯显示)// 然后进入掉电状态,利用外部中断0口来唤醒单片机工作// 唤醒后单片机将通过P0^0-3口的灯闪烁显示开始工作////************************************************************************** **//#include <STC12C5A60S2.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar Power_Down_Flag = 0; //进入掉电状态标志sbit Chip_Start_LED = P0^0; //单片机开始工作指示灯sbit Power_Down_LED_INT0 = P0^1; //INT0口掉电唤醒指示灯sbit N_Power_Down_LED_INT0 = P0^2; //INT0口没有唤醒指示灯sbit Normal_Work_LED = P0^3; //正常工作指示灯sbit Power_Down_Wakeup_INT0= P3^2; //外中断唤醒输入口void Delay_ms( uint time );void Normal_work(void);void Intp_init(void);void After_Powr_Down(void);//***********************************//// 软件延时 ////***********************************//void Delay_ms( uint time ){uint t; //延时时间 = (time*1003+16)us while(time--){for( t = 0; t < 82; t++ );}}//***********************************//// 正常工作指示//***********************************//void Normal_work(void){Normal_Work_LED = 1;Delay_ms(500);Normal_Work_LED = 0;Delay_ms(500);}void After_Power_Down(void){uchar i ;for( i = 0; i < 100; i++ ){P0 = 0x0f;Delay_ms(500);P0 = 0x00;Delay_ms(500);}}//***********************************//// 中断初始化 ////***********************************//void Intp_init(void){IT0 = 0; //外部中断源0为低电平触发EX0 = 1; //允许外部中断EA = 1; //开总中断}//***********************************//// 主程序 ////***********************************//void main(){uchar j = 0;uchar wakeup_counter = 0; //记录掉电次数P0 = 0x00;Chip_Start_LED = 1; //单片机开始工作Intp_init(); //外中断0初始化while(1){P2 = wakeup_counter;wakeup_counter++;for( j = 0; j < 250; j++ ){Normal_work(); //系统正常工作指示}Power_Down_Flag = 1; //系统开始进入掉电状态PCON = 0x02;_nop_();_nop_();_nop_();_nop_();After_Power_Down(); //掉电唤醒后}}//**********************************//// 中断服务//**********************************//void INT0_Service(void) interrupt 0{if( Power_Down_Flag ) //掉电唤醒状态指示 {Power_Down_Flag = 0;Power_Down_LED_INT0 = 1;while( Power_Down_Wakeup_INT0 == 0 ){_nop_(); //等待高电平}Power_Down_LED_INT0 = 0;}else //未掉电状态{N_Power_Down_LED_INT0 = 1; //不是掉电唤醒指示while( Power_Down_Wakeup_INT0 == 0 ){_nop_();}N_Power_Down_LED_INT0 = 0;}}//**************************************************************************** //// STC12C5A60S2 A/D转换模块////// 说明: STC12C5A60S2单片机有8路10位高速AD转换器,P1^0-P1^7//// 涉及寄存器:P1ASF(模拟功能控制寄存器)、ADC_CONTR(ADC控制寄存器)// ADC_RES、ADC_RESL(转换结果寄存器)//// 注意: 1、初次打开内部A/D模拟电源需适当延时等内部模拟电源稳定后,再启动A/D转换// 启动A/D后,在转换结束前不改变任何I/O口的状态,有利于高精度A/D 转换// 若能将定时器/串行/中断系统关闭更好。
实验三STC15系列单片机内部双通道10位AD转换程序
/*T8接T3和T2;或T8接T3,T7接T2;调电位器R36可改变内部10位AD转换0和1通道的电压Vin0或Vin1,采样周期5ms;送AD的电压用万用表在T8(对T6)测量;按照十六进制,0通道数字量由LCD显示(1行);1通道数字量由LCD显示(2行);0通道对应理论值在左边5个数码管显示(1个符号位,2个整数位,2个小数位);1通道对应理论值在右边5个数码管显示(1个符号位,2个整数位,2个小数位);研究2通道间是否需要适当延时*/#in clude <15f2k.h>#in clude <ab sacc.h>#d efine u8c uns igned char code//存放于代码中的无符号8位字符型缩写定义#de fineu8 unsi gnedchar//无符号8位字符型缩写定义#defin e u16 un signe d int //无符号16位整型缩写定义#def ine w ritec md XBYTE[0xEC FF]//1602写指令端口地址,E正脉冲有下降沿(A12=0),R/W=A9=0写,RS=A8=0写指令#defin e rea dstat e XB YTE[0xEEFF]//1602读状态端口地址,E正脉冲有高电平(A12=0),R/W=A9=1读,RS=A8=0读状态#de finewrite data XBYT E[0xE DFF]//1602写数据端口地址,E正脉冲有下降沿(A12=0),R/W=A9=0写,R S=A8=1读数据#defi ne Di splay seg X BYTE[0x7FF F]//数码管段码锁存器写端口地址(A15=0)#defi ne Di splay bit X BYTE[0xBFF F]//数码管位码锁存器写端口地址(A14=0)#defi ne LC D_CLR0x01 //清屏,清DD RAM内容为空,AC=00H#defi ne LC D_MOD E 0x38 //模式设置,001DLN F**,D L=1是8位数据接口,N=1两行显示,F=0是5*7点阵字符#def ine L CD_ON0x0c //显示开关控制,00001DCB,D=1开显示,C=0关光标,B=0关闪烁#de fineLCD_A_MODE 0x06//输入方式设置,000001I/DS,I/D=1数据读写后A C自动增1,S=0数据读写后画面不动b it new_cycl e_fla g=0; //有新采样数据标志,1有新数据sb it LSIG N=P1^6; //左边的符号位数码管公共端连接引脚,=0可能亮sbit RS IGN=P1^7; //右边的符号位数码管公共端连接引脚,=0可能亮u8r_kTH,m_kT H,r_k TL,m_kTL;//0通道和1通道AD转换结果u8 di spbuf[10],statu s,i; //10个数码管显示段码缓存区数组和AD转换状态及计算用中间变量int Vi n0x100,Vin1x100; //据AD值推算的0通道和1通道输入的100倍(显示用) u16A xx,j; //显示时用的中间变量float Vi n0,Vi n1; //据AD值推算的0通道和1通道输入-11.0V~+10.914Vu8 M=0; //扫描显示位计数变量定义u8cSG[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x 79,0x71};//0-F段码表u8c BT[10]={0xfe,0xfd,0xfb,0xf7,0xff,0xef,0xdf,0xbf,0x7f,0xff};//位码表u8c dis p1[16]={'0',' ','C','h','a','n','n','e','l',' ','A','D',' ',' ','H',''};u8c di sp2[16]={'1','','C','h','a','n','n','e','l',' ','A','D',' ',' ','H',' '};/***********LCD写指令************/voi d LCD write cmd(c har c md) //要传递指令{ w hile((read state&0x80)!=0); //查询LC D忙否?B F=1表示忙,循环,直到BF=0退出循环wr itecm d=cmd; //写指令,即把指令送[0xE3F F]端口}/***********L CD写数据************/v oid L CDwri tedat a(cha r dat) //要传递数据{ whil e((re adsta te&0x80)!=0); //查询LCD忙否?BF=1表示忙,循环,直到B F=0退出循环write data=dat;//写数据,即把数据送[0xE7FF]端口}/***********LCD初始化************/void LCD_init(void) //清屏/8位数据接口/1行/5*7点阵字符/关显示/AC自动增1{ L CDwri tecmd(LCD_MODE); //写模式设置指令 LCDw ritec md(LC D_ON); //写显示开关控制指令LCDwr itecm d(LCD_A_MO DE);//写输入方式设置指令L CDwri tecmd(LCD_CLR);//写清屏指令}/*******1602液晶屏幕初始化*******/voi d Dis play_init(void)//1602显示初始化{ LC Dwrit ecmd(0x80); //写指令,设置DDRA M指针AC=0x00fo r(i=0;i<16;i++) LCDw rited ata(d isp1[i]);//往第1行写数据:"0chan nel A D: H "LCDwr itecm d(0xc0); //写指令,设置DD RAM指针AC=0x40for(i=0;i<16;i++) LC Dwrit edata(disp2[i]);//往第2行写数据:"1ch annel AD: H "}/**********内部AD初始化**********/voi d AD_init(void)//内部AD初始化{ CLK_DIV&=0xDF; //MC KO_S1 MCKO_S0 A DRJ T X_RX- CLK S2CL KS1 C LKS0 //A DRJ=0,ADC_RES[7:0]存高8位ADC结果,AD C_RES L[1:0]存低2位ADC结果AD C_CON TR=0x80; //开A/D转换电源 for(j=0;j<10000;j++); //适当延时,一般延时1ms以内即可P1A SF=0x03; //开启P1.0和P1.1作为0通道和1通道模拟量输入通道A DC_CO NTR=0xC0;//ADC_POWER SPEE D1 SP EED0ADC_F LAG A DC_ST ART C HS2 C HS1 C HS0=1 10 0 0 000B//选择180个时钟周期转换1次,暂时不启动AD转换,选择0通道for(j=0;j<200;j++);//适当延时,20u s~200us即可}/***********T0T1初始化***********/v oid T0T1_i nit(v oid) //10数码管扫描1周AD转换1次,每管显1ms,AD周期10ms{ AUX R|=0x c0; //T0、T1定时器时钟1T模式,T0定时1m s,AD时间127.3us TMOD=0x20; //设置定时器模式,T0方式0定时,T1方式2定时T L0=0x66; //频率=11059200/(65536-0xea66)=1999.855Hz TH0=0xea; //定时周期=1/1999.855=0.000500036s=0.500036msEA=1;//允许中断E T0=1;//允许T0中断TR0=1; //定时器0开始计时}/*AD值倒推输入电压显示缓存区的更新*/voiddisp_g(voi d) //A D值倒推输入电压显示缓存区的更新{ i f(Vin0x100<0) //如果据0通道AD值推算的输入Vin0的100倍是负数{ Axx=-Vin0x100; //取绝对值 disp buf[9]=0x40; //符号位数码管对应送负号的段码}els e //据0通道AD值推算的输入Vin0的100倍是正数 { Ax x=Vin0x100; //取据AD值推算的输入Vi n0的100倍 dis pbuf[9]=0x00; //符号位数码管对应送正号的段码}i=(u8)(Axx/1000); //计算电压伏特十位 disp buf[8]=SG[i]; //电压十位数码管显示缓存更新段码 i=(u8)(Ax x/100%10); //计算电压伏特个位d ispbu f[7]=SG[i]|0x80; //电压个位数码管显示缓存更新段码(含小数点)i=(u8)(Axx/10%10); //计算电压小数后第1位dispb uf[6]=SG[i]; //电压小数后第1位数码管显示缓存更新段码i=(u8)(Axx%10);//计算电压小数后第2位d ispbu f[5]=SG[i]; //电压小数后第2位更新i f(Vin1x100<0) //如果据1通道AD值推算的输入Vin1的100倍是负数{ Axx=-Vin1x100; //取绝对值 disp buf[4]=0x40; //符号位数码管对应送负号的段码}els e //据1通道AD值推算的输入Vin1的100倍是正数 { Ax x=Vin1x100; //取据AD值推算的输入Vi n1的100倍 dis pbuf[4]=0x00; //符号位数码管对应送正号的段码}i=(u8)(Axx/1000); //计算电压伏特十位 disp buf[3]=SG[i]; //电压十位数码管显示缓存更新段码 i=(u8)(Ax x/100%10); //计算电压伏特个位d ispbu f[2]=SG[i]|0x80; //电压个位数码管显示缓存更新段码(含小数点)i=(u8)(Axx/10%10); //计算电压小数后第1位dispb uf[1]=SG[i]; //电压小数后第1位数码管显示缓存更新段码i=(u8)(Axx%10);//计算电压小数后第2位d ispbu f[0]=SG[i]; //电压小数后第2位更新}/*****AD结果显示缓存区的更新******/void disp_f(vo id) //A D结果显示缓存区的更新{ //0通道A D结果显示缓存区的更新L CDwri tecmd(0x8c); //写指令,设置DDR AM指针A C=0x4di=(r_k TH&0x f0)>>4; //取0通道8位AD数据的十六进制高位 if(i<10)LCDwr iteda ta(i+0x30);//更新AD数十六进制高位(数字)的A SCII码el se LC Dwrit edata(i+0x37); //更新AD数十六进制高位(大写字母)的AS CII码 i=r_kTH&0x0f; //取0通道8位AD数据的十六进制低位i f(i<10) LC Dwrit edata(i+0x30);//更新AD数十六进制高位(数字)的ASC II码 else LCDw rited ata(i+0x37); //更新AD数十六进制高位(大写字母)的ASCI I码LCDwr iteda ta('H'); //LCDwr iteda ta(r_kTL+0x30);//更新A D数十六进制高位(数字)的AS CII码 //1通道AD结果显示缓存区的更新LCD write cmd(0xcc); //写指令,设置DDRAM指针AC=0x4di=(m_kTH&0xf0)>>4; //取1通道8位AD数据的十六进制高位i f(i<10) LC Dwrit edata(i+0x30);//更新AD数十六进制高位(数字)的ASC II码 else LCDw rited ata(i+0x37); //更新AD数十六进制高位(大写字母)的ASCI I码i=m_k TH&0x0f; //取1通道8位AD数据的十六进制低位if(i<10) LCDw rited ata(i+0x30);//更新AD数十六进制高位(数字)的ASCII码e lse L CDwri tedat a(i+0x37);//更新AD数十六进制高位(大写字母)的A SCII码 LC Dwrit edata('H'); //LC Dwrit edata(m_kT L+0x30); //更新AD数十六进制高位(数字)的ASCI I码}/*************主程序*************/voi d ma in(vo id) //{ L CD_in it();//1602液晶显示模块初始化Dis play_init(); //1602液晶屏显示内容初始化 AD_i nit(); //内部AD初始化T0T1_in it(); //T0、T1初始化程序(11.0592MH z)do{ if(new_c ycle_flag==1) //有新采样数据标志,Vs1=-(R6/R5)*V in0=-0.2Vi n0 { //Vs2=-(R10/R8)*Vs1-(R10/R9)*(-5)=2.5+0.2Vin0 //当Vin0=-10V时,Vs2=0.5V;当Vin0=10V时,Vs2=4.5V //N=((2.5+0.2Vin0)/5)*256;V in0=0.09765625*N-12.5//Vs3=-(R17/R18)*Vin1=-0.2Vin1 //V s4=-(R13/R15)*V s3-(R13/R14)*(-5)=2.5+0.2Vin1 Vin0*=(fl oat)r_kTH; //A D转换需要127.3us,抽空做点计算 Vin0-=12.5; // Vin0x100=(int)(Vin0*100); //A D值倒推输入电压的100倍;小数点定点在第7位Vin1*=(flo at)m_kTH; //当V in1=-10V时,Vs4=0.5V;当Vin1=10V时,Vs4=4.5V Vin1-=12.5; //N=((2.5+0.2V in1)/5)*256;Vin1=0.09765625*N-12.5 Vin1x100=(int)(Vin1*100); //A D值倒推输入电压的100倍;小数点定点在第2位disp_g(); //0通道和1通道AD值倒推的输入电压显示缓存区的更新disp_f(); //0通道和1通道AD结果显示缓存区的更新n ew_cy cle_f lag=0; //新采样数据标志清0 }}whil e(1);}/*********T0中断服务程序*********/voi d t0() int errup t 1 u sing1 //0.5m s中断,自动重装,每次均要进行显示处理{ if(M==10) //5ms到了吗?因为0.5ms*10=5ms{ADC_C ONTR|=0x08; //到了5ms,启动0输入通道AD转换 new_cycl e_fla g=1;//置有新采样数据标志 M=0;//M清0s tatus=0; //状态变量先清0 whil e(sta tus==0) st atus=ADC_C ONTR& 0x10;//转换结束否?ADC_C ONTR=0xC1; //ADC_P OWERSPEED1 SPE ED0 A DC_FL AGAD C_STA RT CH S2 CH S1 CH S0=110 00 001B//选择180个时钟周期转换1次,将ADC_FLAG清0,暂时不启动AD转换,选择1通道 r_kTH=A DC_RE S; //读取0通道AD结果的高8位 r_kT L=ADC_RESL&0x03; //读取0通道AD结果的低2位,不用 Vin0=0.09765625; //AD转换需要127.3us,抽空预置常数 ADC_CONT R|=0x08; //启动1输入通道A D转换 Vi n1=0.09765625; // st atus=0; //状态变量先清0while(stat us==0) sta tus=A DC_CO NTR & 0x10;//转换结束否?A DC_CO NTR=0xC0; //A DC_PO WER S PEED1 SPEE D0 AD C_FLA GADC_STAR T CHS2 CHS1 CHS0=1 10 0 0 000B //选择180个时钟周期转换1次,将ADC_FLAG清0,暂时不启动AD转换,选择0通道 m_k TH=AD C_RES; //读取1通道AD结果的高8位m_kTL=ADC_RESL&0x03; //读取1通道AD结果的低2位,不用}RS IGN=1; //关闭右边符号位显示LSI GN=1; //关闭左边符号位显示 Disp laybi t=0xf f; //关闭8个数码管的显示 Disp layse g=dis pbuf[M]; //查显示缓存表送数显的段端口D ispla ybit=BT[M]; //查位码表送数显的位端口if(M==4) R SIGN=0; //扫描到右边符号位则该位显示 if(M==9) LSI GN=0; //扫描到左边符号位则该位显示 M++; //修改下一次的显示位}。
STC12F程序
// ShowResult(2); //显示通道2
// ShowResult(3); //显示通道3
// ShowResult(4); //显示通道4
// ShowResult(7); //显示通道7
// XBYTE[0xFF81]=0x00;
// XBYTE[0xFF80]=0x10;
// P2=0xff;
/*
#pragma asm
a = 0xf9 ;
BUS_SPEED= BUS_SPEE & a;
void ShowResult(BYTE ch);
void main()
{ int h;
int l;
// InitUart(); //初始化串口
// InitADC(); //初始化ADC
/* --- Web: --------------------------------------------*/
/* --- Web: --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
SBUF = dat; //发送当前数据
//xi=PBYTE[0x001f]; //读取外部RAM16位地址 0x001f地址的数据
while (1)
{ h++;
if(h>=255)h=0;
l=0xff00+h;
// ShowResult(0); //显示通道0
/* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序 */
山寨t12焊台温控器,单片机数码管显示按键调温
山寨t12焊台温控器,单片机数码管显示按键调温偶然弄了两根T12的烙铁芯。
学习了它的相关知识自己瞎捣鼓了一下,利用一个杂牌936焊台的主机壳子用3d打印机打了一个面板。
这个山寨版的控制器大致功能如下:1.按键调节温度高低并用数码管显示出来,按键短按依次加减,按键长按快速加减。
2.本次开机后默认上次关机前的调节温度。
(正在弄还没有实现)3.带有休眠功能,烙铁放在烙铁架上一段时间后自动降温到一设定值,达到休眠目的。
从烙铁架上拿起来后恢复到原来设定的温度。
4.慢慢再补充。
先从电路做起描述:STC15F204 T12温控焊台电路图图片:电路.gif制作过程图片:01(3).jpg图片:02(2).jpg图片:03(3).jpg电路基本搞定,再来面板。
CAD初学,简单弄的面板图片:面板02.png图片:面板01.png简易3D打印机图片:11(6).jpg图片:12(5).jpg按键,用红色材料图片:按键01.png图片:14(4).jpg图片:15(4).jpg打好,去掉毛边和支撑物图片:16(5).jpg图片:17(3).jpg还挺匹配的图片:18(2).jpg临时装上去,看看效果图片:20.jpg数码管看着不犀利有办法,找了一条深颜色的汽车贴膜贴上去图片:13.jpg果然帅多了图片:11.jpg装好图片:10.jpg开烧。
图片:02.jpg电路稍微做了调整,LM358放大倍数调整为200多倍。
描述:STC15F204 T12温控焊台电路图图片:1.jpg STC15F204_T12_C.rar (45 K)下载次数:2C程序如下。
头文件、源程序、电路图上面附件中也有,初学阶段仅供参考。
待机状态温度显示基本稳定上下浮动1、2度,使用状态遇到大焊点会偏差几度,这个以后慢慢学习改进。
#include"STC15F204EA.h"#include <intrins.h>#define uchar unsignedchar#define uint unsigned intsbit baiwei=P3^7;sbitshiwei=P3^6;sbit gewei=P3^5;sbit danwei=P3^4;sbit dian=P2^3;sbitout=P3^3;sbit up=P3^2;sbit down=P3^1;sbit xiumian=P1^0;ucharcodeled[]={0xd7,0x42,0xe5,0xe6,0x72,0xb6,0xb7,0xc2,0xf7,0xf6}; //定义数码管0-9数组uintADC_result6,shan_sz,shan_dw,wendu,sheding,aa,tt01,tt_xm1,tt _xm2,tt_aj,js_xm;ucharsheding_bz,jiare_bz,bz1,bz2,qieh_w,tt00,jiareshu,bz_xs,tt1,ab1, ab2,fen,miao;//定义变量void delay(uintz) //延时{uintx,y;for(x=z;x>0;x--)for(y=100;y>0;y--);}/*********AD转换,得出热电偶被放大后的电压值**********/uintget_ad_result(uchar channel){ucharad_finished=0; //存储A/D转换标志ADC_RES=0;//高8位清零ADC_RESL=0;//低2位清零channel&=0x07;//00000111清零高5位ADC_CONTR=0x60;//转换速率为70个时钟周期转换1次_nop_();ADC_CONTR|=channel;//选择A/D当前通道_nop_();ADC_CONTR|=0x80;//启动A/D电源delay(1);//延时一下使输入电压达到稳定ADC_CONTR|=0x08;//0000,1000令ADCS = 1,启动A/D转换,ad_finished=0;while(ad_finished==0) //等待A/D转换结束{ad_finished=(ADC_CONTR&0x10);//0001,0000测试A/D转换结束否}ADC_CONTR&=0xE7;//1111,0111清ADC_FLAG 位,关闭A/D转换,return(ADC_RES*256+ADC_RESL);//返回A/D高8位+低2位转换结果}/*********初始化*********/voidinit(){TMOD=0x11;//设定定时器工作方式EA=1;//开总中断ET0=1;//开定时器0TR0=1;//启动定时器0TH0=(65536-1000)/256; //高8位装初值1msTL0=(65536-1000)%256;//低8位装初值ET1=1;//开定时器1TR1=1;//启动定时器1TH1=(65536-2000)/256; //高8位装初值2msTL1=(65536-2000)%256;//低8位装初值}/********EEPROM读写程序*******/voidOPEN_IAP()//开启ISP/IAP{EA=0;//关闭总中断避免中断影响IAP_CONTR=0x82;//允许ISP/IAP,系统时钟<20Mhz时,设置等待时间}voidCLOSE_IAP()//关闭ISP/IAP{IAP_CONTR=0x00;//禁止ISP/IAPIAP_ADDRH=0xFF;IAP_ADDRL=0xFF;EA=1;}uintREAD_IAP_BYTE(ucharaddr) //从EEPROM指定单元中读数据{IAP_CMD=0x01;IAP_ADDRH=(addr&0xFF00)>>8;IAP_ADDRL=addr&0x00FF;IAP_TRIG=0x5A;IAP_TRIG=0xA5;//对IAP_TRIG先写0x5A再写0xA5,命令才会生效returnIAP_DATA;}void ERASE_IAP_SECTOR(intaddr) //写数据前要先擦除扇区{IAP_CMD=0x03;IAP_ADDRH=(addr&0xFF00)>>8;IAP_ADDRL=addr&0x00FF;IAP_TRIG=0x5A;IAP_TRIG=0xA5;//对IAP_TRIG先写0x5A再写0xA5,命令才会生效}voidWRITE_IAP_BYTE(int addr,ucharwriteval) //把一个字节写入指定单元{IAP_CMD=0x02;IAP_ADDRH=(addr&0xFF00)>>8;IAP_ADDRL=addr&0x00FF;IAP_DATA=writeval;IAP_TRIG=0x5A;IAP_TRIG=0xA5;//对IAP_TRIG先写0x5A再写0xA5,命令才会生效}/*********主程序********/voidmain(){init(); P1ASF=0x40;//01000000 将P1.6置为模拟口AUXR1|=0x04; //0000 0100令ADRJ=1,10位A/D转换结果的最高2位放在ADC_RES 寄存器,低8位放在ADC_RESLADC_CONTR|=0x80; //打开A/D 转换电源启动A/D转换P3M0=0xf8;//11111000设定P3.3/4/5/6/7口为强推挽输出模式P2M0=0xff;//11111111 设定P2口为强推挽输出模式jiare_bz=1;out=0;sheding_bz=0; delay(500);//初始化后适当延时后再读写EEPROM,保证有效性OPEN_IAP();ab1=READ_IAP_BYTE(0x0001);//读出保存的百位ab2=READ_IAP_BYTE(0x0002);//读出保存的十位、个位CLOSE_IAP(); sheding=ab1*100+ab2;//算出上次的设定值,高两位*100+低两位if(sheding<2000)sheding=2000;//如果设定值过低默认成2000 while(1){if(sheding_bz)//写入EEPROM,每次更改设定值后写入一次{out=0;OPEN_IAP();//开启ERASE_IAP_SECTOR(0x0001); //擦除扇区WRITE_IAP_BYTE(0x0001,sheding/100);//设定值的百位写入0001地址WRITE_IAP_BYTE(0x0002,sheding%100);//设定值的十位、个位写入0002地址CLOSE_IAP();//关闭sheding_bz=0;//标志置0,使得写EEPROM操作运行一次即可jiare_bz=1;}}}voidtimer0() interrupt1 //定时器0中断程序1ms {TH0=0xfc;//(65536-1000)/256TL0=0x18;//(65536-1000)%256/**************按键检测、测温、加热程序***************/if((up&down)==0){bz_xs=1;//显示切换标志置1tt01=0;//计时变量tt01置0bz2=1;//标志2置1jiare_bz=0;//加热标志置0miao=0;fen=0;//按键按下清除休眠计时shan_dw=0;shan_sz=0;if(tt_aj<1000)tt_aj++;if(tt_aj>500) //超过500ms说明是长按,1ms一次快速加减{if(up==0){if(sheding<4500)sheding++;}if(down==0){if(sheding>200)sheding--;}}else{if(bz1==0)//根据标志位情况短按自加减一次{if(up==0){if(sheding<4500)sheding+=10;}if(down==0){if(sheding>200)sheding-=10;}bz1=1;}}}else//按键抬起,测温、加热步骤{tt_aj=0;bz1=0; if(tt01<2000)tt01++;if(tt01>1500)//按键弹起1.5秒后显示标志置0显示实际温度{if(bz2)//标志2为1,设定标志置1,让新数值写入EEPROM{sheding_bz=1;bz2=0;//同时标志2置0,目的是让只写入一次即可}bz_xs=0;} if(jiare_bz)//加热标志为1时才启动加热动作{tt00++;if(jiareshu>tt00)out=1;elseout=0;if(wendu>4500)//超温停止加热out=0;if(tt00>=200)//加热200ms之后断电测温{if(tt00<205)//5ms时间断电检测{out=0;if(tt00>203)//断电延时后采集热电偶温度数据ADC_result6=get_ad_result(6); //A/D转换6通道// wendu=ADC_result6*4.8;wendu=ADC_result6*8.0; //热电偶电压经过运放放大200多倍后采样显示,模拟大概温度if(fen<2)//休眠计时不到设定值时加热温度为设定温度aa=sheding+5;elseif(fen<5)//2-5分钟内温度降低为250度{if(sheding>2500)aa=2500;}elseif(fen<10)//5-10分钟内降低为200度{if(sheding>2000)aa=2000;}elseif(fen<20) //10-20分钟内为150度{if(sheding>1500)aa=1500;}else//超过20分钟为0aa=0; if(wendu>aa) //烙铁温度高于设定温度{if(wendu-aa<=30)jiareshu=wendu-aa;elsejiareshu=0;}else//温度低于设定温度{ if(a a-wendu>400) //逐渐逼近式加热方式jiareshu=200;else if(aa-wendu>300)jiareshu=180;else if(aa-wendu>200)jiareshu=150;else if(aa-wendu>100)jiareshu=130;elsejiareshu=aa-wendu+aa/100;}}else//加热、断电测量温度后充值计数变量tt00tt00=0;}}elseout=0;}}voidtimer1() interrupt 3//定时器1服务程序2ms{TH1=0xf8;//(65536-2000)/256TL1=0x30;//(65536-2000)%256/***********显示程序************/if(bz_xs)//按键按下显示正在调整的数值wendu=sheding;//显示设定时的数值if(qieh_w>=3)//位切换标识变量,2ms轮流显示一位休眠时数字闪亮qieh_w=0;elseqieh_w++; switch(qieh_w){case0:baiwei=0;// P2=led[wendu%10];P2=0x9d;//10011101 显示单位℃度if(shan_dw<250)//烙铁离开烙铁架时℃闪亮danwei=1;//显示单位elsedanwei=0;break;case1://4位数实际显示3位,最右一位不显示。
通过编码开关(旋转编码器)控制数码管的加减一我爱单片机
通过编码开关(旋转编码器)控制数码管的加减一我爱单片机赞助商链接//直上调试好的程序看看能否换个M币哈哈!//通过编码开关(旋转编码器)控制数码管的加减一#include<AT89X52.H>#define uchar unsigned char#define uint unsigned int#define cycle 1 //定义动作周期,编码器旋转多少格有效#define NULL 0 //定义编码器不动作时的还回值#define E_RIGHT 0x0e //定义右旋转还回值#define E_LEFT 0x0f //定义左旋转还回值/*=====数码管位及按键定义=====*/sbit dula=P2^6; //数码管段选,锁存器控制信号sbit wela=P2^7; //数码管位选,锁存器控制信号sbit PINA = P1^0; //定义IOsbit PINB = P1^1;uchar WheelNow,WheelOld,RightCount,LeftCount;/*=====0-9=====A-G=====*/uchar a[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//数码管显示编码unsignedsled_bit_table[]={0x5f,0x6f,0x77,0x7b,0x7d,0x7e,0xff};/*定义点亮的数码管与数组的关系*//*=====四个数码管显示数据存放处=====*/uchar one,two,three,four;uint wc=0;/*=====函数定义=====*/ void delay(uint x);void display(void);//void key();void led_analyze(uint i);/*====延时函数=====*/ void delay(uint x){uint i;for(i=0;i<x;i++);}/*====显示函数=====*/ void display(void){//送段码dula=0;P0 =a[one];dula=1;dula=0;//数码管位选wela=0;P0=sled_bit_table[0]; //开显示wela=1;wela=0;delay(200); //调用键盘扫描wela=0;P0=sled_bit_table[6];wela=1;wela=0; //关显示dula=0;P0=a[two];dula=1;dula=0;//数码管位选wela=0;P0=sled_bit_table[1]; //开显示wela=1;wela=0;delay(200); //调用键盘扫描wela=0;P0=sled_bit_table[6];wela=1;wela=0; //关显示dula=0;P0=a[three];dula=1;dula=0;//数码管位选wela=0;P0=sled_bit_table[2]; //开显示wela=1;wela=0;delay(200); //调用键盘扫描wela=0;P0=sled_bit_table[6];wela=1;wela=0; //关显示dula=0;P0=a[four];dula=1;dula=0;//数码管位选wela=0;P0=sled_bit_table[3]; //开显示wela=1;wela=0;delay(200); //调用键盘扫描wela=0;P0=sled_bit_table[6];wela=1;wela=0; //关显示}/*====分解显示数据=====*/void led_analyze(uint i){i=i%10000;four=i/1000; // 千位three=(i/100)%10; // 百位two=(i%100)/10; // 十位one=(i%100)%10; // 个位}//===================================== ============uchar WheelRight(){LeftCount=0;RightCount++;if (RightCount>=cycle){RightCount=0;return(E_RIGHT);}elsereturn(NULL);}//===================================== ================uchar WheelLeft(){RightCount=0;LeftCount++;if (LeftCount>=cycle){LeftCount=0;return(E_LEFT);}elsereturn(NULL);}//===================================== ============================uchar EncoderProcess(){uchar keytmp;PINA = 1;PINB = 1;WheelNow=WheelNow<<1;if (PINA==1) WheelNow=WheelNow+1; // 读 PINAWheelNow=WheelNow<<1;if (PINB==1) WheelNow=WheelNow+1; // 读 PINBWheelNow=WheelNow & 0x03; // 将 WheelNow 的 2 - 7 位清零,保留 0 - 1 两个位的状态.if (WheelNow==0x00) return(NULL); //当 PINA 和 PINB 都为低电平时退出,低电平区不做处理keytmp=WheelNow;keytmp ^=WheelOld; // 判断新读的数据同旧数据if (keytmp==0) return(NULL); // 新读的数据同旧数据一样时退出.if (WheelOld==0x01 && WheelNow==0x02){ // 是左旋转否WheelOld=WheelNow;return(WheelLeft()); //左旋转}elseif (WheelOld==0x02 && WheelNow==0x01){ // 是右旋转否WheelOld=WheelNow;return(WheelRight()); //右旋转}WheelOld=WheelNow; // 保存当前值return(NULL); // 当 PINA 和 PINB 都为高电平时表示编码器没有动作,退出}//===================================== ===================================== void inc(){wc++;if(wc>9999) wc=0;//如果WG大于9999则将它清零led_analyze(wc);} // 在此处设置断点看 num 加的变化//===================================== ===============================void dec(){wc--;if(wc>9999) wc=9999;led_analyze(wc);} // 在此处设置断点看 num 减的变化//===================================== ====================================== void main(){while (1){switch(EncoderProcess()){case E_RIGHT: inc(); break;case E_LEFT: dec(); break;}display();}}。
STC12C5A60S2单片机各个模块程序代码
//****************************************************************************// // STC12C5A60S2可编程时钟模块////// 说明:STC12C5A60S2单片机有三路可编程时钟输出CLKOUT0/T0/P3.4// CLKOUT1/T1/P3.5、CLKOUT2/P1.0//// 涉及寄存器:AUXR(辅助寄存器)、W AKE_CLKO(时钟与系统掉电唤醒控制寄存器)// BRT(独立波特率发生器定时器寄存器)//// 程序说明:// 本程序可选实现P3.4输出CLKOUT0时钟、P3.5输出CLKOUT1时钟// P1.0输出CLKOUT2时钟//////****************************************************************************/ /#include <STC12C5A60S2.H>#include <intrins.h>//#define Port_BRT //如果想测试独立波特率发生器时钟输出请打开此句//若想测试CLKOUT1和CLKOUT0请注释此句#ifdef Port_BRT /*条件编译独立波特率发生器时钟输出*///*********************************//// CLKOUT2时钟初始化////*********************************//void CLKOUT_init(void){WAKE_CLKO = 0x04; //Bit2-BRTCLKO 允许P1.0配置为独立波特率发生器的时钟输出//BRT工作在1T模式下时的输出频率= Sysclk/(256-BRT)/2//BRT工作在12T模式下时输出频率= Sysclk/12/(256-BRT)/2 AUXR = 0x14; //Bit4-BRTR 允许独立波特率发生器运行//Bit2-BRTx12 BRT工作在1T模式下BRT = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频}#else /*条件编译CLKOUT0时钟输出*///*********************************//// CLKOUT0时钟和CLKOUT1初始化////*********************************//void CLKOUT_init(void){WAKE_CLKO = 0x03; //允许将P3.4/T0脚配置为定时器0的时钟输出CLKOUT0//T0工作在1T模式时的输出频率= SYSclk/(256-TH0)/2//T0工作在12T模式时的输出频率= SYSclk/12/(256-TH0)/2//1T指的是每1个时钟加1,是普通C51的12倍//12T指的是每12个时钟加1与普通C51一样//允许将P3.5/T1脚配置为定时器1的时钟输出CLKOUT1,只能工作在定时器模式2下//T1工作在1T模式时的输出频率= SYSclk/(256-TH0)/2//T1工作在12T模式时的输出频率= SYSclk/12/(256-TH0)/2//1T指的是每1个时钟加1,是普通C51的12倍//12T指的是每12个时钟加1与普通C51一样AUXR = 0xc0; //T0定时器速度是普通8051的12倍,即工作在1T模式下//T1定时器速度是普通8051的12倍,即工作在1T模式下TMOD = 0x22; //定时器0工作模式为方式2,自动装载时间常数//定时器1工作模式为方式2,自动装载时间常数TH0 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频TL0 = 0xff;TH1 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频TL1 = 0xff;TR1 = 1;TR0 = 1;}#endif//**********************************//// 主程序////**********************************//void main(){CLKOUT_init();while(1);}//****************************************************************************// // STC12C5A60S2系统时钟模块////// 说明:STC12C5A60S2单片机有两个时钟源,内部R/C振荡时钟和外部晶体时钟// 出厂标准配置是使用外部晶体或时钟////// 涉及寄存器:CLK_DIV(时钟分频寄存器)// 由该寄存器的Bit0-2组合可实现对时钟源进行0、2、4、8、16// 32、64、128分频// //// 程序说明:// 对外部时钟进行分频得到Sysclk,然后经过P1.0的独立波特率// 时钟输出功能Sysclk/2输出时钟频率//****************************************************************************// #include <STC12C5A60S2.h>#include <intrins.h>#define Bus_clk 12 //若要修改系统时钟直接在此处修改//12 为12M 的sysclk//6 为6M 的sysclk//3 为3M 的sysclk//1500 为 1.5M 的sysclk//750 为750kHz 的sysclk//375 为375kHz 的sysclk//187500 为187.5kHz 的sysclk//93750 为93.75kHz 的sysclk//*********************************************//// 系统时钟初始化////*********************************************//void Sysclk_init(void){WAKE_CLKO = 0x04; //配置P1.0口为频率输出AUXR = 0x14; //允许波特率时钟工作//工作模式为1TBRT = 0xff;#if( Bus_clk == 12 )CLK_DIV = 0x00;#elif( Bus_clk == 6 )CLK_DIV = 0x01;#elif( Bus_clk == 3 )CLK_DIV = 0x02;#elif( Bus_clk == 1500 )CLK_DIV = 0x03;#elif( Bus_clk == 750 )CLK_DIV = 0x04;#elif( Bus_clk == 375 )CLK_DIV = 0x05;#elif( Bus_clk == 187500 )CLK_DIV = 0x06;#elif( Bus_clk == 93750 )CLK_DIV = 0x07;#endif}//**********************************************//// 主程序////**********************************************//void main(){Sysclk_init();while(1);}//****************************************************************************// // STC12C5A60S2系统省电模块////// 说明:STC12C5A60S2单片机有三种省电模式以降低功耗.空闲模式,低速模式// 掉电模式////// 涉及寄存器:PCON(电源控制寄存器)// Bit0 - IDL 控制单片机进入IDLE空闲模式// Bit1 - PD 控制单片机进入掉电模式// //// 程序说明:程序实现让单片机先工作一阵子(通过P0^3指示灯显示)// 然后进入掉电状态,利用外部中断0口来唤醒单片机工作// 唤醒后单片机将通过P0^0-3口的灯闪烁显示开始工作////****************************************************************************/ /#include <STC12C5A60S2.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar Power_Down_Flag = 0; //进入掉电状态标志sbit Chip_Start_LED = P0^0; //单片机开始工作指示灯sbit Power_Down_LED_INT0 = P0^1; //INT0口掉电唤醒指示灯sbit N_Power_Down_LED_INT0 = P0^2; //INT0口没有唤醒指示灯sbit Normal_Work_LED = P0^3; //正常工作指示灯sbit Power_Down_Wakeup_INT0= P3^2; //外中断唤醒输入口void Delay_ms( uint time );void Normal_work(void);void Intp_init(void);void After_Powr_Down(void);//***********************************//// 软件延时////***********************************//void Delay_ms( uint time ){uint t; //延时时间= (time*1003+16)us while(time--){for( t = 0; t < 82; t++ );}}//***********************************//// 正常工作指示//***********************************//void Normal_work(void){Normal_Work_LED = 1;Delay_ms(500);Normal_Work_LED = 0;Delay_ms(500);}void After_Power_Down(void){uchar i ;for( i = 0; i < 100; i++ ){P0 = 0x0f;Delay_ms(500);P0 = 0x00;Delay_ms(500);}}//***********************************//// 中断初始化////***********************************//void Intp_init(void){IT0 = 0; //外部中断源0为低电平触发EX0 = 1; //允许外部中断EA = 1; //开总中断}//***********************************//// 主程序////***********************************//void main(){uchar j = 0;uchar wakeup_counter = 0; //记录掉电次数P0 = 0x00;Chip_Start_LED = 1; //单片机开始工作Intp_init(); //外中断0初始化while(1){P2 = wakeup_counter;wakeup_counter++;for( j = 0; j < 250; j++ ){Normal_work(); //系统正常工作指示}Power_Down_Flag = 1; //系统开始进入掉电状态PCON = 0x02;_nop_();_nop_();_nop_();_nop_();After_Power_Down(); //掉电唤醒后}}//**********************************//// 中断服务//**********************************//void INT0_Service(void) interrupt 0{if( Power_Down_Flag ) //掉电唤醒状态指示{Power_Down_Flag = 0;Power_Down_LED_INT0 = 1;while( Power_Down_Wakeup_INT0 == 0 ){_nop_(); //等待高电平}Power_Down_LED_INT0 = 0;}else //未掉电状态{N_Power_Down_LED_INT0 = 1; //不是掉电唤醒指示while( Power_Down_Wakeup_INT0 == 0 ){_nop_();}N_Power_Down_LED_INT0 = 0;}}//****************************************************************************// // STC12C5A60S2 A/D转换模块////// 说明:STC12C5A60S2单片机有8路10位高速AD转换器,P1^0-P1^7//// 涉及寄存器:P1ASF(模拟功能控制寄存器)、ADC_CONTR(ADC控制寄存器)// ADC_RES、ADC_RESL(转换结果寄存器)//// 注意: 1、初次打开内部A/D模拟电源需适当延时等内部模拟电源稳定后,再启动A/D转换// 启动A/D后,在转换结束前不改变任何I/O口的状态,有利于高精度A/D转换// 若能将定时器/串行/中断系统关闭更好。
STC单片机唯一ID保护及例子及思路
STC单片机唯一ID保护及例子及思路STC单片机唯一ID保护的例子及思路(摘自STC-ISP V6.XX【重要说明】部分)关于ID号在大批量生产中的应用方法(较多客户的用法)(转载)先烧一个程序进去(选择下次下载用户程序时不擦除用户EEPROM区),读程序区的ID号(STC15系列是程序区的最后7个字节),经用户自己的复杂的加密算法对程序区的ID号加密运算后生成一个新的数---用户自加密ID号,写入STC15系列用户的EEPROM区的EEPROM。
再烧一个最终出厂的程序进去(选择下次下载用户程序时将用户EEPROM区一并擦除),在用户程序区多处读程序区的ID号和用户自加密ID号比较(经用户自己的复杂的解密算法解密后),如不对应,则6个月后随机异常,或200次开机后随机异常。
最终出厂的程序不含加密算法。
另外,在程序区的多个地方判断用户自己的程序是否被修改,如被修改,则6个月后随机异常,或200次开机后随机异常,将不用的用户程序区用所谓的有效程序全部填满。
《应用笔记》单片机加密保护的几种方式:1、法律保护由完善的法律加强对盗版的打击。
在单片机程序里添加自己的版权、LOGO标记等,作为法庭上的证据(当然要加密保存,并反跟踪,程序运行中要校验是否被修改,如是则作相应的处理)。
2、技术保护。
其实理论上所有的单片机加密都会被破解,只是成本的问题(含时间成本、金钱成本等)。
只要做到解密的成本足够大,让破解者觉得无利可图即算成功!通常是加密的容易而破解难。
现代芯片的加密主要有工艺上缩小线宽、将保密位深埋、读写协议保密、读取敏感区域时自动重启等等方法,让破解者不能取得内部BIN执行代码。
假如一个系统的成本为:开发+测试+投产只需5万元,而破解得到BIN 文件却要10万元,这时哪谁还去做破解的傻事??而且如果开发者使用了关联单片机唯一ID的保护方式,哪怕破解者千辛万苦取得了BIN文件还不能直接使用,就可以大大增加了系统的保密性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
S T C15F204E A单片机旋转编码器版白光T12控制器代码(开发固件)(b y金向维)-CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIAN/*************STC15F204EA单片机旋转编码器版白光T12控制器代码(开发固件)(by金向维)********* **********/#include <STC15F104E.H> //单片机头文件,24MHz时钟频率#include "INTRINS.h" //头文件unsigned char code duanma[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x73}; //共阴数码管段码数据(0,1,2,3,4 ,5,6,7,8,9),倒数第二个是显示负号-的数据,倒数第一个是显示字母P的数据unsigned int code wendubiao[62]={924,959,996,1033,1071,1110,1150,1190,1232,1273,1315,1358,1401,14 43,1487,1501,1574,1619,1663,1706,1751,1756,1776,1810,1853,1903,1958,2017,207 8,2141,2204,2266,2327,2387,2444,2500,2554,2607,2657,2706,2738,2800,2844,288 9,2931,2974,3016,3056,3098,3139,3179,3218,3257,3296,3333,3372,3408,3446,348 4,3519, 3554,3590}; //根据NTC电阻随温度变化进而引起电压变化得出的数据,用来查表计算室温(进而对热电偶冷端补偿)sbit t12=P2^0; //T12通过P2.0控制sbit bw=P3^4; //数码管百位位选为P3.4sbit sw=P3^5; //数码管十位位选为P3.5sbit gw=P3^6; //数码管个位位选为P3.6sbit tihuan=P3^7; //数码管的a段本应该用P1.0控制,由于P1.0被用来控制T12,所以要用P3.7替代P1.0sbit encoderb=P1^4; //编码器的b脚接P1.4sbit encodera=P3^2; //编码器的a脚接P3.2sbit zhendongkaiguan=P0^1; //震动开关接P0.1sbit bianmaanniu=P3^3; //编码器的按键接P3.3sbit a7=P2^7; //数码管小数点sbit a6=P2^6; //数码管g段sbit a5=P2^5; //数码管f段sbit a4=P2^4; //数码管e段sbit a3=P2^3; //数码管d段sbit a2=P2^2; //数码管c段sbit a1=P2^1; //数码管d段bit e=1, f=1; //e f 用来保存编码器上一次的状态bit huancunkaiguan=0; //用于改变设定温度后延时显示设定温度(而不是立刻显示t 12温度)signed int huancun; //显示函数直接显示huancun,要显示一个数据将必须这个数据赋值给缓存(由于数码管只有三位,为了在显示三位数同时保持四位数的精度,所以实际显示的是数据除以10,并支持显示负数)signed int shiwen; //10倍实际室温,即实际室温乘以10(为了精确)(允许的室温范围为-11度至50度)signed int t12wendu; //T12烙铁头的实际温度(非热电偶的温差)(同样为10倍温度)signed int shedingwendu; //设定温度(范围200~450度)signed int wencha; //T12两个周期间的温差signed int jiareshu; //每200ms加热周期内需要加热的次数(一次等于1ms,相当于加热占空比)unsigned char zhouqijishu; //加热周期200ms计数unsigned int huancunjishu; //用于改变设定温度后延时显示设定温度(而不是立刻显示t12温度)unsigned long cankaodianya0, t12dianya, ntcdianya, dianyuandianya;/********************************1ms延时函数******************************************* ******/void delay_ms (unsigned int a) //24MHz时钟时的1毫秒延时函数{unsigned int b;while(a--){for(b=0;b<1200;b++);}}/********************************10us延时函数****************************************** ******/void delay_10us (unsigned int a) //24MHz时钟时的10微秒延时函数{unsigned int b;while(a--){for(b=0;b<12;b++);}}/********************************数码管延时关断函数************************************ ******/void guanduan (void) //用于关断数码管的位选{delay_ms(1); //延时bw=1; //关断百位sw=1; //关断十位gw=1; //关断个位}/********************************公共函数10(显示)*************************************** *****/void gonggonghanshu10(unsigned char a){a7=a&0x80; //小数点a6=a&0x40; //ga5=a&0x20; //fa4=a&0x10; //ea3=a&0x08; //da2=a&0x04; //ca1=a&0x02; //btihuan=a&0x01; //a}/********************************显示函数********************************************** ******/void display(signed int a) //显示函数(显示实际数据除以10,支持显示负数){unsigned char baiwei, shiwei, gewei, d; //定义百位,十位,个位,每次显示帧数signed int c; //用于处理数字aif(a<0) //如果a是负数c=-a; //取a的相反数else //否则c=a; //就直接取a c=c/10;baiwei=c/100; //计算百位c=c%100;shiwei=c/10; //计算十位c=c%10;gewei=c; //计算个位for(d=0;d<20;d++) //显示部分,每次显示20个循环( 20帧){if(a<0) //如果a是负数,则百位显示负号gonggonghanshu10(duanma[10]);else //否则直接显示百位gonggonghanshu10(duanma[baiwei]); //显示百位bw=0; //打开百位guanduan(); //延时关断百位gonggonghanshu10(duanma[shiwei]); //显示十位sw=0; //打开十位guanduan(); //延时关断十位gonggonghanshu10(duanma[gewei]); //显示个位gw=0; //打开个位guanduan(); //延时关断个位}}/********************************ADC公共函数******************************************* *******/void gonggonghanshu2(void) //此函数测量单片机电源电压{ADC_CONTR=0x88; //ADC_POWER, SPEED1, SPEED0, ADC_FLAG---ADC_START, CHS2, CHS1, CHS0delay_10us(2); //延时等待转换结束ADC_RESL=ADC_RESL&0x03; //取转换结果低八位中的低二位cankaodianya0=(ADC_RES*4+ADC_RESL); //把结果转换成十进制数据(10位ADC,最大值1 024)dianyuandianya=2549760/cankaodianya0; //计算电源电压,单位mV}/********************************ADC测电压函数***************************************** *******/void adc (void) //ADC函数,用于测量和计算各种电压{signed char a; //查NTC表用gonggonghanshu2(); //公共函数2(此函数功能是测量电源电压,单位mV)ADC_CONTR=0x89; //ADC控制寄存器设置,转换采用最低速度速,低速更精确(测量t12电压务必使用最低速度AD转换,实测高速误差大)delay_10us(2);ADC_RESL=ADC_RESL&0x03;t12dianya=(ADC_RES*4+ADC_RESL);t12dianya=2490*t12dianya/cankaodianya0; //计算t12电压,单位mVADC_CONTR=0x8a; //ADC控制寄存器设置delay_10us(2);ADC_RESL=ADC_RESL&0x03;ntcdianya=(ADC_RES*4+ADC_RESL);ntcdianya=2490*ntcdianya/cankaodianya0; //计算ntc电压,单位mVfor(a=0;wendubiao[a]<ntcdianya;a++) //查表计算室温{if(a>=61) //如果超出表的范围就取允许的最高温度(50度)break; //并且退出查表}shiwen=(a-11)*10; //得出室温(实际室温乘以10) t12wendu=(t12dianya-100)*43*10/260+shiwen; //计算t12的实际温度,其中260为运放增益if(t12wendu<shiwen) //如果t12温度小于室温t12wendu=shiwen; //就取室温if(t12wendu>5000) //如果得出的温度超过500度,说明没有插入烙铁头或参数错误(因为烙铁头的温度不可能超过500度)t12wendu=5000; //显示500作为错误指示(注意显示函数显示的是1/10,所以要显示500,需要赋值5000)if(huancunkaiguan==1) //如果缓存开关开,说明刚刚改变了设定温度huancun=shedingwendu; //于是显示设定温度(而不是t12温度) elsehuancun=t12wendu; //否则直接显示t12温度}/********************************定时器0初始化函数************************************* ******/void timer0init (void) //定时器0初始化程序,24MHz频率下,每1ms中断一次{TMOD=0x00; //定时模式,16位自动重装TH0=0xf8; //计时1msTL0=0x2f;ET0=1; //开启定时器0中断TR0=1; //启动定时器0}/********************************公共函数6(记录编码器状态)****************************** ****/void gonggonghanshu6(void){e=encodera; //记录编码器a脚此次状态f=encoderb; //记录编码器b脚此次状态}/********************************编码器函数(正常加热模式调用)*************************** *****/void bianmaqi(void){if(e==1&&f==1&&encodera==1&&encoderb==0) //和前一次状态比较确定为右旋{shedingwendu=shedingwendu+100; //步进if(shedingwendu>4500) //最高允许450度shedingwendu=4500;huancun=shedingwendu; //显示改变后的设定温度huancunkaiguan=1; //打开缓存开关(用于延时显示设定温度1.5秒)huancunjishu=0; //重新开始缓存计数}if(e==1&&f==1&&encodera==0&&encoderb==1) //和前一次状态比较确定为左旋{shedingwendu=shedingwendu-100; //步进if(shedingwendu<2000) //最低允许200度shedingwendu=2000;huancun=shedingwendu; //显示改变后的设定温度huancunkaiguan=1; //打开缓存开关(用于延时显示设定温度1.5秒)huancunjishu=0; //重新开始缓存计数}gonggonghanshu6(); //记录编码器状态}/********************************定时器0中断函数*************************************** *****/void timer0(void) interrupt 1 //定时器0中断函数,检测编码器,掉电存储等操作(仅用于正常工作模式){unsigned char buchang;bianmaqi(); //调用编码器函数if(huancunkaiguan==1) //延时显示计数huancunjishu++;zhouqijishu++; //加热周期计数if(jiareshu>190) //最多加热190msjiareshu=190;if(zhouqijishu<=jiareshu) //如果当前计数小于等于加热数t12=1; //就加热else //否则t12=0; //不加热if(t12wendu==5000) //如果t12温度为500,说明没有插入烙铁头或参数严重错误t12=0; //停止加热if(huancunjishu==1500) //如果达到了设定温度延时显示的1.5秒{huancunkaiguan=0; //关闭缓存开关huancunjishu=0; //停止缓存计数huancun=t12wendu; //由显示设定温度改为显示t12温度}if(zhouqijishu==200) //t12停止加热后2ms再检测温度(给电容留出放电时间,防止检测的温度偏高) {adc(); //检测电压,计算温度zhouqijishu=0; //重新开始加热周期计数////////////////////以下为加热算法(请自行理解,不作注释)/////////////////if(t12wendu>shedingwendu){if(t12wendu-shedingwendu<=20)jiareshu=(shedingwendu-1500)/160;elsejiareshu=0;}if(t12wendu<=shedingwendu){wencha=shedingwendu-t12wendu;if(wencha>20){buchang++;if(buchang>150)buchang=150;}elsebuchang=0;if(shedingwendu-t12wendu>=300)jiareshu=198;else if(shedingwendu-t12wendu>=200)jiareshu=160;else if(shedingwendu-t12wendu>=150)jiareshu=130;else if(shedingwendu-t12wendu>=100)jiareshu=90+wencha/2+buchang;else if(shedingwendu-t12wendu>=50)jiareshu=50+buchang*2;elsejiareshu=(shedingwendu-1000)/80+wencha*2/3+buchang;}}}/********************************主函数************************************************ *****/void main (void) //主函数{P1M0=0x00; //P1除P1.0,P1.1,P1.2为输入模式外均为正常模式P1M1=0x07;P1ASF=0x07; //设置P1相应ADC转换的I/O口为ADC输入模式P2M0=0xff; //P2都是推挽模式P2M1=0x00;P3M0=0xf0; //P3.4,P3.5,P3.6,P3.7为推挽模式,P3.2,P3.3为输入模式,P3M1=0x06; //其余正常模式ADC_CONTR=0xe0; //打开ADC电源shedingwendu=3000; //设为300度IE=0x88; //打开定时器0中断,关闭定时器1中断timer0init(); //初始化定时器0 while(1){display(huancun); //数码管显示数据}}。