注:
每個EXP實驗的文件夾下文件夾分別是P_ASM、P_EMULATOR_C,P_PROTEUS_C,P_EMULATOR_ASM。
P_PROTEUS_ASM 為PROTEUS匯編實例工程
P_PROTEUS_C 為PROTEUS C51仿真實例工程
P_EMULATOR_C 為硬件仿真器(可選配件)C51實例工程
P_EMULATOR_ASM 為硬件仿真器匯編實例工程
一般情況下P_PROTEUS_ASM,P_PROTEUS_C和P_EMULATOR_C和P_EMULATOR_ASM都支持ISP下載脫機運行
P_ISP_C,P_ISP_ASM為ISP下載脫機運行實例。比如看門狗實驗,仿真器不支持,因為復位信號被仿真器接管,所以就只能做硬件脫機實驗,通過ISP下載程序。
如果文件夾帶有(缺省)說明暫時沒有提供此程序,可根據需要再添加。
0.png (51.41 KB, 下載次數: 54)
下載附件
2017-5-5 16:42 上傳
匯編和c的代碼都有很全面.
c語言程序:
- /*************************************************
- *文件名稱: main.c
- *作 者:
- *版 本: V1.00
- *說 明: 紅外遙控器解碼實驗
- *修改記錄:
- --------------------------------------------------
- *Descriptoon:
- *接線說明:P32-紅外接收,P25-RS,P26-RW,P27-EN,
- P00~P07-DB0~DB7
- **************************************************/
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- //char code SST516[3] _at_ 0x003b;
- #define c(x)(x*110592/120000) //晶振11.0592
- uchar Lcd_Buf[4]; //顯示數據緩沖區
- unsigned char Ir_Buf[4]; //用于保存解碼結果
- sbit Ir_Pin=P3^2; //紅外線數據接口
- sbit rs=P2^0; //LCD數據命令端
- sbit rw=P2^1; //讀寫接口
- sbit lcde=P2^2; //使能接口
- uchar code table[]=" WWW#WINDWAY$CN ";//LCD顯示數據
- uchar code table1[]="Wait for IR in..";
- uchar code table2[]=" IR DATA...";
-
- unsigned char code Led_Tab[]={
- 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,
- 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共陽極數碼顯示碼0-F
- unsigned char code Led_Sel[]={0xf,0xf,0xb,0x7}; //數碼管位選,屏蔽前兩位
- unsigned char Led_Buf[4]; //顯示緩沖區
- char Led_Index; //定義位選
- unsigned char Ir_Buf[4]; //用于保存解碼結果
- sbit LCD_E = P2^7;
- //========1MS延時====================================
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=113;y>0;y--);
- }
- //======LCD寫命令=====
- void write_com(uchar com)
- {
- rs=0;
- lcde=0;
- P0=com;
- lcde=1;
- delay(1);//延時1MS跳過忙信號
- lcde=0;
- delay(1);
- }
- //======LCD寫數據=====================================
- void write_date(uchar date)
- {
- rs=1;
- lcde=0;
- P0=date;
- lcde=1;
- delay(1);
- lcde=0;
- delay(1);
- }
- //=====初始化函數=====================================
- void init()
- {
- uchar num;
- rw=0; //允許LCD寫
- lcde=0;
- write_com(0x38);//顯示模式設置
- write_com(0x0c);//顯示開及光標設置
- write_com(0x06);//顯示光標移動設置
- write_com(0x01);//清屏
- write_com(0x80);//顯示首地址
- for(num=0;num<15;num++)//顯示第一行
- {
- write_date(table[num]);
- delay(1);
- }
- write_com(0x80+0x40);//顯示第二行
- for(num=0;num<16;num++)
- {
- write_date(table1[num]);
- delay(1);
- }
- TMOD=0x10; //設置定時器0、1工作模式為1
- }
- //=====顯示解碼========================================
- void write_ir(uchar date)
- {
- uchar tmp, num,ff;
- if(ff==0)
- {
- ff++;
- write_com(0x01);
- write_com(0x80);
- for(num=0;num<12;num++)
- {
- write_date(table2[num]);
- delay(1);
- }
- }
-
- write_com(0xC0+6);//定位在第二行第六位
- tmp = date>>4; // 高四位
- write_date(tmp > 9 ? 'A'+tmp-10 : '0'+tmp);
- write_com(0xC0+7);//定位第二行第七位
- tmp = date&0x0F; // 低四位
- write_date(tmp > 9 ? 'A'+tmp-10 : '0'+tmp);
- }
- //======================================================
- //解碼取回低電平
- unsigned int Ir_Get_Low()
- {
- TL1=0;
- TH1=0;
- TR1=1;
- while(!Ir_Pin && (TH1&0x80)==0); //等待低電平到來
- TR1=0;
- return TH1*256+TL1;//提取低電平時間間隔時長
- }
- //======================================================
- //解碼取回高電平========================================
- unsigned int Ir_Get_High()
- {
- TL1=0;
- TH1=0;
- TR1=1;
- while(Ir_Pin && (TH1&0x80)==0);//等待高電平到來
- TR1=0;
- return TH1*256+TL1;//提取高電平時間間隔時長
- }
- //======================================================
- //======================================================
- void main()
- {
- unsigned int temp;
- char i,j;
- init(); //初始化
- //=====用do做循環,等待遙控按鍵=========================
- do{
- restart:
- while(Ir_Pin) ;//等待低電平
- temp=Ir_Get_Low();//把低電平附給變量
- if(temp<c(8500) || temp>c(9500)) continue;//引導脈沖低電平等待9000us
- temp=Ir_Get_High();//把高電平附給變量
- if(temp<c(4000) || temp>c(5000)) continue;//引導脈沖高電平等待4500us
- //連續讀出32個字節
- for(i=0;i<4;i++) //4個字節
- {
- for(j=0;j<8;j++) //每個字節8位
- {
- temp=Ir_Get_Low();
- if(temp<c(200) || temp>c(800)) goto restart;//等待560us跳過低電平
- temp=Ir_Get_High();
- if(temp<c(200) || temp>c(2000)) goto restart;//等待1000us跳過高電平
- Ir_Buf[i]>>=1;//把電平移進數組
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
匯編語言:
- ;-----------------------------------------------
- IRCOM EQU 20H ;20H-23H IR使用
- X EQU 26H ;LCD 地址變量
- IRIN EQU P3.2
- ; BEEP EQU P3.7
- ; RELAY EQU P1.0
-
- RS EQU P2.0
- RW EQU P2.1
- EN EQU P2.2
- ;------------------------------------------------
- ORG 0000H
- JMP MAIN
- ;------------------------------------------------
- ORG 0100H
- MAIN:
- MOV SP,#40H
- MOV A,#00H
- MOV R0,#20H
- LOOP0: MOV @R0,A ;20H-26H清零
- INC R0
- CJNE R0,#27H,LOOP0
- SETB IRIN
- CALL SET_LCD
- CALL MENU1
- LOOP1:
- CALL IR_IN
- CALL IR_SHOW
- ; MOV A,22H
- ; CJNE A,#40H,LOOP2 ;K17鍵按下
- ; CLR RELAY ;繼電器吸合
- ;LOOP2: CJNE A,#04H,LOOP3 ;K19鍵按下
- ; SETB RELAY ;繼電器關閉
- ;LOOP3:
- JMP LOOP1
-
- ;-----------------------------------------------------
- ; LCD 初始化設置
- ;-----------------------------------------------------
- SET_LCD:
- CLR EN
- CALL INIT_LCD ;初始化 LCD
- CALL DELAY1
- MOV DPTR,#INFO1 ;指針指到顯示信息1
- MOV A,#1 ;顯示在第一行
- CALL LCD_SHOW
- MOV DPTR,#INFO2 ;指針指到顯示信息2
- MOV A,#2 ;顯示在第二行
- CALL LCD_SHOW
- RET
- ;-----------------------------------------------------
- INIT_LCD: ;8位I/O控制 LCD 接口初始化
- MOV A,#38H ;雙列顯示,字形5*7點陣
- CALL WCOM
- CALL DELAY1
- MOV A,#38H ;雙列顯示,字形5*7點陣
- CALL WCOM
- CALL DELAY1
- MOV A,#38H ;雙列顯示,字形5*7點陣
- CALL WCOM
- CALL DELAY1
- MOV A,#0CH ;開顯示,關光標,
- CALL WCOM
- CALL DELAY1
- MOV A,#01H ;清除 LCD 顯示屏
- CALL WCOM
- CALL DELAY1
- RET
- ;----------------------------------------------------
- LCD_SHOW: ;在LCD的第一行或第二行顯示信息字符
- CJNE A,#1,LINE2 ;判斷是否為第一行
- LINE1: MOV A,#80H ;設置 LCD 的第一行地址
- CALL WCOM ;寫入命令
- CALL CLR_LINE ;清除該行字符數據
- MOV A,#80H ;設置 LCD 的第一行地址
- CALL WCOM ;寫入命令
- JMP FILL
- LINE2: MOV A,#0C0H ;設置 LCD 的第二行地址
- CALL WCOM ;寫入命令
- CALL CLR_LINE ;清除該行字符數據
- MOV A,#0C0H ;設置 LCD 的第二行地址
- CALL WCOM
- FILL: CLR A ;填入字符
- MOVC A,@A+DPTR ;由消息區取出字符
- CJNE A,#0,LC1 ;判斷是否為結束碼
- RET
- LC1: CALL WDATA ;寫入數據
- INC DPTR ;指針加1
- JMP FILL ;繼續填入字符
- RET
- ;---------------------------------------------------
- CLR_LINE: ;清除該行 LCD 的字符
- MOV R0,#24
- CL1: MOV A,#' '
- CALL WDATA
- DJNZ R0,CL1
- RET
- ;----------------------------------------------------
- MENU1: ;LCD 顯示工作菜單信息
- MOV DPTR,#MENU2
- MOV A,#1 ;在第一行顯示信息
- CALL LCD_SHOW
- RET
- MENU2: DB " REMOTE CONTROL ",0
- ;-----------------------------------------------------
- INFO1: DB " ",0 ;LCD 第一行顯示信息
- INFO2: DB " IR-CODE: --H ",0 ;LCD 第二行顯示信息
- ;-----------------------------------------------------
- ;-----------------------------------------------------
- ; 寫指令、數據使能子程序
- ;-----------------------------------------------------
- WCOM:
- MOV P0,A ;寫指令使能
- CLR RS ;RS=L,RW=L,D0-D7=指令碼,E=高脈沖
- CLR RW
- SETB EN
- CALL DELAY0
- CLR EN
- RET
-
- WDATA:
- MOV P0,A ;寫數據使能
- SETB RS ;RS=H,RW=L,D0-D7=數據,E=高脈沖
- CLR RW
- SETB EN
- CALL DELAY0
- CLR EN
- RET
- DELAY0: MOV R7,#250 ;延時500微秒
- DJNZ R7,$
- RET
- ;---------------------------------------------------
- ;在 LCD 第二行顯示字符
- ;A=ASC DATA, B=LINE X POS
- ;---------------------------------------------------
- LCDP2: ;在LCD的第二行顯示字符
- PUSH ACC ;
- MOV A,B ;設置顯示地址
- ADD A,#0C0H ;設置LCD的第二行地址
- CALL WCOM ;寫入命令
- POP ACC ;由堆棧取出A
- CALL WDATA ;寫入數據
- RET
- ;---------------------------------------------------
- ; IR 譯碼子程序
- ;---------------------------------------------------
- IR_IN:
- MOV R0,#IRCOM
- I1: JNB IRIN,I2 ;等待 IR 信號出現
- JMP I1
- I2: MOV R4,#20
- I20: CALL DEL
- DJNZ R4,I20
- JB IRIN,I1 ;確認IR信號出現
- I21: JB IRIN,I3 ;等 IR 變為高電平
- CALL DEL
- JMP I21
- I3: MOV R3,#0 ;8位數清為0
- LL: JNB IRIN,I4 ;等 IR 變為低電平
- CALL DEL
- JMP LL
- I4: JB IRIN,I5 ;等 IR 變為高電平
- CALL DEL
- JMP I4
- I5: MOV R2,#0 ;0.14ms 計數
- L1: CALL DEL
- JB IRIN, N1 ;等 IR 變為高電平
- ;IR=0,檢查R2中的計數值
- MOV A,#8
- CLR C
- SUBB A,R2 ;判斷高低位
- ;IF C=0 BIT=0
- MOV A,@R0
- RRC A
- MOV @R0,A ;處理完一位
- INC R3
- CJNE R3,#8,LL ;需處理完8位
- MOV R3,#0
- INC R0
- CJNE R0,#24H,LL ;收集到4字節了
- JMP OK
- N1: INC R2
- CJNE R2,#30,L1 ;0.14ms 計數過長則時間到自動離開
- OK: RET
- ;--------------------------------------------------------------------
- IR_SHOW:
- MOV A,22H
- CPL A ;將22H取反后和23H比較
- CJNE A,23H,IR_SHOW1 ;如果不等表示接收數據發生錯誤,放棄。
- CALL CONV
- ; CALL BEEP_BL ;蜂鳴器鳴響表示解碼成功
- IR_SHOW1: RET
- ;--------------------------------------------------------------------
- ;轉換為 ASCII 碼并顯示
- ;--------------------------------------------------------------------
- CONV:
- MOV X,#11 ;設置顯示起始位置
- MOV A,22H
- ANL A,#0F0H ;取出高四位二進制數
- SWAP A ;高四位與低四位互換
- PUSH ACC ;壓入堆棧
- CLR C ;C=0
- SUBB A,#0AH ;減10
- POP ACC ;彈出堆棧
- JC ASCII0 ;該數小于10,轉ASCII0
- ADD A,#07H ;大于10的數加上37H
- ASCII0: ADD A,#30H ;小于10的數加上30H
- MOV B,X
- CALL LCDP2
- MOV A,22H
- ANL A,#0FH ;取出低四位二進制數
- PUSH ACC
- CLR C
- SUBB A,#0AH ;減10
- POP ACC
- JC ASCII1 ;該數小于10,轉ASCII0
- ADD A,#07H ;大于10的數加上37H
- ASCII1: ADD A,#30H ;小于10的數加上30H
- INC X
- MOV B,X
- CALL LCDP2
- RET
- ;--------------------------------------------------------
- ;蜂鳴器響一聲子程序
- ;--------------------------------------------------------
- BEEP_BL:
- MOV R6,#100
- BL1: CALL DEX1
- ; CPL BEEP
- DJNZ R6,BL1
- MOV R5,#25
- CALL DELAY
- RET
- DEX1: MOV R7,#180
- DEX2: NOP
- DJNZ R7,DEX2
- RET
- DELAY: ;延時R5×10MS
- MOV R6,#50
- D1: MOV R7,#100
- DJNZ R7,$
- DJNZ R6,D1
- DJNZ R5,DELAY
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
下載:
EXP19_紅外遙控器解碼實驗.zip
(70.27 KB, 下載次數: 54)
2017-5-5 11:15 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|