News:

;) This forum is the property of Proton software developers

Main Menu

TMR1 trouble

Started by midali, Dec 26, 2024, 09:34 PM

Previous topic - Next topic

midali

Hello everyone,

I need to read a lenght pulse between 1000 to 2000 us (from RC receiver) and sent the value via 115200 baud Usart . I have a trouble with TMR1 :

Device = 16F1938

Config1 FCMEN_OFF, FOSC_INTOSC, WDTE_OFF, MCLRE_OFF, PWRTE_OFF, CP_ON, MCLRE_OFF, BOREN_OFF, CLKOUTEN_OFF, FCMEN_OFF
Config2 WRT_OFF, VCAPEN_OFF, PLLEN_OFF, STVREN_OFF, LVP_OFF

Declare  Xtal = 32
OSCCON  = %11110100 'set to 8 x 4PLL MHz

TRISC  = %10000000             
PORTA  = 0
ANSELA = 0

T1CON=%00110000        '=Tmr1 OFF  %00110001=Tmr1 ON
All_Digital=true

'***************** Serial port declares ********************************
Declare Hserial_Baud=115200
Declare Hserial_SPBRG=34
Declare Hserial_Clear=On

'****************** Variables declares ********************************           
Dim Time As Word

'****************** Read pulse lenght  ********************************       
begin: 
        T1CON=%00110000            'Tmr1 Off
        TMR1H=0                    'clear TMR1
        TMR1L=0
    While PORTA.5 = 0:Wend         'wait to rise the pulse
   
        T1CON=%00110001            'start timer
       
    Do
        Time=TMR1L+(TMR1H<<8)      'fix the time
    Loop Until PORTA.5 = 0
       
         T1CON=%00110000            'Tmr1 Off
         
    HSerOutLn [Dec Time]
GoTo begin


I received on serial port random values :

1548
1518
1522
1509
1486
1518
1522
1522
1474
1534
1623
1516
1531
1501
1581
1494
1513
1540

Any help is welcome!





trastikata

Hello midali,

QuoteDo
        Time=TMR1L+(TMR1H<<8)      'fix the time
    Loop Until PORTA.5 = 0

Why reading the timer inside the loop? Read it after exiting the loop and stopping the timer.

Device = 16F1938

Config1 FCMEN_OFF, FOSC_INTOSC, WDTE_OFF, MCLRE_OFF, PWRTE_OFF, CP_ON, MCLRE_OFF, BOREN_OFF, CLKOUTEN_OFF, FCMEN_OFF
Config2 WRT_OFF, VCAPEN_OFF, PLLEN_OFF, STVREN_OFF, LVP_OFF

Declare  Xtal = 32
OSCCON  = %11110100 'set to 8 x 4PLL MHz

TRISC  = %10000000             
PORTA  = 0
ANSELA = 0

T1CON=%00110000        '=Tmr1 OFF  %00110001=Tmr1 ON
All_Digital=true

'***************** Serial port declares ********************************
Declare Hserial_Baud=115200
Declare Hserial_SPBRG=34
Declare Hserial_Clear=On

'****************** Variables declares ********************************           
Dim Time As Word

'****************** Read pulse lenght  ********************************       
begin:
        T1CON=%00110000            'Tmr1 Off
        TMR1H=0                    'clear TMR1
        TMR1L=0
    While PORTA.5 = 0:Wend         'wait to rise the pulse
   
        T1CON=%00110001            'start timer
       
   While PORTA.5 = 1:Wend         

         T1CON=%00110000            'Tmr1 Off
         
         Time=TMR1L+(TMR1H<<8)      'fix the time
         
    HSerOutLn [Dec Time]
GoTo begin


RGV250

Hi,
Trastikata beat me to it, only thing I would add is create a 16 bit timer so you do not need to do the shifts etc.
I think something like 
Symbol Time = TMR1L.Word  'Create a 16-bit variable out of TMR1L

Bob

midali

Changed, but the same .

Device = 16F1938

Config1 FCMEN_OFF, FOSC_INTOSC, WDTE_OFF, MCLRE_OFF, PWRTE_OFF, CP_ON, MCLRE_OFF, BOREN_OFF, CLKOUTEN_OFF, FCMEN_OFF
Config2 WRT_OFF, VCAPEN_OFF, PLLEN_OFF, STVREN_OFF, LVP_OFF

Declare  Xtal = 32
OSCCON  = %11110100 'set to 8 x 4PLL MHz

TRISC  = %10000000             
PORTA  = 0
ANSELA = 0

T1CON=%00110000        '=Tmr1 OFF  %00110001=Tmr1 ON
All_Digital=true

'***************** Serial port declares ********************************
Declare Hserial_Baud=115200
Declare Hserial_SPBRG=34
Declare Hserial_Clear=On

'****************** Variables declares ********************************           
Symbol Time = TMR1L.Word
'****************** Read pulse lenght  ********************************       
begin:
        T1CON=%00110000            'Tmr1 Off
        Time = 0
    While PORTA.5 = 0:Wend         'wait to rise the pulse
   
        T1CON=%00110001            'start timer
       
   While PORTA.5 = 1:Wend         

         T1CON=%00110000            'Tmr1 Off
         
    HSerOutLn [Dec Time]
GoTo begin

serial :
1526
1503
1508
1493
1529
1533
1524
1490
1503
1508
1558
1540
1508
1510
1463

trastikata

Are you sure the pulse source is precise? Where is that pulse coming from and what does it represent?

midali

The pulses are from RC receiver. For sure I measured with a oscilloscope and pulse is stable, 1.5ms at 72,58 Hz

trastikata

#6
If the pulses are precise, then it seems the internal RC oscillator of the PIC is not stable enough. You can try just for the test running the PIC with a crystal clock source.

midali

Quote from: trastikata on Dec 27, 2024, 08:55 AMAre you sure the pulse source is precise? Where is that pulse coming from and what does it represent?

Captured the data on serial with YAT and work. I disconnect and reconnect the Serial Comm from Positron Compiler and now the serial data is displaied right !
Wow, the troubles was from SerialComm .

Thank you very much Trastikata and Bob


midali

I change the PIC to 16F15323 and Timer1 not start . According with datasheet seems to be all ok, but I'm sure that I omitted something . I need again the help .
Thank you !

Device = 16F15323 ;Define device as 16F15323
Declare Xtal = 32 ;Define MCU clock frequency
'Declare Xtal = 4 ;Define MCU clock frequency

 Config1 FCMEN_OFF, CSWEN_ON, CLKOUTEN_OFF, RSTOSC_HFINT32, FEXTOSC_OFF
 Config2 MCLRE_OFF, PWRTE_ON, LPBOREN_OFF, BOREN_OFF, PPS1WAY_OFF, STVREN_ON
 Config3 WDTCPS_WDTCPS_2, WDTE_OFF
 Config4 BBSIZE_BB1K, BBEN_OFF, SAFEN_OFF, WRTAPP_OFF, WRTC_OFF, LVP_OFF
 Config5 CP_ON
 
OSCCON1 = %01100000 ;HFINTOSC 32 MHz
OSCFRQ  = %00000110 ;HFINTOSC 32 MHz

'OSCCON1 = %01100000 ;HFINTOSC 4 MHz
'OSCFRQ  = %00000010 ;HFINTOSC 4 MHz

 TRISA = %00001000 ;Configure PORTA
 TRISC = %00100100 ;Configure PORTC
 
 ANSELA = 0 ;Disable PORTA ADC Module
 ANSELC = 0 ;Disable PORTC ADC Module

 PORTA = %00000000
 PORTC = %00000000

T1CON=%00110100        '=Tmr1 OFF  %00110101=Tmr1 ON
All_Digital=true

'***************** Serial port declares ********************************
Declare Hserial_Baud=115200
Declare HRSOut_Pin = PORTC.5
Declare Hserial_SPBRG=34
Declare Hserial_Clear=On

'****************** Variables declares ********************************           
Symbol Time = TMR1L.Word
'****************** Read pulse lenght  ********************************       
begin:
        T1CON=%00110100            'Tmr1 Off
        Time = 0
    While PORTC.2 = 0:Wend         'wait to rise the pulse
        T1CON=%00110101            'start timer
       
   While PORTC.2 = 1:Wend         

         T1CON=%00110100            'Tmr1 Off
         
   HSerOutLn [Dec Time]
GoTo begin


RGV250

#9
Removed, Miss read it.

Bob

trastikata

Hi,

PIC16F1938 has much different register set from PIC16F15323.

OSCCON1 = %01100000 is not valid. Anyway if the config word is set for 32 MHz you don't need to change anything.

The code seems to be missing where you reset and read the Timer1? In addition Timer1 in PIC16F15323 has different registers set.

I'd suggest you check all registers in your code again according PIC16F15323 datasheet..



midali

Hi Trastikata,

   Config word is set on 32 MHz but tomorrow I'll check again for safety .
   Start Timer1 is set according with data sheet :
T1CON=%00110101            'start timer   I readed a full day in datasheet but I don't know to set corectly the registers for TMR1 .






trastikata

#12
midali,

OSCCON1 NOSC[2:0]/COSC[2:0] 011 is not valid. I'd suggest you don't set anything in OSCCON1 and OSCFRQ because the fuse RSTOSC_HFINT32 already sets internal oscillator to 32 MHz.

T1CLK is not set. Probably you'd want to set it to 0x01 - Clock source = Fosc/4.

For better accuracy I'd use Timer1 in 16b mode 1/1 prescaller, instead of 8b mode with 1/8 prescaller like it is set now in your code.

Try this code:

Device = 16F15323 ;Define device as 16F15323
Declare Xtal = 32 ;Define MCU clock frequency


Config1 FCMEN_OFF, CSWEN_ON, CLKOUTEN_OFF, RSTOSC_HFINT32, FEXTOSC_OFF
Config2 MCLRE_OFF, PWRTE_ON, LPBOREN_OFF, BOREN_OFF, PPS1WAY_OFF, STVREN_ON
Config3 WDTCPS_WDTCPS_2, WDTE_OFF
Config4 BBSIZE_BB1K, BBEN_OFF, SAFEN_OFF, WRTAPP_OFF, WRTC_OFF, LVP_OFF
Config5 CP_ON

TRISA = %00001000 ;Configure PORTA
TRISC = %00100100 ;Configure PORTC
 
ANSELA = 0 ;Disable PORTA ADC Module
ANSELC = 0 ;Disable PORTC ADC Module

PORTA = %00000000
PORTC = %00000000

T1CLK = 0x01 'Clock source Fosc/4

All_Digital=true

'***************** Serial port declares ********************************
Declare Hserial_Baud=115200
Declare HRSOut_Pin = PORTC.5
Declare Hserial_SPBRG=34
Declare Hserial_Clear=On

'****************** Variables declares ********************************          
Symbol Time = TMR1L.Word
'****************** Read pulse lenght  ********************************      
begin:
        T1CON=0x02                  '1:1 Prescaler value / 16b / Off
        Time = 0
    While PORTC.2 = 0:Wend          'wait to rise the pulse
        T1CON=0x03                  '1:1 Prescaler value / 16b / On
      
   While PORTC.2 = 1:Wend        

         T1CON=0x02                 '1:1 Prescaler value / 16b / Off
             
   HSerOutLn [Dec Time]
GoTo begin

P.s. Since you are using a newer device and timer with gate control, I'd rather use the Timer1 Gate Control Pin T1GPPS to trigger the timer and measure the pulse width without running in a loop waiting for pin change.

GDeSantis

This is what I use for the PIC16F15323 internal RC oscillator settings and it works OK.

midali

Hi Trastikata,

It work right.
Thank you very much for your help ! I really apreciate that you spend your free time for me ! I started to understand how to set TMR1