; 26 сетября 2005 г. Р зр бот л Ильиых Адрей smana [at] udm.ru 2005г. ; ПРОГРАММА, т хоетр для к рбюр торого двиг теля с БСЗ ; отсчитыв ет врея з 50 ипульсов с д тчик Холл , з те пересчитыв ет в об/и ; по форуле (50x1000000x60)/(125xT50x2) или 12000000/T50, ; где 50 - количество отсчитыв еых ипульсов, че больше те выше точость ; 1000000x60 - кол-во ксек в 1 и. ; 125 - врея переполеия TMR0, в ксек ; T50 - кол-во переполеий TMR0 ; 2 - делитель, т к к к з 1 оборот колев л происходит 2 ипульс с д тчик Холл (т.е.2 лог уля) ; результ т выводится дисплей по 4-битой шие ; точость т хоетр : при 3000 об/и +-0,75 об/и при 1000 +-0,1 об/и теоретически :-) ; е использует прерыв ия ; еще прикруче т йер ; кв рц = 4,096 МГц ; ЖКИ ИНДИКАТОР 2х16 МТ-16SD-2YLG ; ч сть подпрогр взят из иет LIST P=16F84a #include __config _CP_OFF&_WDT_OFF&_PWRTE_ON&_XT_OSC ; Подключеие к ЖКИ ; RВ4...R7 - д ые ; RВ1 - Е ; RВ2 - R/W ; RВ3 - RS ; Опис ие используеых перееых koeff equ D'195' E EQU 1 ; LCD Enable control line R_W EQU 2 ; LCD Read/Write control line RS EQU 3 ; LCD Register Select control line LCD_DATA EQU PORTB LCD_CNTL EQU PORTB LCD_DATA_TRIS EQU PORTB rab2 equ 0x0C rab3 equ 0x0D Char equ 0x0E temp equ 0x0F ms5 equ 0x10 ms200 equ 0x11 LSD equ 0x15 MSD equ 0x16 ; перееые для преобр зов 24 бит числ в двоичо десятичое nratorH equ 0x17 nratorM equ 0x18 nratorL equ 0x19 R0 equ 0x1A R1 equ 0x1B R2 equ 0x1C R3 equ 0x1D COUNT equ 0x1E TEMP equ 0x1F ; перееые связ с подпрогр ой делеия ;nratorH equ 0x17 ;nratorM equ 0x18 ;nratorL equ 0x19 denomH equ 0x20 denomM equ 0x21 denomL equ 0x22 remainH equ 0x23 remainM equ 0x24 remainL equ 0x25 BCount equ 0x26 shiftH equ 0x27 shiftM equ 0x28 shiftL equ 0x29 ; перееые связ со счето ипульсов с д тчик stat equ 0x2A count_impuls equ 0x2B ; перееые т йер mksek_5000 equ 0x2C msek_1000 equ 0x2D sek equ 0x12 min equ 0x13 hours equ 0x14 ;*** Н ч ло прогр ы *** org 0x00 goto START START clrf PORTA ; очищ е портА clrf PORTB ; очищ е портB clrf ms5 clrf ms200 clrf sek clrf min clrf hours clrf mksek_5000 clrf msek_1000 clrf stat clrf count_impuls bsf STATUS, RP0 ; переходи стр ицу 1 movlw b'00000001' ; первый регистр порт A определяе к к вход ост льые к к выход movwf PORTA movlw b'00000000' ; все регистры порт B определяе к к выход movwf PORTB bsf STATUS, RP0 movlw b'10000000' ; 1:2 increment evry 1,953125 mksek, for modulе 64 overload 125 mksek movwf OPTION_REG bcf STATUS, RP0 ; переходи стр ицу 0 movlw b'00000000' ; з прещ е все прерыв ия movwf INTCON call LCD_Init call init_text_lcd ;*************************************************************************************************** beg movlw koeff movwf TMR0 w_d check_ms nop btfss INTCON,T0IF goto check_ms movlw koeff movwf TMR0 bcf INTCON,T0IF call timer incf ms5,f movf ms5,W xorlw D'2' btfss STATUS,Z goto prov clrf ms5 incf ms200,f movf ms200,W xorlw D'200' btfss STATUS,Z goto prov clrf ms200 call update_lcd_tah0 prov btfsc PORTA,0 goto w_d1 goto w_d w_d1 btfsc PORTA,0 goto w_d1 count_time movlw koeff movwf TMR0 clrf ms5 clrf ms200 ;************** Теперь счит е 50 ипульсов и врея *********************************************** MAIN check_1ms nop btfss INTCON,T0IF goto check_1ms movlw koeff movwf TMR0 bcf INTCON,T0IF call timer incf ms5,f movf ms5,W xorlw D'100' btfss STATUS,Z goto prov1 clrf ms5 incf ms200,f movf ms200,W xorlw D'200' btfss STATUS,Z goto prov1 clrf ms200 call update_lcd_tah0 goto beg prov1 incf denomL,f btfss STATUS,Z goto count_tahom incf denomM,f btfss STATUS,Z goto count_tahom incf denomH,f btfss STATUS,Z goto count_tahom clrf denomL clrf denomM clrf denomH count_tahom btfss stat,1 goto count_tahom1 btfsc PORTA,0 goto MAIN clrf stat incf count_impuls,f movf count_impuls,W xorlw D'50' btfss STATUS,Z goto MAIN clrf count_impuls call update_lcd_tah call update_lcd_timer clrf denomL clrf denomM clrf denomH goto beg count_tahom1 btfsc PORTA,0 bsf stat,1 goto MAIN ;************** когд ет оборотов выводи ули ЖКИ ******************************************** update_lcd_tah0 movlw H'8B' call send_cmd clrw call convert call send_char clrw call convert call send_char clrw call convert call send_char clrw call convert call send_char return ;*************************************************************************************************** BinBCD clrf MSD movwf LSD gtenth movlw .10 subwf LSD,W btfss STATUS,C goto over movwf LSD incf MSD,f goto gtenth over retlw 0 ;*************************************************************************************************** convert addwf PCL,f retlw H'30' ; 0 retlw H'31' ; 1 retlw H'32' ; 2 retlw H'33' ; 3 retlw H'34' ; 4 retlw H'35' ; 5 retlw H'36' ; 6 retlw H'37' ; 7 retlw H'38' ; 8 retlw H'39' ; 9 ;********** Подпрогр иици лиз ции ЖКИ и уст овк п р етров ********************************* LCD_Init call delay20 ; з держк 20 сек, рекоедов о з водо bcf LCD_CNTL, E ; з прещ е з пись в жки bcf LCD_CNTL, RS ; выбир е перед чу ко д bcf LCD_CNTL, R_W ; выбор режи з писи movlw 0x0f ; скируе л дший полуб йт и andwf LCD_DATA,F ; очищ е ст рший полуб йт (лог уожеие ежду W и LCD_DATA) movlw H'30' ; b'0010 1010' б йт упр влеия по 4-битоу итерфейсу iorwf LCD_DATA,F ; дел е лог сложеие и результ т выоди жки bsf LCD_CNTL, E ; р зреш е з пись в жки bcf LCD_CNTL, E ; з прещ е з пись в жки call delay5 ; з держк 5 сек, з вод требует 40 ксек bsf LCD_CNTL, E ; р зреш е з пись в жки bcf LCD_CNTL, E ; з прещ е з пись в жки call delay5 ; з держк 5 сек, з вод требует 40 ксек bsf LCD_CNTL, E ; р зреш е з пись в жки bcf LCD_CNTL, E ; з прещ е з пись в жки call delay5 ; з держк 5 сек, з вод требует 40 ксек movlw H'28' ; 4 битый режи call send_cmd movlw b'00001100' ; h'0C' включеие дисплея, выключеие курсор call send_cmd movlw H'01' ; очищ ет дисплей и поещ ет курсор в с ую левую позицию call send_cmd return ;********** Подпрогр ы з держек ****************************************************************** delay100 call delay20 ; з держк 100 с delay80 call delay20 ; з держк 80 с delay60 call delay20 ; з держк 60 с delay40 call delay20 ; з держк 40 с delay20 call delay5 ; з держк 20 с delay15 call delay5 ; з держк 15 с delay10 call delay5 ; з держк 10 с delay5 movlw d'5' ; з держк 5 с movwf rab2 ; delay1 movlw D'249' ; з держк 1 c movwf rab3 d1m nop decfsz rab3,f ; 4 x 250 = 1 ms goto d1m decfsz rab2,f goto delay1 return ;*************************************************************************************************** d100mks movlw .25 movwf rab3 dll nop ; 4 x 25 = 100 mkc decfsz rab3,f goto dll return ;******************************************************************* ;* Send_Cmd - Sends command to LCD * ;* This routine splits the command into the upper and lower * ;* nibbles and sends them to the LCD, upper nibble first. * ;******************************************************************* send_cmd movwf Char ; Character to be sent is in W call Wait_Busy ; Wait for LCD to be ready movlw 0x0f andwf LCD_DATA,F ; Clear the upper nibble movf Char,w andlw 0xF0 ; Get upper nibble iorwf LCD_DATA,F ; Send data to LCD bcf LCD_CNTL,R_W ; Set LCD to write bcf LCD_CNTL,RS ; Set LCD to command mode bsf LCD_CNTL,E ; toggle E for LCD bcf LCD_CNTL,E movlw 0x0f andwf LCD_DATA,F ; Clear the upper nibble swapf Char,W andlw 0xF0 ; Get lower nibble iorwf LCD_DATA,F ; Send data to LCD bsf LCD_CNTL,E ; toggle E for LCD bcf LCD_CNTL,E return ;************************************************************************************************** ;******************************************************************* ;*SendChar - Sends character to LCD * ;*This routine splits the character into the upper and lower * ;*nibbles and sends them to the LCD, upper nibble first. * ;******************************************************************* send_char movwf Char ; Character to be sent is in W call Wait_Busy ; Wait for LCD to be ready movlw 0x0f andwf LCD_DATA,F ; Clear the upper nibble movf Char,w andlw 0xF0 ; Get upper nibble iorwf LCD_DATA,F ; Send data to LCD bcf LCD_CNTL, R_W ; Set LCD to write bsf LCD_CNTL, RS ; Set LCD to data mode bsf LCD_CNTL, E ; toggle E for LCD bcf LCD_CNTL, E movlw 0x0f andwf LCD_DATA,F ; Clear the upper nibble swapf Char,W andlw 0xF0 ; Get lower nibble iorwf LCD_DATA,F ; Send data to LCD bsf LCD_CNTL, E ; toggle E for LCD bcf LCD_CNTL, E return ;*************************************************************************************************** Wait_Busy bsf STATUS, RP0 ; Select Register page 1 movlw 0xf0 ; Set port to input iorwf LCD_DATA_TRIS,W ; Only set upper half of port movwf LCD_DATA_TRIS bcf STATUS, RP0 ; Select Register page 0 bcf LCD_CNTL, RS ; Set LCD for Command mode bsf LCD_CNTL, R_W ; Setup to read busy flag bsf LCD_CNTL, E ; Set E high movf LCD_DATA, W ; Read upper nibble busy flag, DDRam address bcf LCD_CNTL, E ; Set E low andlw 0xF0 ; Mask out lower nibble movwf temp bsf LCD_CNTL, E ; Toggle E to get lower nibble swapf LCD_DATA, w ; Read lower nibble busy flag, DDRam address bcf LCD_CNTL, E andlw 0x0F ; Mask out upper nibble iorwf temp,f ; Combine nibbles, RES in Temp !!!!!!!!!!!!!!! btfsc temp, 7 ; Check busy flag, high = busy goto Wait_Busy ; If busy, check again bcf LCD_CNTL, R_W bsf STATUS, RP0 ; Select Register page 1 movlw 0x0F andwf LCD_DATA_TRIS,W movwf LCD_DATA_TRIS ; Set Port for output bcf STATUS, RP0 ; Select Register page 0 return ;******* CONVERT 24 BIT BIN TO PACKED BCD ********************************************************* B2_BCD BCF STATUS,C MOVLW 0x18 MOVWF COUNT CLRF R0 CLRF R1 CLRF R2 CLRF R3 LOOP16 RLF nratorL,F RLF nratorM,F RLF nratorH,F RLF R0,F RLF R1,F RLF R2,F RLF R3,F DECFSZ COUNT,1 GOTO ADJDEC RETLW 0 ADJDEC MOVLW R3 MOVWF FSR CALL ADJBCD MOVLW R2 MOVWF FSR CALL ADJBCD MOVLW R1 MOVWF FSR CALL ADJBCD MOVLW R0 MOVWF FSR CALL ADJBCD GOTO LOOP16 ADJBCD MOVLW 0x03 ADDWF 0,W MOVWF TEMP BTFSC TEMP,3 MOVWF 0 MOVLW 0x30 ADDWF 0,W MOVWF TEMP BTFSC TEMP,7 MOVWF 0 RETLW 0 ;************************************************************************************************* init_text_lcd movlw H'81' call send_cmd movlw H'EE' ; о call send_char movlw H'E1' ; б call send_char movlw H'2F' ; / call send_char movlw H'EC' ; call send_char movlw H'E8' ; и call send_char movlw H'ED' ; call send_char movlw H'C1' call send_cmd movlw H'D2' ; Т call send_char movlw H'E0' ; call send_char movlw H'E9' ; й call send_char movlw H'EC' ; call send_char movlw H'E5' ; е call send_char movlw H'F0' ; р call send_char movlw H'20' ; _ call send_char return ;************************************************************************************************* update_lcd_timer movlw H'CA' call send_cmd movf hours,W call BinBCD movf MSD,W call convert call send_char movf LSD,W call convert call send_char movlw H'3A' call send_char movf min,W call BinBCD movf MSD,W call convert call send_char movf LSD,W call convert call send_char return ;************************************************************************************************* ; SUBROUTINE - 24 BIT DIVISION ; numerator: nratorH nratorM nratorL ; denominator: denomH denomM denomL ; ; result: nratorH nratorM nratorL ; remainder: remainH remainM remainL ; divizn movlw D'24' movwf BCount movf nratorH,w movwf shiftH movf nratorM,w movwf shiftM movf nratorL,w movwf shiftL clrf nratorH clrf nratorM clrf nratorL clrf remainH clrf remainM clrf remainL dloop bcf STATUS,C rlf shiftL,f rlf shiftM,f rlf shiftH,f rlf remainL,f rlf remainM,f rlf remainH,f movf denomH,w subwf remainH,w btfss STATUS,Z goto nochk ; movf denomM,w subwf remainM,w btfss STATUS,Z goto nochk ; movf denomL,w subwf remainL,w nochk btfss STATUS,C goto nogo ; movf denomL,w subwf remainL,f btfss STATUS,C decf remainM,f movf remainM,w xorlw 0xff btfsc STATUS,Z decf remainH,f movf denomM,w subwf remainM,f btfss STATUS,C decf remainH,f movf denomH,w subwf remainH,f bsf STATUS,C nogo rlf nratorL,f rlf nratorM,f rlf nratorH,f decfsz BCount,f goto dloop return ;*************************************************************************************************** update_lcd_tah movlw H'B7' movwf nratorH movlw H'1B' movwf nratorM movlw H'00' movwf nratorL call divizn call B2_BCD movlw H'8B' call send_cmd ;swapf R3,W ;andlw 0x0F ;call convert ;call send_char ;movf R3,W ;andlw 0x0F ;call convert ;call send_char ;swapf R2,W ;andlw 0x0F ;call convert ;call send_char ;movf R2,W ;andlw 0x0F ;call convert ;call send_char swapf R1,W andlw 0x0F btfss STATUS,Z goto write_3reg_tah movlw 0x20 call send_char goto write_2reg_tah write_3reg_tah swapf R1,W andlw 0x0F call convert call send_char write_2reg_tah movf R1,W andlw 0x0F call convert call send_char swapf R0,W andlw 0x0F call convert call send_char movf R0,W andlw 0x0F call convert call send_char retlw 0 ;*************************************************************************************************** timer incf mksek_5000,f movf mksek_5000,W xorlw D'40' btfss STATUS,Z return clrf mksek_5000 incf msek_1000,f movf msek_1000,W xorlw D'200' btfss STATUS,Z return clrf msek_1000 incf sek,f movf sek,W xorlw D'60' btfss STATUS,Z return clrf sek incf min,f movf min,W xorlw D'60' btfss STATUS,Z return clrf min incf hours,f movf hours,W xorlw D'24' btfss STATUS,Z return clrf hours return end