Society of Robots - Robot Forum
Software => Software => Topic started by: katherina on September 25, 2007, 03:19:13 AM
-
i'm doing a pic programming using c. it will display temperature in celcius on the LCD. i found this program in the internet. what does this means?? I have no idea... :
/*initial program*/
/* keys definition */
#define INCREF PORTD.F0
#define DECREF PORTD.F1
#define UNIT PORTD.F7
/* segments definition */
#define SA 1
#define SB 2
#define SC 4
#define SD 8
#define SE 16
#define SF 32
#define SG 64
#define DP 128
/* 7 segments table */
const unsigned char segment[10] =
{
SA+SB+SC+SD+SE+SF, // 0
SB+SC, // 1
SA+SB+SG+SE+SD, // 2
SA+SB+SG+SC+SD, // 3
SF+SG+SB+SC, // 4
SA+SF+SG+SC+SD, // 5
SA+SF+SG+SE+SC+SD, // 6
SA+SB+SC, // 7
SA+SB+SC+SD+SE+SF+SG, // 8
SA+SB+SC+SD+SF+SG // 9
} ;
/* other symbols */
#define segDEG SA+SB+SF+SG
#define segMINUS SG
#define segF SA+SE+SF+SG
#define segC SA+SD+SE+SF
this is the rest of the program:
/* this counter is incremented on each TIMER0 overflow */
long cntr ;
/* display table */
unsigned char data[4] ;
/* current digit to display */
unsigned char dcurr ;
/* result of the measure */
int temp ;
/* offset of the sensor */
int ref = 116 ;
/* convert binary to 7 segment digit, blank on zero is allowed by m */
unsigned char modulo10Seg(unsigned char v, unsigned char m)
{
return((m || v) ? segment[v % 10] : 0) ;
}
/* interrupt routine, called on each timer0 overflow
* period does not matter, as long as display does not flicker
*/
void interrupt(void)
{
if(INTCON.T0IF) // timer 0 overflow ?
{
cntr++ ; // increment counter
dcurr++ ; // next digit
PORTB = 0 ; // turn digit off
if(dcurr == 4) // last digit ?
{
PORTA = 0b00000001 ; // light the first digit
dcurr = 0 ;
}
else
{
PORTA <<= 1 ; // light the next digit
}
PORTB = data[dcurr] ; // assign 7 segments value
INTCON.T0IF = 0 ; // done
}
}
/* main program*/
void main()
TRISB = 0; //set port B as output
PORTB = 0;
OPTION_REG = 0x80; //set timer 0,no prescaler
INTCON = 0xA0; //allow timer 0 overflow interrupt
for(;;) //forever
{
if (cntr>= 4000) //if enough time since last sample
{
/* read the sensor */
ADCON1 = 0x00; //set port A as analog input
TRISA = 0xff; //set port A as input
temp = ref - Adc_Read(7); // read RE2 ADC
ADCON1 = 0x07; //set port A as Digital IO
TRISA = 0; //set port A as output
/* CONVERT TO READABLE VALUE */
temp *= 221; //temperature coefficient of silicon junction
temp /= 102;
temp = 25 + temp; //get the result in celcius
if(temp < 0) // value to be displayed is negative ?
{
data[0] = segMINUS ; // yes, first digit is minus
data[1] = modulo10seg(temp / 10, 0) ; // tenths are blanked if zero
}
else
{
data[0] = modulo10seg(temp / 100, 0) ; // no, display hundreds (if they are)
data[1] = modulo10seg(temp / 10, 1) ; // thenths
}
data[2] = modulo10seg(temp, 1) ; // units
data[3] = fahrenheit ? segF : segC ; // unit symbol
cntr = 0 ; // reset counter
}
I also do not understand the interrupt routine here... someone please explain to me wats goin on in the program.... i really appreciate it.
and... what is that "modulo10seg" for???
please someone...
:'(
-
ok I just noticed this post of yours . . . im crosslinking it to avoid more confusing . . .
http://www.societyofrobots.com/robotforum/index.php?topic=1954.0
Im a fairly bad programmer so I want to share with you my method of programming something I dont understand . . .
First I find source code on the internet like you did and try to understand it . . . but there are many programmers who dont know how to comment or structure source code so that others can understand . . . I would say that this source code is kind of hard to understand, although Ive seen much worse. Try running it on your kit and see what happens. If it works, then try tweaking it and see what changes. The pins will probably be different though, going to my next point . . .
The next step is to read manuals, such as looking up what an interrupt is, reading tutorials, etc. Look up the datasheet for the PIC16F877 and just look everything up. It will be a bit overwhelming at first, but just keep at it and it will come to you over time.
After I try the above, I start with a blank 'hello world' source code. Just enough code to not get any errors. If it had any more, then it would just be confusing and hard to understand. Then I just add code, test, add code, test, etc and just build up my program from scratch. Learn a little, write a little, learn more, write more, and keep doing that. Dont try to understand everything at once.
For my most recent robot program (mapping and navigation), I had found source code for it online but I just couldnt figure it out to use it. So instead I did a lot of reading and built up my program from scratch - took me about a month, but I learned quite a lot in the process. :)
-
It's a code for thermometer. First it reads value using A/D converter, scales it and then it displays it on 4 digit LED display.
modulo10Seg is a helper function which converts number to segments.
For example if you want to display number 235 on 4 digit display, your program need to find out single digit numbers.
For hundreds:
235 / 100 = 2
2 % 10 = 2
Then to display this number you have to turn on correct segments on LED display. This is done using a lookup array.
For tenths:
235 / 10 = 23
23 % 10 = 3
...again lookup in table array.
and finally for ones:
235 % 10 = 5
...
Timer function is used for multiplexing between 4 LED displays. This is used in order to decrease number of pins needed to driver a display. You can connect 4 digit LED display with 7 (segment) + 4 (select display) = 11 lines using multiplexing or using 4 x 7 = 28 if you connect each segment to a single pin. Using multiplexing only one of four LED displays is turned on at once.
Multiplexing: http://derbytimer.com/diy/multiplexing.php (http://derbytimer.com/diy/multiplexing.php)
Code is really good commented btw...
-
For lcd: http://www.spickles.org/projects/4-bit-lcd/ (http://www.spickles.org/projects/4-bit-lcd/)
-
Code is really good commented btw...
you havent seen my commenting ;)
but Im not CS, so I probably require a bit more commenting to understand source code . . . doh!
-
thanx... i dun understand the SA, SB, etc part...
wat does all that means btw... thre's no explanation
i have a bad time learning this thing as my lecturer suddenly ask us to do a project using PIC n didn't taught anything on it. i hv read the data sheet. however, im so blur...
-
Well... LED is made out of 7 segments and normally you can name them from A to G.. or SA to SG, like in this picture:
(http://www.farma-drustvo.si/rok/led.jpg)
I gave segments the same name as they are used in the above code.
So to show number 1 you have to turn on SB and SC. To show number 0 you have to turn on all segments except the middle one (SG) and so on. All numbers are described with segments there.
What's up with all those defines and all the numbers? They are multiples of 2 and if you look them in binary they look like:
0000 0001
0000 0010
0000 0100
...
Each bit corresponds to a output pin that is connected to a segments.
For example when this program writes out number one it looks up the array segment for number one (stored in segment[1]) and gets value 6 which is 0000 0110 in binary. And then it writes this number to port register (PORTB) which causes pins PB1 and PB2 to go high (all other on PORTB go/stay low) and segments SB and SC light on and you see a 1. Yeeeee!
-
tq v.much... that really helps a lot... tq again :)
-
more questions.... what is this for?
/* offset of the sensor */
int ref = 116 ;
what does that means n wat for?
does it vary from sensor to sensor?
im using LM35 as my temperature sensor....
-
That 'ref' is sensor stuff yes... forget it ;)
LM35 datasheet says: 0 mV + 10 mV / ?C
So 0?C = 0 mV, 150?C = 1500 mV (1.5 V).
If you use Vdd of 5V and 10 bit A/D it means that 0V is value A/D register will have value of 0 and at 5V 1023 (2^10 - 1).
So temp in ?C would be: ADResult / 1024 * 5000 / 10.
You should do:
temp = ADResult * 500;
temp = temp / 1024; // or better temp = temp >> 10;
If you need tenths of celsius multiply by 5000 instead of 500. But then you need to use long type (32 bit) instead of int (16) for storing the result of multiplication.
-
ok... tQ...
what bout dis :
/* keys definition */
#define INCREF PORTD.F0
#define DECREF PORTD.F1
#define UNIT PORTD.F7
D.F0??? why F0? why dun they just put portd.1?
-
What's up with all those defines and all the numbers? They are multiples of 2 and if you look them in binary they look like:
0000 0001
0000 0010
0000 0100
...
ok... but...
why do they have to be in multiples of two?
why is it like that? can't it be in 1,2,3,4,5?
-
why do they have to be in multiples of two?
because binary works that way :)
http://en.wikipedia.org/wiki/Binary_numeral_system (http://en.wikipedia.org/wiki/Binary_numeral_system)
-
/* interrupt routine, called on each timer0 overflow
* period does not matter, as long as display does not flicker
*/
void interrupt(void)
{
if(INTCON.T0IF) // timer 0 overflow ?
{
cntr++ ; // increment counter
dcurr++ ; // next digit
PORTB = 0 ; // turn digit off
if(dcurr == 4) // last digit ?
{
PORTA = 0b00000001 ; // light the first digit
dcurr = 0 ;
}
else
{
PORTA <<= 1 ; // light the next digit
}
PORTB = data[dcurr] ; // assign 7 segments value
INTCON.T0IF = 0 ; // done
}
}
may i know wats d purpose of this interrupt routine?
n how does it operate???
-
It is used for multiplexing the LED display.
-
thanx a lot 4 d help... we really appreciate it ;D