Small package decade counter? - Page 1
Forum section: electronics / projects

author: rcbuck
author_rank: Frequent Contributor
timestamp: March 30, 2019, 06:32:20 am
content: Does anyone know of a small package decade counter? I need to divide a 100 Hz signal by 10. The smallest units I can find are in SOIC-14 or SOIC-16.Nexperia has a new line of fixed division counters, the 74AHC1G421x series, but unfortunately no divide by 10.

author: DC1MC
author_rank: Super Contributor
timestamp: March 30, 2019, 06:45:59 am
content: GreenPak SLG46536V 50c in STQFN-14 (2.0 x 2.2 mm)

author: Ian.M
author_rank: Super Contributor
timestamp: March 30, 2019, 06:57:46 am
content: If you don't want to go down the GreenPak road, you could program a PIC10F part in SOT23-6 or DFN-8 (2.0 x3.0 mm) to do the job (PIC10F200 if you can tolerate the propagation delay of doing it in software, or PIC10F320 to use its CLC if you need minimal delay), then order them preprogrammed from MicrochipDirect for production.

author: oPossum
author_rank: Super Contributor
timestamp: March 30, 2019, 12:33:49 pm
content: 74HC4017 is available in a 2.5 x 3.5 mm DHVQFN package.

author: rcbuck
author_rank: Frequent Contributor
timestamp: March 30, 2019, 04:59:19 pm
content: The GreenPak and and DHVQFN solutions are too small to solder by hand. I can't tolerate the propagation delay of a PIC. Looks like I will have to use a 74HC4017 in a TSSOP package. Thanks for the suggestions.

author: DaJMasta
author_rank: Super Contributor
timestamp: March 30, 2019, 05:23:52 pm
content: +1 to using a micro for very small size, you could easily get a SOIC-8 or even a SOT-323-6 and have it act as a 10x divider. They're not as popular as the binary counters, so they're less likely to come in a lot of varieties, though if you scour the net you can likely find something in TSSOP size, at least.

author: Ian.M
author_rank: Super Contributor
timestamp: March 30, 2019, 06:16:00 pm
content: If you use the PIC10F320 I mentioned's CLC module, you can get the propagation delay down to tens of nanoseconds.Method:Set up the CLC as a D type flipflop, clocked by your input signal on RA2 (T0CKI/CLC1IN1), a software selectable fixed 0 or 1 level to D, and Q output to RA1 (CLC1 out). Set up Timer 0 for external clock (T0CKI) and preload it with 251 so it will rollover on the fifth input pulse. Do NOT enable interrupts.The main program consists of an endless loop that waits for TMR0IF to get set, then clears it, reloads Timer 0 with 251, and toggles the CLC flipflop D input by XORing a 1 into the appropriate bit of CLC0POL. That should only take 10 instruction cycles worst case, so it should be possible to divide input signals of up to 2MHz. The output will be a 1/10 frequency squarewave with very little propagation delay from the active edge of the input signal.

author: rcbuck
author_rank: Frequent Contributor
timestamp: March 30, 2019, 07:37:46 pm
content: Thanks Ian. I don't have a PIC10F320 but I am going to place a Mouser order on Monday. I will order a couple and give it a try.I have a question about how to use a 74HC40103 but will start another thread for that.

author: rcbuck
author_rank: Frequent Contributor
timestamp: March 30, 2019, 08:09:24 pm
content: Ian, I also need to divide a 400 Hz signal by 200. It appears the PIC10F320 could handle that without breaking a sweat. If it only takes about 10 instruction cycles, I would have a safety zone of about 45 instructions. Does that sound right to you?I will post the 74HC40103 question anyway since I am curious about how it works.

author: Ian.M
author_rank: Super Contributor
timestamp: March 30, 2019, 08:39:50 pm
content: I said, the loop can be done in 10 instruction cycles:Code:radix dec ;default to decimal numbersmovlw -5 ; Prepare W with Timer 'bump' valueLoop:btfss INTCON, TMR0IF ;Wait for Timer 0 rollovergoto Loop ;(2 Tcy)addwf TMR0,F ;'Bump' timer to 5 counts before rolloverbcf INTCON, TMR0IF ;Clear rollover flagmovlw 1<<LC1G2POL ;toggle flipflop D inputxorwf CLC1POLmovlw -5 ; reload W with Timer 'bump' valuegoto Loop ;(2 Tcy)However if it just misses the rollover I think it will actually take 12 cycles all-in, so at 16MHz Fosc, you cant have less than 3us between output edges.I was also wrong about the max input frequency - Timer 0 increment is inhibited for 2 Tcy after its written, which in the code above happens between 3 and 6 Tcy after rollover so there cant be less than 8 Tcy between active input edges or it risks missing one. That limits the max input frequency to 500KHz.However as your signals are more than three orders of magnitude slower, you shouldn't run into any speed issues - you can even afford to drop the PIC clock speed to reduce power consumption.The same code will do for any even division ratio between 2 and 510, just change the constant in the 'Bump timer' MOVLW.N.B. Don't forget to clear ANSELA in the initialisation to make all pins digital, or it wont 'see' the input signal!

author: rcbuck
author_rank: Frequent Contributor
timestamp: March 30, 2019, 08:55:21 pm
content: Thanks Ian. I will test it late next week.

author: Ian.M
author_rank: Super Contributor
timestamp: March 30, 2019, 09:19:16 pm
content: For division ratios that are a multiple of four and are 16 or greater its even simpler - configure the PIC10F320 to use your signal as its system clock input and it will execute one instruction every four clock cycles so its just a matter of writing a program to toggle a pin with a delay in the loop to get the right division ratio:Code:Loop:bsf LATA,0 ;Pulse RA0 onbcf LATA,0 ;for four cycles; delay goes heregoto Loop ;(2 Tcy)Or for the squarewave version, which has a minimum division ratio of 24:Code:Loop:bsf LATA,0 ;Pulse RA0 on; delay goes herenop ; to match GOTO execution timenopbcf LATA,0 ; and back off; same delay goes heregoto Loop ;(2 Tcy)Edit: although its standard midrange core it has a LATA SFR so code fixed to use it!

author: Benta
author_rank: Super Contributor
timestamp: March 31, 2019, 06:42:25 pm
content: Just use one of the cheap SO-8 divide-by-10 prescalers. Who cares if it's specified for 200 MHz, it will work anyway.

author: rcbuck
author_rank: Frequent Contributor
timestamp: April 01, 2019, 03:15:06 am
content: Ian, is it possible for RA2 to feed both TMR0 and the CLC module?

author: Ian.M
author_rank: Super Contributor
timestamp: April 01, 2019, 05:30:48 am
content: I wouldn't expect any issues with RA2 feeding both TMR0 and the CLC module, and still being readable as an input pin. FIGURE 10-1: I/O PORT OPERATION in the datasheet indicates the feed to all the peripheral inputs is a straight tap-off from the input of the PORTA read buffers, after the ANSELA gating. Also there's nothing in the TIMER 0 or CLC sections to indicate that their inputs require exclusive use of the input pin. Worst case: if I'm wrong, link RA2 and RA0 and feed the input to both of them then the CLC can use CL1IN0 on RA0 instead of CLC1IN1 on RA2..Perhaps you are thinking of the PIC10F2xx families, which have a Timer 0 module tha takes exclusive use of GP2?

author: rcbuck
author_rank: Frequent Contributor
timestamp: April 01, 2019, 06:47:01 am
content: Thanks Ian. Like you, I didn't see anything that indicated you couldn't drive both TMR0 and the CLC module. But Microchip's documentation is notoriously bad about leaving out critical information. Or inserting incorrect information.The only way to confirm what works is to give it a try.

author: JPortici
author_rank: Super Contributor
timestamp: April 01, 2019, 07:31:15 am
content: FWIW it's not THAT hard to solder a QFN with 0.5mm pitch.. i find it much harder to do a 0.5mm TQFP. You just need a fine tip on the ironQuoteIt's not. You haven't read many datasheets if you think that.QuoteSee above.Another idea: Could you use the NCO module? Once you set the accumulator increment you're good to go, no need to reload

author: Ian.M
author_rank: Super Contributor
timestamp: April 01, 2019, 08:48:05 am
content: Nope. I considered the NCO, but its got a 20 bit accumulator and only a 16 bit increment register so there's four overflow bits you cant directly increment, therefore its max output frequency in pulse mode is fractionally under 1/16 of the input frequency, and for an exact integer division ratio the best it can do is 1/32. It also doesn't work out to an exact ratio if you try to divide by 200.Its also a great pity Timer 2 doesn't have an external clock inut and Timer 0 doesn't have a period register

author: JPortici
author_rank: Super Contributor
timestamp: April 01, 2019, 09:38:03 am
content: Ah pity. True that, but the 10F322 is baseline for a reasonWhat about the ATTINY 10 then? i see that these are the new parts in SOT-323 package, apparently it has a timer with period match/output compare and external clock input

author: rcbuck
author_rank: Frequent Contributor
timestamp: April 02, 2019, 12:19:36 am
content: QuoteMaybe notoriously was a little heavy handed. However, over the last couple of years the copy/paste errors seem to have increased.https://www.microchip.com/forums/m1064174.aspx?high=datasheet+errorshttps://www.microchip.com/forums/m1075692.aspxhttps://www.microchip.com/forums/m1071093.aspxhttps://www.microchip.com/forums/m896832.aspx?high=datasheet+errorshttps://www.microchip.com/forums/m1012037.aspx?high=datasheet+errorsMaybe they are trying to do too much with too little resources.About 6 months ago I designed a board using the PIC16F1719. Section 13.0 saysQuoteI made the mistake of interpreting that to mean ALL port pins have IOC capability. I did not read the entire section about each individual PORTx operation. I designed the board and ordered prototypes. When I started writing the program for the board that is when I discovered that none of the PORTD pins have IOC. As luck would have it, I had used one of the PORTD pins as part of the IOC operation. Luckily I was able to work around it by just checking the switch each time through the main loop. I realize it was my mistake by not reading the additional 27 pages about each of the I/O ports. Now I do. It is just another example of a copy/paste error.

author: cv007
author_rank: Frequent Contributor
timestamp: April 02, 2019, 02:43:29 am
content: If sticking to powers of 2, you can use fixed duty cycle of nco. Since we are talking relatively low speeds (100Hz,400Hz), there is plenty of time to load a few registers.NCO INC = 1use NCO CLK pindiv10 = 256 - 10/2div200 = 256- 200/2loop:ACCL = div10ACCU = 255ACCH = 255wait while NCO1IF == 0NCO1IF = 0

author: rcbuck
author_rank: Frequent Contributor
timestamp: April 04, 2019, 07:08:28 pm
content: Ian, I have programmed a PIC10F322 but am not getting any division of the input signal. The output on pin RA1 (CLC1) is the same as the input on RA2 (T0CLKI). I also tried to assign CLC1IN2 to RA2 which would mean T0CKI and the Flip-Flop had the same inputs. That also gives me 200 Hz out of RA1.Code:#include "p10f322.inc"; CONFIG__CONFIG _FOSC_INTOSC & _BOREN_OFF & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _LVP_OFF & _LPBOR_OFF & _BORV_LO & _WRT_OFFRES_VECT CODE 0x0000 ; processor reset vectorGOTO START ; go to beginning of programMAIN_PROG CODE; let linker place main programradix dec ;default to decimal numbersSTARTCLRF TRISA ; all pins are outputsCLRF LATA ; clear all latchesCLRF ANSELA ; all pins digitalbsfTRISA, 0; RA0 is an inputbsfTRISA, 2 ; RA2 is an inputCLRW; setup CLC module, input on RA2, Flip-Flop output on RA1movlw 0x01movwf CLC1SEL1 ; CLCIN1 assigned to LC1D3S, RA0movlw 0xC4movwf CLC1CON ; D Flip-Flop, port pin output enabled, module enabledmovlw 0xAAmovwf CLC1GLS0 ; gating OR, no inversion; setup TMR0movlw 0xE8 ; External clock on RA2, rising edge, no prescalemovwf OPTION_REGmovlw -5 ; Prepare W with Timer 'bump' valueLoop:btfss INTCON, TMR0IF ;Wait for Timer 0 rollovergoto Loop ;(2 Tcy)addwf TMR0,F ;'Bump' timer to 5 counts before rolloverbcf INTCON, TMR0IF ;Clear rollover flagmovlw 1<<LC1G2POL ;toggle flipflop D inputxorwf CLC1POLmovlw -5 ; reload W with Timer 'bump' valuegoto Loop ;(2 Tcy)ENDDo you see any problem with the code setup? I don't completely understand the CLC module but I think I have is setup correctly.Edit: Corrected a couple of errors in the CLC code setup area.

author: cv007
author_rank: Frequent Contributor
timestamp: April 04, 2019, 08:29:43 pm
content: Here is an nco version, can try if you want. I don't know if it will work. The nco io looks like its supposed to be async, so just have to worry about reloading acc values before the next rising edge which should not be a problem with the speeds you are talking about.Code:#include <xc.h>#define DIV 10 //div ncoclk in by (power of 2)#define RELOADval 256-(DIV/2) //if DIV was not power of 2, it is nowvoid main(void) {ANSELAbits.ANSA1 = 0; //RA1, NCO1CLK <-TRISAbits.TRISA2 = 0; //RA2, NCO1 ->NCO1INCL = 1; //inc by 1NCO1CONbits.N1OE = 1; //NCO1 ->NCO1CONbits.N1EN = 1; //NCO1 onfor(;;){NCO1ACCH = NCO1ACCU = 255;NCO1ACCL = RELOADval;while( PIR1bits.NCO1IF == 0 );PIR1bits.NCO1IF = 0;}}NCO1CLKbits.N1CKS may need to be setup, the default reset value shows as using the NCO1CLK pin (0b00), but the nco diagram shows NCO1CLK as 0b11.I don't know if this would also work if needing any div value (not just powers of 2)-Code:#include <xc.h>#define DIV 10#define RELOADval 256-DIVvoid main(void) {//RA0 = CLC1IN0 (clock in)ANSELAbits.ANSA0 = 0; //digitalCLC1CONbits.LC1MODE = 2; //4input ANDCLC1SEL0bits.LC1D1S = 1; //same source for all - CLC1INCLC1SEL0bits.LC1D2S = 1; //pinouts use CLC1IN0,CLC1IN1CLC1SEL1bits.LC1D3S = 1; //clc datasheet chapter uses CLC1IN1,CLCIN2CLC1SEL1bits.LC1D4S = 1; //so assume CLC1IN0 = CLC1IN1, CLC1IN1 = CLC1IN2CLC1GLS0 = 0x55; //AND all 4 to gateCLC1GLS1 = 0x55;CLC1GLS2 = 0x55;CLC1GLS3 = 0x55;CLC1POL = 15; //(invert for AND)//RA2 NCO1 output (divided clock out)TRISAbits.TRISA2 = 0;NCO1INCL = 1;NCO1CONbits.N1OE = 1;NCO1CLKbits.N1CKS = 0b11; //LC1OUT (diagram shows 0b10)NCO1CONbits.N1EN = 1; //enable ncoCLC1CONbits.LC1EN = 1; //enable clcfor(;;){PIR1bits.NCO1IF = 0;NCO1ACCH = NCO1ACCU = 255;NCO1ACCL = RELOADval;while( PIR1bits.NCO1IF == 0 ){while( CLC1CONbits.LC1OUT == 0 ); //wait for clock edgeCLC1POL ^= 0x80; //flip polarity}}}The clc is just used to get a 'pulse' to the nco clock via lc1out, manually changing polarity on each edge of the input clock. The nco still does divide by 2 as it toggles its output on each rising edge, but now any value can be used since we provide a rising edge on each clock transition. The LC1OUT is clocked on Q1, so you are then somewhat tied to fosc a little and lose total async (if important). CLC1 output and NCO1CLK input are on the same pin, but I don't think you could get both to work (could try, though)- then you would be about as async as possible.

author: rcbuck
author_rank: Frequent Contributor
timestamp: April 05, 2019, 06:18:34 am
content: cv007, I don't think the NCO can be used. I don't think it is accurate enough. I don't want to depend on the processor clock for any of the timing requirements.From reading the Microchip documents I believe the PIC10F322 will work. The only thing that is confusing about the CLC module is the output. There is no selection for CLC1OUT. However, I think that CLC1 is actually the output.I have a PIC12F1501 that has the CLC module in it. I will test that tomorrow to see if I can get it to work.If I can't get the CLC module to work in the PICs I will just use a larger package discrete decade divider chip.

author: cv007
author_rank: Frequent Contributor
timestamp: April 05, 2019, 06:57:09 am
content: QuoteFrom what I read, the nco clock input, adder, output are all on their own where the adder works on the rising edge. The only processor involvement is the instructions to watch the nco flag, and load the accumulator. It seems there is no way to avoid having some instructions involved so you will always have that no matter what, but they do not affect your divided clock until you get to a speed where the instructions get in the way. With a 16MHz clock, I think a 400 khz clock input can be done (16M/4/10 instruction cycles, or whatever needed can be done before the next rising edge).The version where the clc clocks the nco will introduce jitter on the incoming edges as the lc1out is clocked at Q1 (this version is only if odd div values needed). If the ncoclk input (ra1) works when the clc1 out (ra1) is also working (don't know), then the lc1out can be eliminated and the clc1 output directly drives the nco, and the resulting divided clock is again async to fosc.QuoteI'm not sure what that means. The nco can count to 5 just fine(from -5 to 0 anyway)- the accumulator is pre-loaded, the increment value is 1, then the accumulator is incremented by 1 on every rising edge of ncoclk. When the accumulator overflows, the nco output toggles its output (all async from what I can tell). You now reload the accumulator, and do again.