CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Need programming help of pic16f506
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
nikolas



Joined: 09 Oct 2011
Posts: 32

View user's profile Send private message

Need programming help of pic16f506
PostPosted: Sun Oct 09, 2011 11:23 am     Reply with quote

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
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 1:35 pm     Reply with quote

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); 
  }
}
 
nikolas



Joined: 09 Oct 2011
Posts: 32

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 5:08 pm     Reply with quote

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
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 5:18 pm     Reply with quote

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.
nikolas



Joined: 09 Oct 2011
Posts: 32

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 5:36 pm     Reply with quote

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..??
nikolas



Joined: 09 Oct 2011
Posts: 32

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 6:11 pm     Reply with quote

this is the datasheet of the lcd..

http://www.lumex.com/specs/LDS-C516RI.pdf
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 6:14 pm     Reply with quote

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.
nikolas



Joined: 09 Oct 2011
Posts: 32

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 6:23 pm     Reply with quote

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.
nikolas



Joined: 09 Oct 2011
Posts: 32

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 6:32 pm     Reply with quote

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??
nikolas



Joined: 09 Oct 2011
Posts: 32

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 7:23 pm     Reply with quote

To display for instance "1"
is something regarded to be better than the other ??
Code:

void 1gear
{
RC2=1;
RC3=1;
RC5=0;
RC4=0;
RC0=0;
RC1=0;
}

or
Code:

void 1gear
{
Output_high(RC2);
Output_high(RC3);
Output_low(RC5);
Output_low(RC4);
Output_low(RC0);
Output_low(RC1);
}

or something else ???

These are according to
http://www.codeproject.com/KB/system/PICC_Lite_Tutorial.aspx
and
http://www.swarthmore.edu/NatSci/echeeve1/Ref/C%20for%20PIC/C_Intro.html
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Oct 10, 2011 2:27 am     Reply with quote

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
nikolas



Joined: 09 Oct 2011
Posts: 32

View user's profile Send private message

PostPosted: Mon Oct 10, 2011 7:17 am     Reply with quote

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) ?
nikolas



Joined: 09 Oct 2011
Posts: 32

View user's profile Send private message

PostPosted: Mon Oct 10, 2011 1:54 pm     Reply with quote

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??
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 10, 2011 1:58 pm     Reply with quote

'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:
Code:

 _ 
|_| 
|_| 

To display a '0', you turn on 6 of them:
Code:

 _ 
| | 
|_| 
nikolas



Joined: 09 Oct 2011
Posts: 32

View user's profile Send private message

PostPosted: Mon Oct 10, 2011 3:07 pm     Reply with quote

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) ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
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