Top Banner
; PIC16F84 code for the NK0E weather station project. The purpose ; of this project is to provide a hardware interface which measures ; temperature, wind speed, wind direction, humidity, and pressure ; and communicates it to a PC via serial communications when ; requested. Note that the data collected and transmitted must be ; processed by the PC in order to obtain the actual measurement ; values (i.e. no calibration is done in the PIC code). ; ; The hardware circuit makes use of two major components: the ; PIC16F84 itself and a MAX232 TTL-RS232 level converter. ; The MAX232 converts the TTL signals from the PIC to RS232 levels ; for the PC (and vice versa). ; ; The PIC16F84 pin assignments are as follows: ; ; RA1: serial out to PC ; RA2: clock out to SHT11 temp/humid sensor ; RA3: data in/out for SHT11 temp/humid sensor ; RB0: serial in from PC (generates interrupt) ; ; This software implements the following command set: ; ; Received Reply Description ;----------------------------------- ; 't' 12345 CR LF Get the temperature raw data. Five digits ; or e1 CR LF are always returned, with leading zeroes ; or e2 CR LF if necessary, followed by a carriage return ; and line feed. See the SHT11 data sheet ; for instructions on computing the temperature. ; A return of e1 indicates that the SHT11 didn't ; acknowledge the request. A return of e2 ; indicates that no data was returned by the SHT11 ; within the wait period (255 ms). ; 'h' 12345 CR LF Get the humidity raw data. Five digits ; or e1 CR LF are always returned, with leading zeroes
25

PIC16F84 Code for the NK0E Weather Station Project

Mar 26, 2015

Download

Documents

Son Nguyen
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: PIC16F84 Code for the NK0E Weather Station Project

; PIC16F84 code for the NK0E weather station project. The purpose; of this project is to provide a hardware interface which measures; temperature, wind speed, wind direction, humidity, and pressure; and communicates it to a PC via serial communications when; requested. Note that the data collected and transmitted must be; processed by the PC in order to obtain the actual measurement; values (i.e. no calibration is done in the PIC code).;; The hardware circuit makes use of two major components: the ; PIC16F84 itself and a MAX232 TTL-RS232 level converter.; The MAX232 converts the TTL signals from the PIC to RS232 levels; for the PC (and vice versa).;; The PIC16F84 pin assignments are as follows:;; RA1: serial out to PC; RA2: clock out to SHT11 temp/humid sensor; RA3: data in/out for SHT11 temp/humid sensor; RB0: serial in from PC (generates interrupt);; This software implements the following command set:;; Received Reply Description;-----------------------------------; 't' 12345 CR LF Get the temperature raw data. Five digits; or e1 CR LF are always returned, with leading zeroes; or e2 CR LF if necessary, followed by a carriage return; and line feed. See the SHT11 data sheet; for instructions on computing the temperature.; A return of e1 indicates that the SHT11 didn't; acknowledge the request. A return of e2; indicates that no data was returned by the SHT11; within the wait period (255 ms).; 'h' 12345 CR LF Get the humidity raw data. Five digits; or e1 CR LF are always returned, with leading zeroes; or e2 CR LF if necessary, followed by a carriage return; and line feed. See the SHT11 data sheet for; instructions on computing the humidity.; A return of e1 indicates that the SHT11 didn't; acknowledge the request. A return of e2; indicates that no data was returned by the SHT11

Page 2: PIC16F84 Code for the NK0E Weather Station Project

; within the wait period (255 ms).; 'v' version info Gets the version number of the firmware.; returns an ASCII string followed by a ; carriage return and line feed.;; Written using Microchip MPLAB v5.40;; Please direct any questions, comments, or suggestions to the; author: David Ek; [email protected];; History:;; Rev 1 (23 Jul 2002):; Creation. Returns dummy temperature data. This version used; for installment 2 of the PIC WX articles in QQ.; Rev 2 (26 Sep 2002):; Added code for the Sensirion SHT11 temperature/humidity sensor; for installment 3 of the PIC WX articles in QQ.;;----------------------------------------------------------------

list p=16f84radix dec__config _CP_OFF & _WDT_OFF & _XT_OSC

include "p16f84.inc"

; defines:

; These are used by the serial comm routines for timing. Note that; slower speeds may not work well because the delays might be larger; than 255, requiring the use of the prescalar.

_Clkspd equ 1000000 ;external clock / 4_BaudRate equ 9600 ;desired baud rate_Period equ (_Clkspd/_BaudRate) ;clock cycles / bit

_StartRxDelay equ (_Period/2 - 15)/3 ;this is how long to;wait to get to the;middle of the start;bit. This is loops,;not clock cycles.

_BitRxDelay equ 277 - _Period ;this is what to load;into TMR0 for correct;interval between bits;on RX

Page 3: PIC16F84 Code for the NK0E Weather Station Project

_BitTxDelay equ 285 - _Period ;this is what to load;into TMR0 for correct;interval between bits;on TX

_StopTxDelay equ 272 - _Period ;this is what to load;into TMR0 for correct;interval betweeen last;bit and stop bit on TX

; defines for I/0 pins:

_SER_IN equ 0 ;Serial input line (PORTB)_SER_OUT equ 1 ;Serial output line (PORTA)_SHT11_SCK equ 2 ;clock line for SHT11 sensor

;(PORTA)_SHT11_DAT equ 3 ;data line for SHT11 sensor

;(PORTA)

; macros for the bin-to-ascii conversion routines:

loadw macro arg1movlw high(arg1)movwf himovlw low(arg1)movwf loendm

dodigit macro arg1movlw high(arg1)movwf shimovlw low(arg1)movwf slocall dosubendm

; memory locations:

cblock 0x0C

BitCount ;number of bits left to send or;receive, not including start & stop;bits

RXChar ;received character while being receivedRXBuff ;most recently received character

TXChar ;character to transmit

SerialReg ;status register:;bit 0: on if character has been; received;bit 1: on if busy with RX/TX

Page 4: PIC16F84 Code for the NK0E Weather Station Project

;bit 2: on if sending, off if receiving;bit 3: on if next bit to send is stop bit

WSave ;copy of W register

SSave ;copy of the Status register

SHT11Byte ;a byte of data sent to or returned by the SHT11

counter ;generic counter register

hi ;hi byte for number to be converted to asciilo ;lo byte for number to be converted to asciishi ;hi byte for subtractor for conversion to asciislo ;lo byte for subtractor for conversion to asciidigit ;ascii digit converted from binary. Also used as

;input to SendErrorCode

MSDelay ;register for WaitMS timing

endc

org 0x00goto Main

org 0x04

;--------------------------------------------------------------------;-----Serial Communication Routines----------------------------------;--------------------------------------------------------------------;; The serial comm routines generate 1 start bit, 8 data bits, 1 stop bit, ; no parity. The baud rate is determined by the delay programmed; into the onboard timer. The sending and receiving is interrupt driven,; meaning other tasks can be carried on while the characters are being; sent and received.;;-----Main Interrupt Routine-----------------------------------------;; for timing: 4 cycles from interrupt time to get here.

; Save the W and STATUS registers:

Intmovwf WSave

Page 5: PIC16F84 Code for the NK0E Weather Station Project

swapf STATUS,W ;use swapf to prevent anymovwf SSave ;status flags from being changed

; cycles so far since interrupt occurred: 7

; Okay, I'm doing something goofy here. Instead of actually checking; the overflow bits themselves, I'm using the enable bits to determine; which interrupt occurred. I can do this because there should only; ever be one type of interrupt active at a time. The problem with; checking the overflow bits is that the T0IF bit can get set even; if that interrupt is disabled.

; Check first for a timer overflow interrupt. The overflow bit gets; set even if the interrupt is disabled.

btfsc INTCON,T0IEgoto DoBit ;we're in the middle of sending or

;receiving

; 10 cycles executed on entry to DoBit

; If not a timer overflow interrupt, check for external interrupt:

btfsc INTCON,INTE ;RB0 is our receive line and itgoto StartRX ;generates an interrupt on a high-

;to-low transition

; 12 cycles executed on entry to StartRX

; Else, must be something we don't care about:

;do nothing for now

; Restore the W and STATUS registers:

Restore swapf SSave,Wmovwf STATUSswapf WSave,Fswapf WSave,W

retfie

;------end Main Interrupt Routine------------------------------------

Page 6: PIC16F84 Code for the NK0E Weather Station Project

;------Subroutine SerSetup-------------------------------------------

SerSetup

; set up the option register for internal counting, WDT disabled,; no prescaler.

clrf TMR0bsf STATUS,RP0clrwdt ;set bits in OPTION_REG tomovlw b'10001000' ;enable internal clock counting,movwf OPTION_REG ;disable watchdog timer.bcf STATUS,RP0 ;switch to bank 0

; set the output line to idle (high)

bsf PORTA,_SER_OUT ;set the output line to idle;(high) state

movlw b'00000001'movwf PORTB

; enable the external interrupt via RB0

movlw b'10010000' ;set bits in INTCON to enablemovwf INTCON ;external interrupt

; initialize the SerialReg:

clrf SerialReg

return

;------end SetSetup--------------------------------------------------

;------Subroutine StartRX--------------------------------------------;; This subroutine is called by the main interrupt routine when an; external interrupt on RB0 occurs. This means we're receiving the; start bit for a character. We want to enable the external TMR0; interrupt and prepare to receive the character.

StartRX

; wait halfway through the bit to see if it's real:

bcf INTCON,INTF ;clear the interrupt

Page 7: PIC16F84 Code for the NK0E Weather Station Project

movlw _StartRxDelaymovwf BitCount ;this is the 15th instruction since

;the interrupt. Note--we're using;BitCount for this loop purely for;convenience. Usually it's used to;actually count the bits we TX/RX.

RXWait decfsz BitCount,F ;this loop takes 3 times the initial

goto RXWait ;value of BitCount clock cycles

; now we should be at the middle of the start bit. Is the input still; low? If not, goto Restore and ignore this interrupt.

btfsc PORTB,_SER_INgoto Restore

; if we get to here it must really be the start bit. Load TMR0,; disable the external interrupt, and enable the TMR0 interrupt.

; load up the appropriate delay to get us to the middle of the; first bit:

movlw _BitRxDelaymovwf TMR0 ;4 cycles from read of PORTBmovlw b'00100000'movwf INTCON

; set the SerialReg to indicate that the routines are busy getting; a character:

movlw b'00000010'movwf SerialReg

; initialize BitCount:

movlw 8movwf BitCount

; okay, now we return.

goto Restore

;------end StartRX---------------------------------------------------

;------DoBit---------------------------------------------------------;

Page 8: PIC16F84 Code for the NK0E Weather Station Project

; sends or receives the next bit. Bits are sent/received from least; to most significant bit.

DoBit

; clear the TMR0 overflow interrupt flag:

bcf INTCON,T0IF

; Are we receiving?

btfsc SerialReg,2goto Sending

; check to see if we're receiving the stop bit:

movf BitCount,Fbtfsc STATUS,Zgoto GetStopBit

; if we get to here, we're in the middle of receiving. Get the next; bit: (16 cycles to get to the next instruction from the start of; the interrupt).

rrf PORTB,W ;rrf PORTB into W. This sets;the carry bit if RB0 was high.

rrf RXChar,F ;doing a rrf on RXChar brings;in the carry bit to the MSB.

; Decrement the bit counter.

decf BitCount,F

; reload TMR0 for the next interrupt, and; go to the end of the interrupt routine.

movlw _BitRxDelaymovwf TMR0 ;21 cycles from start of interruptgoto Restore

; if we get to here it's because we need to check for the stop bit.

GetStopBitbtfss PORTB,_SER_IN ;is the RX line low? If so, it's notgoto Done ;the stop bit. Otherwise, set themovlw b'00000001' ;SerialReg to show a character hasmovwf SerialReg ;been receivedmovf RXChar,W ;copy the received character to RXBuff

Page 9: PIC16F84 Code for the NK0E Weather Station Project

movwf RXBuffgoto Done

; We got here because we're sending.; check to see if we're finished sending the stop bit:

Sendingbtfsc SerialReg,3goto Done

; check to see if we need to send the stop bit:

movf BitCount,Fbtfsc STATUS,Z ;18th cyclegoto SendStopBit

; if we get to here, we're in the middle of sending. Send the next; bit: (16 cycles to get to the next instruction from the start of; the interrupt).

rrf TXChar,F ;doing rrf on TXChar puts thebtfss STATUS,C ;least significant bit in thegoto SendZero ;carry flag.nopbsf PORTA,_SER_OUT ;if carry is set, send a one.goto EndDoBit ;PORTA,1 is set on the 24th cycle

SendZerobcf PORTA,_SER_OUT ;otherwise, send a zero. (24th cycle)nop ;nop's are for taking the same timenop ;to get to reloading TMR0 as for when

;a one is sent.

; Decrement the bit counter.

EndDoBitdecf BitCount,F

; reload TMR0 for the next interrupt, and; go to the end of the interrupt routine.

movlw _BitTxDelaymovwf TMR0 ;29th cyclegoto Restore

; Here we need to send the stop bit, turn off the TMR0 interrupt,; turn on the external interrupt, and set the SerStatus register; flags appropriately.

Page 10: PIC16F84 Code for the NK0E Weather Station Project

SendStopBitnopnopnopbsf PORTA,_SER_OUT ;no. Send the stop bit. (24th cycle)bsf SerialReg,3 ;set the "sending stop bit" flag

; reload TMR0 for the next interrupt, and; go to the end of the interrupt routine.

movlw _StopTxDelaymovwf TMR0 ;27th cyclegoto Restore

; we're completely done sending or receiving. Clean up.

Done movlw b'00010000' ;set bits in INTCON to enablemovwf INTCON ;external interruptmovlw b'00000001'andwf SerialReg,F ;clear the busy bits in SerialReggoto Restore

;------end DoBit-----------------------------------------------------

;------Subroutine SendChar-------------------------------------------;; This is not called by the interrupt handler. Rather, it activates ; the interrupts needed to send it. Put the character to be sent in; the TXChar file register before calling this subroutine.;

SendChar

; send the start bit:

bcf PORTA,_SER_OUT

; set the SerStatus to indicate that the routines are busy sending; a character:

movlw b'00000110'movwf SerialReg

; load up TMR0 so it overflows at the right time.

nop ;for timingmovlw _BitTxDelay

Page 11: PIC16F84 Code for the NK0E Weather Station Project

movwf TMR0 ;5th cycle after write to PORTA

; clear the external interrupt flag, disable the external interrupt,; and enable the TMR0 interrupt.

movlw b'10100000'movwf INTCON

; set the BitCount for the eight bits to send:

movlw 8movwf BitCount

return

;------end SendChar--------------------------------------------------

;------begin GetAChar------------------------------------------------

GetACharcall Idlebtfss SerialReg,0 ;wait for a character to be receivedgoto GetACharbcf SerialReg,0return

;------end GetAChar--------------------------------------------------

;------begin SendAChar-----------------------------------------------

SendACharcall SendChar

WaitToFinishcall Idlebtfsc SerialReg,1 ;wait for the character to be sentgoto WaitToFinishreturn

;------end SendAChar-------------------------------------------------

;------Subroutine WaitMS---------------------------------------------;; WaitMS is an approximate millisecond delay. It assumes a 4 MHz

Page 12: PIC16F84 Code for the NK0E Weather Station Project

; oscillator, meaning instructions are executed at a rate of 1 MHz.; I got the timing info (number of cycles per instruction) from the; Microchip PIC16F84 data sheet.

; the call to this subroutine takes 2 cycles to execute.

WaitMSmovlw 248 ;1 cyclemovwf MSDelay ;1 cyclenop ;1 cycle--these nops are added to nop ;1 cycle make the total number ofnop ;1 cycle instructions executed in

; the routine to be 1000.;the nop instruction simply does ;nothing except take time to execute.

; The loop below takes four cycles for every time through except the; last, when it takes five (including the time needed to execute the; return). So, the total number of instructions executed in getting; to and returning from this subroutine is:;; 2 to get here; + 2 to set the MSDelay value; + 3 for the nops; + 247*4 for the first 247 times through the loop; + 5 for the last time through the loop and to return; --------; = 1000

RepeatWaitMSnop ;1 cycledecfsz MSDelay,F ;1 cycle if not zero, 2 if zerogoto RepeatWaitMS ;2 cyclesreturn ;2 cycles

;------end WaitMS----------------------------------------------------

;------begin SHT11TXRX-----------------------------------------------;; Sends a byte command to the SHT11 temp/humidity sensor and retrieves; a two-byte response. Sends the response back to the PC as an ASCII; string representation of the number.;

Page 13: PIC16F84 Code for the NK0E Weather Station Project

; Put the byte to send in SHT11Byte before calling this routine.

SHT11TXRX

;make _SHT11_DAT an output

bsf STATUS,RP0 ;switch to bank 1bcf TRISA,_SHT11_DAT ;make Port A data line an outputbcf STATUS,RP0 ;switch back to bank 0

;send the Transmission Start sequence:

bsf PORTA,_SHT11_DAT ;set the data line highbsf PORTA,_SHT11_SCK ;take the clock line highbcf PORTA,_SHT11_DAT ;take the data line lowbcf PORTA,_SHT11_SCK ;take the clock line lowbsf PORTA,_SHT11_SCK ;take the clock line high againbsf PORTA,_SHT11_DAT ;set the data line high again

;load up the counter to loop through the eight bits to send:

movlw 8movwf counter

SHT11SendBitLoopbcf PORTA,_SHT11_SCK ;take the clock line low

btfss SHT11Byte,7 ;is the next bit to send a one?goto SHT11SendZero ;nope. Go send a zero.bsf PORTA,_SHT11_DAT ;if it's a one, send it.goto SHT11SendBit

SHT11SendZerobcf PORTA,_SHT11_DAT ;set the data line to zero

SHT11SendBitbsf PORTA,_SHT11_SCK ;take the clock line high to send

rlf SHT11Byte,F ;move the next bit into MSB

decfsz counter,F ;dec the counter and check for zero.goto SHT11SendBitLoop ;if not zero, more bits to send

bcf PORTA,_SHT11_SCK ;take the clock line low

;no more bits to send. Set the data line to be an input and;wait for the ack from the SHT11:

bsf STATUS,RP0 ;switch to bank 1bsf TRISA,_SHT11_DAT ;make Port A data line an inputbcf STATUS,RP0 ;switch back to bank 0

Page 14: PIC16F84 Code for the NK0E Weather Station Project

; now look for an ack (SHT11 pulls data line low--should; happen on the next rise of the SCK line). If it doesn't; happen, return an 'e' and quit.

bsf PORTA,_SHT11_SCK

SHT11WaitAckbtfss PORTA,_SHT11_DATgoto SHT11GotAck

;if we don't get an ack, quit, send an 'e1' for error and return.

movlw '1'movwf digitcall SendErrorCodegoto SHT11TXRXDone

; we got an Ack. Get ready for the data to be returned. take; the clock line low, and then wait for the data line to be; pulled low again.

SHT11GotAckbcf PORTA,_SHT11_SCK

; now wait for the data. It takes approximately 210 ms for; the temperature measurement, or 55 ms for the humidity; measurement, so we'll wait up to 255 ms before giving up.

movlw 255movwf counter

SHT11WaitDatabtfss PORTA,_SHT11_DATgoto SHT11DataReadycall WaitMSdecfsz counter,Fgoto SHT11WaitData

;if we don't get the data, quit, send an 'e2' error and return.

movlw '2'movwf digitcall SendErrorCodegoto SHT11TXRXDone

SHT11DataReady

; get the most sig byte:

call SHT11GetByte

Page 15: PIC16F84 Code for the NK0E Weather Station Project

movf SHT11Byte,Wmovwf hicall SendAck ;acknowledge the byte

; get the least sig byte:

call SHT11GetBytemovf SHT11Byte,Wmovwf locall SendAck ;acknowledge the byte

call SHT11GetByte ; gets the checksum (not needed)

; Send the data as ASCII:call SendAsciiNum

; Send the terminating CR and LF:call SendCRLF

SHT11TXRXDonereturn

;------end SHT11TXRX--------------------------------------------------

;------begin SHT11GetByte---------------------------------------------;; Gets a byte of data from the SHT11. Assumes that the data; is ready to be sent by the SHT11. Also assumes that _SHT11_DAT has; been set to input. Also assumes that _SHT11_SCK has been set to low.; Returns the byte in SHT11Byte.

SHT11GetByte; clear SHT11Byte:

clrf SHT11Byte

; set counter to get eight bits

movlw 8movwf counter

SHT11GetByteLoopbsf PORTA,_SHT11_SCK ;set the clock high to get the next

bitbtfss PORTA,_SHT11_DAT ;is the next bit a one?goto SHT11GetZeroBit ;no--it's a zerobsf SHT11Byte,0 ;if it's a one, set the LSB in

SHT11Byte

Page 16: PIC16F84 Code for the NK0E Weather Station Project

goto SHT11GotBit

SHT11GetZeroBitbcf SHT11Byte,0 ;set the LSB to zero in SHT11Byte

SHT11GotBitbcf PORTA,_SHT11_SCK ;set the clock line low again.decfsz counter,Fgoto SHT11GetNextBitgoto SHT11GetByteDone

SHT11GetNextBitrlf SHT11Byte,F ;move the bits over to get the next

bitgoto SHT11GetByteLoop

SHT11GetByteDone

return

;------end SHT11GetByte-----------------------------------------------

;------begin SendAck-------------------------------------------------;; send the ack. Set the data line as an output:

SendAckbsf STATUS,RP0 ;switch to bank 1bcf TRISA,_SHT11_DAT ;make Port A data line an outputbcf STATUS,RP0 ;switch back to bank 0

; now send the ack. Take the data line low.

bcf PORTA,_SHT11_DATbsf PORTA,_SHT11_SCKbcf PORTA,_SHT11_SCK

; now make the data line an input again.

bsf STATUS,RP0 ;switch to bank 1bsf TRISA,_SHT11_DAT ;make Port A data line an inputbcf STATUS,RP0 ;switch back to bank 0

return

;------end SendAck---------------------------------------------------

;------begin SendErrorCode-------------------------------------------

Page 17: PIC16F84 Code for the NK0E Weather Station Project

;; send error code back to PC. Error code is 'e' plus a digit. Load; ASCII value of digit into 'digit' register before calling.

SendErrorCodemovlw 'e'movwf TXCharcall SendACharmovf digit,Wmovwf TXCharcall SendACharcall SendCRLFreturn

;------end SendErrorCode---------------------------------------------

;------begin TellTemperature-----------------------------------------

;This subroutine is called when the 't' command is received. Calls;SHT11TXRX.

TellTemperature

movlw 3movwf SHT11Bytecall SHT11TXRX

goto MainLoop

;------end TellTemperature-------------------------------------------

;------begin TellHumidity--------------------------------------------

;This subroutine is called when the 'h' command is received. Calls;SHT11TXRX.

TellHumidity

movlw 5movwf SHT11Bytecall SHT11TXRX

goto MainLoop

Page 18: PIC16F84 Code for the NK0E Weather Station Project

;------end TellHumidity----------------------------------------------

;------begin SendCRLF------------------------------------------------;; Send the terminating CR and LF:

SendCRLFmovlw 13movwf TXCharcall SendACharmovlw 10movwf TXCharcall SendACharreturn

;------end SendCRLF--------------------------------------------------

;------begin SendAsciiNum--------------------------------------------;; load lo, hi with 16 bit unsigned num to send

SendAsciiNumdodigit 10000movf digit,Wmovwf TXCharcall SendAChardodigit 1000movf digit,Wmovwf TXCharcall SendAChardodigit 100movf digit,Wmovwf TXCharcall SendAChardodigit 10movf digit,Wmovwf TXCharcall SendACharmovf lo,w ; ls byte is already correctaddlw '0' ; convert to asciimovwf TXCharcall SendACharreturn ; done

; "dosub" is called by the "dodigit" macro defined above.; Subtract the number in shi/slo from hi/lo until the result; is negative, incrementing the ascii equivelent each time.

Page 19: PIC16F84 Code for the NK0E Weather Station Project

dosub movlw '0'-1movwf digit

moresub incf digit,F ; increment ASCII charactermovf slo,w ; subtract current power of 10subwf lo,fmovf shi,wbtfss STATUS,Caddlw 1subwf hi,fbtfsc STATUS,C ; any carry?goto moresub ; no, keep subtracting

movf slo,w ; reverse the last subtractionaddwf lo,fmovf shi,wbtfsc STATUS,Caddlw 1addwf hi,freturn

;------end SendAsciiNum----------------------------------------------

;------begin ReportVersion-------------------------------------------

; send a string with the version in it. The string comes from EEPROM; memory and is null-terminated. The null terminator is not sent. The; protocol dictates that the string sent is terminated by a CR, which; is sent. This subroutine is called when the 'v' command is received.

ReportVersionbcf STATUS,RP0clrf EEADR ;the string we want starts at the

;beginning of EEPROM memory.

GetNextVersionCharbsf STATUS,RP0bsf EECON1,RDbcf STATUS,RP0movf EEDATA,Wbtfsc STATUS,Z ;if the character in W is null, don't

;send any more.goto MainLoop

movwf TXCharcall SendACharincf EEADR,F

Page 20: PIC16F84 Code for the NK0E Weather Station Project

goto GetNextVersionChar

;------end ReportVersion---------------------------------------------

;------begin Idle----------------------------------------------------;; Idle should be called whenever the chip is waiting for something; to happen (waiting for a character to be sent or received, for; example). Here it's not doing anything.

Idlereturn

;------end Idle------------------------------------------------------

;------Main Program--------------------------------------------------

Main

; set up the ports as inputs and outputs as needed.

bsf STATUS,RP0 ;switch to bank 1movlw 0xFFmovwf TRISB ;make Port B inputmovlw 0x00movwf TRISA ;make Port A outputbcf STATUS,RP0

clrf PORTA

call SerSetup ;set up serial comm routines & int.

; this main program simply waits for characters to be received, then; calls the handler for the command indicated by the received character.

MainLoopcall GetAChar ;wait for a character

movf RXBuff,W ;move the rx char into Wsublw 't' ;compare with 't' characterbtfsc STATUS,Zgoto TellTemperature ;if t, report the temperature

movf RXBuff,W ;move the rx char into Wsublw 'h' ;compare with 'h' character

Page 21: PIC16F84 Code for the NK0E Weather Station Project

btfsc STATUS,Zgoto TellHumidity ;if h, report the humidity

movf RXBuff,W ;move the rx char into Wsublw 'v' ;compare with 'v' characterbtfsc STATUS,Zgoto ReportVersion ;if v, report the version number

goto MainLoop

;------Version EEPROM------------------------------------------------

org 0x2100de "WxPIC v0.3b (c) 2002 by NK0E",0x0D,0x0A,0x00 ;

Version 0.3bend