Language: C.
Info:
PicKit 3.
PIC18F1220.
Master clock is 10 MHz.
10-bit ADC.
Using timer0 (16-bit mode). The maximum number of combinations on timer0 is 65536.
RB2/INT2 is set as an input.
A potentiometer is connected to RA0/AN0.
RB1 is generating a waveform on a display segment.
The PIC18F1220 that I'm programming is connected to a PIC16F684 that has a built-in program that has a toothed wheel simulator and generates sync pulses once per the revolution of the toothed wheel. The RPM can be adjusted with switches, thus changing the intervals at which the sync pulses go high.
Goals:
1. (achieved) Detect the rising edge of incoming sync pulse that is generated by the other PIC (PIC16F684 with built-in program). This is being detected on input pin RB2/INT2.
2. (partially achieved) Every time a rising edge is detected on RB2, the display segment that is connected to RB1 should light up and stay high for X ms, then stay turn off until the next time a rising edge is detected on RB2. This duration X is to be adjustable depending on the potentiometer that is connected to RA0/AN0. The range should be between 0.25 ms and 4 ms depending on the setting of the potentiometer.
Result:
According to an oscilloscope, my program seems to detect each incoming rising edge on RB2 and the time that the display segment stays high for is adjustable depending on the pot setting, but it is adjustable between about 4.4 ms and 0.75 ms instead of between 4 ms down to 0.25 ms. It works in principle but I need to get the correct range.
When I tried to get the 0.25 ms delay by bypassing the AD conversion, and feeding the corresponding number directly into tmr0, it does stay on for 0.25 ms, as expected. I suspect that the problem might have something to do with the AD conversion currently only reading ADRESH and supposedly ignoring whatever is in ADRESL and the problem seems to become more noticeable the shorter a delay I'm trying to achieve here (adding 0.4 ms to 4 ms is not as noticeable as adding it to 0.25 ms). Unless I use larger delays, it seems to add/remove something that causes the number that is fed into the timer not to match up with the range - when I check my calculations in Excel, they do match up with the desired range. I have previously tried to use While loops to detect the incoming rising edges instead of interrupts and the result was the same, inaccurate, range. However, when I change the calculations so that the smallest duration X is 250 ms instead of 0.25 ms, it does seem to get the range that would be expected. This suggests that it could be something to do with the least significant bits as when the desired delay is 250 ms or higher, to have 0.4 ms added in the background won't make a noticeable difference, but adding 0.4 ms to 0.25 ms does make a big difference. Any idea how I could solve this problem and get a more precise range between 4 ms and 0.25 ms (or 0.25 ms to 4 ms, depending on whether I want to go from high to low or low to high)?
Info:
PicKit 3.
PIC18F1220.
Master clock is 10 MHz.
10-bit ADC.
Using timer0 (16-bit mode). The maximum number of combinations on timer0 is 65536.
RB2/INT2 is set as an input.
A potentiometer is connected to RA0/AN0.
RB1 is generating a waveform on a display segment.
The PIC18F1220 that I'm programming is connected to a PIC16F684 that has a built-in program that has a toothed wheel simulator and generates sync pulses once per the revolution of the toothed wheel. The RPM can be adjusted with switches, thus changing the intervals at which the sync pulses go high.
Goals:
1. (achieved) Detect the rising edge of incoming sync pulse that is generated by the other PIC (PIC16F684 with built-in program). This is being detected on input pin RB2/INT2.
2. (partially achieved) Every time a rising edge is detected on RB2, the display segment that is connected to RB1 should light up and stay high for X ms, then stay turn off until the next time a rising edge is detected on RB2. This duration X is to be adjustable depending on the potentiometer that is connected to RA0/AN0. The range should be between 0.25 ms and 4 ms depending on the setting of the potentiometer.
Result:
According to an oscilloscope, my program seems to detect each incoming rising edge on RB2 and the time that the display segment stays high for is adjustable depending on the pot setting, but it is adjustable between about 4.4 ms and 0.75 ms instead of between 4 ms down to 0.25 ms. It works in principle but I need to get the correct range.
When I tried to get the 0.25 ms delay by bypassing the AD conversion, and feeding the corresponding number directly into tmr0, it does stay on for 0.25 ms, as expected. I suspect that the problem might have something to do with the AD conversion currently only reading ADRESH and supposedly ignoring whatever is in ADRESL and the problem seems to become more noticeable the shorter a delay I'm trying to achieve here (adding 0.4 ms to 4 ms is not as noticeable as adding it to 0.25 ms). Unless I use larger delays, it seems to add/remove something that causes the number that is fed into the timer not to match up with the range - when I check my calculations in Excel, they do match up with the desired range. I have previously tried to use While loops to detect the incoming rising edges instead of interrupts and the result was the same, inaccurate, range. However, when I change the calculations so that the smallest duration X is 250 ms instead of 0.25 ms, it does seem to get the range that would be expected. This suggests that it could be something to do with the least significant bits as when the desired delay is 250 ms or higher, to have 0.4 ms added in the background won't make a noticeable difference, but adding 0.4 ms to 0.25 ms does make a big difference. Any idea how I could solve this problem and get a more precise range between 4 ms and 0.25 ms (or 0.25 ms to 4 ms, depending on whether I want to go from high to low or low to high)?
Last edited: