|
Tài trợ cho PIC Vietnam |
MPASM Lập trình bằng hợp ngữ là một việc làm vô cùng vất vả, tuy nhiên, để hiểu và làm việc với vi điều khiển, hợp ngữ trở thành một công cụ khá đắc lực ... |
|
Ðiều Chỉnh | Xếp Bài |
11-04-2013, 12:30 PM | #1 |
Đệ tử 1 túi
Tham gia ngày: Sep 2007
Bài gửi: 11
: |
16F887 giao tiếp với 18B20 (one_wire)
Chạy mô phỏng với Protues, kết quả nhận được toàn là FFH (Low) FFH (high).
Không biết sai chổ nào, các giúp đở . Pic 16F887, thạch anh 4MHz. như vậy mỗi chu kỳ lệnh = 1us. Khả năng sai là ở WRITE_TIME_SLOT và READ_TIME_SLOT; thay đổi tới lui cũng không được. Nhờ giúp đở. ;============================== Code Main: MAIN call RESET_18B20 movlw 0CCH movwf TEMP call WRITE_18B20 ;SKIP ROM command movlw 44H movwf TEMP call WRITE_18B20 ;temperature convert command ;==== call delay_750ms ;==== call RESET_18B20 movlw 0CCH movwf TEMP call WRITE_18B20 ;SKIP ROM command movlw 0BEH movwf TEMP call WRITE_18B20 ;READ temperature command call READ_18B20 ;READ temperature low byte movfw TEMP movwf PORTC movwf TEMP1 ;keep in TEMP1 call READ_18B20 ;READ temperature high byte movfw TEMP movwf PORTD movwf TEMP2 ;keep in TEMP2 goto MAIN ;========== RESET_18B20 banksel TRISB bcf Tris_DQ banksel PORTB bcf DQ movlw 0A4H ;500us movwf COUNT decfsz COUNT,1 goto $-1 banksel TRISB bsf Tris_DQ banksel PORTB movlw 0F4H movwf COUNT loop_reset_18B20 btfss DQ goto OK_RESET_18B20 decfsz COUNT,1 goto loop_reset_18B20 ;otherwise continue reset bsf DQ nop nop goto RESET_18B20 OK_RESET_18B20 btfss DQ goto $-1 banksel TRISA bcf Tris_DQ banksel PORTB bsf DQ return ;=========== WRITE_18B20 movlw 08H movwf COUNT1 WRITE_18B20_1 rrf TEMP,1 call WRITE_TIME_SLOT decfsz COUNT1,1 ;if finish 8 bit data goto WRITE_18B20_1 movlw 23H ;106us movwf COUNT decfsz COUNT,1 goto $-1 return ;============= WRITE_TIME_SLOT ;viet 1 bit bcf DQ nop nop bsf DQ ;3us movlw 04H ;17us movwf COUNT decfsz COUNT,1 goto $-1 btfss STATUS,C ;judge the write data is 0 or 1 goto WRITE_END bsf DQ WRITE_END movlw 13H ;58us movwf COUNT decfsz COUNT,1 goto $-1 bsf DQ nop return ;================ READ_18B20 movlw 08H movwf COUNT1 READ_18B20_1 call READ_TIME_SLOT decfsz COUNT1,1 ;if finish reading 8 bit goto READ_18B20_1 movlw 1FH movwf COUNT decfsz COUNT,1 goto $-1 return ;================== READ_TIME_SLOT bcf DQ nop nop bsf DQ ;3us banksel TRISA bsf Tris_DQ banksel PORTA movlw 04H ;16us movwf COUNT ; decfsz COUNT,1 goto $-1 bsf STATUS,C btfss DQ bcf STATUS,C rrf TEMP,1 movlw 11H movwf COUNT ; decfsz COUNT,1 goto $-1 ;pull low 56us banksel TRISA bcf DQ banksel PORTA bsf DQ nop nop return ;================== delay_750ms movlw 04H movwf DQ_DELAY3 DELAY_750MS_3 movlw 0FFH movwf DQ_DELAY2 DELAY_750MS_2 movlw 0FFH movwf DQ_DELAY1 DELAY_750MS_1 decfsz DQ_DELAY1,1 goto DELAY_750MS_1 decfsz DQ_DELAY2,1 goto DELAY_750MS_2 decfsz DQ_DELAY3,1 goto DELAY_750MS_3 return ;============= thay đổi nội dung bởi: duc thang, 11-04-2013 lúc 04:00 PM. |
12-04-2013, 10:48 AM | #2 | |
Đệ tử 7 túi
Tham gia ngày: May 2005
Bài gửi: 258
: |
Trích:
__________________
viết chương trình cho vdk chạy ổn định là cả một vấn đề. |
|
12-04-2013, 06:58 PM | #3 |
Đệ tử 1 túi
Tham gia ngày: Sep 2007
Bài gửi: 11
: |
Cám ơn bạn gửi đường link, nhưng không down được.
Bạm xem lại giùm. |
13-04-2013, 11:51 AM | #4 |
Đệ tử 7 túi
Tham gia ngày: May 2005
Bài gửi: 258
: |
vẫn down bình thường.
Code:
;************************************************* ********************** LIST P = 16F877A; definitions used in this program for the PIC16F877A chip #include "P16F877A.INC"; the definition of this program contains the file __CONFIG 3F72H; crystal configuration HS, watchdog banned, power-on delay enabled, the brown-out reset enable ; Low-voltage programming prohibited, the code does not protect #define DQ PORTC, 7 #define DIR TRISC,7 E EQU H'0005' RW EQU H'0004' SR EQU H'0006' XUAT_LCD EQU PORTB XUAT_DIEU_KHIEN EQU PORTD CBLOCK 20H Y1 Y2 COUNT1 COUNT2 COMD DATE BIN_L; to convert the byte GE; converted bits SHI; converted 10 DATE_L DATE_H NUM1 NUM2 NUM3 DATA1 TAM_H TAM_L TAM10 TAM_11 CHUA_DAU LUU_GIA_TRI_CU_H LUU_GIA_TRI_CU_L CHO_HIEN_THI TAM_BANG HET_BANG LUU TAM ENDC ;************************************************* ********************** ; Reset vector definition (for the 16F877A) ;************************************************* ********************** ORG 0000H; reset vector address GOTO MAIN; program jump to the main program MAIN ;------------------------------------------------- --------------------- TRA_BANG ADDWF PCL ,1 DT" NHIET DO PHONG ",0x00 ;************************************************* ********************** ; The main program areas ;************************************************* ********************** MAIN NOP ;CALL INTIAL BSF STATUS, RP0; the definition of the current body is the body 1, in the right direction to modify register MOVLW 06H MOVWF ADCON1; off A mouth of the analog channel MOVLW 00H MOVWF TRISB; Segment display port as an output port MOVWF TRISD; Segment display port as an output port MOVWF TRISE; Segment display port as an output port BSF DIR; make the data line is input BCF STATUS, RP0; so that the current body is the body 0 ;MOVLW 00H; close Segment ;MOVWF PORTC MOVLW 00H; closed-bit code MOVWF PORTD BCF XUAT_DIEU_KHIEN,E BCF XUAT_DIEU_KHIEN,RW BCF XUAT_DIEU_KHIEN,SR CLRF LUU_GIA_TRI_CU_H CLRF LUU_GIA_TRI_CU_L CALL CAI_DAT_LCD START BTFSS DQ; data line idle state is high GOTO $ -1 CALL RESET; reset DS18B20 MOVLW 0CCH; skip read ROM command CALL WR18B20 MOVLW 44H; Temperature Conversion CALL WR18B20 CALL DELAY_750US; delay 750us CALL RESET; reset DS18B20 MOVLW 0CCH; skip read ROM command CALL WR18B20 MOVLW 0BEH; reading the 9 bytes of internal RAM contents CALL WR18B20 NOP CALL RE18B20; reading data CALL NHIET_DO_CO_THAY_DOI_KHONG MOVLW 0xFF SUBWF CHO_HIEN_THI,0 BTFSC STATUS,Z GOTO KHONG_THAY_DOI_HIEN_THI CALL gia_tri_am_hay_duong CALL BIN_BCD CALL HIEN_THI_LCD KHONG_THAY_DOI_HIEN_THI CALL DELAY CALL DELAY CALL DELAY CALL DELAY ;------------------------ Display processing ----------------------- --------------- GOTO START ;************************************************* ********************** ; Initialization and consumer video ;************************************************* ********************** INTIAL BSF STATUS, RP0; the definition of the current body is the body 1, in the right direction to modify register MOVLW 06H MOVWF ADCON1; off A mouth of the analog channel MOVLW 00H MOVWF TRISB; Segment display port as an output port MOVWF TRISD; Segment display port as an output port MOVWF TRISE; Segment display port as an output port BSF DIR; make the data line is input BCF STATUS, RP0; so that the current body is the body 0 ;MOVLW 00H; close Segment ;MOVWF PORTC MOVLW 00H; closed-bit code MOVWF PORTD BTFSS DQ; data line idle state is high GOTO $ -1 CALL RESET; reset DS18B20 MOVLW 0CCH; skip read ROM command CALL WR18B20 MOVLW 44H; Temperature Conversion CALL WR18B20 CALL DELAY_750US; delay 750us CALL RESET; reset DS18B20 MOVLW 0CCH; skip read ROM command CALL WR18B20 MOVLW 0BEH; reading the 9 bytes of internal RAM contents CALL WR18B20 NOP NOP CALL RE18B20; reading data CALL DELAY_MAX; delay 600ms CALL DELAY_MAX CALL DELAY_MAX RETLW 00H ;================================================= ====================== ;************************************************* ********************** ; Delay 200ms ;************************************************* ********************** DELAY_MAX MOVLW 0FFH MOVWF Y1 MOVLW 0FFH MOVWF Y2 DECFSZ Y2 GOTO $ -1 DECFSZ Y1 GOTO $ -5 RETLW 00H ;************************************************* ********************** ; Delay 6ms ;************************************************* ********************** DELAY MOVLW 03FH MOVWF Y1 MOVLW 020H MOVWF Y2 DECFSZ Y2 GOTO $ -1 DECFSZ Y1 GOTO $ -5 RETLW 00H ;************************************************* ********************** ; Delay 750us subroutine ;************************************************* ********************** DELAY_750US MOVLW 09H MOVWF Y1 MOVLW 01AH MOVWF Y2 DECFSZ Y2 GOTO $ -1 DECFSZ Y1 GOTO $ -5 RETLW 00H ;************************************************* ********************** ; DS18B20 reset and respond to routine ;************************************************* ********************** RESET BSF STATUS, RP0; so that the current body is the body a BCF DIR; so that the output data bit BCF STATUS, RP0; so that the current body is the body 0 BSF DQ; pulled data bits NOP; air circulation BCF DQ; pull down data bits MOVLW .200 ; delay 600us MOVWF Y1 DECFSZ Y1 GOTO $ -1 BSF STATUS, RP0; so that the current body is the body a BSF DIR; make the data bits as input BCF STATUS, RP0; so that the current body is the body 0 MOVLW .30; Delay 90us MOVWF Y1 DECFSZ Y1 GOTO $ -1 BTFSC DQ; the host receives a low pulse, jump to the next one GOTO RESET MOVLW .80; delay 240us MOVWF Y1 DECFSZ Y1 GOTO $ -1 BTFSS DQ; the host receives a high pulse, jump to the next one GOTO RESET RETLW 00H; return to 00H, the end of reset response ;************************************************* ********************** ; Write DS18B20 subroutine ;************************************************* ********************** WR18B20 MOVWF COMD; to write the data in write COMD MOVLW .8 MOVWF COUNT2; large circle 8 times WR0 BSF STATUS, RP0; so that the current body is the body a BCF DIR; so that the output data bit BCF STATUS, RP0; so that the current body is the body 0 BCF DQ; pull down the data line NOP NOP MOVLW .2 MOVWF COUNT1; delay 9us WR1 DECFSZ COUNT1, 1 GOTO WR1 BTFSC COMD, 0; COMD the lowest level of 0 Jump to the next one BSF DQ; pulled the data cable BTFSC COMD, 0; COMD the lowest level of 0 Jump to the next one NOP BCF STATUS, C; into the bit position 0 RRF COMD, 1; into the bit-bit, COMD to the right one MOVLW .20; Delay 60us MOVWF COUNT1 WR2 DECFSZ COUNT1, 1 GOTO WR2 BSF DQ; pulled the data cable, idle state BSF STATUS, RP0; so that the current body is the body a BSF DIR; make the data bits as input BCF STATUS, RP0; so that the current body is the body 0 DECFSZ COUNT2, 1; 8 cycles then jump out to a GOTO WR0 RETLW 00H ;************************************************* ********************** ; Read 18B20 subroutine ;************************************************* ********************** RE18B20 CLRF DATE_H CLRF DATE_L MOVLW .16 MOVWF COUNT2 RE0 BSF STATUS, RP0; so that the current body is the body a BCF DIR; so that the output data bit BCF STATUS, RP0; so that the current body is the body 0 BCF DQ MOVLW .2 MOVWF COUNT1 RE1 DECFSZ COUNT1, 1 GOTO RE1 BSF STATUS, RP0; so that the current body is the body a BSF DIR; make the data bits as input BCF STATUS, RP0; so that the current body is the body 0 NOP BTFSS DQ; if the data line is high, then C = 1 BCF STATUS, C BTFSC DQ; if the data line is low, then C = 0 BSF STATUS, C RRF DATE_H, 1; These data on the existence DATE RRF DATE_L, 1 MOVLW .20 ; Delay 60us MOVWF COUNT1 RE2 DECFSZ COUNT1, 1 GOTO RE2 DECFSZ COUNT2, 1 GOTO RE0 BSF DQ RETLW 00H ;))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) NHIET_DO_CO_THAY_DOI_KHONG MOVF DATE_L,0 SUBWF LUU_GIA_TRI_CU_L,0 BTFSS STATUS,Z GOTO CO_THAY_DOI GOTO KHONG_THAY_DOI CO_THAY_DOI MOVF DATE_L,0 MOVWF LUU_GIA_TRI_CU_L CLRF CHO_HIEN_THI GOTO THOAT KHONG_THAY_DOI MOVLW 0xFF MOVWF CHO_HIEN_THI THOAT RETURN ;""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""' gia_tri_am_hay_duong MOVF DATE_H,0 MOVWF TAM_H SWAPF TAM_H,1 MOVLW B'01110000' ANDWF TAM_H,1 MOVF DATE_L,0 MOVWF TAM_L SWAPF TAM_L,1 MOVLW B'00001111' ANDWF TAM_L,0 IORWF TAM_H,1 XAC_DINH_GIA_TRI_AM_HAY_DUONG BTFSS DATE_H,7 GOTO GIA_TRI_DUONG BTFSS DATE_H,6 GOTO GIA_TRI_DUONG BTFSS DATE_H,5 GOTO GIA_TRI_DUONG BTFSS DATE_H,4 GOTO GIA_TRI_DUONG BTFSS DATE_H,3 GOTO GIA_TRI_DUONG GIA_TRI_AM COMF TAM_H,1 BCF TAM_H,7 INCF TAM_H,1 MOVLW '-' MOVWF CHUA_DAU MOVF TAM_H,0 MOVWF DATA1 GOTO HET GIA_TRI_DUONG MOVF TAM_H,0 MOVWF DATA1 MOVLW ' ' MOVWF CHUA_DAU HET RETURN ;================================================= ============= BIN_BCD clrf NUM2 ; Clear register of 10's unit Check movlw 0x0A ; Subtract with 10 until the result lower 10 subwf DATA1,w ; Fisrt subtraction < 10 ? btfss STATUS,C goto Less1 ; If < 10 then return incf NUM2,f ; If > 10 then increase 10's unit movlw 0x0A ; Subtract with 10 subwf DATA1,f ; Test Again. Is it lower 10 ? goto Check Less1 movf DATA1,w ; If < 10, send data to 1's unit movwf NUM1 ; clrf NUM3 ; Clear 100's unit Check2 movlw 0x0A subwf NUM2,w ; 10's unit > 10 ? btfss STATUS,C return ; If < 10 then return incf NUM3,f movlw 0x0A ; If > 10 then subtraction again subwf NUM2,f ; and check until the result is lower 10 goto Check2 RETURN XUAT_DU_LIEU MOVWF XUAT_LCD CALL LENH RETLW .0 ;*****LENH******* LENH BSF PORTD,E CALL DL BCF PORTD,E RETURN ;**CAI_DAT_LCD*** CAI_DAT_LCD MOVLW 0x01;XOA MAN HINH MOVWF XUAT_LCD CALL LENH ;*************** MOVLW 0x38;8BIT,2 DONG,5*7 DOT MOVWF XUAT_LCD CALL LENH ;*************** MOVLW 0x0C MOVWF XUAT_LCD CALL LENH ;**************** MOVLW 0x06;TANG CON TRO MOVWF XUAT_LCD CALL LENH ;CHO HIEN THI DONG_1 BSF XUAT_DIEU_KHIEN,SR MOVLW .0 MOVWF LUU BSF XUAT_DIEU_KHIEN,SR;SR=1 HIEU LA DU LIEU TIEP MOVF LUU,0 CALL TRA_BANG MOVWF TAM;DU LIEU SAU KHI TRA BANG LUU TAI DAY CLRW ;XOA W SUBWF TAM ,0 BTFSS STATUS,Z;NEU DU LIEU SAU KHI TRA BANG =0 THI KET THUC BANG TRA GOTO TRA_TIEP RETURN TRA_TIEP MOVF TAM,0;DUA DU LIEU RA LCD CALL XUAT_DU_LIEU INCF LUU,1 GOTO TIEP RETURN ;*****DL******* DL MOVLW .4 MOVWF TAM_11 LOPP MOVLW .250 MOVWF TAM10 LOP DECFSZ TAM10,1 GOTO LOP DECFSZ TAM_11,1 GOTO LOPP RETURN HIEN_THI_LCD BCF XUAT_DIEU_KHIEN,SR MOVLW B'11000100';DONG 2 MOVWF XUAT_LCD CALL LENH BSF XUAT_DIEU_KHIEN,SR MOVF CHUA_DAU,0 CALL XUAT_DU_LIEU MOVLW .0 SUBWF NUM3,0 BTFSC STATUS,Z GOTO HANG_CHUC MOVF NUM3,0 ADDLW 0x30 CALL XUAT_DU_LIEU GOTO HIEN_THI_HANG_CHUC HANG_CHUC MOVLW .0 SUBWF NUM2,0 BTFSC STATUS,Z GOTO HANG_DVI HIEN_THI_HANG_CHUC MOVF NUM2,0 ADDLW 0x30 CALL XUAT_DU_LIEU HANG_DVI MOVF NUM1,0 ADDLW 0x30 CALL XUAT_DU_LIEU MOVLW '.' CALL XUAT_DU_LIEU MOVLW 'O' CALL XUAT_DU_LIEU MOVLW 'C' CALL XUAT_DU_LIEU RETURN END; end of the process
__________________
viết chương trình cho vdk chạy ổn định là cả một vấn đề. |
Ðiều Chỉnh | |
Xếp Bài | |
|
|