Jump to content
ELFORUM - Forumul electronistilor

capacimetru cu pic


Recommended Posts

Buna seara tuturor!In primul rind vreau sa precizez ca sint incepator in domeniu si as avea nevoie de putin ajutor,si anume :as vrea sa construiesc un capacimetru cu un pic 16f876.Problema mea este ca programul pentru pic este in asm si mie mi l-ar trebui in bin ca sa-l pot scrie cu programatorul .Daca m-ar putea ajuta cineva cu niste indicatii as fi recunoscator.Va multumesc anticipat!

Link to comment
  • Replies 8
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

asta-i programul: list p=16f876;*****************************************************;* Pinbelegung;* ---------------------------------- ;* PORTA: 0 < Spannung U vom ELKO;* 1 -;* 2 -;* 3 -;* 4 -;* 5 -;* 6 -;* 7 -;*;* PORTB: 0 LCD Display E;* 1 -;* 2 LCD Display RS;* 3 LCD Display R/W;* 4 LCD Display D4;* 5 LCD Display D5;* 6 LCD Display D6;* 7 LCD Display D7;* ;* PORTC: 0 > 250 Ohm zum ELKO (70 + 180);* 1 -;* 2 -;* 3 -;* 4 -;* 5 -;* 6 - ;* 7 -;* ;*****************************************************;;sprut (zero) Bredendiek 01/2004;; ELKO-Messgerät mit LCD; Messung der Kapazität in ?F; Auflösung: 1 ?F; C maximal: 65 000 ?F;; Prozessor 16F876 ;; Prozessor-Takt 10 MHz;; LCD am PortB;*****************************************************; Includedatei für den 16F876 einbinden #include ERRORLEVEL -302 ;SUPPRESS BANK SELECTION MESSAGES; Configuration festlegen:; Power on Timer, kein Watchdog, HS-Oscillator, kein Brown out, kein LV-programming __CONFIG _PWRTE_ON & _WDT_OFF & _HS_OSC & _BODEN_OFF & _LVP_OFF;*****************************************************; Variablen festlegen;16 Bit Rechenregisterxw0 equ 0x21 ; Rechenregisterxw1 equ 0x22 ; f0 equ 0x23 ; Rechenregisterf1 equ 0x24 ; counter equ 0x25 ; Flags equ 0x26 ; SZT equ 0x27 ; BCD-RegisterST equ 0x28 ; SZ equ 0x29 ; SH equ 0x2A ; SE equ 0x2B ; loops equ 0x2C ; timer für waitloops2 equ 0x2D ; timer für waitLcdStatus equ 0x2E ;LcdDaten equ 0x2F ;C0 equ 0x30 ; Kapazitätsregister in ?FC1 equ 0x31Temp equ 0x32Ini_con Equ B'00000000' ; TMR0 -> Interupt disableIni_opt Equ B'00000010' ; pull-up; für LCD-Pins#define LcdE PORTB,0 ; enable Lcd#define LcdRw PORTB,3 ; read Lcd#define LcdRs PORTB,2 ; Daten Lcd (nicht control) #define LcdPort PORTB ; Datenbus des LCD (obere 4 Bit)#define achteStelle B'10001000' ; #define achteStelle2 B'11001000' ; #define R250 PORTC, 0 ; Pin mit 250-Ohm zum ELKO#define Fehler Flags,0#define Leading0 Flags,1;***************************************************** org 0 goto InitTxt00 dt "Capacimetru",' '+80hTxt01 dt "o.k. ",' '+80hTxt10 dt "C scurt ",' '+80hTxt11 dt "Descarca ",' '+80h; Das Programm beginnt mit der InitialisierungInit bsf STATUS, RP0 ; Bank 1 movlw Ini_opt ; pull-up on movwf OPTION_REG movlw B'00000000' ; PortB alle outputs movwf TRISB bcf STATUS, RP0 ; Bank 0 clrf PORTB movlw Ini_con ; Interupt disable movwf INTCON ; ADC initialisieren ; ADC einschalten BSF ADCON0, 0 ; ADON=1 ; ADC-Eingang AN0 auswählen BCF ADCON0, 5 ; ADCHS2=0 BCF ADCON0, 4 ; ADCHS1=0 BCF ADCON0, 3 ; ADCHS0=0 ; ADC speed für 5 ... 20 MHz einstellen ; 44,8?s = 22,3 kHz max BSF ADCON0, 7 ; ADCS1=1 BCF ADCON0, 6 ; ADCS0=0 ; Daten rechtsbündig BSF STATUS,RP0 ; Bank1 clrf ADCON1 ; RA0,1,2,3,5 aktiv; Referenz Vdd&Vss BSF ADCON1, 7 ; ADFM=1, Daten rechtsbündig BCF STATUS,RP0 ; Bank0;Display initialisieren call InitLcd movlw B'10000000' ; 1. Zeile call OutLcdControl movlw '(' ; simbolul pe display call OutLcdDaten movlw 'c' ; simbolul pe display call OutLcdDaten movlw ')' ; simbolul pe display call OutLcdDaten movlw ' ' ; call OutLcdDaten movlw 'D' ; simbolul pe display call OutLcdDaten movlw '.' ; simbolul pe display call OutLcdDaten movlw 'O' ; simbolul pe display call OutLcdDaten movlw 'l' ; simbolul pe display call OutLcdDaten movlw 't' ; simbolul pe display call OutLcdDaten movlw 'e' ; simbolul pe display call OutLcdDaten movlw 'a' ; call OutLcdDaten movlw 'n' ; call OutLcdDaten movlw 'u' ; call OutLcdDaten movlw Txt00 ; 'txt 00' zum Display call Write movlw D'255' ; 255 ms Pause movwf loops call WAIT ; movlw D'255' ; 255 ms Pause movwf loops call WAIT ; movlw D'255' ; 255 ms Pause movwf loops call WAIT ; movlw D'255' ; 255 ms Pause movwf loops call WAIT ; movlw D'255' ; 255 ms Pause movwf loops call WAIT ; movlw D'255' ; 255 ms Pause movwf loops call WAIT ; movlw D'255' ; 255 ms Pause movwf loops call WAIT ; movlw D'255' ; 255 ms Pause movwf loops call WAIT ; call InitLcd goto MainloopMainloop call Kapazitaet ; Messung der Kapazität movfw C0 movwf f0 movfw C1 movwf f1 call B2D ; Wandlung in dezimal nach SZT,ST,SH,SH,SE call Ausgabe_uF ; Kapazität anzeigen am LCD 1.Zeile vorn movlw Txt01 ; 'o.k.' zum Display call Write movlw D'255' ; 255 ms Pause movwf loops call WAIT ; movlw D'255' ; 255 ms Pause movwf loops call WAIT ; movlw D'255' ; 255 ms Pause movwf loops call WAIT ; movlw D'255' ; 255 ms Pause movwf loops call WAIT ; goto Mainloop;*****************************************************; Kapazität bestimmen; Ergebnis nach C1, C0 [?F]Kapazitaet call Entladen ; ELKO entladen movlw Txt10 ; 'Messe C' zum Display call Write clrf C0 ; Kapazitätsregister löschen clrf C1 ; Timer0 auf 0,1733 ms einstellen (5770 Hz); ; 10MHz/5770Hz = 1733 = 4 x 2 x 217 ; Vorteiler 2:1 ; 217 Zähltakte 256-217=39 movlw B'10000000' bsf STATUS, RP0 ; Bank 1 movwf OPTION_REG bcf STATUS, RP0 ; Bank 0 ; ELKO laden bsf R250 bsf STATUS, RP0 ; Bank 1 bcf TRISC,0 ; RC0 output bcf STATUS, RP0 ; Bank 0 bsf R250Kap_loop movlw D'39' movwf TMR0 bcf INTCON,T0IF call ADC ; AN0 nach f1,f0 btfsc f1,1 ; > 511 ? goto Kap_Ende ; nein: U>2,5V incf C0,f btfsc STATUS,Z incf C1,f btfsc STATUS,Z goto Kap_ERROR ; C > 65 000 ?F Anzeige 00 000?FKap_loop2 btfss INTCON,T0IF goto Kap_loop2 goto Kap_loop ; Kap_EndeKap_ERROR bsf STATUS, RP0 ; Bank 1 bsf TRISC,0 ; RC0 input bcf STATUS, RP0 ; Bank 0 return;*****************************************************; ELKO entladen auf 40 mVEntladen ; ELKO entladen movlw Txt11 ; 'Entlade' zum Display call Write bcf R250 bsf STATUS, RP0 ; Bank 1 bcf TRISC,0 ; RC0 output bcf STATUS, RP0 ; Bank 0 bcf R250Entladen_loop call ADC ; AN0 nach f1,f0 movfw f1 btfss STATUS,Z ; < 256 ? (< 1,28V) goto Entladen_loop ; nein movlw B'11111000' andwf f0,w btfss STATUS,Z ; < 8 ? (< 0,04V) goto Entladen_loop ; nein bsf STATUS, RP0 ; Bank 1 bsf TRISC,0 ; RC0 input bcf STATUS, RP0 ; Bank 0 return;*****************************************************; Spannung mit ADC messen; Ergebnis nach f1,f0ADC BSF ADCON0, 2 ; ADC startenADCloop BTFSC ADCON0, 2 ; ist der ADC fertig? GOTO ADCloop ; nein, weiter warten movfw ADRESH ; obere 2 Bit auslesen movwf f1 ; obere 2-Bit nach U1H bsf STATUS,RP0 ; Bank1 movfw ADRESL ; untere 8 Bit auslesen bcf STATUS,RP0 ; Bank0 movwf f0 ; untere 8-Bit nach U1L return;*****************************************************;16 bit Adition, C-Flag bei Überlauf gesetztAdd16 ; 16-bit add: f := f + xw movf xw0,W ; xw0 nach W addwf f0,F ; f0 := f0 + xw0 movf xw1,W ; xw1 nach W btfsc STATUS,C ; fall ein Überlauf auftrat: incfsz xw1,W ; xw1+1 nach W addwf f1,F ; f1 := f1 + xw1 return ; fertig;*****************************************************; 16 Bit Subtraktion, bei Überlauf (neg. Ergebnis) ist C gesetztSub16 ; 16 bit f:=f-xw bcf Fehler ; extraflags löschen movf xw0, w ; f0:=f0-xw0 subwf f0, f btfsc STATUS,C goto Sub16a movlw 0x01 ; borgen von f1 subwf f1, f btfss STATUS,C bsf Fehler ; UnterlaufSub16a movf xw1,w ; f1:=f1-xw1 subwf f1 ,f btfss STATUS,C bsf Fehler ; Unterlauf bcf STATUS, C ; C-Flag invertieren btfsc Fehler bsf STATUS, C return;*****************************************************; Wandlung einer Binärzahl (< 100 000) in eine 5-stellige Dezimalzahl; Die Binärzahl steht in f1,f0; die Dezimalstellen werden in SZT (zehntausender), ST (tausender), SH (hunderter),; SZ (zehner) und SE (einer) gespeichert.B2D ; Test auf zehntausender 10 000d = 0x2710 movlw 0x27 movwf xw1 movlw 0x10 movwf xw0 call B2Da movwf SZT ; Test auf tausender 1000d = 0x03E8 movlw 0x03 movwf xw1 movlw 0xE8 movwf xw0 call B2Da movwf ST ; Test auf hunderter 100d = 0x0064 clrf xw1 movlw 0x64 movwf xw0 call B2Da movwf SH ; Test auf zehner 10d = 0x000A clrf xw1 movlw 0x0A movwf xw0 call B2Da movwf SZ movfw f0 movwf SE returnB2Da clrf counterB2Sb incf counter, f ; wie oft abgezogen? call Sub16 ; f:=f-xw btfss STATUS, C ; zu oft abgezogen? goto B2Sb ; nein: noch einmal call Add16 ; f:=f+xw decf counter, w return;*****************************************************;Anzeige der Dezimalzahl am LCD in der Form '12 345?F';Unterdrückung führender NullenAusgabe_uF movlw B'10000000' ; 1. Zeile call OutLcdControl movlw 'C' ; litera C pe display call OutLcdDaten movlw ' ' ; call OutLcdDaten movlw '=' ; simbolul = pe display call OutLcdDaten bsf Leading0 movfw SZT call AusLed movfw ST call AusLed movlw ' ' ; Lücke call OutLcdDaten movfw SH call AusLed movfw SZ call AusLed bcf Leading0 movfw SE call AusLed movlw B'11100100' ; ? call OutLcdDaten movlw 'F' call OutLcdDaten returnAusLed btfss STATUS,Z bcf Leading0 iorlw '0' ;wandeln in ASCCI btfsc Leading0 movlw ' ' ;führende 0 call OutLcdDaten return ;*****************************************************;* Write;* Ausgabe eines Strings der ab W im Speicher steht;* Note: Endekennzeichen ist Zeichen mit Bit 7 = 1;* Input : W zeigt auf String (RETLWs)Write movwf Temp ; Temp = Pointer movlw achteStelle2 ; 2. Zeile 8. stelle call OutLcdControl decf Temp,fGoWrite call PclSub2 ; Pointer erhöhen und nächstes Zeichen lesen addlw 80h ; ist Bit 7 gesetzt? EOT btfsc STATUS,C goto OutLcdDaten ; letztes Zeichen andlw 7fh ; zeichen wieder herstellen call OutLcdDaten ; Ausgabe goto GoWrite PclSub2 incf Temp, F ; Pointer auf nächstes Zeichen movf Temp, W ; Pointer nach W movwf PCL ; Sprung zur Addresse auf die PCLATH,W zeigt;*****************************************************;+++LCD-Routinen**************************************;*****************************************************;LCD initialisieren, Begrüßung ausgebenInitLcd movlw D'255' ; 250 ms Pause nach dem Einschalten movwf loops call WAIT movlw B'00110000' ; 1 movwf LcdPort bsf LcdE nop bcf LcdE movlw D'50' ; 50 ms Pause movwf loops call WAIT movlw B'00110000' ; 2 call Control8Bit movlw B'00110000' ; 3 call Control8Bit movlw B'00100000' ; 4 call Control8Bit movlw B'00000001' ; löschen und cusor home call OutLcdControl movlw B'00101000' ; 5 function set, 4-bit 2-zeilig, 5x7 call OutLcdControl movlw B'00001000' ; 6 display off call OutLcdControl movlw B'00000110' ; 7 entry mode, increment, disable display-shift call OutLcdControl movlw B'00000011' ; 8 cursor home, cursor home call OutLcdControl movlw B'00001100' ; 9 display on, Kursor aus , Blinken aus call OutLcdControl return;*****************************************************; ein Steuerbyte 8-bittig übertragenControl8Bit movwf LcdPort bsf LcdE nop bcf LcdE movlw D'10' movwf loops call WAIT return;*****************************************************; darauf warten, daß das Display bereit zur Datenannahme istLcdBusy bsf STATUS, RP0 ; make Port B4..7 input movlw B'11110000' iorwf TRISB, f bcf STATUS, RP0BusyLoop bcf LcdRs bsf LcdRw ; Lesen bsf LcdE nop movf LcdPort, w movwf LcdStatus bcf LcdE nop bsf LcdE ; Enable nop bcf LcdE btfsc LcdStatus, 7 ; teste bit 7 goto BusyLoop bcf LcdRw bsf STATUS, RP0 ; make Port B4..7 output movlw B'00001111' andwf TRISB, f bcf STATUS, RP0 return ;*****************************************************; aus W ein Byte mit Steuerdaten zum Display übertragenOutLcdControl movwf LcdDaten call LcdBusy movf LcdDaten, w andlw H'F0' movwf LcdPort ; Hi-teil Daten schreiben bsf LcdE nop bcf LcdE ; Disable LcdBus swapf LcdDaten, w andlw H'F0' movwf LcdPort ; Lo-teil Daten schreiben bsf LcdE nop bcf LcdE ; Disable LcdBus return;*****************************************************; aus W ein Datenbyte zum Display übertragenOutLcdDaten movwf LcdDaten call LcdBusy movf LcdDaten, w andlw H'F0' movwf LcdPort ; Hi-teil Daten schreiben bsf LcdRs ; Daten bsf LcdE ; Enable LcdBus nop bcf LcdE ; Disable LcdBus swapf LcdDaten, w andlw H'F0' movwf LcdPort ; Lo-teil Daten schreiben bsf LcdRs ; Daten bsf LcdE nop bcf LcdE ; Disable LcdBus bcf LcdRs ; return;*****************************************************;Zeitverzögerung um loops * 1 ms; 10 MHz externer Takt bedeutet 2,5 MHz interner Takt; also dauert 1 ms genau 2500 Befehle; 250 Schleifen a 10 Befehle sind 2500 Befehle = 1 msWAITtop movlw .250 ; timing adjustment variable (1ms) movwf loops2top2 nop ; sit and wait nop nop nop nop nop nop decfsz loops2, F ; inner loops complete? goto top2 ; no, go again ; decfsz loops, F ; outer loops complete? goto top ; no, go again retlw 0 ; yes, return from subWAIT;***************************************************** end

Link to comment

Multumesc!Am reusit cu mplab.Multumesc pt sfat ca la un moment dat nu am fost sigur ca se poate cu mplab ,dar tinand cont de sfaturile date am reusit dar mai am o mica dilema :hexul meu a iesit putin mai mare decat al vostru 2,420 fata de :2,363 respectiv 2,384.E vreo problema? de ce apar diferente?

Link to comment

La o analiza a hex-ului se pare ca unele tabele de strig-uri sunt putin mai lungi cu cateva linii retlw 0x20. Nu stiu ce cauta acolo,poate ai folosit alt fisier asm. Intre hex-ul dat de mine si cel al lui fratello diferenta nu este de cat la cei 4 bytes pentru ID.La mine sunt setati la el nu.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.Terms of Use si Guidelines