Thnx for the fast answere.
Wel, i only make intcon.6 0 in the isr-loop.
Hope you can help me..
Thnx for the fast answere.
Wel, i only make intcon.6 0 in the isr-loop.
Hope you can help me..
TRY
or another variant ofCode:@ __CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON CMCON=7 TRISA=0 TRISB=0 PORTA=0 PORTB=0 PIE1 = %00000010 '0------- Disable EE write complete interrupt '-0------ Disable comparator interrupt '--0----- Disable USART receive interrupt '---0---- Disable USART transmit interrupt '----x--- unimplemented '-----0-- Disable CCP1 interrupt '------1- Enable TMR2 to PR2 match interrupt '-------0 Disable TMR1 overflow interrupt T2CON = %00000010 'X------- Unimplemented '-0000--- postscale 1:1 '-----0-- Timer2 off '------10 prescaler 1:16 GIE VAR INTCON.7 PEIE VAR INTCON.6 TMR2IF VAR PIR1.1 TMR2ON VAR T2CON.2 RELOAD CON 131 ON INTERRUPT GOTO ISR TMR2 = RELOAD PR2 = 0 PEIE = 1 ' Enable peripheral interupt GIE = 1 ' enable Global interrupt TMR2ON = 1 ' TMR2 ON GOTO LOOP disable ISR: TOGGLE PORTB.0 TMR2ON = 0 TMR2 = RELOAD TMR2ON = 1 TMR2IF = 0 ' Clear interrupt flag resume enable LOOP: 'TOGGLE PORTB.1 GOTO LOOP
The second one is probably the best method to deal with Timer2. have a look to section 6.0 of your datasheet.Code:@ __CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON CMCON=7 TRISA=0 TRISB=0 PORTA=0 PORTB=0 PIE1 = %00000010 '0------- Disable EE write complete interrupt '-0------ Disable comparator interrupt '--0----- Disable USART receive interrupt '---0---- Disable USART transmit interrupt '----x--- unimplemented '-----0-- Disable CCP1 interrupt '------1- Enable TMR2 to PR2 match interrupt '-------0 Disable TMR1 overflow interrupt T2CON = %00000010 'X------- Unimplemented '-0000--- postscale 1:1 '-----0-- Timer2 off '------10 prescaler 1:16 GIE VAR INTCON.7 PEIE VAR INTCON.6 TMR2IF VAR PIR1.1 TMR2ON VAR T2CON.2 ON INTERRUPT GOTO ISR PR2 = 124 ' load period register for 2mSec PEIE = 1 ' Enable peripheral interupt GIE = 1 ' enable Global interrupt TMR2ON = 1 ' TMR2 ON GOTO LOOP disable ISR: TOGGLE PORTB.0 TMR2IF = 0 ' Clear interrupt flag resume enable LOOP: 'TOGGLE PORTB.1 GOTO LOOP
Last edited by mister_e; - 27th December 2007 at 20:07.
Steve
It's not a bug, it's a random feature.
There's no problem, only learning opportunities.
Thanks, it works now!
First i tried to inplement your code in mine but that didnd work.
So I fit my program in yours and the first test works.
Here's my code fore enyone with the same problem.
Now I'm have to set all my other code in it. Hope it don't make problems with the changed config now.
Code:@ device pic16F628a, INTRC_OSC_NOCLKOUT @ device pic16F628a, MCLR_ON @ device pic16F628a, LVP_OFF @ device pic16F628a, WDT_OFF @ device pic16F628a, PWRT_ON @ device pic16F628a, BOD_ON INCLUDE "modedefs.bas" 'for shiftout CMCON=7 TRISA=0 TRISB=0 PORTA=0 PORTB=0 PIE1 = %00000010 '0------- Disable EE write complete interrupt '-0------ Disable comparator interrupt '--0----- Disable USART receive interrupt '---0---- Disable USART transmit interrupt '----x--- unimplemented '-----0-- Disable CCP1 interrupt '------1- Enable TMR2 to PR2 match interrupt '-------0 Disable TMR1 overflow interrupt T2CON = %00000010 'X------- Unimplemented '-0000--- postscale 1:1 '-----0-- Timer2 off '------10 prescaler 1:16 segments var byte counter var byte GIE VAR INTCON.7 PEIE VAR INTCON.6 TMR2IF VAR PIR1.1 TMR2ON VAR T2CON.2 ON INTERRUPT GOTO ISR PR2 = 124 ' load period register for 2mSec PEIE = 1 ' Enable peripheral interupt GIE = 1 ' enable Global interrupt TMR2ON = 1 ' TMR2 ON GOTO LOOP disable ISR: 'first half of the displays segments=%01011011 '5 counter=%01010101 'on displays SHIFTOUT PORTB.0, PORTB.1, LSBFIRST,[counter\8,segments\8] 'data, clock pulsout PORTA.4,1 'for latch 74hc595 'remaining displays segments = %00110000 '1 counter=%10101010 SHIFTOUT PORTB.0, PORTB.1, LSBFIRST,[counter\8,segments\8] 'data, clock pulsout PORTA.4,1 'for latch 74hc595 '------- ^^my try TOGGLE PORTB.0 TMR2IF = 0 ' Clear interrupt flag resume enable LOOP: 'TOGGLE PORTB.1 GOTO LOOP end
Dear,
I still have a problem.
I have merged all the code and the beginning works fine now.
It go's to the loop: makes a I2C read.
Go's to another loop for I2C write(only if needed).
Then it have to wait for the the interupt.
At the interrupt is starts to shiftout the data for the display.
Until here it works fine.
The problem is: it keeps doing that and NEVER goes back to the loop..
This didn't I know becose in the testprogram there was noting to do in the loop..
I can post the code when someone needs it but it's the same as above, only with some onther code inside it.
Dos anyone know what I do wrong?
ISRs should be keep as short as possible, i feel that what you do inside may need much time than 2mSec?
If so...you may stop the timer, do your stuff, re-start the timer and clear the interrupt flag.. but yeah you loose all of this needed 2mSec accuracy... even using Darrel's favorite ON INTERRUPT
Try to reduce your 2mSec to let's say 5-10 mSec
But that's a feeling. Post your whole code here with the I2C stuff.
Last edited by mister_e; - 28th December 2007 at 21:24.
Steve
It's not a bug, it's a random feature.
There's no problem, only learning opportunities.
My isr is long, but at 4MHz and no delay instructions it has not to be the problem.
Well, I tried to set the presale to 1:16. 1:4 had to make a interrupt every 2mSec.
after that I tried to turn off the timer and after that, turn it back on. All had no effect.
So, I came back here.
This is all my code:
first config, var's and isr
then main loop
after that the complete menu
Much of the code was for a rtc-clock using a lcd. Thats why some of the loops are empty now.
Code:@ device pic16F628a, INTRC_OSC_NOCLKOUT @ device pic16F628a, MCLR_ON @ device pic16F628a, LVP_OFF @ device pic16F628a, WDT_OFF @ device pic16F628a, PWRT_ON @ device pic16F628a, BOD_OFF'ON INCLUDE "modedefs.bas" 'for shiftout pause 50 ' Defines ' ---------------- 'I2C pins DS_SCL VAR PORTA.0 ' I2C clock pin DS_SDA VAR PORTA.1 ' I2C data pin 'RTC CON %11010000 ' RTC device address (byte addressing) not needed 'Setting the RTC so we can get out 1Hz tick output '------------------------------------------------- ' -------------- RTC definitions ----------------- SecReg CON $00 ' seconds address (00 - 59) ' MSB of SecReg must be set to a 0 to enable RTC MinReg CON $01 ' minutes address (00 - 59) HourReg CON $02 ' hours address (01 - 12) or (00 - 23) DayReg CON $03 ' day address (1 - 7) DateReg CON $04 ' date address (01 - 28/29, 30, 31) MonthReg CON $05 ' month address (01 - 12) YearReg CON $06 ' year address (00 - 99) ContReg CON $07 ' control register RTCflag CON 0 ' RTC flag (location 0 of internal EEPROM) cntrl CON %00010000 ' sets the SQW/OUT to 1Hz pulse, logic level low ' The variable below holds the values entered: 'menu var's _sec VAR BYTE ' $00 set seconds _min VAR BYTE ' $56 set minutes _hr VAR BYTE ' $23 set hour _day VAR BYTE ' $06 set day _date VAR BYTE ' $28 set date _mon VAR BYTE ' $02 set month _yr VAR BYTE ' $03 set year 'rtc var's sec VAR BYTE ' seconds MINs VAR BYTE ' minutes hr VAR BYTE ' hours day VAR BYTE ' day date VAR BYTE ' date mon VAR BYTE ' month yr VAR BYTE ' year 'button input '------------------- SetButton var PORTa.7 ' Press to Set/memorise Button DecButton var PORTa.3 ' Press to Decrement Button IncButton var PORTa.2 ' Press to Increment Button 'other var's '------------------ CounterA var byte ' General purpose Variable CounterB var byte ' General purpose Variable CounterC var byte ' General purpose Variable CounterD var byte ' General purpose Variable ButtonRepeat con 200 ' Timeperiod (in mS for Edit Buttons auto-repeat ' should you want to hold them down... RTCCtrl var byte ' Control TimeOut var word ' Variable for SetUp Menu Time-Out SetTime var byte ' 12/24 Hour Clock RTCWDay var byte ' Weekday timeformat var word ' place for displaying am/pm counter var byte counter2 var byte counter3 var word ' delaycounter counter4 var word ' counter at redisplayloop segments var byte myBCD var byte toDEC var byte 'I/O pins 'port conditions '--------------- CMCON=7 TRISA=0 TRISB=0 PORTA=0 PORTB=0 'timer and interruptconditions '---------------- PIE1 = %00000010 '0------- Disable EE write complete interrupt '-0------ Disable comparator interrupt '--0----- Disable USART receive interrupt '---0---- Disable USART transmit interrupt '----x--- unimplemented '-----0-- Disable CCP1 interrupt '------1- Enable TMR2 to PR2 match interrupt '-------0 Disable TMR1 overflow interrupt T2CON = %00000010 'X------- Unimplemented '-0000--- postscale 1:1 '-----0-- Timer2 off '------10 prescaler 1:16 GIE VAR INTCON.7 PEIE VAR INTCON.6 TMR2IF VAR PIR1.1 TMR2ON VAR T2CON.2 RELOAD CON 131 ON INTERRUPT GOTO ISR TMR2 = RELOAD PR2 = 0 ' load period register for 2mSec PEIE = 1 ' Enable peripheral interupt GIE = 1 ' enable Global interrupt TMR2ON = 1 ' TMR2 ON GOTO LOOP disable ISR: 'interruptroutine TMR2ON=0 'later to use to reduce the isr text. then only shiftout the var's if counter3=>200 then 'number of shiftouts counter3=0 else counter3=counter3+1 endif 'hours 'the one that is 0 wil blink 'for segments the opposite counter = %01111111 '1 segment toDEC = hr if hr.6=1 then '12 uurs mode todec = todec <<3 todec = todec >>7 else '24 uurs mode todec = todec <<2 todec = todec >>6 endif gosub findsegments if hr.6 = 1 then 'add in the am/pm indication if hr.5 = 1 then segments.7 = %1 endif endif gosub segmentsshiftout counter = %10111111 '2 segment toDEC = hr toDEC = toDEC << 4 'shiftout unusable data todec = todec >> 4 'shiftback usable data gosub findsegments if portA.6 = 1 then segments.7 = %1 'add the blinkin dot gosub segmentsshiftout 'minits counter = %11011111 '3 segment toDEC = MINs todec = todec >> 4 'shiftback usable gosub findsegments gosub segmentsshiftout counter = %11101111 '4 segment toDEC = MINs todec = todec << 4 'shiftout unusable data todec = todec >> 4 gosub findsegments gosub segmentsshiftout 'seconds counter = %11110111 '5 segment toDEC = sec todec = todec >> 4 'shiftback usable gosub findsegments gosub segmentsshiftout counter = %11111011 '6 segment toDEC = sec todec = todec << 4 'shiftout unusable data todec = todec >> 4 gosub findsegments if hr.6=1 then 'mode indication segments.7=%1 endif gosub segmentsshiftout counter = %11111111 'to take care that no segment is blinking harder todec = %00000000'todec >> 4 gosub segmentsshiftout segmentsshiftout: SHIFTOUT PORTB.0, PORTB.1, LSBFIRST,[counter\8,segments\8] 'data, clock pulsout PORTA.4,1 return findsegments: if todec=%00000000 then '0 segments = %01111110 endif if todec=%00000001 then '1 segments = %00110000 endif if todec=%00000010 then '2 segments = %01101101 endif if todec=%00000011 then '3 segments = %01111001 endif if todec=%00000100 then '4 segments = %00110011 endif if todec=%00000101 then '5 segments = %01011011 endif if todec=%00000110 then '6 segments = %01011111 endif if todec=%00000111 then '7 segments = %01110000 endif if todec=%00001000 then '8 segments = %01111111 endif if todec=%00001001 then '9 segments = %01111011 endif return TMR2 = RELOAD TMR2ON = 1 TMR2if=0 ' Clear interrupt flag resume enable LOOP: I2CRead DS_SDA,DS_SCL,$D0,$00, [sec,MINs,hr,day,date,mon,yr] ' Read Ds1307 If sec.7=1 then goto coldstart If setbutton = 0 then 'if setbutton is pressed _hr=hr _min=MINs _sec=sec gosub SetButtonRelease Gosub SetTimeAndDate 'after release endif counter3=0 repeat 'show the segments for 5 times. pauseus 10 until counter3 > 5 GoTo Loop end Segmentswrite2:'write settimevar's to timevar's in bcd CounterA=_hr If SetTime=1 then If CounterA>12 then CounterA=CounterA-12 If CounterA=0 then CounterA=12 endif Gosub ConvertBCD hr=CounterB ' Save the Hours Value If SetTime=1 then hr.6=1 ' Save the 12 Hour Mode Flag If _hr=>12 then hr.5=1 ' Save the 'PM' Flag endif ' ' Save Minutes ' ------------ CounterA=_min Gosub ConvertBCD MINs=CounterB ' ' Save Seconds ' ------------ CounterA=_sec Gosub ConvertBCD sec=CounterB 'gosub segmentswrite return 'paste here the other half of the code
Last edited by ADCON; - 28th December 2007 at 22:45.
the text wat to long to set in one message
Code:'paste here the above code SetTimeAndDate: '============= Setup: SetTime=hr.6 ' Determines 12/24 Hour mode If SetTime=1 then ' Regardless of 12/24 options, SetHour always ' contains the hours in 24 hour clock format ' otherwise there's twice the amount of work ' to keep track in the edit routines _hr=(hr>>4)&$01 ' if 12-hour mode else _hr=(hr>>4)&$03 ' if 24 hour mode endif _hr=_hr*10+(hr&$0F) If SetTime=1 then If hr.5=1 then If _hr<12 then _hr=hr+12 ' Add-in the AM/PM indicator else If _hr=12 then _hr=0 endif endif _Min=((Mins>>4)&$0F)*10+(Mins&$0F) _Sec=((Sec>>4)&$0F)*10+(sec&$0F) _yr=((yr>>4)&$0F)*10+(yr&$0F) _mon=((mon>>4)&$0F)*10+(mon&$0F) _day=((day>>4)&$0F)*10+(day&$0F) ' ' Setup Menu Loop ' --------------- CounterC=0 ' Set to Start of Setup (seven steps from 0 to 6) TimeOut=0 ' Zero the Time-Out counter SetupLoop: ' ' Now Display the Data ' -------------------- SetupDisplayLoop: ' ' 12/24 Hour Option ' ----------------- ' ' The Data-Entry Bit ' ------------------ SetupEntryLoop: 'datainput. ' ' Decrement(down) Button Pressed ' ------------------------ If DecButton=0 then ' ' 12/24 Clock Selection ' --------------------- If CounterC=0 then If SetTime=0 then SetTime=1 else SetTime=0 endif endif ' ' Decrement Hours ' --------------- If CounterC=1 then If _hr=0 then _hr=23 else _hr=_hr-1 endif endif ' ' Decrement Minutes ' ----------------- If CounterC=2 then If _Min=0 then _Min=59 else _Min=_Min-1 endif endif ' ' Decrement Seconds ' ----------------- ' Kinda overkill to include setting seconds, ' but if you got codespace to burn... If CounterC=3 then If _Sec=0 then _Sec=59 else _Sec=_Sec-1 endif endif gosub Pauseloop TimeOut=0 Goto SetUpDisplayLoop endif ' ' Increment(up) Button Pressed ' ------------------------ ' This is just like Decrement but opposite... If IncButton=0 then ' ' 12/24 Clock Selection ' --------------------- If CounterC=0 then If SetTime=1 then SetTime=0 else SetTime=1 endif endif ' ' Increment Hours ' --------------- If CounterC=1 then If _hr=>23 then _hr=0 else _hr=_hr+1 endif endif ' ' Increment Minutes ' ----------------- If CounterC=2 then If _min=>59 then _Min=0 else _Min=_Min+1 endif endif ' ' Increment Seconds ' ----------------- ' Kinda overkill to include setting seconds, ' but if you got codespace to burn... If CounterC=3 then If _Sec=>59 then _Sec=0 else _Sec=_Sec+1 endif endif gosub Pauseloop TimeOut=0 Goto SetupDisplayLoop endif ' ' Set Button Pressed ' ------------------ If setbutton =0 then CounterC=CounterC+1 ' Increment Menu Item TimeOut=0 endif If CounterC>3 then 'old menu counterC>6######################### ' Save Data if all edit items exhaused ' ' Save 12/24 Hours to BCD DS1307's Format ' --------------------------------------- CounterA=_hr If SetTime=1 then If CounterA>12 then CounterA=CounterA-12 If CounterA=0 then CounterA=12 endif Gosub ConvertBCD hr=CounterB ' Save the Hours Value If SetTime=1 then hr.6=1 ' Save the 12 Hour Mode Flag If _hr=>12 then hr.5=1 ' Save the 'PM' Flag endif ' ' Save Minutes ' ------------ CounterA=_min Gosub ConvertBCD MINs=CounterB ' ' Save Seconds ' ------------ CounterA=_sec Gosub ConvertBCD sec=CounterB ' ' Do the Business ' --------------- rtcwrite: I2CWrite DS_SDA, DS_SCL,$D0,$00,[sec,MINs,hr,RTCWDay,day,mon,yr,RTCCtrl] Gosub SetButtonRelease Goto ReDisplay endif Gosub SetButtonRelease Goto SetupLoop ' Loop for Next Menu Item ' ' Menu TimeOut Counter ' -------------------- gosub Segmentswrite2 TimeOut=TimeOut+1 'not jet working good If TimeOut>20000 then goto ReDisplay ' User paused too long ' Return User to Time & Date Display ' This will however bounce the User to the original ' Setup Menu start point if the DS1307 has not ' been initialised Goto SetupEntryLoop ' Loop for Button Press Pauseloop: 'some timedelay counter3=0 repeat pauseus 10 until counter3 > 50 return 'just a routine to make sure you didn't push the button by faulth '------------------------------------ SetButtonRelease: 'delay for button counter3=0 while setbutton=0 pauseus 10 Wend if counter3=>29 then repeat pauseus 10 until counter3 > 70 else goto loop endif Return FindDays: 'deleted Return DisplayMonth:'deleted DisplaySequence: 'deleted Return ' ' Subroutine Converts back to BCD ' ------------------------------- ' CounterA is the entry variable ' CounterB holds the converted BCD result on exit ConvertBCD: CounterB=CounterA DIG 1 CounterB=CounterB<<4 CounterB=CounterB+CounterA DIG 0 Return Redisplay: 'deleted return Am_or_Pm: 'deleted return coldstart: 'only started when rtc starts from cold '--xx-- _yr=0:_date =0:_mon =0:_day=0:_hr=0:_min=0:_sec=0 ' The constants below set the RTC to: 16:30:00 on 13-07-2003 _yr=$03 _mon=$07 _date=$13 _hr=$16 _sec=$00 _min=$30 I2CWrite DS_SDA, DS_SCL, $D0,$00,[_sec,_min,_hr,_day,_date,_mon,_yr,cntrl] Return
Last edited by ADCON; - 28th December 2007 at 22:46.
Bookmarks