Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

RTC loses its way

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
njepsen

Bascom Member



Joined: 13 Aug 2007
Posts: 471

newzealand.gif
PostPosted: Fri Nov 20, 2015 1:47 am    Post subject: RTC loses its way Reply with quote

I have a problem with a RTC which from time to time, (no pun intended) suddenly loses 6 moths if I run a particular subroutine.
Here is the code snippets which works OK, and has been reliable for a year or more.


Code:


'*******************************************************************************
$regfile = "m1284pdef.dat"                                  'my processor
$crystal = 9830400                                          'system crystal

$framesize = 800                                            ' Located at top of 16k of SRAM
$hwstack = 250                                              '
$swstack = 250                                              '
$frameprotect = 1
'various dim statements are here


'we want to set up counter 1 to toggle 1x per sec
Dim Timer1preset As Long                                    'therefor prescale = 65536 - 39062.5 = 26473
Config Timer1 = timer , Prescale = 1024                 'counts 9830400/1024 = 9600 per sec
                                                                          'timer preset = 65536 - 9600 = 55936
Config Clock = User
Config Date = Dmy , Separator = /
Timer1preset = 55936    

$baud = 9600
Open "com1:" For Binary As #3                                
Config Serialin = Buffered , Size = 200 , Cts = Pind.4 , Rts = Pind.7 , Threshold_full = 30 , Threshold_empty = 30
Config Serialout = Buffered , Size = 250

 '*************************************************************
'main loop is here
do
   code
   call housekeeping()  ' this gets called often
code
code

loop


'*************************************************************

sub housekeeping()

    'This sub increments the local RTC
    'No interrupts are used
    'The 'A compare' is set to zero and the compare flag  tifr1.OCF1A
    'goes high when counter1 = 0, which happens every 1 sec
    'Sub takes about 5uSec

   ocr1aH = 0                                               'set compare hi byte to 0
   ocr1al = 0                                               'set compare lo byte to 0


   if tifr1.OCF1A = 1 then                                  'Timer Int Flag Register. Compare with 0 is true
      timer1 = 55936
      tifr1.OCF1A = 1                                       'reset bit 1. see pg140 of atmega 1284 data sheet
      if mytimeoutb_sec > 0 then Decr mytimeoutb_sec        '1 sec used in timer loops
      incr local_sec
      time$ = time(local_sec)                               'calculate time & update RTC This could be moved also
    '  date$ = date(local_sec)                               'calculate date & update RTC  moved to main loop
   end if
 end sub

'*******************************************************************
 


This next piece of code looks for 32 numbers from a noise meter, which is on a ser port #3. If the loop runs once,
then there is no problem.
BUT if the loop runs 5 times because the noise meter is turned off for example,
then during this loop, the date$ and time$ values go back to February 2015.

Code:


      #If enable_thirds = 1
        Retries = 0
        msg_id = 99
        do
            incr retries
            call timedelay_ms(100)
            Print #3 , "XC1;"                               'meter preset
            call timedelay_ms(100)
            Print #3 , "XW2;"                              'meter preset
            call timedelay_ms(100)
            Print #3 , "BL8 , 32;"                          'ask meter for 32 1/3rd octave values
            call receive_meter_RS232(32)

        Loop Until Retries > 5 Or Msg_id = 0
      #endif

'*******************************************************************************
 


here are the two subs that are called from the problem sub.
Code:


'***********************************************
Sub Timedelay_ms(byval Mydelay As Integer)
 'delay in ms
 'does not need timer1
   local dly as integer
   dly = 0
   While dly < Mydelay
      call housekeeping()
      waitms 1
      Incr dly
      Reset Watchdog
   Wend
End Sub

'******************************************************************************

'*******************************************************************************
   sub Receive_meter_RS232(byval targetcommacountint as integer)

   Mytimeoutb_sec = 20                                      '20 secs
   Msg_id = 99
   Commacounti = 0
   charcount = Temph                                                'restore pointer

 do

      rxbyte = inkey(#3)
      If Rxbyte = 32 Then Rxbyte = 0
      If Rxbyte = 10 Then Rxbyte = 0
      If Rxbyte = 13 Then
         Rxbyte = 44
         Incr Commacounti
      End If
      If Rxbyte <> 0 Then                  
                   
         Incr Charcount                                     'used when writing to sd card
         Bigbuffer(charcount) = Rxbyte               'store my data in  buffer

      End If

      Reset Watchdog
      call housekeeping()
      If Commacounti = Targetcommacountint Then
            Msg_id = 0
            Print #1 , ""
            Print #1 , ">> expected " ; Targetcommacountint ; ",got " ; Commacounti       'print target & actual
            clearmeter
            exit sub                    'this is the normal exit from this sub
      end if

   Loop Until Mytimeoutb_sec = 0
      tempstr1 = ">> wrong comma count.Target =  " + str(Targetcommacountint) + ",got " + str(Commacounti)
      print #1 , tempstr1
     
      'back up the pointer
      while charcount > temph
             decr Charcount
      wend
                                                   '


end sub

 '******************************************************************************


(BASCOM-AVR version : 2.0.7.7 , Latest : 2.0.7.8 )

_________________
Neil
Back to top
View user's profile
enniom

Bascom Member



Joined: 20 Oct 2009
Posts: 548

PostPosted: Fri Nov 20, 2015 3:48 am    Post subject: Reply with quote

1. Can you be sure that Charcount is always within the dimensioned value of Bigbuffer?

2. What is clearmeter?
Back to top
View user's profile
njepsen

Bascom Member



Joined: 13 Aug 2007
Posts: 471

newzealand.gif
PostPosted: Fri Nov 20, 2015 4:02 am    Post subject: Reply with quote

Bigbuffer is dimensioned to 10,000 bytes and elsewhere in the code, its size is checked
& the pointer reset to 1. (this has never happened )

here is clearmeter
Code:


 '******************************************************************************
sub clearmeter()                                            'clear out meter tx buffer
   'clear meter serial port buffer
   mytimeoutb_sec = 3
   Do

      Rxbyte = Inkey(#3)
      Print #1 , "W" ;
      Reset Watchdog
      call timedelay_ms(2)
   Loop Until Ischarwaiting(#3) = 0 or mytimeoutb_sec = 0
end sub


'******************************************************************************

_________________
Neil
Back to top
View user's profile
enniom

Bascom Member



Joined: 20 Oct 2009
Posts: 548

PostPosted: Fri Nov 20, 2015 4:39 am    Post subject: Reply with quote

Only other thought.

Code:
while charcount > temph
              decr Charcount
       wend


Is it possible that this can assign a value of 0 or roll-under to 65535 (I assume Charcount is a Word to accommodate the 10,000-byte buffer size)?
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2335

blank.gif
PostPosted: Fri Nov 20, 2015 7:17 am    Post subject: Reply with quote

enniom wrote:
Code:
while charcount > temph
              decr Charcount
       wend

Is it possible that this can assign a value of 0 or roll-under to 65535 (I assume Charcount is a Word to accommodate the 10,000-byte buffer size)?

That's only an odd and cycle-intensive way of writing:
Code:
charcount = temph
Back to top
View user's profile
enniom

Bascom Member



Joined: 20 Oct 2009
Posts: 548

PostPosted: Fri Nov 20, 2015 1:02 pm    Post subject: Reply with quote

Hi Neil,

You use $Frameprotect.

Are you passing variables in subroutines used in ISRs?

If so, could these be overrunning the $Framesize?
Back to top
View user's profile
njepsen

Bascom Member



Joined: 13 Aug 2007
Posts: 471

newzealand.gif
PostPosted: Wed Nov 25, 2015 3:39 am    Post subject: Reply with quote

Hi enniom,
Thanks for taking time to look at this. I think You mean - am I passing variables in subs that are also used in ISRs?
The answer is no.
I only have 3 IRSs. Timer rollover for T0,T1 and T3, and the serial ports. I have included the timer ISRs below.
T0 simply flashes a LED, T2 is the RTC, and T3 calls a sub that checks a flag.

The problem with this bug is I can wallpaper over it so it doesnt happen, but I dont know what is causing it.

Code:

 '*****************************************************************************
sub timer3overflow()
      'T3 rolls over every 5 seconds
      'ttrn is checked every 30 seconds
       timer3 = 17536                                           '65536 - 9600x5
      call check TTRN                                            ' time to read noise

end sub
 '***********************************************
sub Timer0overflow()

   'called 37 x per second
   'flashes LED once per sec
   $asm

       push r24                                             ;save r24
       in r24, sreg                                         ;r24<-sreg
       push r24                                             ;save status register to stack
       lds r24, {btimer0}                                   ;load direct
       inc r24
       cpi r24,37                                           ;compare
       brlo timer0overflo                                       ;br if r24 < 37
       clr r24                                              ;clear r24
       sbi heartbeat_pin,heartbeat_bit                       ; write 1 to pin = toggle led
   timer0overflo:
       sts {btimer0},r24                      ;store btimer0 <- r24
       pop r24
       out sreg , r24                                       'get Sregister back
       pop r24

   $end asm
end sub

'********************************************************************************

 '*****************************************************************************
sub Check_ttrn()
   'is it TTRN  (time to read noise).
   'This sub called once every 5 sec under interrupt of timer3
   'Dn5 lets it happen only once per 15 min
   'TTRN is latched in this sub and unlatched when data is sent
  'dn5 = a semiphore bit called 'done5'



   if dn5 = 0 then
            If _min = 0 Or _min = 15 Or _min = 30 Or _min = 45 Then
               Dn5 = 1
               Ttrn = 1                                     'time to read noise
               Print #1 , ">> time to read noise"
            End If
   else
            If _min <> 0 and _min <> 15 and _min <> 30 and _min <> 45 and ttrn = 0 Then
               Dn5 = 0

            end if

   end if

end sub

 '*****************************************************************************

*

_________________
Neil
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum