How to program a 12F508

Thread Starter

q12x

Joined Sep 25, 2015
1,690
I made some progress so far... I THINK... but I'm not completely sure since this is my first time on this subject, and try to believe me; I think that counting the pulses with my pic, will do the job. Here is my circuit. In the right side is the original circuit from the interweb, and on the left, is my simulator doing a great job when the pot is changed.
Screenshot_3.jpg
Im not sure how to connect everything to the PIC...but I have Proteus for that as well. I will probably do that next.
 

Thread Starter

q12x

Joined Sep 25, 2015
1,690
This 555 circuit doesn't work for me in Proteus. It was a shot. I'll think on other things.
 

trebla

Joined Jun 29, 2019
542
You can use old RC timing trick i used years ago when PICs (available to me) were without ADC. See TIP #13.1 here.
I used only one pin without the reference resistor and got quite good results.
 

LesJones

Joined Jan 8, 2017
4,189
Why can't you select a PIC that has ALL the peripheral features you require. For example a PIC12F675, PIB12F1622, PIC12F1640.
From the way you are using the 555 you do not understand how it works. You need to read the data sheet. Your circuit would probably work for input voltages between +5 and about +4. With a 5 volt supply the threshold voltage would be 3.33 volts so when it got close to that value it would stop oscillating.

Les.
 

Thread Starter

q12x

Joined Sep 25, 2015
1,690
Why can't you select a PIC that has ALL the peripheral features you require. For example a PIC12F675, PIB12F1622, PIC12F1640.
Because I have a ton of 12F508 and also I am learning stuff in the same time, like mister @trebla here is helping me with. I also think we can skin the cat in more ways. With your help I will discover (faster) these ways. As I mentioned, this is my first practical need of an ADC in my life. It's a good little project from which I can learn a thing or two. I've already learned the counting oscilations from the 555 circuit. I got the idea now, is what I say.
From the way you are using the 555 you do not understand how it works. You need to read the data sheet. Your circuit would probably work for input voltages between +5 and about +4. With a 5 volt supply the threshold voltage would be 3.33 volts so when it got close to that value it would stop oscillating.
No I do not understand the 555. I am not an engineer or an electronist or electrician. I know some stuff, but definetly not all. I will have to read the 555 datasheet someday, you are right here. Hehe.




You can use old RC timing trick i used years ago when PICs (available to me) were without ADC. See TIP #13.1 here.
I used only one pin without the reference resistor and got quite good results.
Ohoooo, fantastic book my friend !!! I didn't know about it. That's a ton of reading. I will, in time (read it all).
I will read your #13.1 circuit now !

There is another version of the RC timing AD.
I just f* finished this whole circuit around that 555 ADC that took me a good couple of hours to make (the Q12 one). At least it is my idea of wiring and implementation, which im not 100% sure if is totally correct. Im more afraid of blowing up the pickit2 programmer !!!
q20210617 - PIC12F508 and ADC copy 1.jpg -- q20210617 - 555 ADC b copy 1.jpg
I really like your circuit better than my 555 one, because of its simplicity !!!!!
And I will definitely implement it, but after I read your page (and book) and also test your circuit in my simulator.
My BIGGEST concern right now is how to wire to the demo board (without nuke pickit2).
Thank you so much!!! so far, very surprising and interesting answer mister @trebla. You're my friend forever ! But you know it already. Hehe.
 

trebla

Joined Jun 29, 2019
542
If you connect a potentiometer to a pin3 like on your second schematics you may make short on it. Connect the pot ends between GND and pin 3 and connect the viper to beeper.
 

Thread Starter

q12x

Joined Sep 25, 2015
1,690
I think I understand you. Viper = wiper = not a bad name, hehe.
Like this, right? This part I will definitely use it. Even the ADC will be changed into your simpler way, which I love it.
1623929553472.png
The RC trick from your linked page is pure genius and I completely get it ! And I will completely make it !
 
Last edited:

Thread Starter

q12x

Joined Sep 25, 2015
1,690
I did my best and it didn't do anything.
The circuit is fine:
Screenshot_3.jpg
1623947264360.png
And I did use a 30pF cap and 1k resistor exactly how he said it there.
The idea is very nice, but so hard to implement it. At least for me it is.
I didn't hook up the buzzer. I am using only the leds on the testing board to debug what is going on.

Here is my code:
C:
#include <12F508.h>
#include <stdint.h>
#use delay(clock=4000000)
#Fuses INTRC,NOWDT,NOPROTECT,NOMCLR
//in your pickit2 programmer:
//OSCCAL for 12f508 that PK2 Auto Generate was: 0C32
//VDD On checkbox = checked
///MCLR box must be unchecked

void main(void) {
setup_counters (RTCC_INTERNAL,RTCC_DIV_2);

//PIN_B3 input only
//PIN_B0 = led 1
//PIN_B2 = is set as Output and Input to charge the RC thing

int k = 0;

   while (TRUE)
   {
   //Restart - I want to see when is starting
   Start:
   output_high(PIN_B0);delay_ms(2000);
   output_low(PIN_B0);delay_ms(1000);
   k = 0;
 
   //RC charging
   output_high(PIN_B2);
   delay_ms(1);
   input(PIN_B2);

   //Counting and Verifying
   while (PIN_B2!=0)
   {
   k++;
   delay_ms(10);
   if(k==1000){ Break; }
   }
 
//PIN_B2 never = 0. The program just stay in this -while loop-, if I didnt break from it.
   if(PIN_B2==0){output_high(PIN_B1);}

   for(int i = 0;i<2;i++)
   {
   output_high(PIN_B4);
   delay_ms(100);
   output_low(PIN_B4);
   delay_ms(100);
   }
   }
}
 
Last edited:

trebla

Joined Jun 29, 2019
542
I think you must use :
while(input(PIN_B2) {
....
}

To make pin to input you can use function set_tris_b(value) but the function state = input(pin) sets the pin to input and gives also state (0 or 1) of the pin.

Also try different capacitors and resistors, in my schematics is cap 100nF and resistor about 1.5k to 7k.
 

Thread Starter

q12x

Joined Sep 25, 2015
1,690
I made All the changes and still, didn't work.
I've also changed the components values as you suggested: C=100n and R=1k
I made another circuit, specifically your circuit, and still didn't work.
q20210618 - PIC12F508 RC copy 1.jpg
I was thinking, maybe this prototyping board tracks are interfering, but remember that I must use jumpers to actually connect the pins to the leds. I also draw on my artpage, the connections for jumpers. Because the PIC is 8 pins. So practically, those pins, without jumpers are literally in air.
So it's not the circuit tracks.
C:
...
//RC charging
   output_high(PIN_B2);
   delay_ms(1);
   input(PIN_B2);

   //Counting and Verifying
   while (PIN_B2!=0)
   {
   k++;
...
   {
- Your suggestion " while(input(PIN_B2)) " is not correct, because it is saying: "while pin_b2 is set as an input" and I just made it an input one line before him. What I'm saying there with my statement: "while (PIN_B2!=0)", I'm saying: "while Pin_b2 is different than value 0" - it can be 0.1, 1, 10, or 100, or -0.1,-1,-10,-100, execute the code below. I really do not know what value that pin is !!! I wished I knew, I could make the code more specific and more functional.
- I still tried your code "while(input(PIN_B2))" and also "while(input(PIN_B2)!=0)" but nothing worked. In both RC circuits.
- I think the code is not correct! I think the RC circuits are fine, but the code is not good yet. I am missing something important. And this morning I was thinking on my 555 ADC circuit. He is actively pulsing and sending pulses to the pin I am connecting to. Continuously. I didnt build it yet, I only imagine it. So the code should count these pulses somehow, but I have no idea how long a pulse is and no idea how to measure it precisely enough that the code should be able to count them precisely.
- I understand that this RC circuit is actually 1 pulse, from the moment I stop feeding it Voltage , and make the pin as an input to count the time it is discharging. But this is my real problem, I really dont know when is completely discharged and what value is when is completely off. In my mind it should be 0, that's why I made that statement while (PIN_B2!=0). But if it is not 0? If is 0.15 or some residual floating voltage?
- I am still new in CCS C language and I'm sure is a high probability to make mistakes. I don't know where to check which pins correspond to the CCS C naming. For example: in CCS C pin 2 of the PIC is called PIN_B5 but in the 12F508 datasheet is called GP5. I know is intuitive but still, I want to read it somewhere, black on white. I am guessing a lot in this programming language, because I am new to it. I should had practice it more. I didn't. But I will. It's a promise. Until I will get better, you are my trusty right wing, mister @trebla.
And as always, thank you for your help ! You are awesome !
I've also read the pdf circuit with the RC. It is a bit more complex (explained) than anything I did so far. I started with the simplest circuits I could think of, from what you give me. That was my thought, "start from simple toward complex". It is and was always a rule in my book, for everything, especially in art. Haha. Ok, thats it. I wait your feedback and after that, will think on other ways to make this work.
 

trebla

Joined Jun 29, 2019
542
As i remember, in my code was sequence like this:

Set output high
wait until CAP is full //this time must be 2 times bigger than the max RC constant
reset timer
switch pin to input
test input until low
read timer

This algorihtm worked quite precise and stays working well, i used my gadget years without any issue.
Do not use ceramic capacitors, they are temperature and voltage dependent.

Function input(pin) sets pin to input but also returns pin state 1 or 0. In C 1 means "TRUE" and 0 means "FALSE".
So the while(input(pin)) works until the pin state remains 1.

You can set port pin to input using set_tris_b() function and test input using value = bit_test(byte, bit) function but you must declare the port variable:

#byte gpio 0x06 //while(bit_test(gpio, 2)

You can define pin:

#bit rc_pin gpio.2

and then you can test it:

while(rc_pin) {

...
}

Without oscilloscope is hard to tell what is happening in your circuit. Unfortunately i have very busy in this time but if i have time i can try to reconstruct my code which was lost due my old Linux machine crash years ago (i lost half a drive because SCSI card gives some halt signals to PC)
 

Thread Starter

q12x

Joined Sep 25, 2015
1,690
Without oscilloscope is hard to tell what is happening in your circuit. Unfortunately i have very busy in this time but if i have time i can try to reconstruct my code which was lost due my old Linux machine crash years ago (i lost half a drive because SCSI card gives some halt signals to PC)
I have a DSO138 oscilloscope.
1624009790061.png
I lost my Entire HDD data 2 times in my life. It was horrible, so I know how you feel.
Don't worry, we will figure this thing out.
At the momment, I am pursuing the NEXT most logical and easy to implement ( nothing is really easy) method. I am building the 555 ADC. Because I like how it is pulsing continuously and I can deal with that signal a little bit more logically. All I want for the moment is to see it working. If I see it working, I can understand the principle, believe me when I say, all this is brand new to me. I have to understand what is going on. I kind of understanding it, but not 100%, but like 90%. There are some missing pieces.
 
Last edited:

Thread Starter

q12x

Joined Sep 25, 2015
1,690
I failed again. I build the 555 ADC and the pulses are not showing like in my simulator. I changed a bunch of components, in the hope they are bad components, but still, nothing. I build it again on breadboard, which took me a couple of minutes instead of hours that I trustfully build directly on my board the first circuit. What a failure. I am upset I spent such much time building the first board and trusting it will work, without checking first on the breadboard. I got very enthusiastic. On the breadboard, I got a series of spikes but still, not good enough. In my simulator everything is working perfectly ! Damn, I trust that simulator. I'll have to rethink the entire 555 circuit as an ADC, or try to find other circuits and test them on breadboard first, because it literally takes a couple of minutes.
I tested it under the osciloscope, thats how I managed to see the spikes.
Mister @LesJones here, warned me about this 555 circuit. I was so trusty because it worked in simulator.
 

trebla

Joined Jun 29, 2019
542
Digging in my archives, i found one list file printout for some version of my servo control gadget. Turns out, the algorithm is somewhat more complex for this schematics i posted in #85 :

1. Output pin high at least during 4 x RC constant time
2. Reset counter
3. Output low
4. Convert output to input
5. Wait 10 cycles
6. Increment counter by 1
7. Read input
8. If input reads 1 then go to line 3 again
9. If input reads 0 then read counter and go to another routine

I will try later to rewrite this code in CCS C and see how it works
 

Thread Starter

q12x

Joined Sep 25, 2015
1,690
Yes, I am busting my head as well, with my level of logic that I can master at the moment (remember, ADC is my first practical usage right now). I managed to build a successful ADC with 555 and watch it on my osciloscope. I worked hand in hand with my trusty simulator who is VERY close to reality (not perfect but way more than "good enough"). My simulator helped me imensly, especially for the components values configuration. For ex, I bring down the pot value from the original 100k to a 10k pot, and also tweak the cap and resistor to a great degree of finesse to fit somewhat acceptable train of square pulses.
I'm learning some interesting stuff from this experiment as well.
Here is the working circuit:
Screenshot_2.jpg

I also updated my simulator to a newer version (and that took time and concentration) and I was very surprised that is actually better than my older version. Usually they bring crap to new updates, as a general rule or at least in my general experience. But not this time.
- The idea, is to connect this entire 555 circuit to an USB port (5V) (separated from the PIC voltage supply) and the output (through that transistor) will fluctuate (PIC voltage supply)on GP3(input only) of the pic12f508 with common ground for everything. Pretty much like in my last circuit I draw but this one is actually doing it's job.
I've put a 1k resistor in the transistor emitor symbolizing the PIC internal resistance or something, not to be a simple (short) wire to ground.
This is hardcore stuff (for me). But if I can manage to understand it's workings, I can simplify it with your RC circuit, which I kind of understand it, but not completely 100%, YET.
The idea is to figure out how this thing should work. And if I can understand it, then simplification is the next stage. It's my logic so far. Will see how will play out.
Good luck on your side as well ! And thanks for the commitment. It is a fascinating subject indeed.
 
Last edited:

trebla

Joined Jun 29, 2019
542
Converted this routine to CCS C. Result is not that fast as in assy but this adds only few dead cycles:

AD input with RC timing:
#include <12F508.h>
#include <stdint.h>
#use delay(clock=4000000)
#Fuses INTRC,NOWDT,NOPROTECT,NOMCLR

#byte gpio = 0x06 //define port as byte

#define POT1 PIN_B2 //pin with RC circuit

void main(void) {

    setup_counters (RTCC_INTERNAL,RTCC_DIV_2);
    //uint8_t i, adres8;
    uint16_t adres16; //conversion result
    

    output_b(0); //clear outputs
    
    
    output_high(POT1); //initial cap charge
    delay_ms(50);   
            
    while(TRUE) { // do forever
        
        
        
        adres16 = 0; //clear conversion counter
        
        do {
            output_low(POT1); // shot discharge (2us)
            set_tris_b(0b00000100); //make pin gpio.2 to input
            delay_cycles(10); // wait to stabilize
            adres16++; //increment the counter
        } while(bit_test(gpio, 2)); // do while cap charge remains enough
        
        output_high(POT1);    //charge cap again   
        //delay_ms(50); // if no other delay in this program
        
        output_toggle(PIN_B0); //signal with the led
        
        delay_ms(adres16); //blinking rate
    }
}
Tested with the same demo board (DM164120-1), capacitor 0.1 uF, resistor 2k and pot 4,7k. Gives LED flashing rate about 82ms to 248ms.
 

Thread Starter

q12x

Joined Sep 25, 2015
1,690
My friend ! It is working ! Fantastic job !
I just tested your code and the led is blinking faster as I turn the POT.
Thank you ! It is a bit hard coded, I changed some stuff initially, but after carefully reading your code, I realized I should leave it exactly as you send it and it totally worked.
set_tris_b(0b00000100); //make pin gpio.2 to input
Very good that you commented each line !!!! Very good !
In my circuit diagram I had connected RA5 to 1k resistor. By changing the link wire into RA2(09) to 1k resistor, enabled your program. That's the only modification I had to make on my board to coincide with your hard coded program.
Here is my wiring and circuit (updated):

00  - q20210618 - PIC12F508 RC circuit to use.jpg
 
Last edited:

Thread Starter

q12x

Joined Sep 25, 2015
1,690
I just realized that in the moment you are switching PIN_B2 to Input , you actually have 2 grounds at both ends of this little RC circuit !!!!
So... it's a bit of miracle that you catch that little voltage on the (grounded) pin !
I think... it is better to make this pin as a -V instead of 0V, this way, we can be very sure it will surge through the pin and not the other side. It's an idea, probably a bad one, since now is working, I should shut up. Haha. Great job my friend !
 
Top