![]() | ![]() | ![]() |
| |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
![]() |
| | Tools |
| | #1 |
|
Hi, I'm using PIC16F628A for displaying the LCD clock. I've just started and I'm using timer2 interrupt for counting the real time. I've set the interrupt rate to be 40 ms. So I need to count for 25 times to get 1 second accurate. Postscale 10 Prescale 16 4 MHz crystal = 1 us per instruction PR2 249 So, 10 * 16 * 250 * 1 us = 40 ms When I turn on the power, the clock is running, faster than as expected which is almost 2 to 3 times faster. This is the code I have: Code: LIST P=16F628A #include <P16F628A.inc> ERRORLEVEL 0, -302 __config 0x3101 cblock 0x20 count count1 counta countb templcd CountL1 CountL2 count1sec HourTen HourOne MinTen MinOne SecTen SecOne L1C0 ;line1, column 0, and so on.. L1C1 L1C2 L1C3 L1C4 L1C5 L1C6 L1C7 L1C8 L1C9 L1C10 L1C11 L1C12 L1C13 L1C14 L1C15 L2C0 L2C1 L2C2 L2C3 L2C4 L2C5 L2C6 L2C7 L2C8 L2C9 L2C10 L2C11 L2C12 L2C13 L2C14 L2C15 w_temp s_temp p_temp endc LCD_PORT Equ PORTA LCD_TRIS Equ TRISA LCD_RS Equ 0x04 ;LCD handshake lines LCD_E Equ 0x00 org 0x0000 goto Initialize org 0x0004 Interrupt movwf w_temp swapf STATUS, w clrf STATUS movwf s_temp movf PCLATH, w movwf p_temp clrf PCLATH Check1sec decf count1sec, f btfss STATUS, Z ;interrupt happens 25 times? goto Display ;if no display with the same value movlw d'25' ;if yes count for 1 second movwf count1sec StartCount movf SecOne, w xorlw d'9' btfss STATUS, Z goto ISO goto ReSO ISO incf SecOne, f goto CValue ReSO clrf SecOne movf SecTen, w xorlw d'5' btfss STATUS, Z goto IST goto ReST IST incf SecTen, f goto CValue ReST clrf SecTen movf MinOne, w xorlw d'9' btfss STATUS, Z goto IMO goto ReMO IMO incf MinOne, f goto CValue ReMO clrf MinOne movf MinTen, w xorlw d'5' btfss STATUS, Z goto IMT goto ReMT IMT incf MinTen, f goto CValue ReMT clrf MinTen movf HourTen, w btfss STATUS, Z goto CHO movf HourOne, w xorlw d'9' btfss STATUS, Z goto IHO goto ReHO IHO incf HourOne, f goto CValue ReHO clrf HourOne incf HourTen, f goto CValue CHO movf HourOne, w xorlw d'2' btfss STATUS, Z goto IHO clrf HourOne decf HourOne, f goto CValue CValue movf HourTen, w movwf L2C4 movf HourOne, w movwf L2C5 movlw 0x0A movwf L2C6 movf MinTen, w movwf L2C7 movf MinOne, w movwf L2C8 movlw 0x0A movwf L2C9 movf SecTen, w movwf L2C10 movf SecOne, w movwf L2C11 Display movf CountL2, w xorlw d'12' btfsc STATUS, Z call RestoreCL2 movf CountL2, w call LCD_Line2 movf INDF, w call ILCD_Char incf CountL2, f incf FSR call LCD_Line1 goto Int_Re RestoreCL2 movlw d'4' movwf CountL2 movlw L2C4 movwf FSR return ILCD_Cmd movwf templcd swapf templcd, w ;send upper nibble andlw 0x0f ;clear upper 4 bits of W movwf LCD_PORT bcf LCD_PORT, LCD_RS ;RS line to 0 call Pulse_e ;Pulse the E line high movf templcd, w ;send lower nibble andlw 0x0f ;clear upper 4 bits of W movwf LCD_PORT bcf LCD_PORT, LCD_RS ;RS line to 0 call Pulse_e ;Pulse the E line high call Delay5 return ILCD_Char addlw 0x30 movwf templcd swapf templcd, w ;send upper nibble andlw 0x0f ;clear upper 4 bits of W movwf LCD_PORT bsf LCD_PORT, LCD_RS ;RS line to 1 call Pulse_e ;Pulse the E line high movf templcd, w ;send lower nibble andlw 0x0f ;clear upper 4 bits of W movwf LCD_PORT bsf LCD_PORT, LCD_RS ;RS line to 1 call Pulse_e ;Pulse the E line high call Delay5 return Int_Re movf p_temp, w movwf PCLATH swapf s_temp, w movwf STATUS swapf w_temp, f swapf w_temp, w retfie Initialize movlw 0x07 movwf CMCON bsf STATUS, RP0 ;bank1 movlw 0x00 movwf TRISA movwf TRISB bcf STATUS, RP0 ;bank0 call Delay100 LCD_Init movlw 0x20 ;Set 4 bit mode call LCD_Cmd movlw 0x28 ;Set display shift call LCD_Cmd movlw 0x06 ;Set display character mode call LCD_Cmd movlw 0x0C ;Set display on and cursor off call LCD_Cmd call LCD_Clr ;clear display clrf PORTA movlw d'25' ;interrupt for 25 times = 1 second movwf count1sec movlw d'4' movwf CountL2 movlw HourTen movwf FSR NEXT clrf INDF movf FSR, w xorlw L2C15 btfsc STATUS, Z goto $+3 incf FSR, f goto NEXT movlw L2C4 movwf FSR movlw 0x0A movwf L2C6 movwf L2C9 movlw b'01001111' ;postscale 10, prescale 16, tmr2 on movwf T2CON bsf STATUS, RP0 movlw d'249' ;1 us x 10 x 16 x 250 = 40 ms interrupt rate movwf PR2 bsf PIE1, TMR2IE bcf STATUS, RP0 bsf INTCON, PEIE bsf INTCON, GIE Start ;main program here . . LCD_Line1 movlw 0x80 ;move to 1st row, first column call LCD_Cmd return LCD_Line2 addlw 0xc0 ;move to 2nd row, first column call LCD_Cmd return Delay255 movlw 0xff ;delay 255 mS goto d0 Delay100 movlw d'100' ;delay 100mS goto d0 Delay50 movlw d'50' ;delay 50mS goto d0 Delay20 movlw d'20' ;delay 20mS goto d0 Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock) goto d0 Delay4 movlw 0x04 goto d0 d0 movwf count1 d1 movlw 0xC7 ;delay 1mS movwf counta movlw 0x01 movwf countb Delay_0 decfsz counta, f goto $+2 decfsz countb, f goto Delay_0 decfsz count1 ,f goto d1 return Pulse_e bsf PORTB, LCD_E nop bcf PORTB, LCD_E return LCD_Clr movlw 0x01 ;Clear display call LCD_Cmd return end I have to clear them in initialize.Thanks
__________________ bananasiong | |
| |
| | #2 |
|
Can you complement an output pin at each interrupt? Place a scope on that pin and check if you really have 40ms. That way you are sure about your timer setting. If you have 40 ms the problem is your code and since I don't know PIC I can't help you further | |
| |
| | #3 |
|
You are not clearing the interrupt flag. Try inserting bcf PIR1,TMR2IF in your ISR. Mike. | |
| |
| | #4 |
|
hi, There seems to be labelling error, LCD_ and ILCD , which is it? If I correct this error and run it thru PIC sim, I get 'stack under flow' error Also in MPLAB IDE the program keeps dropping thru the ISR and keeps on re-initialising, thats probably why its running fast. Also as Mike says, Try inserting bcf PIR1,TMR2IF in your ISR.
__________________ Eric " Good enough is Perfect " I will NOT answer PM's requesting technical help, please use the Forum PIC tutorials: Nigel's www.winpicprog.co.uk/ Bill's: www.blueroomelectronics.com/ | |
| |
| | #5 | |
| Quote:
Code: hang goto hang Mike. | ||
| |
| | #6 |
|
hi mike, >> I can't see why it would drop through the ISR. It is messy though having subroutines embedded inside the ISR code. I agree its messy, the drop thru 'seemed' to happen in simulation. One point IIRC, he refreshes the display even when there is no change in the data?.. Some of the delays in the LCD write module I'm sure total out to more that his 40mSec Intr??? Hope he reworks the code and re-posts, like to see run OK. Regards
__________________ Eric " Good enough is Perfect " I will NOT answer PM's requesting technical help, please use the Forum PIC tutorials: Nigel's www.winpicprog.co.uk/ Bill's: www.blueroomelectronics.com/ | |
| |
| | #7 |
|
It all seems a bit confused?, calling subroutines within an interrupt routine isn't a good idea, and you should really keep ISR's as short and fast as possible - it's a seriously bad idea to have the display routines called from with in an ISR. I've posted timer2 clock code (with alarm as well) in this forum a couple of times in the past - my ISR routine updates the clock registers and NOTHING else. The display is updated in the main routine, this is by far the best way to do it!. | |
| |
| | #8 |
|
ditto what Nigel said. Keep interrupts as simple as possible, deal with only what you absolutely have to deal with and process everything else in the main program. This is one of the things they really hammer home in embedded systems courses in college.
| |
| |
| | #9 | |
| Quote:
I know that it isn't a good idea especially calling a delay routine in the ISR. I have just started and this is my first program on LCD. If the display routine is not in the same as where the clock register is updated, when there is any changes to the clock register, and at the same time, the program is not running in the display routine (delay routine maybe), then the clock will not be updated correctly.
__________________ bananasiong | ||
| |
| | #10 |
|
You simply update the clock in the main program, either check to see if the seconds counter has changed, and if so then update the clock. Or, even simpler, set a flag in the interrupt routine every time the seconds are incremented - the main routine checks this flag, and updates when it's set - it then resets the flag ready for the next time. Any other operations (such as adjusting the clock) are also done in the same main loop, something like this: Code: Main:
Call Check_Flag ;check flag, update display if required
Call Check_Keys ;check if any keys pressed, and service them
Call Check_Alarm ;check if alarm should be triggered
Call Check_Anythingelse ;whatever you need to do
Goto Main
| |
| |
| | #11 |
|
Oh... seems I'm starting from the wrong direction. I will post up once I finish modifying the program. Thanks all
__________________ bananasiong | |
| |
|
| Tags |
| fast, pic, running |
| Thread Tools | |
| Display Modes | |
| |
Similar | ||||
| Title | Starter | Forum | Replies | Latest |
| ULTRA clean 9VDC Power Supply Project | Peter_wadley | Electronic Projects | 51 | 13th May 2009 07:58 AM |
| PIC Start Time Problem - PIC 16F628A | Suraj143 | Micro Controllers | 10 | 22nd May 2007 04:00 PM |
| Computer CLock Running Fast | bryan | Electronic Projects Design/Ideas/Reviews | 4 | 7th May 2005 06:34 AM |
| Newcomers, please read! (PIC regarded) Upd. 0xD | Jay.slovak | Micro Controllers | 0 | 17th April 2005 02:05 PM |
| pic running fast??? 12F629 problems.... | SnM | Micro Controllers | 4 | 26th January 2005 03:32 AM |