![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
nikolas
Joined: 09 Oct 2011 Posts: 32
|
Need programming help of pic16f506 |
Posted: Sun Oct 09, 2011 11:23 am |
|
|
hi guys..
My name is Nikolas and I'm from Greece.
I've acquired the following schematic for making a custom gear indicator for my Vstrom bike.
However, I have a really hard time with the pic16f506 since I'm not keen with pic microprocessors.
The schematic is the following.
The range of the voltage of the pink wire is the following.
1st gear = 1.782v
2nd gear = 2.242v
3rd gear = 2.960v
4th gear = 3.630v
5th gear = 4.310v
6th gear = 4.660v
Neutral = 5.000v
So let's suppose that the input in pin 13 is "x"
in c++ someone would think of something like this.
Code: |
main()
{
int x,y
for (;;){
cin << x;
y=x;
if x<2 *
cout <<"1" **
else if x<2,5
cout << "2"
else if x<3,3
cout <<"3"
else if x<4
cout << "4"
else if x<4,5
cout << "5"
else if x< 4,8
cout << "6"
else
cout << "0"
while (x==y){
cin <<x}
}
return 0;
exit();
}
|
Something like that I guess... (I used loops, because I don't know, if the processor, realizes when x changes, or needs to read constantly x value that's why I used "while" loop).
Anyway...someone more experienced, may have a more optimized idea.
But what happens when it comes to pic16f506?? Can someone help me on this part ???
*The values I used for comparison, are volts, I don't actually know, what input the pin13 gets, and how it handles it, so I used volts, little greater, than the expected ones.
**The cout is also, what ideally want to be displayed on the lcd, but i don't know either, what values the lcd needs in order to display, 1,2,3,4,5,6.
Thank you in advance |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 09, 2011 1:35 pm |
|
|
Quote: |
But what happens when it comes to pic16f506?? Can someone help me on this part ???
|
Here is a test program for the ADC in the 16F506. I tested this just now
in hardware. I used vs. 4.073 of the PCB compiler. I installed the 16F506
on a Microchip "low pin count" board. I connected pin C3 to another board
that has a Max232 chip on it, to provide the conversion to RS232 levels.
I used a Pickit 2 programmer and because it uses pin RA0 (AN0) for ICSP
I had to unplug it from the board while running the program because it
was loading down the RA0 pin so I could only get 4v from the trimpot.
When I unplugged it, then I could get the full +5v from the trimpot.
I turned the trimpot on the Low Pin Count board through it's full range of
0v to 5v and the following output was displayed in the TeraTerm window
on my PC. It's working.
Quote: |
0
0
21
38
66
84
120
163
230
255
255
255
|
Code: |
#include <16F506.h>
#fuses INTRC_IO, IOSC4, NOWDT
#use delay(clock = 4M)
#use rs232(baud=9600, xmit=PIN_C3)
//===============================
void main()
{
int8 result;
setup_adc_ports(AN0_AN2);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
delay_us(10);
while(1)
{
result = read_adc();
printf("%u \n\r", result);
delay_ms(500);
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
nikolas
Joined: 09 Oct 2011 Posts: 32
|
|
Posted: Sun Oct 09, 2011 5:08 pm |
|
|
so this code, is going to give me the desired output..???
quite smaller than i expected i guess..
the results that came back, what are they about..??
Code: | 0
0
21
38
66
84
120
163
230
255
255
255 |
i hope you can bear with my "newbie" questions so that i can understand completely what i am doing.. ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 09, 2011 5:18 pm |
|
|
Quote: | quite smaller than i expected i guess..
|
Download the 16F506 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/41268D.pdf
On the front page, on the right side, it says:
Quote: |
• Analog-to-Digital (A/D) Converter:
- 8-bit resolution
|
An 8-bit value can go from 0 to 255.
Quote: | the results that came back, what are they about..??
|
I answered that in my post:
Quote: |
I turned the trimpot on the Low Pin Count board through it's full range of
0v to 5v and the following output was displayed in the TeraTerm window
on my PC.
|
In other words, 0 volts in gives 0 out from the ADC. +5 volts in gives
255 from the ADC. And it's linear in between. |
|
![](templates/subSilver/images/spacer.gif) |
nikolas
Joined: 09 Oct 2011 Posts: 32
|
|
Posted: Sun Oct 09, 2011 5:36 pm |
|
|
you are right about the 8 bit value..
so the lcd display takes as an input these values and will give the desired results..? or anything else is required as well..??
for instance,
value 255 (5volts) will give a "0" indication on the lcd..?? and so on..?? |
|
![](templates/subSilver/images/spacer.gif) |
nikolas
Joined: 09 Oct 2011 Posts: 32
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 09, 2011 6:14 pm |
|
|
That's a 7-segment LCD.
The way you were talking your first post, you implied all you needed was
a jump-start on how to make a CCS program to read the A/D, which I
posted for you. But really, you want the whole program. I feel like
I did the first half. |
|
![](templates/subSilver/images/spacer.gif) |
nikolas
Joined: 09 Oct 2011 Posts: 32
|
|
Posted: Sun Oct 09, 2011 6:23 pm |
|
|
PCM programmer wrote: | That's a 7-segment LCD.
The way you were talking your first post, you implied all you needed was
a jump-start on how to make a CCS program to read the A/D, which I
posted for you. But really, you want the whole program. I feel like
I did the first half. |
You've done too much indeed, it's just that all the programming that I've been involved into so far, was always windows based programming with standard keyboard input and standard screen output.
I've never been involved, at low level programming needing to take into consideration specific pinouts and voltages.
so pretty much i need as much of the program as possible.
I can understand, if you feel like that you are doing the entire job, I wish I could contribute more, but this field is beyond what i know so far.
So if you can help me i would be very grateful, but if you can't it completely understandable.
I mentioned a code (with mistakes) in my first post that i would use in a OS based program, but with the pic and the lcd. I'm completely lost. |
|
![](templates/subSilver/images/spacer.gif) |
nikolas
Joined: 09 Oct 2011 Posts: 32
|
|
Posted: Sun Oct 09, 2011 6:32 pm |
|
|
if my googling is right,
the 7 segment lcd would involve subroutines
sth like this
Code: | void 1gear() {
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(A, LOW);
digitalWrite(G, LOW);
digitalWrite(F, LOW);
|
so i guess the "result" variable would have to go through some comparisons, that each one would call the right subroutine..
how do you "match" though the 5,6,7,8,9,10,12 pinouts from the pic, with the corresponding pinouts of the lcd?? |
|
![](templates/subSilver/images/spacer.gif) |
nikolas
Joined: 09 Oct 2011 Posts: 32
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Mon Oct 10, 2011 2:27 am |
|
|
The normal way, is to use a look up table.
Otherwise you need ten separate routines for the ten possible 'digits'.
So:
Code: |
int8 dbits[10] = {63,12,91,94,108,118,119,28,127,126};
void display_digit(int8 val) {
int8 itemp;
if (val>9) return; //Impossible to display
itemp=dbits[val];
if (itemp & 64) {
//Here extra bit on B1 needs to go on
output_high(PIN_B1);
}
else {
output_low(PIN_B1); //else off
}
output_c(itemp & 63); //send other six bits;
}
|
This should (no guarantees on the table entries....), accept 0-9, and display these. try something like the adc value/26 feeding this.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
nikolas
Joined: 09 Oct 2011 Posts: 32
|
|
Posted: Mon Oct 10, 2011 7:17 am |
|
|
Ttelmah wrote: | The normal way, is to use a look up table.
Otherwise you need ten separate routines for the ten possible 'digits'.
So:
Code: |
int8 dbits[10] = {63,12,91,94,108,118,119,28,127,126};
void display_digit(int8 val) {
int8 itemp;
if (val>9) return; //Impossible to display
itemp=dbits[val];
if (itemp & 64) {
//Here extra bit on B1 needs to go on
output_high(PIN_B1);
}
else {
output_low(PIN_B1); //else off
}
output_c(itemp & 63); //send other six bits;
}
|
This should (no guarantees on the table entries....), accept 0-9, and display these. try something like the adc value/26 feeding this.
Best Wishes |
hi mate, thank you for your response..
is this code enough so that the correct pinout will feed the lcd display..??
also i have a couple of questions..
the variable "val" where does it come from..???? is the input of the variable "result" of the previous example..? (divided perhaps by "2")?
also what is the case about (itemp & 64) and (itemp & 63) ? |
|
![](templates/subSilver/images/spacer.gif) |
nikolas
Joined: 09 Oct 2011 Posts: 32
|
|
Posted: Mon Oct 10, 2011 1:54 pm |
|
|
Ttelmah wrote: |
This should (no guarantees on the table entries....), accept 0-9, and display these. try something like the adc value/26 feeding this.
Best Wishes |
after a pm that i received, and checking again your code, obviously, you mean that from the code that "PCM programmer" gave, that the
"result" variable, that takes values from 0 to 255 will be divided by 26 so that we can get the "desired" array value.
perhaps using a function call like this
Code: | temp=result/26;
display_digit(temp); |
the array values, 63 , 12, 91 etc stand for the actual desired display? 0,1,2 etc..?
also "pin_b1" is the RB1 pin of the pic?? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 10, 2011 1:58 pm |
|
|
'val' holds the "gear number".
The process is:
1. Read the ADC voltage. That gives a number from 0 to 255.
That number comes from the read_adc() function.
2. Translate the ADC value (0 to 255) into a "gear number", which would
be 0 to 6, with 0 being Neutral, and 6 being "6th gear". You need to
write a function to do this, probably with a bunch of if-else greater than,
less than statements. Carefully test this routine, giving it sample inputs
and prove that it provides the correct output in all cases. You can do this
testing in either a hardware or software simulation environment
3. Then display the gear number on the single-digit segmented display.
This requires a routine to translate the number 0 to 6 into a code to
enable the correct segments for each digit. For example, the first
segment code in Ttelmah's table is 63. This is 0x3F in hex, and in
binary it's 0011 1111. Note that 6 of the bits are set to 1. Well, that's
what is required to turn on the 6 segments that make up a '0' digit on
the 7-segment display.
There are 7 segments on your display:
To display a '0', you turn on 6 of them:
|
|
![](templates/subSilver/images/spacer.gif) |
nikolas
Joined: 09 Oct 2011 Posts: 32
|
|
Posted: Mon Oct 10, 2011 3:07 pm |
|
|
what does the (PIN_B1) stand for?
also in the if statement, there is a bitwise and
so for example (itemp & 64 )
this should give
for instance itemp = 12
itemp => 00001100
64 => 01000000
this would give us
itemp & 64 01001100
so what do we actually check by if ( itemp & 64 ) if this is different from 0?
and if so what does the output_high(PIN_BIN1 would return..??
also the 3rd paragraph that you mention PCM programmer, when we have for instance neutral => 63 => 0011 11111
how will this be written in order our pic to give the right 1s in the pins..??
pintf? output_high(63) ? |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|