/*--------------------------------------------------------------------------------------------------------------------------------------------***该程序为一个完整的温度控制器程序**最小系统温控板(后附图)**实现功能:**1、2X2的矩阵按键:分别实现(温度+,温度-,温度**确认,回到初始化状态)**2、先按键设定你要的温度值,然后按下确认键,**此时,水泥电阻开始加热,数码管动态显示电阻**此时的温度。
实现控制水泥电阻被加热到你所需要**的温度值。
并且能够稳定在你所设定的温度下。
当**实际温度超过你设定的温度,蜂鸣器报警。
****包括各个模块及详细的注释**方便C51单片机入门级别者阅读**--------------------------------------------------------------------------------------*/#include<stc12c5a.h>//该头文件可以百度到typedef unsigned char uchar;typedef unsigned int uint;sbit heat=P1^3;uchar makesure;//s62键为makesure确定键(若按下则置1)uchar tp=0;uchar num=0;uchar ad=0;uchar s60,s61,s62,s63,temp;//定义四个按键void smgshow(uchar num,uchar tp);//声明数码管显示函数void keyask(void);//键盘扫描uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数码管编码/*--------------------------------------------------------------------------------------------------------------------------------------------*三个小函数**delayus()--1us延时**delay1ms()--1ms延时**buzzeron()--蜂鸣器响*----------------------------------------------------*/void delayus(uint xus)//--------------------1us基准延时函数{uint i,j;for(i=0;i<xus;i++)for(j=0;j<10;j++);}void delay1ms(unsigned int i)//-------------------1ms基准延时函数{unsigned char j;while(i--){for(j=0;j<115;j++){;}}}void buzzeron(void)//--------------------蜂鸣器响动函数{unsigned int t;P1M1&=~0x10;P1M0|=0X10;for(t=0;t<100;t++){P14=0;smgshow(num,tp);P14=1;smgshow(num,tp);}P14=0;}/*--------------------------------------------------------------------------------------------------------------------------------------------***函数名:Init()****描述:各端口初始化****参数:无****返回值:无*------------------------------------------------------*/void Init(){P1M1&=~0X08;//P1^3口推挽输出P1M0|=0X08;P0M1=0X00;//P0口全部推挽输出P0M0=0XFF;P1M0&=~0X02;//P1^1口高阻输入避免各器件及电路对P11口的干扰P1M1|=0x02;ADC_CONTR|=0x80;//启动BIT3=0x08(ADC_STARTAD)开启转换delayus(1);AUXR1&=~0X04;//AD值存储方式ADC_CONTR=0XE1;//打开AD通道}/*--------------------------------------------------------------------------------------------------------------------------------------------***函数名:keyboardset()****描述:键盘检测及设置,由两个函数构成**先用keyask函数扫描哪个键按下,**然后用keyboardset执行相应功能******参数:无****返回值:无*------------------------------------------------------------------------------------*/void keyboardset(void){uchar i;P1M1&=0xef;P1M0|=0x10;//推挽输出,以驱动蜂鸣器P14=0x00;{keyask();//按键扫描if((s60+s61+s62+s63)!=0){if(s60==1){if(num>0)num=num-1;smgshow(num,tp);}if(s61==1){num=num+1;smgshow(num,tp);if(num>=99)num=99;}if(s62==1){if(num>tp)makesure=1;return;}if(s63==1){makesure=0;return;}for(i=0;i<20;i++)//每按一次,响一次{P1=0x10;delay1ms(1);P1=0x00;delay1ms(1);}}else{smgshow(num,tp);}}}void keyask(void)//---------------------------------------------------------------------------按键扫描函数{s60=0;s61=0;s62=0;s63=0;P3=0xb0;//第一行扫描10110000temp=P3&0x30;if(temp!=0x30){delay1ms(10);if(temp!=0x30)//消除抖动switch(temp){case(0x20):s60=1;while(!(P3&0x10));break;//while消抖case(0x10):s61=1;while(!(P3&0x20));break;}}P3=0x70;//第二行扫描temp=P3&0x30;if(temp!=0x30){delay1ms(10);if(temp!=0x30)switch(temp){case(0x20):s62=1;while(!(P3&0x10));break;case(0x10):s63=1;while(!(P3&0x20));break;}}}/*--------------------------------------------------------------------------------------------------------------------------------------------***函数名:getAd()****描述:AD初始化及采集****参数:无****返回值:sum*------------------------------------------------------------------------------*/uchar getAd(void){uchar i;uint sum=0;for(i=0;i<8;i++){ADC_CONTR|=0x08;//启动BIT3=0x08(ADC_STARTAD)开启转换delayus(1);P1ASF=0X02;//P1口模拟功能控制位00000010开启P11while((ADC_CONTR&0x10)==0x00);//等待转换结束(等ADC_FLAG置1转换结束)ADC_CONTR&=~0x10;//ADC_FLAG软件清零sum+=ADC_RES;//SUM存电压值}sum>>=3;//右移3位,除以8,求平均值return(uchar)sum;//强制转换将sum转换为uchar形式}uchar code adlist[]={0x63,0x63,0x62,0x62,0x61,0x61,0x60,0x60,0x5f,0x5e,0x5e,0x5d,0x5c,0x5c,0x5b,0x5a,0x5a,0x59,0x58,0x57,0x57,0x56,0x55,0x54,0x53,0x52,0x51,0x50,0x4f,0x4e,0x4d,0x4c,0x4b,0x4a,0x49,0x48,0x47,0x46,0x46,0x45,0x44,0x43,0x42,0x42,0x41,0x40,0x3f,0x3f,0x3e,0x3d,0x3d,0x3c,0x3b,0x3b,0x3a,0x39,0x38,0x38,0x37,0x36,0x36,0x36,0x35,0x35,0x34,0x33,0x33,0x32,0x32,0x31,0x31,0x30,0x30,0x2f,0x2f,0x2e,0x2e,0x2d,0x2d,0x2c,0x2c,0x2b,0x2b,0x2a,0x2a,0x29,0x29,0x28,0x28,0x27,0x27,0x26,0x26,0x25,0x25,0x24,0x24,0x24,0x23,0x23,0x22,0x22,0x21,0x21,0x20,0x20,0x20,0x1f,0x1f,0x1e,0x1e,0x1d,0x1d,0x1d,0x1c,0x1c,0x1b,0x1b,0x1a,0x1a,0x1a,0x1a,0x19,0x19,0x18,0x18,0x18,0x17,0x16,0x16,0x15,0x15,0x15,0x14,0x14,0x13,0x13,0x13,0x12,0x12,0x11,0x11,0x10,0x10,0x10,0x0f,0x0f,0x0e,0x0e,0x0e,0x0d,0x0d,0x0c,0x0c,0x0b,0x0b,0x0b,0x0a,0x0a,0x09,0x09,0x08,0x08,0x08,0x07,0x07,0x07,0x06,0x06,0x06,0x05,0x05,0x05,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00};//AD转换的温度值表/*--------------------------------------------------------------------------------------------------------------------------------------------***函数名:smgshow()****描述:数码管显示(动态)****参数:num,tp****返回值:无*------------------------------------------------------------------------------*/void smgshow(uchar num,uchar tp){P0=table[num/10];//千位P27=1;P26=0;P25=0;P24=0;delay1ms(2);P0=table[num%10];//百位P27=0;P26=1;P25=0;P24=0;delay1ms(2);P0=table[tp/10];//十位P27=0;P26=0;P25=1;P24=0;delay1ms(2);P0=table[tp%10];//个位P27=0;P26=0;P25=0;P24=1;delay1ms(2);}/*--------------------------------------------------------------------------------------------------------------------------------------------***主函数****先初始化,再进入循环*********------------------------------------------------------------------------------*/void main(){Init();//各端口初始化while(1)//进入死循环{keyboardset();//----------键盘检测及设置ad=getAd();//----------得到的AD值tp=adlist[ad/2];//----------经查表得到的温度赋给tpif(makesure==1)//----------等待s62确认键是否按下{if(num>=tp)//----------当设定值大于实际温度值时加热{heat=1;//----------电阻加热}if(tp>num)//-----------当设定值小于实际温度值时停止加热{heat=0;//-----------停止加热buzzeron();//-----------蜂鸣器响}}smgshow(num,tp);//-----------数码管显示}}/*---------------------------------------------------------------------------------------------------------------------------------by灏*/原理图:实物图:。