;**************************************************************** ;*--------------------------------------------------------------* ;* Temperatuur lezing * ;*--------------------------------------------------------------* ;**************************************************************** LIST P=PIC16F877A #INCLUDE P16F877A.INC __CONFIG _CP_OFF & _DEBUG_OFF & _LVP_OFF & _PWRTE_ON & _WDT_OFF & _BODEN_OFF & _XT_OSC ;---------------------------------------------------------------- ;Definieren van de registers en geheugenplaatsen ;---------------------------------------------------------------- KnoppenTemp EQU PORTA ;Knoppen voor temperatuurregeling LCDControl EQU PORTB ;Poort voor stuurFlag_Signbitalen LCD (= outputs) ResSel EQU H'0004' ;Register Select Signal= pin4 LCD ;(0 = characters als kommando's aan LCD gegeven ) ReadWrite EQU H'0003' ;Read Write Signal LCD = pin5 LCD (0 = schrijven) Enable EQU H'0002' ;Enable signal LCD = pin6 LCD (initiatie communicatie tss LCD en PIC) Sensor EQU PORTC ; LCDData EQU PORTD ;Poort voor het doorsturen van characters (= outputs) TC_SCK EQU H'0006' ;1=binnenhalen van bits, 0=niet TC_CS EQU H'0000' ;aan/uit Maak dit controleerbaar. Moet dit wel, aangezien we toch op de klok zijn aangesloten van de PIC ;Of toch niet, Kijk speciale functie van PORTC na en stel PORTC ook nog in om Serial Data te kunnen ontvangen TC_SI EQU H'0004' ;data (temperatuur) Temp_Lo EQU H'30' ;Denk eraan => elke geheugenplaats is = 1 byte, dus 8 bits (temp verdeelt over 2 bits) Temp_Hi EQU H'31' Counter EQU H'32' ; teller voor het aantal ingelezen bits van de temperatuur Sign EQU H'33' Flag_Signbit EQU H'0000' TIMER1 EQU H'20' TIMER2 EQU H'21' TIMER3 EQU H'34' TIMER4 EQU H'35' Tmax EQU H'36' ;Temperatuursinterval Tmin EQU H'37' ;++++++++++++++++++++++++++Begin+++++++++++++++++++++++++++++++++ ORG 0 call RESET call InitDisplay goto main ;--------------------------------------------------------------- ;Welke poort is input, welke is output ;--------------------------------------------------------------- RESET bsf STATUS,RP0 ; reg. Bank 1 ;PORTA bcf ADCON1,3 ;Alles van PORTA digitaal zijn bsf ADCON1,2 bsf ADCON1,1 bsf ADCON1,0 movlw B'001111' movwf TRISA ; PortA = input (de niet gebruikte pinnen als output gedefinieerd) ;PORTB movlw B'11000011' ; in-/uitgang definities movwf TRISB ;PORTC movlw B'00010000' ; in-/uitgang definities movwf TRISC ; ;PORTD movlw B'00000000' movwf TRISD ; PortD = output bcf STATUS,RP0 ; reg. Bank 0 ;Alles op 0 zeten ;PORTA movlw B'000000' movwf PORTA ; RA ports clear (=initiatie, uitgangen op 0 zetten) !!!!!!!!!!!!!!!!!!!!!! ;PORTB movlw B'00000000' movwf PORTB ; RB ports clear (=initiatie, uitgangen op 0 zetten) !!!!!!!!!!!!!!!!!!!!!! ;PORTC movlw B'00000000' movwf PORTC ; RC ports clear (=initiatie, uitgangen op 0 zetten) !!!!!!!!!!!!!!!!!!!!!! ;PORTD movlw B'00000000' movwf PORTD ; RD ports clear (=initiatie, uitgangen op 0 zetten) !!!!!!!!!!!!!!!!!!!!!! ;call InitDisplay bsf Sensor,TC_CS ;chip afzetten return ;---------------------------------------------------------------- ;Delay ;---------------------------------------------------------------- Delay5 CLRWDT MOVLW D'255' MOVWF TIMER1 Delay6 MOVLW D'255' MOVWF TIMER2 DECFSZ TIMER2,F GOTO $-1 DECFSZ TIMER1,F GOTO Delay4 RETLW 0 Delay7 CLRWDT MOVLW D'150' MOVWF TIMER3 Delay8 MOVLW D'150' MOVWF TIMER4 DECFSZ TIMER4,F GOTO $-1 DECFSZ TIMER3,F GOTO Delay6 RETLW 0 ;--------------------------------------------------------------- ;Procedure die een bepaald character naar de diplay stuurt ;--------------------------------------------------------------- SendData ;Dit is een zeer algemene procedur om data te versturen, zowel voor LCDControl als LCDData movwf LCDData ;De juiste waarde van LCDControl,ResSel hangt dus af van wat je wilt doen, verander deze waarde dus enkel in de hulpprocedures e niet in SendData bcf LCDControl,Enable bsf LCDControl,Enable ;E = 1, we kunnen schrijven naar de display (als R/W = 0, dit betekent schrijven en niet lezen) MOVLW D'255' ;* MOVWF TIMER1 ;* ; DELAY2 MOVLW D'2' ; x msec MOVWF TIMER2 DECFSZ TIMER2,F ;* GOTO $-1 ;* DECFSZ TIMER1,F GOTO DELAY2 RETLW 0 ;-------------------------------------------------------------------------- ;Procedure om alle characters naar de LCD te sturen (1 procedure per char) ;-------------------------------------------------------------------------- Send_A movlw A'A' goto SendData Send_B movlw A'B' goto SendData Send_C movlw A'C' goto SendData Send_D movlw A'D' goto SendData Send_E movlw A'E' goto SendData Send_F movlw A'F' goto SendData Send_G movlw A'G' goto SendData Send_H movlw A'H' goto SendData Send_I movlw A'I' goto SendData Send_J movlw A'J' goto SendData Send_K movlw A'K' goto SendData Send_L movlw A'L' goto SendData Send_M movlw A'M' goto SendData Send_N movlw A'N' goto SendData Send_O movlw A'O' goto SendData Send_P movlw A'P' goto SendData Send_Q movlw A'Q' goto SendData Send_R movlw A'R' goto SendData Send_S movlw A'S' goto SendData Send_T movlw A'T' goto SendData Send_U movlw A'U' goto SendData Send_V movlw A'V' goto SendData Send_W movlw A'W' goto SendData Send_X movlw A'X' goto SendData Send_Y movlw A'Y' goto SendData Send_Z movlw A'Z' goto SendData Send_a movlw A'a' goto SendData Send_b movlw A'b' goto SendData Send_c movlw A'c' goto SendData Send_d movlw A'd' goto SendData Send_e movlw A'e' goto SendData Send_f movlw A'f' goto SendData Send_g movlw A'g' goto SendData Send_h movlw A'h' goto SendData Send_i movlw A'i' goto SendData Send_j movlw A'j' goto SendData Send_k movlw A'k' goto SendData Send_l movlw A'l' goto SendData Send_m movlw A'm' goto SendData Send_n movlw A'n' goto SendData Send_o movlw A'o' goto SendData Send_p movlw A'p' goto SendData Send_q movlw A'q' goto SendData Send_r movlw A'r' goto SendData Send_s movlw A's' goto SendData Send_t movlw A't' goto SendData Send_u movlw A'u' goto SendData Send_v movlw A'v' goto SendData Send_w movlw A'w' goto SendData Send_x movlw A'x' goto SendData Send_y movlw A'y' goto SendData Send_z movlw A'z' goto SendData Send_0 movlw A'0' goto SendData Send_1 movlw A'1' goto SendData Send_2 movlw A'2' goto SendData Send_3 movlw A'3' goto SendData Send_4 movlw A'4' goto SendData Send_5 movlw A'5' goto SendData Send_6 movlw A'6' goto SendData Send_7 movlw A'7' goto SendData Send_8 movlw A'8' goto SendData Send_9 movlw A'9' goto SendData Send_Space movlw A' ' goto SendData Send_Question movlw A'?' goto SendData Send_Point movlw A'.' goto SendData Send_ArrowUp movlw B'00000010' goto SendData Send_ArrowDown movlw B'00000001' goto SendData Send_ArrowKies movlw B'00000000' goto SendData Send_ArrowRight movlw B'01111110' goto SendData Send_ArrowLeft movlw B'01111111' goto SendData Send_Dubbel movlw A':' goto SendData Send_Minus movlw A'-' goto SendData Send_Plus movlw A'+' goto SendData Send_Exclamation movlw A'!' goto SendData Send_Degrees movlw B'11011111' goto SendData Send_En movlw A'&' goto SendData Send_Equal movlw A'=' goto SendData Send_GoHome bcf LCDControl,ResSel movlw B'00000010' ; Go to Home call SendData bsf LCDControl,ResSel return Send_ClearScreen bcf LCDControl,ResSel ;RS = 0, byte aan PORTD zijn nu commando's movlw B'00000001' ; Clear Display call SendData movlw B'00000010' ; Go to Home call SendData bsf LCDControl,ResSel return Send_NextLine bcf LCDControl,ResSel movlw B'11000000' call SendData bsf LCDControl,ResSel return Delay3 CLRWDT MOVLW D'100' MOVWF TIMER1 Delay4 MOVLW D'100' MOVWF TIMER2 DECFSZ TIMER2,F GOTO $-1 DECFSZ TIMER1,F GOTO Delay4 RETLW 0 ;--------------------------------------------------------------- ;Initialisatie van de display ;--------------------------------------------------------------- InitDisplay call Delay3 bcf LCDControl,ReadWrite ;schrijven naar de display bcf LCDControl,ResSel ;RS = 0, we sturen dus commando's naar de display call Delay3 movlw B'00110000' call SendData call Delay3 movlw B'00110000' call SendData call Delay3 movlw B'00110000' call SendData call Delay3 movlw B'00111000' ;Function set call SendData ;2 maal een 8bit line, volgens de datasheet call Delay3 movlw B'00001110' ;Display on/off Control call SendData call Delay3 movlw B'00000110' ;Entry Mode Set call SendData bsf LCDControl,ResSel ;RS = 1, we sturen dus terug characters naar de display call Delay3 return ;**************************************************************** ; Lezen van de temperatuur ;**************************************************************** ;--------------------------------------------------------------- ;Loop waarin de temp bit per bit wordt gelezen ;--------------------------------------------------------------- TempRead movlw D'16' movwf Counter bcf Sensor,TC_SCK ;Klok op nul zetten. Er wordt geen data ontvangen van de sensor bcf Sensor,TC_CS ;Sensor opzetten call Delay5 call Delay7 return TempLoop ;Er wordt in deze loop geen data ontvangen van de sensor bsf Sensor,TC_SCK ;Zet de klok naar de sensor toe op 1. Er wordt een nieuwe databit gelezen ;Blijkbaar beslis je zelf wanneer de input TC_SI verandert btfsc Sensor,TC_SI ;Als TC_SI = 1 bsf STATUS,C ;wordt de Carry = 1 btfss Sensor,TC_SI ;Als TC_SI = 0 bcf STATUS,C ;wordt de Carry = 0 ;TC_SI is initieel = MSB, om dan bij elke doorgang van de loop te veranderen in de waarde rechts van de vorige call Delay5 bcf Sensor,TC_SCK ;De klok SCK is nu = 0 en wordt dus geen data meer gelezen rlf Temp_Lo ;De data wordt bit per bit in het register in gelezen met een rotate left through Carry = zie code hierboven rlf Temp_Hi ;De rotate left hier gebruikt de waarde die C heeft verkregen door de vorige rlf ;Zo schrijven we dus bit per bit het 16 bit getal in 2 registers decfsz Counter,F ;Counter - 1, als deze uitkomst = 0 goto TempLoop ;niet meer opnieuw TempLoop uitvoeren call Delay5 bsf Sensor,TC_CS ;uitschakelen van sensor call Delay5 return ;**************************************************************** ; Temperatuursregeling - Start ;**************************************************************** ;---------------------------------------------------------------- ;Initialisatie van de Tmax en Tmin ;---------------------------------------------------------------- Init_AllTemps movlw B'00111100' ;Dit is de gereduceerde vorm van 15°C movwf Tmin movlw B'01100100' ;Dit is de gereduceerde vorm van 25°C movwf Tmax movlw B'01101100' ;Temp_Lo een waarde geven enkel om dit stuk code te testen movwf Temp_Lo return ;---------------------------------------------------------------- ;Regeling ;---------------------------------------------------------------- ControleMax movf Tmax,w ;Tmax inschrijven in w subwf Temp_Lo,0 ;verschil (Temp_Lo - Tmax) maken en in w opslaan btfss STATUS,C ;de PIC gebruikt de 2's complement methode om verschillen te berekenen. ;verschil > 0 => carry = 1 ;verschil < 0 => carry = 0 goto ControleMin goto Send_Cooling ControleMin movf Tmin,w ;Tmin inschrijven in w subwf Temp_Lo,0 ;verschil (Temp_Lo - Tmin) maken en in w opslaan btfsc STATUS,C ;de pic gebruikt de 2's complement methode om verschillen te berekenen. ;verschil > 0 => carry = 1 ;verschil < 0 => carry = 0 goto Interval_ok goto Send_Heating Interval_ok goto Send_Off ;---------------------------------------------------------------- ;Extra display procedures ;---------------------------------------------------------------- Send_Cooling call Send_ClearScreen call Send_Space call Send_Space ;2 call Send_Space ;3 call Send_Space ;4 call Send_C ;5 call Send_o ;6 call Send_o ;7 call Send_l ;8 call Send_NextLine call Send_i call Send_n call Send_g goto main Send_Heating call Send_ClearScreen call Send_Space call Send_Space ;2 call Send_Space ;3 call Send_Space ;4 call Send_H ;5 call Send_e ;6 call Send_a ;7 call Send_t ;8 call Send_NextLine call Send_i call Send_n call Send_g goto main Send_Off call Send_ClearScreen call Send_Space call Send_Space ;2 call Send_Space ;3 call Send_Space ;4 call Send_Space ;4 call Send_Space ;4 call Send_O ;5 call Send_f ;6 call Send_NextLine call Send_f goto main ;**************************************************************** ; Temperatuursregeling - Einde ;**************************************************************** ;--------------------------------------------------------------- ;--------------------------------------------------------------- ;Hoofdprogramma ;--------------------------------------------------------------- ;--------------------------------------------------------------- main ;Probleem: Temp_Lo,2 wordt nooit = 1!!!!!!!!!!!!!!!!! ;Temp lezen ;bcf INTCON,GIE ;geen globale interrupts <=> Is dit nodig?????????? ;Ik denk het niet aangezien er al een interrupt mogelijk is door de klok ;Kan dit niet gewoon elke keer als het prog door de mainloop gaat, zonder naar de interrupt call TempRead ;Sensor initialiseren call TempLoop ;call TempCCM ;bsf INTCON,GIE ;enable globale interrupts ;Is de temp conversie compleet? Als bit 2 van Temp_Lo = 1 is de conversie compleet btfss Temp_Lo,2 ;waarom skip if set? Om ervoor te zorgen dat er ook rekening wordt gehouden met het geval dat bit 2 goto main ;verschillend is van 1. In dit geval gaan we gewoon terug naar main movlw B'00001111' movwf LCDData ;Laat de 3 LSB wegvallen (bit 0, 1 en 2), aangezien die niet mee de waarde van de temp bepalen bcf STATUS,C ;Carry = 0 rrf Temp_Lo rrf Temp_Hi bcf STATUS,C ;Carry = 0 rrf Temp_Lo rrf Temp_Hi bcf STATUS,C ;Carry = 0 rrf Temp_Lo rrf Temp_Hi ;Negatieve temperatuur btfsc Temp_Hi,4 ;als bit 4 = 1 bsf Sign,Flag_Signbit ;dan wordt Flag_Signbit = 1 => de temperatuur is negatief btfss Temp_Hi,4 ;als bit 4 = 0 bcf Sign,Flag_Signbit ;dan wordt Flag_Signbit = 0 => de temperatuur is positief btfss Sign,Flag_Signbit ;Als Flag_Signbit = 0 goto main ;ga naar het volgende deel van het programma bsf Temp_Hi,7 ;Dit is omdat we werken met de 2's complement methode om binair een negatief getal weer te geven bsf Temp_Hi,6 bsf Temp_Hi,5 comf Temp_Hi,F ;complement nemen comf Temp_Lo,F ;complement nemen incf Temp_Lo,F ;2 optellen, binair gezien btfsc STATUS,C ;als Carry = 1, betekent dit dat de MSB van Temp_Lo + 1 buiten Temp_Lo valt incf Temp_Hi,F ;moet bij het 2de register ook 1 bijgeteld worden ;Actie van de thermostaat in functie van de afgelezen temp call ControleMax goto main ;++++++++++++++++++++++++++Einde+++++++++++++++++++++++++++++++++ end