![]() | ![]() | ![]() |
| | |||||||
| Notices |
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | LinkBack | Thread Tools | Display Modes |
| | (permalink (permalink)) |
| Hi all I am a beginner, trying to build a Temp controller that will keep the stats like temp at hour intervals for the last month etc. The temp controller will have one heating and one cooling output. Setting up the menus and outputs is not that hard, but I know reading the thermistor (ADC) and this RTC part will be the hardest. I am stuck on the RTC for now... I almost know the 2520 data sheets by hart by now, but that did not help me enough... In my code I just tried to display one digit of the secs for testing (must still figure out how to display the second digit), but it's not counting up... Any help or info will be appreciated... Code: ;****************************************************************************** ; * ; Filename: Temperature Controller based on PIC18F2520 * ; ===================================================== * ; * ; * ; * ; Program written by D, Jordaan * ; * ; V1.00 Aug 2007 Initial menu * ; * ;****************************************************************************** ; ; Processor Type ; ============== ; LIST P=18F2520,r=hex,n=80,x=off,st=off errorlevel -302 ; no bank warnings #include <P18F2520.INC> ; DELAY PARAMETERS FOR 4MEG CRYSTAL clock equ 4000000 ; my crystal frequency dusec equ 1000 ; required delay (1 mSec) #include <timer.inc> ; note, include must be after these two definitions ;****************************************************************************** ; ; Configuration bits ; ================== ; specified here are changes to the .inc file defaults CONFIG OSC=INTIO67, PWRT=ON, BOREN=OFF, WDT=OFF, MCLRE=OFF, LPT1OSC=OFF, PBADEN=OFF CONFIG LVP=OFF, XINST=OFF, DEBUG=OFF ;****************************************************************************** ; ; Variable definitions ; ==================== ; Bank1 variables 0x100 to 0x1FF cblock 0x100 ; BANK1 pntr offset dval lcd_flags lcd_temp t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 ;40 c20 RB0CP secs mins hours endc ; last address entered max FF LEDPORT1 Equ PORTA ;set constants for output ports LEDPORT_1 Equ 2 LEDPORT2 Equ PORTA LEDPORT_2 Equ 1 LEDPORT3 Equ PORTC LEDPORT_3 Equ 3 LEDPORT4 Equ PORTB LEDPORT_4 Equ 0 LEDPORT5 Equ PORTC LEDPORT_5 Equ 4 LEDPORT6 Equ PORTC LEDPORT_6 Equ 5 LEDPORT7 Equ PORTC LEDPORT_7 Equ 6 LEDPORT8 Equ PORTC LEDPORT_8 Equ 7 SWPORT1 Equ PORTA ;set constants for input ports SWPORT_1 Equ 5 SWPORT2 Equ PORTA SWPORT_2 Equ 4 SWPORT3 Equ PORTE SWPORT_3 Equ 3 SWPORT4 Equ PORTA SWPORT_4 Equ 3 SWPORT5 Equ PORTC SWPORT_5 Equ 2 ;****************************************************************************** ; ; Reset vector ; ============ ORG 0x0000 bootup goto Main ;go to start of main code ORG 0008h ; an interrupt redirects the program to here RTCisr ; Start ISR here ; Insert the next 4 lines of code when TMR1 ; can not be reliably updated before clock pulse goes low ; BTFSC TMR1L,0 ; wait for TMR1L<0> to become clear ; BRA $-2 ; (may already be clear) ; BTFSS TMR1L,0 ; wait for TMR1L<0> to become set ; BRA $-2 ; TMR1 has just incremented ; If TMR1 update can be completed before clock pulse goes low BSF TMR1H, 7 ; Preload for 1 sec overflow BCF PIR1, TMR1IF ; Clear interrupt flag INCF secs, F ; Increment seconds MOVLW .59 ; 60 seconds elapsed? CPFSGT secs RETFIE ;RETURN ; No, done CLRF secs ; Clear seconds INCF mins, F ; Increment minutes MOVLW .59 ; 60 minutes elapsed? CPFSGT mins RETFIE; RETURN ; No, done CLRF mins ; clear minutes INCF hours, F ; Increment hours MOVLW .23 ; 24 hours elapsed? CPFSGT hours RETFIE ;RETURN ; No, done CLRF hours ; Reset hours RETFIE ;RETURN ; Done ;****************************************************************************** ;****************************************************************************** ; ; Start of main program ; ===================== ; initialisation of system, clear RAM , setup i/o ports Main movlb D'1' ; define bank1, so it and bank 0/15 (access) ; can be addressed without banking clrf INTCON ; clear interupts clrf STATUS ; reset to bank 0 clearam clrf FSR1H ; FSR routine to clear ram banks 0 -4 only clrf FSR1L clrram clrf POSTINC1 ; clear location and inc movlw 0x05 ; now in bank5 ? subwf FSR1H,W bnz clrram ; carry on clearing if not at bank5 ; ***************************************************************************** ; ; Port Allocation - Standard Multi Controller on 2520 chip ; ; ; PortA ra0 AI NTC1 PortB rb0 OUT TIMER3 ; ra1 OUT HEATER rb1 lcd e1 ; ra2 OUT COOLER1 rb2 lcd rs ; ra3 IN SW3 rb3 lcd rw ; ra4 IN KEY A rb4 lcd d4 ; ra5 IN KEY B rb5 lcd d5 ; ra7 IN Unalloc rb6 lcd d6 ; ra6 IN Unalloc rb7 lcd d7 ; PortC rc0 timer1 xtal PortE re3 IN EXT ALARM ; rc1 timer1 xtal1 ( set by config ) ; rc2 IN SW4 ; rc3 OUT COOLER2 ; rc4 OUT LIGHT1 ; rc5 OUT LIGHT2 ; rc6 OUT TIMER4 ; rc7 OUT ALARM ports clrf PORTA clrf PORTB clrf PORTC movlw b'00001110' ; set portA,0 as adc input bit 7 rjust movwf ADCON1 ; by loading value to adcon1 reg movlw b'00111001' ; set trisa direction is input movwf TRISA ; bit0 adc, bit1,2 DO, bit3,4,5 DI , bit7,6 DO movlw b'00000000' ; set portB as low outputs movwf TRISB movlw b'00000100' ; set portC low outputs, except rc2 DI movwf TRISC ; *************************************************************************** ; ; Start Timers ; ============ ; Timer0 as base for Delay 1ms movlw b'11010000' | PRESCL movwf T0CON ; movlw b'00000001' ; movwf PIE1 ; movlw b'00000001' ; movwf IPR1 RTCinit MOVLW 80h ; Preload TMR1 register pair MOVWF TMR1H ; for 1 second overflow CLRF TMR1L MOVLW b'00001111' ; Configure for external clock, MOVWF T1CON ; Asynchronous operation, external oscillator CLRF secs ; Initialize timekeeping registers CLRF mins ; MOVLW .12 MOVWF hours BSF PIE1, TMR1IE ; Enable Timer1 interrupt ; RETURN ; *************************************************************************** ; ; Init LCD Display ; ================ ; eedata routines inserted in middle of initlcd routine ; needed to come after the setemps which restore eprom call lcd_init ; initialise the LCD driver ; *************************************************************************** ; ; Running Program Starts Here ; =========================== loop call dataone call datatwo call sendone call sendtwo MainMen btfss SWPORT1, SWPORT_1 ;enter menu if SW1 pushed goto LED1ON goto loop ;=============================================================================== ; ; SUBROUTINES ; ;=============================================================================== ;************************************************************************* ;Real-time Clock ;************************************************************************* ;************************************************************************* ; Main Menu ;************************************************************************* LED1ON bsf LEDPORT1, LEDPORT_1 ;turn LED1 on call DataLed1 call sendone ;Send Led 1 on message call DoDelay30 ;wait a bit goto LED1_2 LED1_2 btfss SWPORT1, SWPORT_1 ;check if switch pushed again goto LED2ON ;yes, goto switch led2 on goto LED1_2 ;no, loop and check again LED2ON bcf LEDPORT1, LEDPORT_1 ;turn LED 1 off bsf LEDPORT2, LEDPORT_2 ;turn LED2 on call DataLed2 call sendone ;send LED 2 on message call DoDelay30 ;wait a bit goto LED2_2 LED2_2 btfss SWPORT1, SWPORT_1 ;is SW1 pushed? call ClearPorts ;yes, turn all LED's off and exit menu goto LED2_2 ;no, loop and check again ClearPorts bcf LEDPORT1, LEDPORT_1 ;Switch off led's bcf LEDPORT2, LEDPORT_2 call DoDelay30 goto loop ; *************************************************************************** ; ; Delay Routine for LCD ; ===================== ; using the internal timer, will delay for W times the value of ; "dusec" in microseconds. (used by lcd routine) delay movwf dval dy1 clrf TMR0L bcf INTCON,T0IF movlw TMRVAL ; set timer movwf TMR0L dy2 btfss INTCON,T0IF ; timer overflow yet? goto dy2 ; no decfsz dval,f ; yes, all cycles? goto dy1 ; no return ; yes, delay finished ; *************************************************************************** ; ; Macros for LCD routine ; ====================== dotris macro arg1, arg2 movlw arg1 movwf arg2 endm dodelay macro arg1 movlw arg1 call delay endm DoDelay30 dodelay 30 return ;**************************************************************************** ; ; Routines to display on a 2x16 character LCD Standard 7 bit version ; =========================================== ====================== ; ; LcdInit - call this subroutine before using the display. It uses ; bits 7-1 of PORTB, leaving bit-0 free (although it will ; be configured as an output). ; ; Lcd_C - Sends the byte in W as a command to the display. Checks ; if busy first. ; ; Lcd_D - Sends the byte in W as data. Checks for busy first. ; ; Assumes it can call a routine called "delay" with a required ; time delay in mSecs in W. ; Uses an additional three (3) levels of the stack. ; ; Address of first line on the LCD is 0 ; Address of second line is 64 ; ; by Ron Kreymborg ; ;****************************************************************** lcd_com macro arg1 movlw arg1 call lcd_c endm ; Flags - lcd_Bflg equ 0 lcd_RSflg equ 1 ; I/O portB - lcd_BUSY equ 7 ; input - LCD is busy (0x80) lcd_R_W equ 3 ; output - LCD Read/Write (0x08) lcd_RS equ 2 ; output - Register Select (0x04) lcd_E equ 1 ; output - LCD Enable (0x02) lcd_init clrf PORTB dotris b'00000000',PORTB ; all outputs and low to start bcf lcd_flags,lcd_RSflg dodelay 15 ; 15mSec power up delay movlw b'00110000' ; 8-bit mode movwf PORTB call lcd_clk dodelay 4 ; 4mSec wait movlw b'00110000' ; 8-bit mode movwf PORTB call lcd_clk dodelay 1 ; 1 mSec wait movlw b'00110000' ; 8-bit mode movwf PORTB call lcd_clk dodelay 4 ; 4mSec wait movlw b'00100000' ; set for 4-bit movwf PORTB call lcd_clk ; Reset sequence is done - initialise for us lcd_com b'00101000' ; 4-bits, 2-lines, 5x7 lcd_com b'00001000' ; display off, cursor off, blink off lcd_com b'00001100' ; display on lcd_com b'00000001' ; clear display lcd_com b'00000110' ; increment, no display shift return ; Check whether the LCD is busy. Loop until it isn't. When ; it's free, output the byte passed in W, MS nibble first. lcd_d bsf lcd_flags,lcd_RSflg ; set RS flag for data goto lcd_o1 lcd_c bcf lcd_flags,lcd_RSflg ; clear RS flag for commands lcd_o1 movwf lcd_temp ; save control word dotris b'11110000',PORTB ; RB7-4 as inputs for busy movlw 1 << lcd_R_W movwf PORTB ; set up for read lcd_o2 bcf lcd_flags,lcd_Bflg ; assume not busy bsf PORTB,lcd_E ; clock high nop ; little wait btfsc PORTB,lcd_BUSY ; busy set? bsf lcd_flags,lcd_Bflg ; yes bcf PORTB,lcd_E ; clock low nop ; little wait nop call lcd_clk ; get low bits but ignore (for now) btfsc lcd_flags,lcd_Bflg ; was it busy? goto lcd_o2 ; yes dotris b'00000000',PORTB ; RB7-4 outputs again movf lcd_temp,w ; get word to send call lcd_o3 ; send high nibble swapf lcd_temp,w ; get word again lcd_o3 andlw 0xf0 ; just high bits (clears all control bits) movwf PORTB btfsc lcd_flags,lcd_RSflg ; was lcd_RS set? bsf PORTB,lcd_RS ; yes call lcd_clk ; write current nibble return lcd_clk bsf PORTB,lcd_E ; pulse E line high nop bcf PORTB,lcd_E return ;**************************************************************************** ; *************************************************************************** ; ; SR SEND LCD DISPLAY LINE 1 ; =========================== sendone movf c0,w ; get 1st ram iorlw 0x80 ; add address for command line call lcd_c ; for line of lcd movf c1,w call lcd_d movf c2,w call lcd_d movf c3,w call lcd_d movf c4,w call lcd_d movf c5,w call lcd_d movf c6,w call lcd_d movf c7,w call lcd_d movf c8,w call lcd_d movf c9,w call lcd_d movf c10,w call lcd_d movf c11,w call lcd_d movf c12,w call lcd_d movf c13,w call lcd_d movf c14,w call lcd_d movf c15,w call lcd_d movf c16,w call lcd_d movf c17,w call lcd_d movf c18,w call lcd_d movf c19,w call lcd_d movf c20,w call lcd_d return ; *************************************************************************** ; ; SR SEND LCD DISPLAY LINE 2 ; =========================== sendtwo movf t0,w ; get 1st ram iorlw 0x80 ; add address for command line call lcd_c ; for line2 of lcd movf t1,w call lcd_d movf t2,w call lcd_d movf t3,w call lcd_d movf t4,w call lcd_d movf t5,w call lcd_d movf t6,w call lcd_d movf t7,w call lcd_d movf t8,w call lcd_d movf t9,w call lcd_d movf t10,w call lcd_d movf t11,w call lcd_d movf t12,w call lcd_d movf t13,w call lcd_d movf t14,w call lcd_d movf t15,w call lcd_d movf t16,w call lcd_d movf t17,w call lcd_d movf t18,w call lcd_d movf t19,w call lcd_d movf t20,w call lcd_d return ; *************************************************************************** ; ; SR LCD DATA MESSAGES ; ==================== dataone movlw 0x00 ; lcd line1 ram message movwf c0 movlw 'T' movwf c1 movlw 'I' movwf c2 movlw secs ;'M' movwf c3 movlw 'E' movwf c4 movlw ' ' movwf c5 movlw '2' movwf c6 movlw '3' movwf c7 movlw ':' movwf c8 movlw '0' movwf c9 movlw '0' movwf c10 movlw ' ' movwf c11 movlw ' ' movwf c12 movlw ' ' movwf c13 movlw ' ' movwf c14 movlw ' ' movwf c15 movlw ' ' movwf c16 movlw ' ' movwf c17 movlw ' ' movwf c18 movlw ' ' movwf c19 movlw ' ' movwf c20 return datatwo movlw 0x40 ; lcd line2 ram message movwf t0 movlw 'T' movwf t1 movlw 'E' movwf t2 movlw 'M' movwf t3 movlw 'P' movwf t4 movlw ' ' movwf t5 movlw 'C' movwf t6 movlw 'O' movwf t7 movlw 'N' movwf t8 movlw 'T' movwf t9 movlw 'R' movwf t10 movlw 'O' movwf t11 movlw 'L' movwf t12 movlw 'L' movwf t13 movlw 'E' movwf t14 movlw 'R' movwf t15 movlw ' ' movwf t16 movlw ' ' movwf t17 movlw ' ' movwf t18 movlw ' ' movwf t19 movlw ' ' movwf t20 return DataLed1 movlw 0x00 ; lcd line1 ram message movwf c0 movlw 'L' movwf c1 movlw 'E' movwf c2 movlw 'D' movwf c3 movlw ' ' movwf c4 movlw 'O' movwf c5 movlw 'N' movwf c6 movlw 'E' movwf c7 movlw ' ' movwf c8 movlw 'O' movwf c9 movlw 'N' movwf c10 movlw ' ' movwf c11 movlw ' ' movwf c12 movlw ' ' movwf c13 movlw ' ' movwf c14 movlw ' ' movwf c15 movlw ' ' movwf c16 movlw ' ' movwf c17 movlw ' ' movwf c18 movlw ' ' movwf c19 movlw ' ' movwf c20 return DataLed2 movlw 0x00 ; lcd line1 ram message movwf c0 movlw 'L' movwf c1 movlw 'E' movwf c2 movlw 'D' movwf c3 movlw ' ' movwf c4 movlw 'T' movwf c5 movlw 'W' movwf c6 movlw 'O' movwf c7 movlw ' ' movwf c8 movlw 'O' movwf c9 movlw 'N' movwf c10 movlw ' ' movwf c11 movlw ' ' movwf c12 movlw ' ' movwf c13 movlw ' ' movwf c14 movlw ' ' movwf c15 movlw ' ' movwf c16 movlw ' ' movwf c17 movlw ' ' movwf c18 movlw ' ' movwf c19 movlw ' ' movwf c20 return END Code: ; PRESCL and TIMER computation nolist ; Take the processor clock frequency in Hz (clock), and ; the required time delay in uSecs (dusec), and compute ; a value for the prescaler (PRESCL) and another for ; TMR0 (TIMER). _cycle equ clock >> 2 _dfreq equ 1000000 / dusec _divr equ _cycle / _dfreq if (_divr < 512) error "Delay time too short. Assign PSA to WDT." endif _test set _divr / 256 _testB equ _divr % 256 if (_testB > 0) _test set _test + 1 endif if (_test > 1) _temp set 2 PRESCL set 0 endif if (_test > 2) _temp set 4 PRESCL set 1 endif if (_test > 4) _temp set 8 PRESCL set 2 endif if (_test > 8) _temp set 16 PRESCL set 3 endif if (_test > 16) _temp set 32 PRESCL set 4 endif if (_test > 32) _temp set 64 PRESCL set 5 endif if (_test > 64) _temp set 128 PRESCL set 6 endif if (_test > 128) error "Timer requirement is outside range" endif TMRVAL equ 256 - (_cycle / _temp / _dfreq) list | |
| | |
| | (permalink (permalink)) |
| I've not worked much on RTC.. but i can give some suggestions: 1. there are number of RTC's available.. which RTC you are using.. mention that... is it DS1307..? 2. for betterment of yours.. i ask you to follow C-language , JAVA or BASIC for programming of microcontrollers.. Specially when your code is as big as this... 3. i hope you understand I2C communication.. till you get a good reply.. try searhing in this forum on the name RTC and I2C.. regards, simran..
__________________ Simran.. 8051 Specialist.. | |
| | |
| | (permalink (permalink)) |
| The only part I am worried to get working now is TMRisr, but I am not sure if I am correct with using org 0008h, and if I set the interrupt enable bits correct... I set a break point at the start of TMRisr, but it's never called when run in mplab sim.. | |
| | |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Thread | Thread Starter | Forum | Replies | Latest |
| Problem with LCD code? | spondootre | Micro Controllers | 15 | 29th April 2008 09:15 AM |
| Using Oscilloscopes | mechie | Electronic Theory | 9 | 29th November 2007 09:48 PM |
| driving multiplexed 7 segment display | mathur2000 | Micro Controllers | 7 | 24th June 2007 10:07 PM |
| microchip application A590 /display is ok now | prosound90 | Micro Controllers | 20 | 18th November 2006 09:44 PM |
| Display Driver for 16 * 16 matrix display | pmphilip | General Electronics Chat | 2 | 4th January 2006 07:14 PM |