The 16f18877 has a Zero Cross Detector as one of its CIP.
I cannot find this component within FC.
Is the ZCD accessed by utilizing the "CODE" command icon within the flow chart?
Or am I missing something?
Did a search within FC and no results.
16f18877 internal Zero Cross Detector
-
hippalator
- Posts: 38
- http://meble-kuchenne.info.pl
- Joined: Tue Jul 15, 2025 9:05 pm
- Has thanked: 5 times
-
mnfisher
- Valued Contributor
- Posts: 1828
- Joined: Wed Dec 09, 2020 9:37 pm
- Has thanked: 153 times
- Been thanked: 866 times
Re: 16f18877 internal Zero Cross Detector
Yes, you would need to use some C to enable the ZCD module - this would be in either a code block or in a custom interrupt.
See section 21 of the datasheet.
It looks relatively straightforward - but if using it to measure mains zero crossing then great care is needed with the wiring (not something for a breadboard
)
The syntax REGISTERbits.FIELD = n (for example ZDCONbits.EN = 1) or REGISTER = n to set the whole register is used.
Martin
See section 21 of the datasheet.
It looks relatively straightforward - but if using it to measure mains zero crossing then great care is needed with the wiring (not something for a breadboard
The syntax REGISTERbits.FIELD = n (for example ZDCONbits.EN = 1) or REGISTER = n to set the whole register is used.
Martin
-
mnfisher
- Valued Contributor
- Posts: 1828
- Joined: Wed Dec 09, 2020 9:37 pm
- Has thanked: 153 times
- Been thanked: 866 times
Re: 16f18877 internal Zero Cross Detector
I wired up a PIC16F18877 to a signal generator and tried the ZCD hardware.
Note - I tested with a 20MHz external crystal - if you have use the internal oscillator at 32MHz you will need to set OSCCON. (I did a blinkie first to test settings correct!)
This very small sample code - I enable the ZCD interrupt handler (in the 'custom' interrupt enable block) setting INTN to enable negative edge interrupts.
The ISR toggles a pin - I used D1 (set in properties) - this is attached to a logic analyser.
I connected the signal to RA0 via a 10K resistor (and I set the signal to be -2.5 to +2.5V) (15K would probably be a better value for this?)
With a 50Hz signal - I get 20ms pulses at RD1.
Note that if I enable the INTP and INTN interrupts - the wave spends more time in one phase - though the total time is still 20ms. This is a result of the pic attempting to 'balance' the input to 0.75V (I guess) rather than 0V
A little testing and a 5kHz signal works AOK (but 10kHz does not!) Results at 32MHz will vary!
Martin
Note - I tested with a 20MHz external crystal - if you have use the internal oscillator at 32MHz you will need to set OSCCON. (I did a blinkie first to test settings correct!)
This very small sample code - I enable the ZCD interrupt handler (in the 'custom' interrupt enable block) setting INTN to enable negative edge interrupts.
The ISR toggles a pin - I used D1 (set in properties) - this is attached to a logic analyser.
I connected the signal to RA0 via a 10K resistor (and I set the signal to be -2.5 to +2.5V) (15K would probably be a better value for this?)
With a 50Hz signal - I get 20ms pulses at RD1.
Note that if I enable the INTP and INTN interrupts - the wave spends more time in one phase - though the total time is still 20ms. This is a result of the pic attempting to 'balance' the input to 0.75V (I guess) rather than 0V
A little testing and a 5kHz signal works AOK (but 10kHz does not!) Results at 32MHz will vary!
Martin
- Attachments
-
- ZCD_Test.fcfx
- (9 KiB) Downloaded 5 times
-
mnfisher
- Valued Contributor
- Posts: 1828
- Joined: Wed Dec 09, 2020 9:37 pm
- Has thanked: 153 times
- Been thanked: 866 times
Re: 16f18877 internal Zero Cross Detector
Something to try:
The ZCD should be capable of much higher speeds than this (although maybe not toggling a pin - which will take quite a few cycles) - try incrementing a counter in the ISR instead of the pin set - then output the count every 1s to a UART (via a FTDI convertor) or a display.
A capacitor between the signal and GND might also be a good idea (|wound the resistor lead around the MCU (in a ZIF socket) pin - which is not a good idea!)
Martin
The ZCD should be capable of much higher speeds than this (although maybe not toggling a pin - which will take quite a few cycles) - try incrementing a counter in the ISR instead of the pin set - then output the count every 1s to a UART (via a FTDI convertor) or a display.
A capacitor between the signal and GND might also be a good idea (|wound the resistor lead around the MCU (in a ZIF socket) pin - which is not a good idea!)
Martin
-
hippalator
- Posts: 38
- Joined: Tue Jul 15, 2025 9:05 pm
- Has thanked: 5 times
Re: 16f18877 internal Zero Cross Detector
Thank you.
20ms would be 50hz.
My reason for implementing the ZCD is triggering.
The idea is to trigger the AD9834 at zero cross over to either increase or decrease, through software, the output phase to hopefully sync the AD9834's output to a signal and track it utilizing the AD9834's pselect pin (PSK).
Yes there are better ways such as using a PLL IC but that's no fun.
Rohm makes a nice IC that ties straight to the AC mains producing a 5v squarewave output at neg and pos cross over.
Pricey but sure helps with UC memory usage.
20ms would be 50hz.
My reason for implementing the ZCD is triggering.
The idea is to trigger the AD9834 at zero cross over to either increase or decrease, through software, the output phase to hopefully sync the AD9834's output to a signal and track it utilizing the AD9834's pselect pin (PSK).
Yes there are better ways such as using a PLL IC but that's no fun.
Rohm makes a nice IC that ties straight to the AC mains producing a 5v squarewave output at neg and pos cross over.
Pricey but sure helps with UC memory usage.