|
單片機課程設計報告書 設計題目:基于51單片機的簡易計算器 學生姓名: 學生學號: 所在班級: 自動化 指導教師: 目錄 引言 3 第一章 設計目的及方案 1.設計目的 3 2.設計方案 3 第二章 硬件基礎 1.AT89S52簡介 4 2.L1602簡介 4 3.4*4鍵盤矩陣簡介 5 第三章 程序設計 6 第四章 系統總述 1.系統流程圖 11 2.系統電路圖 12 3.實物連接圖 12 第五章 總結體會 13 引言 眾所周知單片機是一種集成在電路芯片,是采用超大 規模集成電路技術把具有數據處理能力的中央處理器CPU隨機存儲器RAM、只讀存儲器ROM、多種I/O口和中斷系統、定時器/計時器等功能(可能還包括顯示驅動電路、脈寬調制電路、模擬多路轉換器、A/D轉換器等電路)集成到一塊硅片上構成的一個小而完善的計算機系統。 目前,一個學習與應用單片機的高潮正在工廠、學校及企事業單位大規模地興起。過去習慣于傳統電子領域的工程師、技術員正面臨著全新的挑戰,如不能在較短時間內學會單片機,勢必會被時代所遺棄,只有勇敢地面對現實,挑戰自我,加強學習,爭取在較短的時間內將單片機技術融會貫通,才能跟上時代的步伐。 它所給人帶來的方便也是不可否定的,它在一塊芯片內集成了計算機的各種功能部件,構成一種單片式的微型計算機。20世紀80年代以來,國際上單片機的發展迅速,其產品之多令人目不暇接,單片機應用不斷深入,新技術層出不窮。20世紀末,電子技術獲得了飛速的發展,在其推動下,現代電子產品幾乎滲透了社會的各個領域,有力地推動了社會生產力的發展和社會信息化程度的提高,同時也使現代電子產品性能進一步提高,產品更新換代的節奏也越來越快。 設計目的: 本設計要制作的是單片機于生活中最為常見的一種應用—簡易計算器。這要求我們以單片機為核心,在熟悉、掌握各種外圍接口電路芯片的工作原理和控制方法的前提下根據所學的知識以及編寫程序來選取合適的器件設計簡易計算器使之實現加減乘除以及清零的功能。 設計方案: 根據計算器的功能要求,選擇AT89C51為主控機,通過擴展必要的外圍接口電路,實現對計算器的設計。外部主要由4*4矩陣鍵盤和一個液晶顯示屏構成,內部由一塊AT89S52單片機構成。計算器電路包括四個部分:選用LCD作為顯示部分,矩陣鍵盤作為輸入部分,運算模塊,單片機控制部分。模塊圖如圖所示: 
本簡易計算器AT89S52單片機作為核心。簡易計算器顯示電路由LCD1602組成, 制作一個單片機計時裝置需要的材料需要有軟硬件的支持,硬件方面AT89S52單片機,晶振,液晶屏LCD1602,鍵盤等部分構成。軟件部分在keil環境下用C語言編寫。本系統可進行簡易的計算。電路采用AT89S52單片機作為核心,功耗小,能在3V的低壓工作,電壓可選用3~5V電壓供電。 第二章 硬件基礎 1.AT89S52簡介: 主要性能:
與MCS-51單片機產品兼容 8K字節在系統可編程Flash存儲器 1000次擦寫周期 全靜態操作:0Hz~33MHz 三級加密程序存儲器 32個可編程I/O口線 三個16位定時器/計數器 八個中斷源 全雙工UART串行通道 低功耗空閑和掉電模式 掉電后中斷可喚醒 看門狗定時器 雙數據指針 掉電標識符 功能特性描述: AT89S52是一種低功耗、高性能CMOS8位微控制器,具有8K 在系統可編程Flash 存儲器。使用Atmel 公司高密度非易失性存儲器技術制造,與工業80C51 產品指令和引腳完全兼容。片上Flash允許程序存儲器在系統可編程,亦適于常規編程器。在單芯片上,擁有靈巧的8 位CPU 和在系統可編程Flash,使得AT89S52為眾多嵌入式控制應用系統提供高靈活、超有效的解決方案。 AT89S52具有以下標準功能: 8k字節Flash,256字節RAM,32 位I/O 口線,看門狗定時器,2 個數據指針,三個16 位定時器/計數器,一個6向量2級中斷結構,全雙工串行口,片內晶振及時鐘電路。另外,AT89S52 可降至0Hz 靜態邏輯操作,支持2種軟件可選擇節電模式。空閑模式下,CPU停止工作,允許RAM、定時器/計數器、串口、中斷繼續工作。掉電保護方式下,RAM內容被保存,振蕩器被凍結,單片機一切工作停止,直到下一個中斷或硬件復位為止。 2.1602液晶顯示器簡介: 液晶(Liquid Crystal)是一種高分子材料,因其特殊的物理、化學、光學特性,廣泛應用輕薄顯示器上。 液晶顯示器(Liquid Crystal Display,LCD)的主要原理是以電流刺激液晶分子產生點、線、面并配合背部燈管構成畫面。 各種型號的液晶通常是按照顯示字符的行數或液晶點陣的行、列數來命名。例如,1602表示每行顯示16個字符,一共可以顯示兩行。這類液晶通常稱為字符型液晶,只能顯示ASCII碼字符。12232表示液晶顯示畫面由122列、32行組成,共有122*32個點來顯示各種圖形。用戶可以通過程序控制這些點中任何一個點顯示或不顯示,從而構成各種圖形畫面。因此,12232稱為圖形型液晶。 液晶體積小,功耗低,顯示操作簡單。但其有致命的弱點,即使用溫度范圍很窄。通用型液晶工作溫度為0到+55攝氏度,存儲溫度為-20到+60攝氏度。 主要參數: 顯示容量:16*2個字符 芯片工作電壓:4.5~5.5V 工作電流:2.0mA 模塊最佳工作電壓:5.0V 字符尺寸:2.95*4.35(WXH)mm RAM地址映射圖: 
向圖中的 00~0F、40~4F 地址中的任意處寫入顯示數據時,液晶可立即顯示出來; 當寫入到 10~27 或 50~67 地址時,必須通過移屏指令將他們一移入可顯示區域方可正常 顯示。 實驗箱4*4鍵盤實物圖: 4*4鍵盤電路圖:  
編碼后按鍵功能:

3.實物連接圖: 
單片機是我所學專業的主要課程之一,不僅培養了我綜合運用所學知識,發現,提出,分析和解決實際問題的能力,而且提高了我實際動手操作能力.現實生活中,單片機在應用可以說得是無處不在。因此在大學中說掌握單片機的開發技術是十分重要的,也是十分必要的。 我在剛剛拿到課程設計題目時有點迷惘,畢竟在前幾周的理論學習中沒有扎實的掌握單片機的理論知識,面對芯片和五顏六色的導線,不知道如何下手,好在通過上網和圖書館查閱相關資料,自己認真鉆研以及虛心詢問同學,終于解決了一個又一個的困難和障礙,成功完成了任務。 通過本次的單片機課程設計,不僅豐富了我的理論知識,而且在實踐過程中更令我學會了堅持、耐心和努力。此次單片機課程設計需要運用到許多之前所學過的知識,令我認識到自己以前學習的一些不足之處,例如對以前所學知識的理解不夠深刻,掌握得不夠牢固,運用不夠靈活。這讓我懂得了認真學習的重要性,以及要孜孜不倦地鉆研所學過的知識,做得融會貫通,不能一覽而過,不求甚解。在邊學習邊動手的過程中,我對AT89S52單片機的構造以及原理有了進一步的了解,同時也加深和鞏固了我對單片機匯編語言的認識。除此之外,由于是第一次做單片機,因此在此次課程設計的過程中,無論是電路繪制還是匯編語言編寫都難免遇到了不少困難和障礙,例如匯編語言編寫出錯、電路元件無從入手等。在面對困難和障礙時,我慶幸自己沒有選擇退縮和逃避,而是通過各種方法,迎難而上,以堅持、耐心和努力勇敢無畏地面對困難,克服困難,解決困難。讓我發現問題、分析問題、解決問題以及動手實踐的能力都有了很大的提高,并了解到理論知識與實踐相結合的重要意義。 從這次的課程設計中,我才真正明白理論結合實際的道理,在以后的學習中,更要把理論聯系實際,把我們所學的理論知識用到實際當中,學習單機片機即是如此,出色的程序最終用實際操作來實現才是完美。十分慶幸擁有這次課程設計,讓我受益匪淺。
單片機源程序如下:
- #include<reg52.h>
- #include<stdio.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define CHECK_BUSY
- sbit RS = P2^4;
- sbit RW = P2^5;
- sbit EN = P2^6;
- void Delay10ms(unsigned int c)
- {
- unsigned char a,b;
- for (;c>0;c--)
- {
- for(b=38;b>0;b--)
- {for(a=130;a>0;a--);
- }
- }
- }
- //判忙函數
- bit LCD_Check_Busy()
- {
- #ifdef CHECK_BUSY
- P0= 0xFF;
- RS=0;
- RW=1;
- EN=0;
- _nop_();
- EN=1;
- return (bit)(P0 & 0x80);
- #else
- return 0;
- #endif
- }
- //命令函數
-
- void write_com(uchar com)
- {
- while(LCD_Check_Busy());
- RS=0;
- RW=0;
- EN=1;
- P0= com;
- _nop_();
- EN=0;
- }
- //數據函數
-
- void write_dat(uchar dat)
- {
- while(LCD_Check_Busy());
- RS=1;
- RW=0;
- EN=1;
- P0= dat;
- _nop_();
- EN=0;
- }
- //字符函數
-
- void LCD_Write_Char(uchar x,uchar y,uchar dat)
- {
- if (y == 0)
- {
- write_com(0x80 + x);
- }
- else
- {
- write_com(0xC0 + x);
- }
- write_dat( dat);
- }
- //字符串函數
- void Write_String(uchar x,uchar y,uchar *s)
- {
-
- while (*s)
- {
- LCD_Write_Char(x,y,*s);
- s++;
- x++;
- }
- }
- //初始化函數
-
- void LCD_Init()
- {
- write_com(0x38);
- Delay10ms(20);
- write_com(0x06);
- Delay10ms(20);
- write_com(0x0C);
- write_com(0x01);
- }
- //按鍵掃描函數
-
- uchar KeyScan()
- {
- unsigned char cord_h,cord_l;
- P3=0x0f;
- cord_h=P3&0x0f;
- if(cord_h!=0x0f)
- {
- Delay10ms(40);
- if((P3& 0x0f)!=0x0f)
- {
- cord_h=P3&0x0f;
- P3=cord_h|0xf0;
- cord_l=P3&0xf0;
- while((P3&0xf0)!=0xf0);//等待松開并輸出
- return(cord_h+cord_l);//鍵盤最后組合碼值
- }
- }
- return(0xff);
- }
- unsigned char KeyPro()
- {
- switch(KeyScan())
- {
- case 0x7e:return '1';break;//按下相應的鍵所顯示相應的值
- case 0x7d:return '2';break;
- case 0x7b:return '3';break;
- case 0x77:return '+';break;
- case 0xbe:return '4';break;
- case 0xbd:return '5';break;
- case 0xbb:return '6';break;
- case 0xb7:return '-';break;
- case 0xde:return '7';break;
- case 0xdd:return '8';break;
- case 0xdb:return '9';break;
- case 0xd7:return 'x';break;
- case 0xee:return '0';break;
- case 0xed:return '.';break;
- case 0xeb:return '=';break;
- case 0xe7:return '/';break;
- default:return 0xff;break;
- }
- }
- main()
- {
- unsigned char num,i,sign;
- unsigned char temp[16];
- bit firstflag;
- float a=0,b=0;
- unsigned char s;
- LCD_Init(); //初始化液晶屏
- Delay10ms(40);//延時
- write_com(0x01);
- Write_String(0,0,"I LIKE MCU");
- Write_String(0,1,"HBKJXY");
- for(s=0;s<25;s++)
- Delay10ms(300);
- write_com(0x01);
- while (1) //主循環
- {
- num=KeyPro(); //掃描鍵盤
- if(num!=0xff) //如果掃描是按鍵有效值則進行處理
- {
- if(i==0)
- write_com(0x01);
- if(('+'==num)|| (i==16) || ('-'==num) || ('x'==num)|| ('/'==num) || ('='==num))//輸入數字最大值16,輸入符號表示輸入結束
- {
- i=0;
- if(firstflag==0)
- {
- sscanf(temp,"%f",&a);
- firstflag=1;
- }
- else
- sscanf(temp,"%f",&b);
- for(s=0;s<16;s++)
- temp[s]=0;
- LCD_Write_Char(0,1,num);
-
- if(num!='=') //判斷當前符號位并做相應處理
- sign=num;
- else
- {
- firstflag=0; //檢測到輸入=號,判斷上次讀入的符號
- switch(sign)
- {
- case '+':a=a+b;
- break;
- case '-':a=a-b;
- break;
- case 'x':a=a*b;
- break;
- case '/':a=a/b;
- break;
- default:break;
- }
- sprintf(temp,"%g",a);
- Write_String(1,1,temp);//顯示到液晶屏
- sign=0;a=b=0; //數據清零
- for(s=0;s<16;s++)
- temp[s]=0;
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
基于51單片機的簡易計算器 .docx
(422.11 KB, 下載次數: 32)
2018-4-21 20:42 上傳
點擊文件名下載附件
51單片機
|