一.課設目的: 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)
2018-12-4 17:34 上傳
點擊文件名下載附件
word
|