|
|
View previous topic :: View next topic |
Author |
Message |
pg1995
Joined: 05 Apr 2014 Posts: 31
|
How to drive two 20x4 lcds ? |
Posted: Mon Jul 07, 2014 3:11 pm |
|
|
Re: Flexible LCD driver for 20x4 LCDs
http://www.ccsinfo.com/forum/viewtopic.php?t=28268
Hi
I was able to learn how to interface an LCD to a microcontroller using the codes given in first post of this thread. Thank you. But I was wondering that if it would be possible to drive two LCDs using those codes. I can't see how. I want to use two 20x4 LCDs. Could you please help me? Thanks. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9254 Location: Greensville,Ontario
|
|
Posted: Mon Jul 07, 2014 8:07 pm |
|
|
The simplest( easiest ?) way is to make 2 copies of the driver. Call them my_LCD_1.c and my_LCD_2.c
Simply recode to functions to be unique to *1.c or *2.c. As well you'll need to define a set of I/O pins for each driver.
This technique uses the most program space. It may be possible to reduce it IF there are 'common' functions. A function that is NOT specific to an LCD module is 'common' and called from either driver.
You can in fact recode into one 'big' driver, actually copying LCD specific functions twice, giving unique names for #1 LCD and #2 LCD access.
Frankly with PICs having tons of space , it's probably not worth the bother, though I did use this for a project using Dallas 1-wire temp sensors. Each sensor had it's own I/O pin made the hardware easy. Loss of one sensor did not affect the other 7 !
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19563
|
|
Posted: Tue Jul 08, 2014 12:38 am |
|
|
The pins can be used for both LCD's.
Only one that needs to be different, is the enable.
If you use PCM_programmer's flex_lcd driver, this can be recoded very easily to support two LCD's.
Start with the 20x4 version:
<http://www.ccsinfo.com/forum/viewtopic.php?t=28268>
Then you need to make the changes shown below:
Code: |
//Two enable pins
#define LCD_E1 PIN_xx
#define LCD_E2 PIN_yy
//Change these to suit your wiring. Note the two enables E1, and E2
int1 select_lcd=0;
//Then replace 'output_low(LCD_E)' everywhere with:
if (select_lcd)
output_low(LCD_E2);
else
output_low(LCD_E1);
//and the same for 'output_high(LCD_E)'
if (select_lcd)
output_high(LCD_E2);
else
output_high(LCD_E1);
|
Then you just change select_lcd between 0 and 1 to select the lcd to use. So:
Code: |
select_lcd=0;
lcd_init(); //initialise the first lcd
select_lcd=1;
lcd_init(); //initialise the second lcd
select_lcd=0;
printf(lcd_putc,"Hello on first");
select_lcd=1;
printf(lcd_putc,"Hello on second");
|
When 'select' is 0, you are talking to the first lcd, and when it is 1, the second. |
|
|
pg1995
Joined: 05 Apr 2014 Posts: 31
|
|
Posted: Tue Jul 08, 2014 9:50 am |
|
|
Thank you, jay, Ttelmah.
I followed Ttelmah's instructions and was able to make two LCDs work. You can have a look on this video: https://www.youtube.com/watch?v=2F0HVVTjYto
Please note that Ttelmah's second code doesn't have anything to do with the driver code and it's only there to show you how to make two LCDs work in the main code.
Here is the driver code with Ttelmah's suggested changes. In other words, now the driver can be used to run two LCDs. You only need to use "select_lcd" to select which LCD of the two to use for display.
Code: |
// Flex_LCD420.c
// These pins are for my Microchip PicDem2-Plus board,
// which I used to test this driver.
// An external 20x4 LCD is connected to these pins.
// Change these pins to match your own board's connections.
//Two enable pins
#define LCD_E1 PIN_C2
#define LCD_E2 PIN_C3
//Change these to suit your wiring. Note the two enables E1, and E2
int1 select_lcd=0;
#define LCD_DB4 PIN_B4
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7
#define LCD_RS PIN_C0
#define LCD_RW PIN_C1
//#define LCD_E PIN_C2
/*
// To prove that the driver can be used with random
// pins, I also tested it with these pins:
#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_B1
#define LCD_DB6 PIN_C5
#define LCD_DB7 PIN_B5
#define LCD_RS PIN_E2
#define LCD_RW PIN_B2
#define LCD_E PIN_D6
*/
// If you want only a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line. Doing so will save one PIC
// pin, but at the cost of losing the ability to read from
// the LCD. It also makes the write time a little longer
// because a static delay must be used, instead of polling
// the LCD's busy bit. Normally a 6-pin interface is only
// used if you are running out of PIC pins, and you need
// to use as few as possible for the LCD.
#define USE_RW_PIN 1
// These are the line addresses for most 4x20 LCDs.
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x40
#define LCD_LINE_3_ADDRESS 0x14
#define LCD_LINE_4_ADDRESS 0x54
// These are the line addresses for LCD's which use
// the Hitachi HD66712U controller chip.
/*
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x20
#define LCD_LINE_3_ADDRESS 0x40
#define LCD_LINE_4_ADDRESS 0x60
*/
//========================================
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines(or more)
int8 lcd_line;
int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Set mode: 4-bit, 2+ lines, 5x8 dots
0xc, // Display on
1, // Clear display
6 // Increment cursor
};
//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note: !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
//output_high(LCD_E);
if (select_lcd)
output_high(LCD_E2);
else
output_high(LCD_E1);
delay_us(2);
//output_low(LCD_E);
if (select_lcd)
output_low(LCD_E2);
else
output_low(LCD_E1);
}
//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine. For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.
#ifdef USE_RW_PIN
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
retval = 0;
//output_high(LCD_E);
if (select_lcd)
output_high(LCD_E2);
else
output_high(LCD_E1);
delay_us(1);
retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
//output_low(LCD_E);
if (select_lcd)
output_low(LCD_E2);
else
output_low(LCD_E1);
delay_us(1);
return(retval);
}
#endif
//---------------------------------------
// Read a byte from the LCD and return it.
#ifdef USE_RW_PIN
int8 lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high = lcd_read_nibble();
low = lcd_read_nibble();
return( (high<<4) | low);
}
#endif
//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef USE_RW_PIN
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef USE_RW_PIN
output_low(LCD_RW);
delay_cycles(1);
#endif
//output_low(LCD_E);
if (select_lcd)
output_low(LCD_E2);
else
output_low(LCD_E1);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------
void lcd_init(void)
{
int8 i;
lcd_line = 1;
output_low(LCD_RS);
#ifdef USE_RW_PIN
output_low(LCD_RW);
#endif
//output_low(LCD_E);
if (select_lcd)
output_low(LCD_E2);
else
output_low(LCD_E1);
// Some LCDs require 15 ms minimum delay after
// power-up. Others require 30 ms. I'm going
// to set it to 35 ms, so it should work with
// all of them.
delay_ms(35);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);
// If the R/W signal is not used, then
// the busy bit can't be polled. One of
// the init commands takes longer than
// the hard-coded delay of 50 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_RW_PIN
delay_ms(5);
#endif
}
}
//----------------------------
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
switch(y)
{
case 1:
address = LCD_LINE_1_ADDRESS;
break;
case 2:
address = LCD_LINE_2_ADDRESS;
break;
case 3:
address = LCD_LINE_3_ADDRESS;
break;
case 4:
address = LCD_LINE_4_ADDRESS;
break;
default:
address = LCD_LINE_1_ADDRESS;
break;
}
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
//-----------------------------
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
lcd_line = 1;
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1, ++lcd_line);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//------------------------------
#ifdef USE_RW_PIN
char lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS);
value = lcd_read_byte();
output_low(LCD_RS);
return(value);
}
#endif
|
This is the main code I used.
Code: |
#include <16f876.h>
#use delay(Clock=20000000)
#fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT,NOLVP
#include <Flex_LCD420.c>
void main()
{
select_lcd=0;
lcd_init(); //initialise the first lcd
printf(lcd_putc, "\f");
delay_ms(500);
select_lcd=1;
lcd_init(); //initialise the second lcd
printf(lcd_putc, "\f");
delay_ms(500);
select_lcd=0;
printf(lcd_putc,"Hello on first");
delay_ms(2000);
select_lcd=1;
printf(lcd_putc,"Hello on second");
delay_ms(3000);
printf(lcd_putc,"\fTwo LCDs can be used");
delay_ms(2000);
select_lcd=0;
printf(lcd_putc,"\fand it's such a fun!");
delay_ms(2000);
select_lcd=1;
printf(lcd_putc,"\fGood Bye :)");
}
|
Thanks a lot for your help.
Regards
PG |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Tue Jul 08, 2014 10:44 am |
|
|
Hi,
I was all excited right up until the moment I realized that this was a purely Proteus exercise......
Doesn't anyone actually build any real hardware anymore?
John |
|
|
pg1995
Joined: 05 Apr 2014 Posts: 31
|
|
Posted: Tue Jul 08, 2014 10:59 am |
|
|
Hi John
Quote: | I was all excited right up until the moment I realized that this was a purely Proteus exercise...... |
There is a possibility that I will be using two LCDs in my school project and before implementing everything in hardware it's always good to experiment with the simulations, isn't it?! Thanks.
Regards
PG |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19563
|
|
Posted: Tue Jul 08, 2014 1:38 pm |
|
|
Not really.
Yes, use simulations _after_ you have the hardware running, to check display layouts and responses etc., but (unfortunately) Proteus in particular will allow things to 'work', that don't on real chips, and then not work with things that do work on real chips.
90% of the time spent 'developing' in Proteus, is wasted. Having got things working in it, you end up having to do the development again in the real hardware..... |
|
|
pg1995
Joined: 05 Apr 2014 Posts: 31
|
|
Posted: Tue Jul 08, 2014 3:35 pm |
|
|
Thank you, Ttelmah.
That's a good suggestion or advice. But sometimes simulators can help you a lot. For instance, if I hadn't use Proteus then I don't think I would have understood exactly what you were suggesting about using two LCDs in such a short time.
Regards
PG |
|
|
pg1995
Joined: 05 Apr 2014 Posts: 31
|
How can I keep those LEDs keep blinking? |
Posted: Tue Jul 08, 2014 4:11 pm |
|
|
Hi
Please have a look on this video: http://youtu.be/HodLLwSKBbA
The main code used by me and given below was provided by PCM programmer in this thread with slight modification to include the LED part (at the start of the 'while' loop), and further I have used the driver also provided by PCM programmer in the same thread.
Now the problem is that the LEDs will blink once and then they won't until the next cycle of the loop. Is this possible that they keep blinking continuously while LCD stuff is being displayed? Could you please help me with this? Thanks.
Code: |
#include <16f876.h>
#use delay(Clock=20000000)
#fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT,NOLVP
#include <Flex_LCD420.c>
void main()
{
int8 i;
int8 b1, b2, b3, b4;
// The lcd_init() function should always be called once,
// near the start of your program.
lcd_init();
// Clear the LCD.
printf(lcd_putc, "\f"); // "\f" clears LCD and takes the cursor to position (1,1)
delay_ms(500);
while(TRUE) {
output_high(pin_c7);
delay_ms(700);
output_low(pin_c7);
output_high(pin_c6);
delay_ms(700);
output_low(pin_c6);
// Test the clear screen and newline commands.
// Also test that we can write to all 4 lines.
printf(lcd_putc, "\fThis is the 1st line");
delay_ms(4000);
printf(lcd_putc, "\nNext is the 2nd line");
delay_ms(4000);
printf(lcd_putc, "\nThis is the 3rd line");
delay_ms(4000);
printf(lcd_putc, "\nFinally the 4th line");
delay_ms(4000);
// Test some additional characters.
printf(lcd_putc, "\fABCDEFGHIJKLMNOPQRST");
delay_ms(4000);
printf(lcd_putc, "\nabcdefghijklmnopqrst");
delay_ms(4000);
printf(lcd_putc, "\n12345678901234567890");
delay_ms(4000);
printf(lcd_putc, "\n!@#$^&*(){}[]:;<>?/=");
delay_ms(4000);
// Clear the LCD.
printf(lcd_putc, "\f");
delay_ms(4000);
// Test that lcd_gotoxy() works. Go to each of
// the four corners and put a number in each one,
// in a clockwise direction, starting with the upper
// left corner.
lcd_gotoxy(4, 2);
printf(lcd_putc, "Put a number in");
lcd_gotoxy(4, 3);
printf(lcd_putc, "each corner.");
lcd_gotoxy(1, 1);
delay_ms(4000);
printf(lcd_putc, "1");
delay_ms(4000);
lcd_gotoxy(20, 1);
printf(lcd_putc, "2");
delay_ms(4000);
lcd_gotoxy(20, 4);
printf(lcd_putc, "3");
delay_ms(4000);
lcd_gotoxy(1, 4);
printf(lcd_putc, "4");
delay_ms(4000);
// Read the character that was written in each corner
// of the LCD and display it. This tests the lcd_getc()
// function.
// The following test can only be done if we can read
// from the LCD. If the RW pin is not used, then the
// LCD is in write-only mode, and we can't do this test.
// The #ifdef statement will prevent the code from
// being compiled, in that case.
#ifdef USE_RW_PIN
// Test if lcd_getc() can read
// a byte from each corner.
b1 = lcd_getc(1,1);
b2 = lcd_getc(20,1);
b3 = lcd_getc(20,4);
b4 = lcd_getc(1,4);
lcd_gotoxy(1, 1);
printf(lcd_putc, "\fRead these bytes\n");
printf(lcd_putc, "from the 4 corners:\n\n");
printf(lcd_putc, " %c %c %c %c", b1, b2, b3, b4); //pg256
delay_ms(4000);
#endif
// Type some characters and backspace over them.
printf(lcd_putc, "\fType characters and\n");
printf(lcd_putc, "backspace over them.");
delay_ms(4000);
// Go to end of 2nd line.
lcd_gotoxy(20, 2);
// Backspace over 2nd line.
for(i = 0; i < 20; i++)
{
printf(lcd_putc," \b\b");
delay_ms(200);
}
// Go to end of first line.
lcd_gotoxy(20, 1);
// Backspace over first line.
for(i = 0; i < 20; i++)
{
printf(lcd_putc," \b\b");
delay_ms(200);
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jul 08, 2014 4:45 pm |
|
|
To have the LEDs blink independently of the main program, you need to
blink them inside a timer interrupt routine. Setup a Timer to interrupt
at some suitable rate, such as every 10ms. Then setup a static variable
inside the Timer interrupt routine, and increment it once for each Timer
interrupt (ie., once every 10ms). Also, initialize the static variable to 0.
When the static variable counts up to 70 (70 x 10ms = 700ms), then
toggle the LED, and reset the static variable back to 0.
It's possible that interrupting the LCD code in certain routines, may
cause the LCD to not operate correctly. If you discover that to be true,
then protect the affected sections of LCD code with
disable_interrupts(INT_TIMERx) and enable_interrupts(INT_TIMERx). |
|
|
pg1995
Joined: 05 Apr 2014 Posts: 31
|
|
Posted: Tue Jul 08, 2014 9:09 pm |
|
|
Thank you, PCM programmer.
I'm trying to understand what you suggested and the following query is related to this.
This is from CCS compiler manual for PIC, June 2013, page #64:
setup_timer_0(RTCC_INTERNAL |RTCC_DIV_2|RTCC_8_BIT)
//sets the internal clock as source and prescale 2. At 20Mhz timer0 will increment every 0.4us in this setup and overflows every 102.4us
A prescalar is used to reduce the frequency of the clock which means increased period. In this case 20 MHz becomes 10 MHz and period is (1/10M)=0.1 us. According to my calculation the increment should take place every 0.1 us and overflow should occur every 25.5 us because 0.1x255=25.5. Could you please let me know where I'm going wrong? Thanks.
A postscalar is used to set the number of overflows which should occur in order to create an interrupt.
Regards
PG |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jul 08, 2014 9:24 pm |
|
|
It's in the PIC data sheet.
What clock is used for Timers ? Answer:
Quote: | 5.0 TIMER0 MODULE
In Timer mode, the Timer0 module will increment every instruction cycle
(without prescaler).
|
and how is the Instruction Cycle clock derived ? Answer:
Quote: | 13.0 INSTRUCTION SET SUMMARY
One instruction cycle consists of four oscillator periods. |
|
|
|
pg1995
Joined: 05 Apr 2014 Posts: 31
|
|
Posted: Tue Jul 08, 2014 10:36 pm |
|
|
Thank you very much.
I believe that I was able to do what you suggested about LEDs blinking independently of the main code. Please have a look on this video: http://youtu.be/QO9xBwHQ7bc
I have used this code. The added sections are spaced from the original code.
Code: |
#include <16f876.h>
#use delay(Clock=20000000)
#fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT,NOLVP
#include <Flex_LCD420.c>
int16 led1=0,led2=0;
#int_timer0
void timer0() {
led1++; led2--;
if (led1==400) {output_toggle(PIN_C6); led1=0;}
if (led2==0) {output_toggle(PIN_C7); led2=400;}
}
void main()
{
int8 i;
int8 b1, b2, b3, b4;
// The lcd_init() function should always be called once,
// near the start of your program.
lcd_init();
// Clear the LCD.
printf(lcd_putc, "\f"); // "\f" clears LCD and takes the cursor to position (1,1)
delay_ms(500);
setup_timer_0(RTCC_INTERNAL |RTCC_DIV_32|RTCC_8_BIT);
output_low(PIN_C6);
output_low(PIN_C7);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
led1=0; led2=1;
while(TRUE) {
// Test the clear screen and newline commands.
// Also test that we can write to all 4 lines.
printf(lcd_putc, "\fThis is the 1st line");
delay_ms(4000);
printf(lcd_putc, "\nNext is the 2nd line");
delay_ms(4000);
printf(lcd_putc, "\nThis is the 3rd line");
delay_ms(4000);
printf(lcd_putc, "\nFinally the 4th line");
delay_ms(4000);
// Test some additional characters.
printf(lcd_putc, "\fABCDEFGHIJKLMNOPQRST");
delay_ms(4000);
printf(lcd_putc, "\nabcdefghijklmnopqrst");
delay_ms(4000);
printf(lcd_putc, "\n12345678901234567890");
delay_ms(4000);
printf(lcd_putc, "\n!@#$^&*(){}[]:;<>?/=");
delay_ms(4000);
// Clear the LCD.
printf(lcd_putc, "\f");
delay_ms(4000);
// Test that lcd_gotoxy() works. Go to each of
// the four corners and put a number in each one,
// in a clockwise direction, starting with the upper
// left corner.
lcd_gotoxy(4, 2);
printf(lcd_putc, "Put a number in");
lcd_gotoxy(4, 3);
printf(lcd_putc, "each corner.");
lcd_gotoxy(1, 1);
delay_ms(4000);
printf(lcd_putc, "1");
delay_ms(4000);
lcd_gotoxy(20, 1);
printf(lcd_putc, "2");
delay_ms(4000);
lcd_gotoxy(20, 4);
printf(lcd_putc, "3");
delay_ms(4000);
lcd_gotoxy(1, 4);
printf(lcd_putc, "4");
delay_ms(4000);
// Read the character that was written in each corner
// of the LCD and display it. This tests the lcd_getc()
// function.
// The following test can only be done if we can read
// from the LCD. If the RW pin is not used, then the
// LCD is in write-only mode, and we can't do this test.
// The #ifdef statement will prevent the code from
// being compiled, in that case.
#ifdef USE_RW_PIN
// Test if lcd_getc() can read
// a byte from each corner.
b1 = lcd_getc(1,1);
b2 = lcd_getc(20,1);
b3 = lcd_getc(20,4);
b4 = lcd_getc(1,4);
lcd_gotoxy(1, 1);
printf(lcd_putc, "\fRead these bytes\n");
printf(lcd_putc, "from the 4 corners:\n\n");
printf(lcd_putc, " %c %c %c %c", b1, b2, b3, b4); //pg256
delay_ms(4000);
#endif
// Type some characters and backspace over them.
printf(lcd_putc, "\fType characters and\n");
printf(lcd_putc, "backspace over them.");
delay_ms(4000);
// Go to end of 2nd line.
lcd_gotoxy(20, 2);
// Backspace over 2nd line.
for(i = 0; i < 20; i++)
{
printf(lcd_putc," \b\b");
delay_ms(200);
}
// Go to end of first line.
lcd_gotoxy(20, 1);
// Backspace over first line.
for(i = 0; i < 20; i++)
{
printf(lcd_putc," \b\b");
delay_ms(200);
}
}
}
|
Regards
PG |
|
|
pg1995
Joined: 05 Apr 2014 Posts: 31
|
error on LCD2 |
Posted: Tue Jul 22, 2014 8:13 am |
|
|
Hi
I was experimenting with the code below. An error occurs on LCD2 (the one at the bottom in the video) when it comes the turn of last case "if (a3 < 250)". When you are almost 14 seconds into the following video, you can notice the error in the display: www.youtube.com/watch?v=CcUZTRpc7q0
Could you please help me to find the error in the code below? Thank you.
Code: |
#include <16f876.h>
#device adc=10
#device *=16
#use delay(Clock=20000000)
#fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT,NOLVP
#include <Flex_LCD420.c>
void main()
{
setup_adc_ports(ALL_ANALOG);
setup_adc(adc_clock_div_32);
select_lcd=0;
lcd_init(); //initialise the first lcd
printf(lcd_putc, "\f");
delay_ms(500);
select_lcd=1;
lcd_init(); //initialise the second lcd
printf(lcd_putc, "\f");
delay_ms(500);
delay_ms(20);
set_adc_channel(0);
delay_ms(20);
int16 a0 = read_adc();
delay_ms(1000);
set_adc_channel(1);
delay_ms(20);
int16 a1 = read_adc();
delay_ms(1000);
set_adc_channel(2);
delay_ms(20);
int16 a2 = read_adc();
delay_ms(1000);
set_adc_channel(3);
delay_ms(20);
int16 a3 = read_adc();
if (a0 > 300) output_high(pin_c4);
select_lcd=0;
printf(lcd_putc,"\fvoltage over 1\n");
printf(lcd_putc, "V>%g", 1.0);
delay_ms(2000);
if (a1 > 400) output_high(pin_c5);
select_lcd=1;
printf(lcd_putc,"\fvoltage over 1.95");
printf(lcd_putc, "\nV>%g", 1.95);
delay_ms(2000);
if (a2 > 600) output_high(pin_c6);
select_lcd=0;
printf(lcd_putc,"\nvoltage over 2.93");
printf(lcd_putc, "\nV>%g", 2.93);
delay_ms(2000);
if (a3 < 250) output_high(pin_c7);
select_lcd=1;
printf(lcd_putc,"\nvoltage less 1");
printf(lcd_putc, "\nV<%g", 1.0);
delay_ms(2000);
}
|
|
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Tue Jul 22, 2014 9:53 am |
|
|
Hi,
Your code had a lot of problems and 'oddities', so it's a bit hard to know where to start, but here goes:
1. The problem that prompted your post is due to the fact that you are missing a 'new line' (\n), so that the second message overwrites the first message. You've got it for the 1st display, but not the 2nd.....
2. Your code will execute once, and then the PIC will go to sleep. Is that what you want? Why not put everything inside a While() loop, so that the code keeps executing, and the displays keep updating?
3. In your Printf statements, you are using a float variable specifier (%g), but then you are providing a constant value. That doesn't make much sense, unless the constant value will become a variable later on?
4. Your use of the conditional 'If' is (probably) flawed. Based on how things are spaced, it appears that 'blocks' of code are supposed to executed (or not!) based on the condition. As coded, that is not what is happening. Consult a C text on the proper use of the conditional 'If', and bracketing....
You really should try some really hardware. Honestly, it is a lot of fun!
John |
|
|
|
|
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
|