View previous topic :: View next topic |
Author |
Message |
Torello
Joined: 29 Sep 2006 Posts: 128
|
TMR2 on PIC18F26Q83 as One Shot |
Posted: Fri Jan 17, 2025 6:05 am |
|
|
Hi,
Reading the datasheet TMR2 has a one-shot mode and an edge detector.
I would like to create a one-shot triggered on a positive edge of an externally applied signal. I want the one-shot output to be usable as a flag in my code
I don't see/find a quick solution with build-in CCS functions. And also not on this forum.
Reading the datasheet it will take me quite some time to get al the registers bits setup in the right way. So before I dive into this matter..
Has anybody has done this before and willing to share? _________________ Regards, Edwin. PCWHD v5.114 |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9372 Location: Greensville,Ontario
|
|
Posted: Fri Jan 17, 2025 6:18 am |
|
|
I'd goto Microchip's website and search for 'application note' or 'technical bulletin' about 'using timer as one shot'... or similar wording.
While the code examples are usually in assembler, all the details to 'setup' will be there. Should be easy to convert into CCS C.
Also try 'google'.....
edit..
curious..I downloaded the datasheet
chapter 26..timer 2, seems fairly easy to use
load register with one shot width (??PR )
load config register('operating modes' 26.7 ) mode=01001
set 'on' to trigger the one shot....
if you can get it to 'free run' ,you're 99% there !!!
I don't have that PIC, so I can't 'code/compile/test'.... |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1365
|
Re: TMR2 on PIC18F26Q83 as One Shot |
Posted: Fri Jan 17, 2025 8:08 am |
|
|
Torello wrote: | Hi,
Reading the datasheet TMR2 has a one-shot mode and an edge detector.
I would like to create a one-shot triggered on a positive edge of an externally applied signal. I want the one-shot output to be usable as a flag in my code
I don't see/find a quick solution with build-in CCS functions. And also not on this forum.
Reading the datasheet it will take me quite some time to get al the registers bits setup in the right way. So before I dive into this matter..
Has anybody has done this before and willing to share? |
I just took a look at the header file for that chip. Under the setup_timer() section there are multiple #defines for the one shot. You should just need to pick the one that matches your conditions:
Code: |
#define T2_ONE_SHOT_START_IMMEDIATELY
#define T2_ONE_SHOT_START_ON_RE
#define T2_ONE_SHOT_START_ON_FE
#define T2_ONE_SHOT_START_ON_BOTH_EDGES
#define T2_ONE_SHOT_START_ON_RE_RESET_ON_RE
#define T2_ONE_SHOT_START_ON_FE_RESET_ON_FE
#define T2_ONE_SHOT_START_ON_RE_RESET_WHEN_LOW
#define T2_ONE_SHOT_START_ON_FE_RESET_WHEN_HIGH
|
For the external signal, you would probably use T2_CLK_T2IN but there are a lot of options for things like the CLC as well you could look into if needed.
I haven't looked at the datasheet, so the part about knowing when it happened I'm not sure about, but the data sheet should tell you what it does to alert the user. If I had to guess it would just be the interrupt flag being set, but I don't know for sure without looking at the datasheet. |
|
|
Torello
Joined: 29 Sep 2006 Posts: 128
|
|
Posted: Fri Jan 17, 2025 9:31 am |
|
|
Thanx for the tips and ideas. Gone try this weekend!
Have a nice weekend, Cheers! _________________ Regards, Edwin. PCWHD v5.114 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19649
|
|
Posted: Fri Jan 17, 2025 10:18 am |
|
|
He'd want the START_ON_RE option. Set the clock to the internal clock,
and preload with a count so it'll wrap when required. When it wraps, the
interrupt will set. |
|
|
Torello
Joined: 29 Sep 2006 Posts: 128
|
|
Posted: Sat Jan 18, 2025 9:27 am |
|
|
Okay.. 4 hours into the game, because the postscale set to bigger than 1:1 in the One-Shot mode prevents the Tmr2IF being set. And thus no interrupt. I started with 5 in the free running mode:no problem. But then got stuck for hours in the one-shot mode.
May happen in more modes...
A pitty that T2ON need to be set every time when the one-shot time is past. And that is not selectable for what I can see..
It's now working:
Code: |
#include <ONESHOT_T2.h>
#INT_TIMER2
void OneShot_T2_Handler() {
output_high(pScope0); nop(10); output_low(pScope0);
T2ON=1; //need to be set for the next edge
}
void main(){
int8 i,j;
setup_oscillator(OSC_HFINTRC_64MHZ);
//------ setup IO
output_drive(pScope0); output_low(pScope0);
output_drive(pScope1); output_low(pScope1);
output_drive(TrigOut); bTrigOut=0;
input(TrigIn);
//setup_timer_2 (mode, period, postscale);
//setup_timer_2(T2_DIV_BY_8 | T2_CLK_FOSC, 159, 1); //period 20u
setup_timer_2(T2_CLK_FOSC | T2_DIV_BY_8 | T2_ONE_SHOT_START_ON_RE |T2_RESET_FROM_T2IN , 159, 1);
//Postscale >1 will be ignored as in datasheet. BUT *also* will prevent interrupt from fireing.
//Missing #PIN_SELECT in 18F26Q83.h ??
T2INPPS = 0b00010011; //assing C3 in the Timer2 Input register
delay_ms(20);
fprintf(Debug, "\n\nProgram start\n\n");
fprintf(debug,"T2TMR: %x\n", T2TMR);
fprintf(debug,"T2PR: %x\n", T2PR);
fprintf(debug,"T2CON: %x\n", T2CON);
fprintf(debug,"T2HLT: %x\n", T2HLT);
fprintf(debug,"T2CLKCON: %x\n", T2CLKCON);
fprintf(debug,"T2RST: %x\n", T2RST);
fprintf(debug,"T2INPPS: %x\n", T2INPPS);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
While(true) {
bTrigOut=1; delay_us(50); btrigout=0; delay_us(50);
}
}
|
Code: |
#ifndef ONESHOT_T2_H
#define ONESHOT_T2_H
#include <18F26Q83.h>
#use fast_io(B)
#use fast_io(C)
#FUSES WDTCLK_LFINTRC,NOEXTOSC, RSTOSC_HFINTRC_1MHZ, PUT_64MS, NOLVP, Nobrownout, NoPPS1Way
#use delay(internal=64000000)
#define nop(x) Delay_cycles(x)
#define pScope0 PIN_B0
#bit bScope0=getenv("SFR:PORTB").0
#define pScope1 PIN_B1
#bit bScope1=getenv("SFR:PORTB").1
#define RS_Tx PIN_B6
#define RS_Rx PIN_B7
#define TrigOut PIN_C2
#bit bTrigOut=getenv("SFR:PORTC").2
#define TrigIN PIN_C3
#define SPI1_SDI PIN_C7 //----Co
#define SPI1_CLKI PIN_C6 //----C1
#define Mclr PIN_E3
//--- RS232 ---------------------------------
#PIN_SELECT U1RX=RS_Rx //must be on port B or C !
#PIN_SELECT U1TX=RS_Tx //must be on port B or C !
#use RS232(stream=debug, UART1, Baud=38400, ERRORS)
//--- TIMER2 --------------------------------
#byte T2TMR = getenv("SFR:T2TMR") // counter reg
#byte T2PR = getenv("SFR:T2PR") // counter reg
#byte T2CON = getenv("SFR:T2CON") // period reg
#bit T2ON = getenv("BIT:T2CON.T2ON") // On/off bit (off will reset counters and state-mschines. Q) also period?)
#byte T2HLT = getenv("SFR:T2HLT")
#bit T2PSYNC = getenv("BIT:T2HLT.PSYNC")
#bit T2CKPOL = getenv("BIT:T2HLT.CKPOL")
#bit T2CKSYNC = getenv("BIT:T2HLT.CKSYNC")
//bit4:0 mode
#Byte T2RST = getenv("SFR:T2RST")
#byte T2INPPS = getenv("SFR:T2INPPS")
#byte T2CLKCON = getenv("SFR:T2CLKCON")
#endif |
_________________ Regards, Edwin. PCWHD v5.114 |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9372 Location: Greensville,Ontario
|
|
Posted: Sat Jan 18, 2025 10:13 pm |
|
|
hmm, never used it but this...is T2ON the 'trigger for the one shot ?
A pity that T2ON need to be set every time when the one-shot time is past.
To me a one shot, well, just works ONCE when triggered.....
Some 'event' triggers the 'one shot, that stays 'active' for a set period of time.
I used to use 74123 'retriggerable' one shots as hardware watchdog timers. As long as the computer sent a pulse to the 74123 faster than the 'time' amount, the output stayed high. If the computer crashed, 74123 would time out and 'safety stuff' was activated.....
I'm not sure how you've configured this 'one shot' or the actual 'trigger', just making observations.... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19649
|
|
Posted: Sun Jan 19, 2025 3:09 am |
|
|
This is a read the data sheet one.
You should be looking at the monostable modes, not the one shot modes,
if you want T2 to stay on.
The one shot mode is _one shot_. It turns off after every operation. Exactly
'what it says on the tin'.
The monostable mode stays on, and will re-trigger on the next applicable
edge.
T2_MONO_STABLE_START_ON_RE |
|
|
Torello
Joined: 29 Sep 2006 Posts: 128
|
|
Posted: Sun Jan 19, 2025 4:18 am |
|
|
Temtronic, no T2ON is in this setup not the trigger input. Pin C3 is and I trigger it by wiring C2 bitbang clock to C3.
I'm not saying it isn't a one-shot. It certainly is, but it would be more applicable to me if the T2ON does not need to be set for the next detection when the one-shot time has past. So I wish it was a 74123; this chip doesn't have a "flip-flop auto-disable after one detection"
I have a free running 16-bit SPI stream on wich I want to sync. The SDI clock has ~23us idle time between bursts (period ~50us)
I was thinking not to 'sync once' but always. The stream is in a light fixture and if a glitch would set the first sync off, the light effect would probably be very nasty.. Band has to stop playing. Nehhh don't want that.
Always, and that the firmware knows when serving the SDI i'rupt is about to read valid values. Or not usable and resync again.
Idea to put a onehot on the clock signal, and check that the clock has been idle when the SDI slave jumps into the interrrupt handler.
But with this T2ON "feature" I need to make shure it is put on again a soon as the one shot time has past. This could aslo be done in an interrupt BUT might give a wrong situation if the sync is just 1 clock (=1.7us) shifted. Both interrupt latencies are about 1.8us; twice than 1 SDI clock period.
But with this spiffy 18F26Q83 (i love it!) there a more options. Maybe the monostable solution. Have to look into that. But today band rehearsing
_________________ Regards, Edwin. PCWHD v5.114 |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9372 Location: Greensville,Ontario
|
|
Posted: Sun Jan 19, 2025 7:46 am |
|
|
thanks for the info !!!!
seems the 'chapter' for just the timer is bigger than the entire datasheet for the first PICs !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19649
|
|
Posted: Sun Jan 19, 2025 7:55 am |
|
|
Anyone else find the #define name for CCS really silly.
MONO_STABLE.
Should be
MONOSTABLE.
A monostable multivibrator doesn't have a break between the mono and the
stable part.....
However that says exactly what this emulates, and the one shot', option,
the same. The original poster wants an operation exactly like a monostable.
Giving an edge, a time interval after each edge in the incoming signal,
not just a single trigger. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9372 Location: Greensville,Ontario
|
|
Posted: Sun Jan 19, 2025 9:44 am |
|
|
aw, but 'mono' means 'one' or 'single'.......
PICS are too 'complicated' now and English is a weird language, and I'm from Canada,eh !!!!
I bet someone could write a 'BIG BOOK for dummies' about JUST how to use Timer2.. ans still NOT cover all the neat things that you could use it for !! |
|
|
Torello
Joined: 29 Sep 2006 Posts: 128
|
|
Posted: Sun Jan 19, 2025 2:11 pm |
|
|
I was wondering what for Microchip is the difference between oneshot and monostable mode.
Seems to be exact what I want:
Subnotes tabel 26-1:
Oneshot mode:
2. When T2TMR = T2PR, the next clock clears ON and stops T2TMR at 00h.
Monostable:
3. When T2TMR = T2PR, the next clock stops T2TMR at 00h but does not clear ON.
Yeahh!
Have not yet tried, but will.
Thanx Ttelmah! _________________ Regards, Edwin. PCWHD v5.114 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19649
|
|
Posted: Mon Jan 20, 2025 2:41 am |
|
|
Key point is that these functions behave exactly the same as the standard
multivibrators of the same name.
A monostable multivibrator gives you the ability to develop an edge a fixed
interval after a trigger, and keep doing it again and again.
A one-shot gives an edge a fixed interval after a trigger, but then does not
do it again till it is rearmed.
So exactly what you want, and exactly what you were seeing. |
|
|
|