一.课设目的: 1.通过本设计,使学生综合运用《单片机原理及应用》及电子技术等课程的内容,为以后从事基于单片机的检测与控制工作奠定一定的基础。 2.主要掌握芯片DS18B20、ULN2803等器件的使用,掌握步进电机的使用。 3.学会用Keil C51语言编写一个完整的程序。 4.掌握单片机应用开发的全过程:分析需求、设计原理图、选用元器件、布线、编程、调试、撰写报告等步骤。 5.掌握Proteus软件的应用。 二.课设内容: 采用单片机内部定时器,设计1s定时,每秒检查一次由温度传感器输入的当前温度。设置温度的上限(t2)和下限(t1),假定当前温度为t。由此可知: 若t≥t2,则控制步进电机顺时针旋转; 若t≤t1,则控制步进电机逆时针旋转; 若t1<t<t2,步进电机停止转动。 三.问题分析及设计思路: 由设计要求可知,需要通过由温度传感器采集的温度来控制步进电机的转动,因此可以在源程序中加入相应的语句加以实现。电路原理图的设计思路如下: 1.单片机P1.0接温度传感器DS18B20,采集外界的当前温度。DS18B20的电源和地线分别接VCC和GND。 2.单片机P2.0~P2.3接74LS04,74LS04的输出接ULN2803,ULN2803的输出通过电阻接步进电机。 3.设计程序每秒检查一次由温度传感器输入的当前温度,根据设置的温度控制步进电机转动的方向或停止步进电机。 四.电路原理图: 
六.实验源程序:
1.在使用Proteus软件绘制电路图时,遇到的器件名称不唯一的问题。 解决方法:在绘制电路图时,必须保证器件名称唯一,否则就会仿真时就会提示出错。需进行修改使其唯一。 2.绘制电路图时,器件的安放及线路连接问题。 解决方法:由于该电路涉及的功能模块比较多,故器件排布及线路连接有些复杂。在进行了多次修改之后,确定了比较合理的布局方式,使电路图看起来较为整洁有条理。 3.在编写源程序时,出现的某些函数无法进行调用的问题。 解决方法:在对老师所给的代码进行分析之后,发现若需要在主程序中对函数进行调用,则应该在代码前面对其进行声明,否则编译时会出现错误。 1.若读取的温度大于20度且小于25度,则电机停止转动: 2.若读取的温度大于等于25度,则电机反转: 
3.若读取的温度小于等于20度,则电机正转: 
通过本次课设,熟悉了proteus软件的使用方法,了解了Keil C51语言编写程序的相关知识。在老师的指导下,解决了课设过程中出现的一些问题,加深了自己对有关知识的理解。特别是使用proteus软件绘制电路图时的一些收获,让我觉得受益匪浅,也对该软件的使用变得更加熟练。在使用Keil C51语言编写程序时,也学习了对单片机源程序编写的一些技巧。在编写单片机源程序时,要设计好各个功能模块,以及延时子程序、相关芯片的复位、显示等。在对各个功能函数进行调用之前,需对其进行初始化。通过本次课设,也对之前学习的知识有了一个回顾和总结,收获很多。
- #include <reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar code fortab[9]={0x0e,0x0c,0x0d,0x09,0x0b,0x03,0x07,0x06,0x00};
- uchar code revtab[9]={0x0e,0x06,0x07,0x03,0x0b,0x09,0x0d,0x0c,0x00};
- int time=500;
- void disp(uchar cc);
- void dsend(uchar bb);
- void dmsec (unsigned int count);
- void tmreset (void);
- void tmpre (void);
- bit tmrbit (void);
- unsigned char tmrbyte (void);
- void tmwbyte (unsigned char dat);
- void tmstart (void);
- uchar tmrtemp (void);
- void dfor(void);
- void drev(void);
- rom();
- //对调用的函数进行初始化定义
- uchar code temper_tab[100]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,
- 0x24,0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
- 0x38,0x39,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x50,0x51,
- 0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x60,0x61,0x62,0x63,0x64,0x65,
- 0x66,0x67,0x68,0x69,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
- 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x90,0x91,0x92,0x93,
- 0x94,0x95,0x96,0x97,0x98,0x99
- }; //定义温度范围,0到100度
- uchar code dis_code[10]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09};
- //0 1 2 3 4 5 6 7 8 9
- sbit TMDAT = P1^0; //根据实实际情况设定
- uchar TMP; //读取后温度值存于TMP中,将其除以2即可得出实际温度;
- uchar f; //结果是否为负温,“0”为正温,“1”为负温。
- //正转子程序
- void dfor(void)
- {
- uchar i;
- uint j;
- for(i=0;i<=8;i++)
- {
- P2=fortab[i];
- for(j=0;j<time;j++);
- }
- }
- //中断服务子程序(反转)
- void drev(void) //interrupt 1 using 0
- {
- uchar i;
- uint j;
- for(i=0;i<=8;i++)
- {
- P2=revtab[i];
- for(j=0;j<time;j++);
- }
- }
-
- void disp(uchar cc)
- {
- uchar temp1,bb;
- temp1=cc;
- bb=temp1&0x0F;
- dsend(bb);
- bb=temp1>>4;
- dsend(bb);
- }
- void dsend(uchar bb)
- {
- uchar i=bb;
- SBUF=dis_code[i];
- while(TI==0);TI=0;
- }
- ////////////////////////////////////////延时部分//////////////////////////
- void dmsec (unsigned int count) //
- { //
- unsigned int i; //
- while (count) //
- { //
- i = 115; //
- while (i>0) i--; //
- count--; //
- } //
- } //
- //////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////// 发送复位//////////////////////////
- void tmreset (void) //
- { //
- unsigned int i; //
- TMDAT = 0; //
- i = 103; //
- while (i>0) i--; // 延时 900 uS(11.0592Mhz时) //
- TMDAT = 1; //
- i = 4; //
- while (i>0) i--; //
- } //
- //////////////////////////////////////////////////////////////////////////
- //判断DS1820是否存在的子程序。最好不要用,因为当器件不存在时将会进入死循环
- ////////////////////////////////////// 等待存在脉冲///////////////////////
- //void tmpre (void) //判断器件是否存在 //
- //{ //
- // unsigned int i; //
- // while (TMDAT); //
- // while (~TMDAT); //
- // i = 4; while (i>0) i--; //
- // } //
- //////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////// 读一位//////////////////////////////
- bit tmrbit (void) //
- { //
- unsigned int i; //
- bit dat; //
- TMDAT = 0; i++; //
- TMDAT = 1; i++; i++; //微量延时 //
- dat = TMDAT; //
- i = 8; while (i>0) i--; // 延时 //
- return (dat); //
- } //
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////// 读一个字节///////////////////////
- unsigned char tmrbyte (void) //
- { //
- unsigned char i,j,dat; //
- dat = 0; //
- for (i=1;i<=8;i++) //
- { //
- j = tmrbit (); //
- dat = (j << 7) | (dat >> 1); //
- } //
- return (dat); //
- } //
- //////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////// 写一个字节////////////////////////
- void tmwbyte (unsigned char dat) //
- { //
- unsigned int i; //
- unsigned char j; //
- bit testb; //
- for (j=1;j<=8;j++) //
- { //
- testb = dat & 0x01; //
- dat = dat >> 1; //
- if (testb) //
- { //
- TMDAT = 0; // 写0 //
- i++; i++; //
- TMDAT = 1; //
- i = 8; while (i>0) i--; //
- } //
- else //
- { //
- TMDAT = 0; // 写0 //
- i = 8; while (i>0) i--; //
- TMDAT = 1; //
- i++; i++; //
- } //
- } //
- } //
- //////////////////////////////////////////////////////////////////////////
- /////////////////////////////////发送ds1820 开始转换//////////////////////
- void tmstart (void) //
- { //
- tmreset (); //复位 //
- //tmpre (); //等待存在脉冲 //
- dmsec (1); //延时 //
- tmwbyte (0xcc); //跳过序列号命令 //
- tmwbyte (0x44); //发转换命令 44H, //
- } //
- //////////////////////////////////////////////////////////////////////////
- /////////////////////////////////// 读取温度//////////////////////////////
- uchar tmrtemp (void) //
- { //
- unsigned char l,h,i; //
- tmreset (); //复位 //
- //tmpre (); //等待存在脉冲 //
- dmsec (1); //延时 //
- tmwbyte (0xcc); //跳过序列号命令 //
- tmwbyte (0xbe); //发送读取命令 //
- l = tmrbyte (); //读取低位温度 //
- h = tmrbyte (); //读取高位温度 //
- TMP=l>>4; //
- if((l>>3)&0x01==0x01) //
- TMP=TMP+1; //
- TMP=((h&0x07)<<4)|TMP; //
- i=TMP; //
- TMP=temper_tab[i]; //
- //
- return(TMP) ; //
- } //
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
- void main(void) //
- { uchar aa,i; //
- do{ //
- tmstart(); //
- dmsec(100); //如果是不断地读取的话可以不延时 //
- aa=tmrtemp(); //读取温度,执行完毕温度将存于TMP中 //
- disp(aa); //
- if(aa<=0x20) //
- dfor(); //对读取温度进行判断,若小于等于20度则电机正转 //
- else if(aa>=0x25) //
- drev(); //若读取温度大于等于25度则电机反转 //
- else; //若读取温度在20度与25度之间,则电机停止转动 //
- …………
- …………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
完整的Word格式文档51黑下载地址:
温控步进电机的实现.doc
(619.62 KB, 下载次数: 59)
|