还是课程设计一直没得到帮助~~

2019-07-15 23:47发布

各位勿怪,小弟是新手,没发过帖子,每次发的都不怎么全。影响各位的,抱歉了~
我们的课程设计,就是把程序调通,但现在出现几个问题,一直没有解决,所以多次发帖,希望大家能帮帮忙~~后面的文档里有程序~~
题目是:基于单片机的快热式家用热水器
程序:快热式热水器程序MCU AT89C51  XAL 12MHzBuild by Gavin Hu, 2005.3.18--------------------------------------*/#include <reg51.h>#include <intrins.h>#include <math.h>void delay(unsigned int);       //延时函数void display(void);             //显示函数unsigned char keyscan(void);    //按键扫描处理函数void heatctrl(void);            //加热控制函数void temptest(void);            //测温函数sbit swkey=P1^0;                //开关键sbit upkey=P1^1;                //加热档位“+”键sbit downkey=P1^2;              //加热档位“-”键sbit buzz=P1^05;                //蜂鸣器输出端sbit triac=P1^6;                //可控硅触发信号输出端sbit relay=P1^7;                //继电器控制信号输出端sbit led1=P2^5;                 //加热档位指示灯1sbit led2=P2^6;                 //加热档位指示灯2sbit led3=P2^7;                 //加热档位指示灯3signed char data ctemp;         //当前测得水温寄存器unsigned char datadispram[2]={0x10,0x10};  //显示区缓存unsigned char data heatpower,px0count;      //加热档位寄存器、外中断0计数器bit tempov,t0tst,testok;        //超温标志、测温开始标志、测温完成标志/*----------------------------------------------  主函数 void main(void)  无参数,无返回值  循环调用显示、键扫描、温度检测、加热控制函数----------------------------------------------*/void main(void){ unsigned char i,j;ctemp=15;                       //初始化水温寄存器heatpower=5;                    //初始化加热档位为5档tempov=0;                       //清除超温标志swkey=0;                        //默认开关键被按下,进入待机状态TMOD=0x11;                      //设定T0和T1工作方式为16位定时器TCON=0x05;                      //设置外中断0和1为下降沿触发IP=0x01;                        //设置外中断0优先IE=0x80;                        //打开总中断while (1)  {  i=1;  do{    for(j=0;j<100;j++)         //循环100次约0.5s      {     if (keyscan()) i=6;       //如果有键按下,显示当前档位3s     display();                //调用显示函数一次约4ms     heatctrl();               //调用加热控制函数     }//end for (b=0;b<100;b++)   temptest();                 //每0.5s进行一次测温    }while (--i);              //通过改变循环次数i的大小决定是否刷新显示 j=abs(ctemp);                 //取温度绝对值 dispram[1]=j%10;              //取个位数送显示 j/=10;                        //取十位数 dispram[0]=j?j:0x11;          //送显示(带灭零) }//end while (1)} /*--------------------------------------  延时函数 void delay(unsigned int dt)  参数:dt,无返回值  延时时间=dt*500机器周期--------------------------------------*/void delay(unsigned int dt){register unsigned char bt;      //定义寄存器变量for (; dt; dt--)  for(bt=250; --bt; );         //此句编译时以“DJNZ”实现,250*2=500机器周期} /*--------------------------------------  显示函数 void display(void)  无参数,无返回值  两位共阳数码管扫描显示--------------------------------------*/void display(void){unsigned char codetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,                           0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff};unsigned char i,a;a=0xfe;                         //位选赋初值for (i=0; i<2; i++)             //循环扫描两位数码管  { P2|=0x1f;                     //清除位选 P0=table[dispram];         //送显示段码 P2&=a;                       //选通一位 delay(4);                     //延时2ms a=_crol_(a,1);                //改变位选字 P0=0xff;                      //消影  }} /*----------------------------------------------------------  按键扫描处理函数 unsigned char keyscan(void)  无参数,返回值:无符号字符型,无键按下为0,有键按下为其它  影响全局变量:heatpower----------------------------------------------------------*/unsigned char keyscan(void){unsigned char i,ch;if (upkey==0)                   //“+”键  { buzz=0;                       //打开蜂鸣器(发出按键音)  for(i=0;i<5;i++) display();  //延时消抖 buzz=1;                       //关闭蜂鸣器  if(heatpower<9) heatpower++; //档位加一 dispram[0]=0; dispram[1]=heatpower;         //显示当前档位  while(upkey==0) display();   //等待键释放 return (1);                   //返回有键按下  }  elseif (downkey==0)          //“-”键  { buzz=0;                       //打开蜂鸣器(发出按键音)  for(i=0;i<5;i++) display();  //延时消抖 buzz=1;                       //关闭蜂鸣器  if(heatpower>0) heatpower--; //档位减一 dispram[0]=0; dispram[1]=heatpower;         //显示当前档位  while(downkey==0) display(); //等待键释放 return (2);                   //返回有键按下  }  elseif (swkey==0)            //开关键  { buzz=0;                       //打开蜂鸣器(发出按键音)  for(i=0;i<30;i++) display(); //延时消抖 buzz=1;                       //关闭蜂鸣器 swkey=1;                      //置位开关键  while(swkey==0) display();   //等待键释放 ch=IE;                        //暂存中断控制字IE IE=0x00;                      //禁止中断 P0=0xff; P1=0xff; P2=0xff;                      //清除端口输出 dispram[0]=0x10; dispram[1]=0x10;              //显示“--” display();  while(1)    {   while (swkey) display();     //等待开关键按下   buzz=0;                      //打开蜂鸣器(发出按键音)    for(i=0;i<10;i++) display();//延时消抖   buzz=1;                      //关闭蜂鸣器    if(swkey==0) break;         //确认开关键被按下    }  while(swkey==0) display();    //等待键释放 IE=ch;                         //还原中断控制字IE return (0);                    //返回无键按下  }  elsereturn (0);               //无任何键按下时由此返回} /*--------------------------------------  加热控制函数 void heatctrl(void)  无参数,无返回值  判断是否加热、加热功率及档位指示灯处理--------------------------------------*/void heatctrl(void){if (!tempov)                     //当没有超温标志时  { relay=0;                       //接通继电器 buzz=1;                        //关闭蜂鸣器 switch (heatpower)             //判断加热档位    {   case 0: {EX1=0;ET1=0;triac=1;led1=1;led2=1;led3=1;break;}//0档不加热,指示灯不亮   case 1:   case 2:   case 3:   case 4: {led1=0;led2=1;led3=1;EX1=1;break;} //1~4档1号指示等亮   case 5:   case 6:   case 7:   case 8: {led1=0;led2=0;led3=1;EX1=1;break;} //5~8档1号、2号指示灯亮   case 9: {EX1=0;ET1=0;led1=0;led2=0;led3=0;triac=0;break;} //9档全功率,指示灯全亮    }  } else                           //当有超温标志时  { relay=1;                       //断开继电器 EX1=0; ET1=0; triac=1;         //关闭可控硅 buzz=0;                        //蜂鸣报警  }} /*--------------------------------------  测温函数 void temptest(void)  无参数,无返回值,  影响全局变量:ctemp,tempov  测量并查表计算温度,判断是否超温--------------------------------------*/void temptest(void){signed char temp,tempmin,tempmax;unsigned int t0rig;unsigned int codetemptab[]={0x6262,0x61eb,0x6171,0x60f7,0x6047,0x5ff7,0x5f6e,0x5eef,0x5e53,0x5dbe,0x5d4b,0x5ca5,0x5c17,                             0x5b6b,0x5ada,0x5a5c,0x599b,0x58ff,0x5869,0x57b0,0x570d,0x5663,0x55c6,0x550e,0x5444,0x5396,                            0x52dd,0x5240,0x5189,0x50b0,0x5005,0x4f20,0x4e69,0x4db1,0x4cef,0x4c42,0x4b64,0x4aaa,0x49e1,                             0x48fc,0x4847,0x476c,0x46b1,0x4604,0x4503,0x4449,0x4356,0x4299,0x41c0,0x40ce,0x3ff0,0x3f2b,                            0x3e33,0x3d86,0x3ca6,0x3bd2,0x3b26,0x3a39,0x3973,0x38a6,0x37ef,0x373f,0x3687,0x35c3,0x3507,                            0x3487,0x33bc,0x32ed,0x324f,0x319e,0x3106,0x3053,0x2fa6,0x2f2a,0x2e88,0x2e00,0x2d63,0x2cd6,                             0x2c65,0x2bae,0x2b28,0x2a97,0x2a07,0x298e,0x2914,0x287a,0x280d,0x278a,0x2703,0x2687,0x2626,                            0x25e5,0x256d,0x24ee,0x2489,0x2414,0x23bc,0x2356,0x22d9,0x2278,0x2203};//温度频率表px0count=2;                      //测频中断函数参数t0tst=1;                         //置测频程序开始标志EX0=1;                           //打开测频外中断testok=0;                        //清除测频程序完成标志while (!testok) display();       //等待测试完成t0rig=(unsigned int)TH0<<8|TL0;  //字节合成字tempmin=0;                       //以下是二分查表法计算温度值tempmax=100;                     //tempmin和tempmax为温度表的范围while (1)  { temp=(tempmax+tempmin)/2;        //假定当前温度为最大值与最小值之中点值  if(t0rig==temptab[temp]) break; //若实际值等于假定值结束查找   else if (t0rig>temptab[temp]) tempmax=temp;//若实际值大于假定值,减小查找范围的最大值   else tempmin=temp;             //若实际值小于假定值,增大查找范围的最小值  if(tempmax-tempmin<=1)          //若查找范围已缩小到1度之间,   {                              //判断实际值更接近哪个端点    if(temptab[tempmax]+temptab[tempmin]>2*t0rig) temp=tempmax;//接近最大值取最大值     else temp=tempmin;           //接近最小值取最小值   break;                         //结束查找    }  }ctemp=temp;                        //刷新当前温度寄存器if (temp>65) tempov=1;             //如果温度超过65度置位超温标志  elseif (temp<45) tempov=0;      //当温度回落到45度以下时清除超温标志} /*------------------------------------------  测温频率测试函数 void tempfrequency(void)  使用外部X0中断,寄存器组1  测出温度——频率转换电路的频率------------------------------------------*/void tempfrequency(void) interrupt 0 using 1{if (--px0count) return;         //找齐起点或计数if (t0tst)                      //如果是起点  { t0tst=0;                      //清除测频开始标志 px0count=100;                 //取100个方波为一次测频 TH0=0; TL0=0;                        //清除计时器T0 TR0=1;                        //开始计时  } else                          //如果是终点  { TR0=0;                        //停止计时 EX0=0;                        //停止测频外中断 testok=1;                     //置位测频完成标志  }} /*------------------------------------------  可控硅触发信号控制函数 void triacctrl(void)  使用定时器T1中断,寄存器组3  向可控硅送出触发信号------------------------------------------*/void triacctrl(void) interrupt 3 using 3{register unsigned char i;triac=0;                       //输出可控硅导通信号ET1=0;                          //关闭定时器T1中断TR1=0;                          //终止定时器运行for (i=0;i<2;i++);              //延时,保证导通信号有足够的宽度triac=1;                        //完成可控硅导通信号}

问题 问题
理论图 理论图
画出的图 画出的图
新建 好压 ZIP 压缩文件.zip 下载积分: 积分 -1 分
121.04 KB, 下载次数: 6, 下载积分: 积分 -1 分 程序~
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。