基于51單片機的紅外控制LCD1602顯示系統
摘要:該設計由硬件和軟件共同組成。首先是硬件部分,該系統的最終實現選用的單片處理器(AT89S52)、21鍵遙控器、LCD1602 顯示、單片機的串行接口電路。因此應充分了解單片機,包括存儲空間,并行口,串行口,串行通信,定時器等,21鍵遙控器鍵值編碼和LCD1602 的顯示,本系統是以單片機為控制器的核心,本系統主要由紅外接收電路、接收紅外信號處理電路、單片機系統及控制電路組成。工作時,可以將21鍵遙控器上按鍵出來的鍵值編碼等信息送到單片機,單片機根據這些信息通過控制電路把要顯示的內容由LCD1602顯示屏顯示出21鍵每個鍵對應的內容,從而實現紅外控制LCD1602顯示。
一、 設計目的
課程名稱:《單片機原理及應用——c51編程+proteus仿真》 張毅剛 著, 學后感:熟悉單片機的人都知道,要學好單片機可不是一件容易的事,倒不是因為單片機很難學,而是很難找到一本專為單片機入門者而編寫的教材。翻一下身邊的單片機教材,都好像是為已經懂單片機的人而寫的,一般先介紹單片機的硬件結構和指令系統,再是系統擴展和外圍器件,順便講一些應用設計(隨便說一下,很多書中的電路設計已經過時,并且有些程序還是錯誤的)。如果按照此種學習方法,想進行產品開發,就必須先把所有的知識全部掌握了才可以進行實際應用。學習使用單片機只能靠循序漸進的積累,下面就本人學習單片機的過程和經驗做簡要介紹。
編程環境和仿真環境
編程環境:keil 4
仿真環境:proteus 8
二、 設計要求
根據仿真圖搭建硬件電路,硬件主要由AT89S52單片機最小系統一個,LCD1602顯示屏一個,21鍵紅外遙控器一個,HS0038紅外接收頭一個,470歐姆電阻一個,電源線一根,母對母杜邦線若干,排阻一個,11.0592晶振一個,貼片電容兩個,47μ電容一個。根據proteus仿真上能夠實現的電路搭建硬件電路
在keil4中編寫代碼,根據紅外的編結碼,和LCD1602顯示屏初始化查忙,寫命令,寫數據,來編寫代碼,了解紅外編結碼是編寫代碼重要的過程。
三、 設計內容
- 最小系統電路
AT89S52芯片
圖一、AT89S52芯片
AT89S52 是一種低功耗、高性能CMOS8位微控制器,具有8K 在系統可編AT89S52-24PU程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、定時器/計數AT89S52引腳圖 DIP封裝器、串口、中斷繼續工 作。掉電保護方式下,RAM內容被保存,振蕩器被凍結,單片機一切工作停止,直到下一個中斷或硬件復位為止。
晶振是晶體振蕩器的簡稱,在電氣上它可以等效成一個電容和一個電阻并聯再串聯一個電容的二端網絡。電工學上這個網絡有兩個諧振點,以頻率的高低分,其中較低的頻率是串聯諧振;較高的頻率是并聯諧振。由于晶體自身的特性致使這兩個頻率的距離相當的接近,在這個極窄的頻率范圍內,晶振等效為一個電感,所以只要晶振的兩端并聯上合適的電容它就會組成并聯諧振電路。這個并聯諧振電路加到一個負反饋電路中就可以構成正弦波振蕩電路,由于晶振等效為電感的頻率范圍很窄,所以即使其他元件的參數變化很大,這個振蕩器的頻率也不會有很大的變化
圖二、晶振電路
紅外接收電路一體化的紅外接收裝置將遙控信號的接收、放大、檢波、整形集于一身,并且輸出可以讓單片機識別的TTL 信號,這樣大大簡化了接收電路的復雜程度和電路的設計工作,方便使用。在本系統中我們采用紅外一體化接收頭HS0038,HS0038 黑色環氧樹脂封裝,不受日光、熒光燈等光源干擾,內附磁屏蔽,功耗低,靈敏度高。在用小功率發射管發射信號情況下,其接收距離可達35m。它能與TTL、COMS 電路兼容。HS0038 為直立側面收光型。它接收紅外信號頻率為38 kHz,周期約26 μs,同時能對信號進行放大、檢波、整形,得到TTL 電平的編碼信號。三個管腳分別是地、+5 V 電源、解調信號輸出端。 紅外一體化接收頭的測試可以利用圖4 所示的電路進行,在HS0038 的電源端與信號輸出端之間接上一只二極管及一只發光二極管后,再配上規定的工作電源(為+5V),當手拿遙
控器對著接收頭按任意鍵時,發光二極管會閃爍,說明紅外接收頭和遙控器工作都正常;如果發光二極管不閃爍發光,說明紅外接收頭和遙控器至少有一個損壞。
圖三、hs0038實物與原件介紹圖
圖四、左邊為遙控器的編結碼,右邊為遙控器的按鍵
主要功能就是顯示紅外遙控傳給單片機的數據,也可以算作紅外對單片機的控制
1602液晶也叫1602字符型液晶,它是一種專門用來顯示字母、數字、符號等的點陣型液晶模塊。它由若干個5X7或者5X11等點陣字符位組成,每個點陣字符位都可以顯示一個字符,每位之間有一個點距的間隔,每行之
間也有間隔,起到了字符間距和行間距的作用,正因為如此所以它不能很好地顯示圖形(用自定義CGRAM,顯示效果也不好)。1602LCD是指顯示的內容為16X2,即可以顯示兩行,每行16個字符液晶模塊(顯示字符和數字)。1602液晶模塊內部的字符發生存儲器(CGROM)已經存儲了160個不同的點陣字符圖形,這些字符有:阿拉伯數字、英文字母的大小寫、常用的符號、和日文假名等,每一個字符都有一個固定的代碼,比如大寫的英文字母"A"的代碼是01000001B(41H),顯示時模塊把地址41H中的點陣字符圖形顯示出來,我們就能看到字母"A"。
圖五、lcd1602proteus圖和實物圖
圖六、lcd1602指令碼
四、 結論、總結與建議
仿真圖結果:
圖七、protues仿真效果
實物圖結果:
圖八、實物效果圖
圖八、實物電路搭建圖
流程圖:
此次試驗的關鍵是鍵盤的編結碼,與對紅外信號發射原理的理解,接收裝置對紅外信號發射脈沖次數的記錄是關鍵。發射管的頻率一般為38kHz。通過這次課設實驗,讓我懂得的實驗要踏實,一步一個腳印的弄,不管遇到什么問題都不能親言放棄,這樣你必定會成功,還會在失敗的路上學習到好多好多經驗,這是一筆寶貴的財富
五、主要參考文獻
[1]唐正. Proteus在單片機教學中的應用[D].華中科技大學,2008.(參考文獻字體字號要求,中文:宋體;英文與數字:Times New Roman,五號)
[2]刁宇清. 基于PROTEUS的單片機仿真實驗系統研究及應用[D].西安工業大學,2011
[3]趙月靜,陳繼榮,張永弟. 單片機原理及應用課程創新實踐教學改革[J]. 實驗技術與管理,2013,01:176-179.
[4]周靈彬,張靖武. PROTEUS的單片機教學與應用仿真[J]. 單片機與嵌入式系統應用,2008,01:76-79.
六、 附錄
源代碼
- #include<reg52.h> //包含頭文件,一般情況不需要改動
- intrins.h>
- sbit IR=P3^2; //紅外接口標志
- sbit LCD_RS=P1^0;
- sbit LCD_RW=P1^1;
- sbit LCD_EN=P2^5;
-
- #define DataPort P0 //定義數據端口 程序中遇到DataPort 則用P0 替換
- Unsigned char code dofly_DuanMa[10]={0X30,0X31,0X32,0X33,0X34,0X35,0X36,0X37,0X38,0X39};// 顯示段碼值0~9
- unsigned char irtime;//紅外用全局變量
-
- bit irpro_ok,irok;
- unsigned char IRcord[4];
- unsigned char irdata[33];
-
- void Ir_work(void);
- void Ircordpro(void);
-
- void delay(unsigned char t) {
- unsigned char i;
- while(t--)
- for(i = 200; i > 0; i--);
- }
- void LCD_write_instruction(unsigned char LCD_instruction) { //寫指令到LCD
- LCD_RS = 0;
- LCD_RW = 0;
- DataPort = LCD_instruction;
- LCD_EN = 1;
- _nop_();
- LCD_EN = 0;
- delay(1);
- }
-
- void LCD_write_data(unsigned char LCD_data) { //輸出一個字節數據到LCD
- LCD_RS = 1;
- LCD_RW = 0;
- DataPort = LCD_data;
- LCD_EN = 1;
- _nop_();
- LCD_EN = 0;
- delay(1);
- }
-
- void LCD_set_position(unsigned char x) { //LCD光標定位到x處
- LCD_write_instruction(0x80|x);
- }
-
- void LCD_printc(unsigned char lcd_data) { //輸出一個字符到LCD
- LCD_write_data(lcd_data);
- }
- void LCD_prints(unsigned char *lcd_string) { //輸出一個字符串到 LCD
- unsigned char i = 0;
- while(lcd_string[i] != 0x00) {
- LCD_write_data(lcd_string[i]);
- i++;
- }
- }
-
- void LCD_initial(void) {
- LCD_RW = 0; //初始化 LCD
- LCD_write_instruction(0x38);
- LCD_write_instruction(0x0c);
- LCD_write_instruction(0x06);
- LCD_write_instruction(0x01);
- }
-
- void tim0_isr (void) interrupt 1 using 1
- {
- irtime++; //用于計數2個下降沿之間的時間
- }
-
- void EX0_ISR (void) interrupt 0 //外部中斷0服務函數
- {
- static unsigned char i; //接收紅外信號處理
- static bit startflag; //是否開始處理標志位
-
- if(startflag)
- {
- if(irtime<63&&irtime>=33)//引導碼 TC9012的頭碼,9ms+4.5ms
- i=0;
- irdata[i]=irtime;//存儲每個電平的持續時間,用于以后判斷是0還是1
- irtime=0;
- i++;
- if(i==33)
- {
- irok=1;
- i=0;
- }
- }
- else
- {
- irtime=0;
- startflag=1;
- }
-
- }
- void TIM0init(void)//定時器0初始化
- {
-
- TMOD=0x02;//定時器0工作方式2,TH0是重裝值,TL0是初值
- TH0=0x00; //重載值
- TL0=0x00; //初始化值
- ET0=1; //開中斷
- TR0=1;
- }
- void EX0init(void)
- {
- IT0 = 1; //指定外部中斷0下降沿觸發,INT0 (P3.2)
- EX0 = 1; //使能外部中斷
- EA = 1; //開總中斷
- }
-
- void Ir_work(void)//紅外鍵值散轉程序
- {
- switch(IRcord[2])//判斷第三個數碼值
- {
- case 0x0C:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints(" NOW: On");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Number: ");
- LCD_set_position(0xC8); //LCD換行顯示
- LCD_printc('0');
- LCD_set_position(0x49); //LCD換行顯示
- LCD_printc(dofly_DuanMa[1]);
- break;//1 顯示相應的按鍵值
- case 0x18:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints(" NOW: On");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Number: ");
- LCD_set_position(0xC8); //LCD換行顯示
- LCD_printc('0');
- LCD_set_position(0xC9); //LCD換行顯示
- LCD_printc(dofly_DuanMa[2]);break;//2
- case 0x5E:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints(" NOW: On");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Number: ");
- LCD_set_position(0xC8); //LCD換行顯示
- LCD_printc('0');
- LCD_set_position(0xC9); //LCD換行顯示
- LCD_printc(dofly_DuanMa[3]);break;//3
- case 0x08:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints(" NOW: On");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Number: ");
- LCD_set_position(0xC8); //LCD換行顯示
- LCD_printc('0');
- LCD_set_position(0xC9); //LCD換行顯示
- LCD_printc(dofly_DuanMa[4]);break;//4
- case 0x1C:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints(" NOW: On");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Number: ");
- LCD_set_position(0xC8); //LCD換行顯示
- LCD_printc('0');
- LCD_set_position(0xC9); //LCD換行顯示
- LCD_printc(dofly_DuanMa[5]);break;//5
- case 0x5A:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints(" NOW: On");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Number: ");
- LCD_set_position(0xC8); //LCD換行顯示
- LCD_printc('0');
- LCD_set_position(0xC9); //LCD換行顯示
- LCD_printc(dofly_DuanMa[6]);break;//6
- case 0x42:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints(" NOW: On");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Number: ");
- LCD_set_position(0xC8); //LCD換行顯示
- LCD_printc('0');
- LCD_set_position(0xC9); //LCD換行顯示
- LCD_printc(dofly_DuanMa[7]);break;//7
- case 0x52:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints(" NOW: On");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Number: ");
- LCD_set_position(0xC8); //LCD換行顯示
- LCD_printc('0');
- LCD_set_position(0xC9); //LCD換行顯示
- LCD_printc(dofly_DuanMa[8]);break;//8
- case 0x4A:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints(" NOW: On");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Number: ");
- LCD_set_position(0xC8); //LCD換行顯示
- LCD_printc('0');
- LCD_set_position(0xC9); //LCD換行顯示
- LCD_printc(dofly_DuanMa[9]);break;//9
- case 0x45:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("WuLian");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Class 152");
- break;//9
- case 0x46:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("NAME: TangFang");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("ID:220153297 ");
- break;//9
- case 0x47:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("NAME:CaiChaoyong");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("ID:220153273 ");
- break;//9
- case 0x44:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("teacher: zzy");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("class:DanPianJi ");
- break;//9
- case 0x40:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("key null");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("key null");
- break;//9
- case 0x43:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("key null 1");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("key null 1");
- break;//9
- case 0x07:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("key null -");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("key null -");
- break;//9
- case 0x15:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("key null +");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("key null +");
- break;//9
- case 0x09:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("key null EQ");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("key null EQ");
- break;//9
- case 0x16:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints(" NOW: On");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("Number: ");
- LCD_set_position(0xC8); //LCD換行顯示
- LCD_printc('0');
- LCD_set_position(0xC9); //LCD換行顯示
- LCD_printc(dofly_DuanMa[0]);break;//7
- case 0x19:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("usb sd");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("usb sd");
- break;//9
- case 0x0d:
- LCD_write_instruction(0x01);
- LCD_set_position(0x00);
- LCD_prints("back!!!");
- LCD_set_position(0x40); //LCD換行顯示
- LCD_prints("back!!!");
- break;//9
- default:break;
- }
-
- irpro_ok=0;//處理完成標志
-
- }
- void Ircordpro(void)//紅外碼值處理函數
- {
- unsigned char i, j, k;
- unsigned char cord,value;
-
- k=1;
- for(i=0;i<4;i++) //處理4個字節
- {
- for(j=1;j<=8;j++) //處理1個字節8位
- {
- cord=irdata[k];
- if(cord>7)//大于某值為1,這個和晶振有絕對關系,這里使用12M計算,此值可以有一定誤差
- value|=0x80;
- if(j<8)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
分工合作
唐*(220153297):1.仿真圖搭建
2.硬件材料選購
3.課設實驗報告的撰寫,硬件資料的查找及整理,課程設計資料的查找分析與整理
4、對搭建出來,和搭檔寫好的代碼進行通讀和理解,分析不足,共同改進不足
蔡*(220153273):1.流程圖的先驅
2.實物圖連接,代碼編寫
3.實物圖調試分析
4.錄制講解整個課設制作的流程
0.png (50.8 KB, 下載次數: 88)
下載附件
2018-6-11 05:12 上傳