Software for PIC 16F876

F

Frits

Guest
Hello,
I want to built a simple datalogger with a PIC 16F876, and found a
nice schema
on the net.
My problem: te software (source) is written in "C", but i need a hex
files to program the PIC processor. I have playing with JAL, but i
have not a "C" knowledge. Can someone help me, and "translate" the C
to hex ?

Thanks

*/

#include <16F876.H>
#device ADC=10
#include
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT

/* INTERNAL EEPROM ASSIGNMENTS */
#define SAMPLE_INTERVAL_HI 0
#define SAMPLE_INTERVAL_LO 1
#define SAMPLE_COUNT_HI 2
#define SAMPLE_COUNT_LO 3
#define LOGGING_STATE 4
#define RANGE 5

/* EXTERNAL EEPROM ASSIGNMENTS */
#define EEPROM_ADDRESS long int
#define EEPROM_BYTE_SIZE 8192
#define EEPROM_SCL PIN_B0
#define EEPROM_SDA PIN_B1

/* LCD STUFF */
#define LCD_D0 PIN_C3
#define LCD_D1 PIN_C4
#define LCD_D2 PIN_C5
#define LCD_D3 PIN_C6
#define LCD_EN PIN_B5
#define LCD_RS PIN_B6
#define LINE_1 0x00
#define LINE_2 0x40
#define CLEAR_DISP 0x01

#define MENU_DEC_SWITCH PIN_C0
#define SELECT_INC_SWITCH PIN_C1
#define RANGE_SHUNT PIN_C2
#define SEL0 PIN_B2
#define SEL1 PIN_B4

#define MINIMUM_INTERVAL 1
#define STATE_START 0
#define STATE_STOP 1
#define STATE_STATUS 2
#define STATE_RESET 3
#define STATE_RANGE 4
#define STATE_INTERVAL 5
#define STATE_VIEW 6
#define STATE_DUMP 7
#define MAX_MENU_STATE 7

#define hi(x) (*(&x+1))

#use delay ( clock=4000000 )
#use standard_io ( A )
#use standard_io ( B )
#use standard_io ( C )
#use rs232 ( baud=9600, xmit=PIN_B3 )
#use i2c ( master, scl=EEPROM_SCL, sda=EEPROM_SDA )

void PrintMenu ( void ); /* protos */
void init_ext_eeprom ( void );
void write_ext_eeprom ( long int lngAddress, BYTE intData );
BYTE read_ext_eeprom ( long int lngAddress );
void SetTime ( void );
void CheckSample ( void );
void CheckSwitches ( void );
char GetEchoNumChar ( void );
void LCD_Init ( void );
void LCD_SetPosition ( unsigned int cX );
void LCD_PutChar ( unsigned int cX );
void LCD_PutCmd ( unsigned int cX );
void LCD_PulseEnable ( void );
void LCD_SetData ( unsigned int cX );
void DisplayVolts ( long iAdcValue, char cLoc );
float ScaleAdc ( long iValue );
void SetRange ( BYTE cDisplay );

static long iIntervalCount, iIntervalTrigger, iSampleCount;
static char cLogging, cSampleFlag, cLedCount;
static char cLoggingIndicatorFlag, cAdcFlag, cToggleFlag;
static char cInterruptCount, cViewing;
static char cMenuState, cSelectFlag, cRange, cSel;
static char cMenuDecSwitchOn, cMenuSwitchCount;
static char cSelIncSwitchOn, cSelectSwitchCount;

void main ( void )
{
init_ext_eeprom(); /* set SDA and SCL to float */
setup_counters ( RTCC_INTERNAL, RTCC_DIV_128 ); /* 31mS roll
*/

LCD_Init();
LCD_PutCmd ( CLEAR_DISP );
LCD_SetPosition ( LINE_1 + 2 );
printf ( LCD_PutChar, "DATA LOGGER" );
LCD_SetPosition ( LINE_2 + 2 );
printf ( LCD_PutChar, "%4lu samples", EEPROM_BYTE_SIZE / 2 );
delay_ms ( 2000 );
LCD_PutCmd ( CLEAR_DISP ); LCD_Init();
LCD_SetPosition ( LINE_1 + 4 );
printf ( LCD_PutChar, "Jon Fick" );
LCD_SetPosition ( LINE_2 + 4 );
printf ( LCD_PutChar, "03/01/04" );
delay_ms ( 2000 );
LCD_PutCmd ( CLEAR_DISP );

/* RESTORE PREVIOUS STATE */
cRange = read_eeprom ( RANGE );
SetRange ( NO ); /* set range, don't display */
iSampleCount = ( 256 * read_eeprom ( SAMPLE_COUNT_HI ) ) +
read_eeprom ( SAMPLE_COUNT_LO );
cLogging = read_eeprom ( LOGGING_STATE ); /* get existing state
*/
iIntervalTrigger = ( 256 * read_eeprom ( SAMPLE_INTERVAL_HI ) ) +
read_eeprom ( SAMPLE_INTERVAL_LO );
if ( iIntervalTrigger == 0 )
{
iIntervalTrigger = 1; /* preset to at least 1 second
sample interval */
}

setup_adc_ports ( RA0_ANALOG ); /* these three statements set
up the ADC */
setup_adc ( ADC_CLOCK_INTERNAL ); /* clock source */
set_adc_channel ( 0 ); /* select channel */
enable_interrupts ( INT_RTCC ); /* turn on timer interrupt */
enable_interrupts ( GLOBAL ); /* enable interrupts */

cSelectFlag = OFF;
cToggleFlag = 0;
cMenuDecSwitchOn = OFF;
cSelIncSwitchOn = OFF;
cMenuSwitchCount = 0;
cSelectSwitchCount = 0;
cMenuState = ( cLogging == YES ) ? STATE_STOP : STATE_START; /*
set first menu */

while ( TRUE ) /* do forever */
{
PrintMenu(); /* display screen */
CheckSwitches(); /* check and do any switch activity */
CheckSample(); /* check if it's time to sample ADC */
}
}

/******************************************************************************/

#int_rtcc
void TimerInterrupt ( void ) /* 32.768mS tic, ~30 interrupts per
second */
{
if ( cInterruptCount++ == 30 ) /* if one second yet */
{
cAdcFlag = ON; /* allow write to display */
cInterruptCount = 0;
if ( cLogging == YES )
{
cLoggingIndicatorFlag = ON; /* time to toggle "running"
indicator on display */
}
if ( ( iIntervalCount++ == iIntervalTrigger - 1 ) && (
cLogging == YES ) ) /* if sample time yet */
{
cSampleFlag = ON; /* signal time
to sample */
iIntervalCount = 0; /* start count
over */
}
}
if ( input ( MENU_DEC_SWITCH ) == LOW )
{
if ( cMenuSwitchCount++ == 0 ) /* debounce for 30mS, (was
2) */
{
cMenuDecSwitchOn = YES; /* signal that switch was
pressed */
cMenuSwitchCount = cViewing ? 252 : 240; /* set up
for auto repeat (faster if viewing) */
}
}
else
{
cMenuSwitchCount = 0; /* switch up, restart */
}
if ( input ( SELECT_INC_SWITCH ) == LOW )
{
if ( cSelectSwitchCount++ == 0 ) /* debounce for 30mS (was 2)
*/
{
cSelIncSwitchOn = YES; /* signal that switch was
pressed */
cSelectSwitchCount = cViewing ? 252 : 240; /* set up
for auto repeat (faster if viewing) */
}
}
else
{
cSelectSwitchCount = 0; /* switch is up, restart
count */
}
set_rtcc ( 4 ); /* restart at adjusted value for 1-second
accuracy */
}

/******************************************************************************/

void CheckSwitches ( void )
{
char cX, cDigit, cDigitPointer, cDone;
long iX, iY, iVal, iPlace;

if ( cMenuDecSwitchOn == YES ) /* if interrupt caught the
switch press */
{
if ( cMenuState++ >= MAX_MENU_STATE ) /* if at maximum */
{
cMenuState = 0; /* roll */
}
cMenuDecSwitchOn = NO; /* turn back off */
}
if ( cSelIncSwitchOn == YES ) /* if interrupt caught the
switch press */
{
cSelectFlag = ON;
cSelIncSwitchOn = NO; /* turn back off */
}

if ( cLogging == NO )
{
cSel = 2 * input ( SEL0 ) + input ( SEL1 ); /* determine
state of SEL inputs, (unused at present) */
}

switch ( cMenuState )
{
case ( STATE_START ):
{
if ( cSelectFlag == ON ) /* if switch is pressed */
{
cSelectFlag = OFF; /* turn flag off */
if ( iSampleCount >= ( EEPROM_BYTE_SIZE / 2 ) ) /*
already at end of memory */
{
LCD_PutCmd ( CLEAR_DISP );
LCD_SetPosition ( LINE_1 + 2);
printf ( LCD_PutChar, "MEMORY FULL" );
LCD_SetPosition ( LINE_2 + 2 );
printf ( LCD_PutChar, "%4lu samples", iSampleCount
);
delay_ms ( 1000 );
LCD_PutCmd ( CLEAR_DISP );
cMenuDecSwitchOn = NO;
cSelIncSwitchOn = NO;
cMenuState = STATE_START; /* menu displays
"START" */
}
else /* if OK to start */
{
cLogging = YES;
write_eeprom ( LOGGING_STATE, YES );
write_eeprom ( RANGE, cRange );
cSampleFlag = ON; /*
immediate sample */
cInterruptCount = 0; /* synchronize interrupt
timing from here */
iIntervalCount = 0; /* synchronize */
cMenuState = STATE_STOP; /* menu displays
"STOP" */
break;
}
}
}
case ( STATE_STOP ):
{
if ( cSelectFlag == ON ) /* if switch is pressed */
{
cSelectFlag = OFF; /* turn flag off */
cLogging = NO;
write_eeprom ( LOGGING_STATE, NO );
cMenuState = STATE_START; /* menu displays "START"
*/
break;
}
}
case ( STATE_RESET ):
{
if ( cSelectFlag == ON ) /* if switch is pressed */
{
cSelectFlag = OFF; /* turn flag off */
write_eeprom ( SAMPLE_COUNT_HI, 0 );
write_eeprom ( SAMPLE_COUNT_LO, 0 );
iSampleCount = 0;
cLogging = NO;
LCD_PutCmd ( CLEAR_DISP );
LCD_SetPosition ( LINE_1 + 0 );
printf ( LCD_PutChar, "Reset..." );
delay_ms ( 1000 );
LCD_SetPosition ( LINE_1 + 8 );
printf ( LCD_PutChar, "complete" );
delay_ms ( 1000 );
LCD_PutCmd ( CLEAR_DISP );
cMenuDecSwitchOn = NO;
cSelIncSwitchOn = NO;
cMenuState = STATE_START; /* menu displays "START"
*/
break;
}
}
case ( STATE_STATUS ):
{
if ( cSelectFlag == ON ) /* if switch is pressed */
{
cSelectFlag = OFF; /* turn flag off */
LCD_PutCmd ( CLEAR_DISP );
LCD_SetPosition ( LINE_1 );
printf ( LCD_PutChar, "Interval: %lus", 256 *
read_eeprom ( SAMPLE_INTERVAL_HI ) + read_eeprom ( SAMPLE_INTERVAL_LO
) );
LCD_SetPosition ( LINE_2 );
printf ( LCD_PutChar, "Samples: %lu", 256 *
read_eeprom ( SAMPLE_COUNT_HI ) + read_eeprom ( SAMPLE_COUNT_LO ) );
delay_ms ( 2000 );
LCD_PutCmd ( CLEAR_DISP );
cMenuDecSwitchOn = NO;
cSelIncSwitchOn = NO;
cMenuState = STATE_START; /* menu displays "LOG" */
break;
}
}
case ( STATE_RANGE ):
{
if ( cSelectFlag == ON ) /* if switch is pressed */
{
cSelectFlag = OFF; /* turn flag off */
LCD_PutCmd ( CLEAR_DISP );
LCD_SetPosition ( LINE_2 + 0 );
printf ( LCD_PutChar, "CHANGE Return" );
LCD_SetPosition ( LINE_1 + 7 );
SetRange ( YES ); /* set range, display */
while ( TRUE )
{
if ( cSelIncSwitchOn == YES )
{
cSelIncSwitchOn = NO;
break;
}
if ( cMenuDecSwitchOn == YES )
{
cMenuDecSwitchOn = NO;
if ( ++cRange >= 2 ) /* increment and
wrap */
{
cRange = 0;
}
LCD_SetPosition ( LINE_1 + 7 );
SetRange ( YES ); /* set range,
display */
}
}
write_eeprom ( RANGE, cRange ); /* save range */
cMenuState = STATE_START; /* menu displays
"START" */
break;
}
}
case ( STATE_INTERVAL ):
{
if ( cSelectFlag == ON ) /* if switch is pressed */
{
cSelectFlag = OFF; /* turn flag off */
LCD_PutCmd ( CLEAR_DISP );
LCD_SetPosition ( LINE_1 );
printf ( LCD_PutChar, "Presently %05lus",
iIntervalTrigger );
LCD_SetPosition ( LINE_2 + 0 );
printf ( LCD_PutChar, "DIGIT 00000s INC" );
cX = LINE_2 + 6; /* point to beginning of zeros
*/
LCD_SetPosition ( cX );
LCD_PutCmd ( 0x0E ); /* display ON, cursor on, no
blink */
cDigit = 0;
cDigitPointer = 0;
iX = 0;
iPlace = 10000;
while ( TRUE )
{
if ( cSelIncSwitchOn == YES )
{
if ( ++cDigit > 9 ) /* increment digit
*/
{
cDigit = 0; /* roll */
}
cSelIncSwitchOn = NO;
cSelIncSwitchOn = NO;
LCD_SetPosition ( cX + cDigitPointer ); /*
set cursor to this digit */
printf ( LCD_PutChar, "%u", cDigit ); /*
display the digit */
LCD_SetPosition ( cX + cDigitPointer ); /*
set cursor back to this digit */
}
if ( cMenuDecSwitchOn == YES )
{
cMenuDecSwitchOn = NO;
iX += cDigit * iPlace; /* add in to total */
iPlace /= 10; /* point to next place
value down */
cDigit = 0; /* zero digit again */
if ( ++cDigitPointer == 5 ) /* point to next
digit */
{
break;
}
LCD_SetPosition ( cX + cDigitPointer );
}
}
if ( iX != 0 ) /* if number was updated */
{
write_eeprom ( SAMPLE_INTERVAL_HI, iX / 256 ); /*
store high byte */
write_eeprom ( SAMPLE_INTERVAL_LO, iX % 256 ); /*
store low byte */
iIntervalTrigger = iX; /* update interval */
}
LCD_PutCmd ( 0x0E ); /* display ON, cursor off, no
blink */
LCD_PutCmd ( CLEAR_DISP );
cMenuState = STATE_START; /* menu displays "LOG" */
break;
}
}
case ( STATE_VIEW ):
{
if ( cSelectFlag == ON ) /* if switch is pressed */
{
cSelectFlag = OFF; /* turn flag off */
iX = 0; /* zero sample number */
iY = ( read_eeprom ( SAMPLE_COUNT_HI ) * 256 ) +
read_eeprom ( SAMPLE_COUNT_LO );
cRange = read_eeprom ( RANGE ); /* used stored
range */
LCD_PutCmd ( CLEAR_DISP );
cDone = NO;
if ( iY != 0 ) /* if any samples at all */
{
LCD_SetPosition ( LINE_1 );
printf ( LCD_PutChar, "#" );
LCD_SetPosition ( LINE_2 );
printf ( LCD_PutChar, "DEC BothDone INC" );
while ( cDone == NO )
{
LCD_SetPosition ( LINE_1 + 1 );
printf ( LCD_PutChar, "%04lu", iX ); /*
display sample number */
iPlace = ( read_ext_eeprom ( iX * 2 ) * 256 )
+ read_ext_eeprom ( ( iX * 2 ) + 1 ); /* retrieve data from EEPROM
*/
DisplayVolts ( iPlace, 10 ); /* display
data at position 7 */
while ( TRUE )
{
cViewing = ON;
if ( ( input ( MENU_DEC_SWITCH ) == LOW )
&& ( input ( SELECT_INC_SWITCH ) == LOW ) )
{
cDone = YES;
break;
}
if ( cMenuDecSwitchOn == YES )
{
cMenuDecSwitchOn = NO;
if ( iX-- == 0 )
{
iX = iY - 1; /* roll negative
*/
}
break;
}
if ( cSelIncSwitchOn == YES )
{
cSelIncSwitchOn = NO;
if ( iX++ >= ( iY - 1 ) )
{
iX = 0; /* roll positive */
}
break;
}
}
cViewing = OFF;
}
}
else
{
LCD_SetPosition ( LINE_1 );
printf ( LCD_PutChar, "No samples yet!" );
delay_ms ( 1000 );
}
LCD_PutCmd ( CLEAR_DISP );
cMenuState = STATE_START; /* menu displays "LOG" */
break;
}
}
case ( STATE_DUMP ):
{
if ( cSelectFlag == ON ) /* if switch is pressed */
{
cSelectFlag = OFF; /* turn flag off */
iY = ( read_eeprom ( SAMPLE_COUNT_HI ) * 256 ) +
read_eeprom ( SAMPLE_COUNT_LO ); /* get number of samples */
cRange = read_eeprom ( RANGE ); /* used stored
range */
LCD_PutCmd ( CLEAR_DISP );
cDone = NO;
if ( iY != 0 ) /* if any samples at all */
{
LCD_SetPosition ( LINE_1 + 0 );
printf ( LCD_PutChar, "Dump 9600-8-N-1 " );
LCD_SetPosition ( LINE_2 );
printf ( LCD_PutChar, " Both=Stop " );
disable_interrupts ( GLOBAL ); /* turn off during
async */
printf ( "\r\n\r\n Sample interval -- %lu
seconds", 256 * read_eeprom ( SAMPLE_INTERVAL_HI ) + read_eeprom (
SAMPLE_INTERVAL_LO ) );
printf ( "\r\n Number of samples- %lu", iY );
printf ( "\r\n\r\nSample\tVolts" );
printf ( "\r\n------\t-----\r\n" );
for ( iX = 0; iX < iY; iX++ )
{
if ( ( input ( MENU_DEC_SWITCH ) == LOW ) && (
input ( SELECT_INC_SWITCH ) == LOW ) )
{
cDone = YES;
break;
}
iVal = ( read_ext_eeprom ( iX * 2 ) * 256 ) +
read_ext_eeprom ( ( iX * 2 ) + 1 ); /* get sample data */
if ( iVal == 0x3FF )
{
printf ( "%lu\tO/L\r\n", iX ); /*
out-of-range */
}
else
{
printf ( "%lu\t%1.2f\r\n", iX, ScaleAdc (
iVal ) ); /* send data sample */
}
delay_ms ( 1 ); /* avoids text glitches in
output stream */
}
enable_interrupts ( GLOBAL ); /* turn on again */
}
else
{
LCD_SetPosition ( LINE_1 );
printf ( LCD_PutChar, "No samples yet!" );
delay_ms ( 1000 );
}
delay_ms ( 1000 ); /* allow time to view 9600
baud msg, etc. */
LCD_PutCmd ( CLEAR_DISP );
cMenuState = STATE_START; /* menu displays "LOG" */
break;
}
}
}
}

void PrintMenu ( void )
{
LCD_SetPosition ( LINE_1 + 15 );
if ( cLogging == NO ) /* if not logging at this time */
{
printf ( LCD_PutChar, " " ); /* blank symbol */
}
else /* if presently logging */
{
if ( cLoggingIndicatorFlag == ON ) /* turned on once per
second by interrupt */
{
cToggleFlag ^= 1; /* toggle the symbol */
if ( cToggleFlag == 1 )
{
printf ( LCD_PutChar, "%c", 255 ); /* symbol */
}
else
{
printf ( LCD_PutChar, " " ); /* blank */
}
cLoggingIndicatorFlag = OFF;
}
}
LCD_SetPosition ( LINE_2 + 0 );
switch ( cMenuState )
{
case STATE_START:
{
if ( cLogging == YES ) /* don't display while logging
*/
{
cMenuState++; /* point to next menu */
break;
}
printf ( LCD_PutChar, "Next START" );
break;
}
case STATE_STOP:
{
if ( cLogging == NO ) /* don't display if not logging
*/
{
cMenuState++; /* point to next menu */
break;
}
printf ( LCD_PutChar, "#%04lu", iSampleCount );
LCD_SetPosition ( LINE_2 + 11 );
printf ( LCD_PutChar, " STOP" );
break;
}
case STATE_INTERVAL:
{
if ( cLogging == YES ) /* prevent changing while
logging */
{
cMenuState++; /* point to next menu */
break;
}
printf ( LCD_PutChar, "Next INTERVAL" );
break;
}
case STATE_STATUS:
{
printf ( LCD_PutChar, "Next STATUS" );
break;
}
case STATE_VIEW:
{
printf ( LCD_PutChar, "Next VIEW" );
break;
}
case STATE_DUMP:
{
printf ( LCD_PutChar, "Next UPLOAD" );
break;
}
case STATE_RESET:
{
if ( cLogging == YES ) /* prevent changing while
logging */
{
cMenuState++; /* point to next menu */
break;
}
printf ( LCD_PutChar, "Next RESET" );
break;
}
case STATE_RANGE:
{
if ( cLogging == YES ) /* prevent changing while
logging */
{
cMenuState++; /* point to next menu */
break;
}
printf ( LCD_PutChar, "Next RANGE" );
break;
}
}
if ( cAdcFlag == ON ) /* if interrupt signalled
an ADC reading */
{
DisplayVolts ( read_adc(), 5 ); /* read ADC, send raw
data to display routine at position 3 */
cAdcFlag = OFF;
}
}

void SetRange ( BYTE cDisplay )
{
switch ( cRange )
{
case ( 0 ): /* if 5V range */
{
output_float ( RANGE_SHUNT ); /* open shunt pulldown
*/
if ( cDisplay == YES )
{
printf ( LCD_PutChar, "5V " ); /* 5V scale */
}
break;
}
case ( 1 ): /* if 14V range */
{
output_low ( RANGE_SHUNT ); /* pull shunt resistor
down */
if ( cDisplay == YES )
{
printf ( LCD_PutChar, "14V" ); /* 14V scale */
}
break;
}
default: /* anything else is 5V range */
{
output_float ( RANGE_SHUNT ); /* open shunt pulldown
*/
if ( cDisplay == YES )
{
printf ( LCD_PutChar, "5V " ); /* 5V scale */
}
break;
}
}
}

void CheckSample ( void )
{
long iVal;

if ( cSampleFlag == ON ) /* if time to sample */
{
if ( iSampleCount >= ( EEPROM_BYTE_SIZE / 2 ) ) /* at end of
memory */
{
cLogging = NO; /* stop any further logging */
write_eeprom ( LOGGING_STATE, NO );
cMenuState = STATE_STATUS; /* display status menu next
*/
}
else
{
iVal = read_adc();
/* iVal = iSampleCount; only for testing */
write_ext_eeprom ( iSampleCount * 2, iVal / 256 ); /*
write high data to external EEPROM */
write_ext_eeprom ( ( iSampleCount * 2 ) + 1, iVal % 256 );
/* write low data */
iSampleCount++; /* point to next memory
location */
write_eeprom ( SAMPLE_COUNT_HI, ( char ) ( iSampleCount /
256 ) ); /* save sample count to internal EEPROM */
write_eeprom ( SAMPLE_COUNT_LO, ( char ) ( iSampleCount %
256 ) );
}
cSampleFlag = OFF; /* reset flag, interrupt turns on
again later */
}
}

void init_ext_eeprom ( void )
{
output_float ( EEPROM_SCL );
output_float ( EEPROM_SDA );
}

void write_ext_eeprom ( long int lngAddress, BYTE intData )
{
i2c_start();
i2c_write ( 0xa0 ); /* set up for writing address and data, chip
address 000 */
i2c_write ( hi ( lngAddress ) ); /* write high address */
i2c_write ( lngAddress ); /* write low address */
i2c_write ( intData ); /* write data */
i2c_stop();
delay_ms ( 11 );
}

BYTE read_ext_eeprom ( long int lngAddress )
{
BYTE intData;

i2c_start();
i2c_write ( 0xa0 ); /* set up for writing address, chip address
000 */
i2c_write ( hi ( lngAddress ) ); /* write high address */
i2c_write ( lngAddress ); /* write low address */
i2c_start();
i2c_write ( 0xa1 ); /* set up for reading data, chip address 000
*/
intData = i2c_read ( 0 ); /* read data */
i2c_stop();
return ( intData );
}

char GetEchoNumChar ( void )
{
char cX;

while ( TRUE )
{
// cX = getc(); /* wait for character */
cX = GETC();
if ( ( cX >= '0' ) && ( cX <= '9' ) ) /* check bounds */
{
break;
}
}
PUTC ( cX ); /* echo to screen */
return ( cX - 0x30 ); /* adjust to numeric
*/
}

void DisplayVolts ( long iAdcValue, char cLoc )
{
LCD_SetPosition ( LINE_1 + cLoc );
if ( iAdcValue == 0x3FF )
{
printf ( LCD_PutChar, " O/L " ); /* out of range */
}
else
{
printf ( LCD_PutChar, "%2.2fV ", ScaleAdc ( iAdcValue ) ); /*
display data sample */
}
}

float ScaleAdc ( long iValue )
{
float fScale;

switch ( cRange )
{
case ( 0 ):
{
fScale = 5; /* 5V scale */
break;
}
case ( 1 ):
{
fScale = 14; /* 14V scale */
break;
}
case ( 2 ):
{
fScale = 5; /* 5V scale */
break;
}
case ( 3 ):
{
fScale = 5; /* 5V scale */
break;
}
}
return ( ( float ) iValue / 1023 * fScale ); /* scale to proper
range, 1023 leaves room for out-of-range */
}

void LCD_Init ( void )
{
LCD_SetData ( 0x00 );
delay_ms ( 200 ); /* wait enough time after Vdd rise */
output_low ( LCD_RS );
LCD_SetData ( 0x03 ); /* init with specific nibbles to start
4-bit mode */
LCD_PulseEnable();
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 ); /* set 4-bit interface */
LCD_PulseEnable(); /* send dual nibbles hereafter, MSN first
*/
LCD_PutCmd ( 0x2C ); /* function set (all lines, 5x7
characters) */
LCD_PutCmd ( 0x0C ); /* display ON, cursor off, no blink */
LCD_PutCmd ( 0x01 ); /* clear display */
LCD_PutCmd ( 0x06 ); /* entry mode set, increment */
}

void LCD_SetPosition ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) | 0x08 );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}

void LCD_PutChar ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
output_high ( LCD_RS );
LCD_SetData ( swap ( cX ) ); /* send high nibble */
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); /* send low nibble */
LCD_PulseEnable();
output_low ( LCD_RS );
}

void LCD_PutCmd ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) ); /* send high nibble */
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); /* send low nibble */
LCD_PulseEnable();
}

void LCD_PulseEnable ( void )
{
output_high ( LCD_EN );
delay_us ( 10 );
output_low ( LCD_EN );
delay_ms ( 5 );
}

void LCD_SetData ( unsigned int cX )
{
output_bit ( LCD_D0, cX & 0x01 );
output_bit ( LCD_D1, cX & 0x02 );
output_bit ( LCD_D2, cX & 0x04 );
output_bit ( LCD_D3, cX & 0x08 );
}
 

Welcome to EDABoard.com

Sponsor

Back
Top