Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Simple code on LM35 + LCD operation, can be used?

Status
Not open for further replies.
just to ask opinion

hello again...i have try the code in the link...still the result quite the same...i wonder why?

any help?

Added after 58 seconds:

i though using LCD 16x1 is quite hard...i'm planning to replace lcd 16x1 with lcd16x2...
 

Re: just to ask opinion

I hope you are doing like that
Code:
#include <16F877A.H> 
#fuses HS, NOWDT, NOPROTECT, PUT, NOLVP 
#use delay(clock=20000000) 
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) 

#include "E:\abdul hayee\pic controller\my examples\current interrupter\lcd16_1.c" 

void main()
{ 
lcd_init(); 

while(1) 
  { 
   printf(lcd_putc, "\f 16x1 LCD Test "); 
   delay_ms(3000); 
   printf(lcd_putc, "\fTest lcd_putc()"); 
   delay_ms(3000); 
   printf(lcd_putc, "\f  Hello World  "); 
   delay_ms(1500); 
   printf(lcd_putc, "\fabcdefghijklmnop"); 
   delay_ms(1500); 
   printf(lcd_putc, "\f0123456789ABCDEF"); 
   delay_ms(1500); 
   printf(lcd_putc, "\f!@#$^&*(){}[]:;<"); 
   delay_ms(2500); 

  } 

}

#include "E:\abdul hayee\pic controller\my examples\current interrupter\lcd16_1.c"
Here you give your location of lcd driver

your driver file of lcd is like that
Code:
// Flex_lcd_16x1.c 

// These are randomly assigned pins, used to test 
// that the driver can work with any arrangement 
// of i/o pins.   

#define LCD_DB4   PIN_B4 
#define LCD_DB5   PIN_B5 
#define LCD_DB6   PIN_B6 
#define LCD_DB7   PIN_B7 

#define LCD_RS    PIN_B0 
#define LCD_RW    PIN_C1 
#define LCD_E     PIN_B1
/* 
#define LCD_DB4   PIN_D4 
#define LCD_DB5   PIN_D5 
#define LCD_DB6   PIN_D6 
#define LCD_DB7   PIN_D7 

#define LCD_RS    PIN_E0 
#define LCD_RW    PIN_E1 
#define LCD_E     PIN_E2 
*/ 

// If you want to use a 6-pin interface for your LCD, then 
// connect the R/W pin on the LCD to ground and comment 
// out the following line.  A 6-pin interface to the LCD 
// is used if only have a few free i/o pins available on 
// your PIC, and you want to use the smallest possible 
// number of pins for the LCD. 
#define USE_LCD_RW   1        

//======================================== 
// Use "2 lines" as the lcd type for the 16x1 LCD. 
// The LCD is the same as an 8x2 LCD, but with the 
// bottom line appended on the right side of the first line. 
#define LCD_TYPE  2         // 0=5x7, 1=5x10, 2=2 lines 
#define LCD_2ND_HALF_ADDRESS  0x40 

#define LCD_WIDTH  16 
#define LCD_HALF_WIDTH  (LCD_WIDTH/2) 

int8 const LCD_INIT_STRING[4] = 
{ 
 0x20 | (LCD_TYPE << 2), // Func set: 4-bit, 2 lines, 5x8 dots 
 0xc,                    // Display on 
 1,                      // Clear display 
 6                       // Increment cursor 
 }; 

int8 lcd_xcoord; 
                              

//------------------------------------- 
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); 
 delay_us(2); 
 output_low(LCD_E); 
} 

//----------------------------------- 
// 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_LCD_RW 
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); 
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); 
delay_us(1);  
    
return(retval);    
}    
#endif 

//--------------------------------------- 
// Read a byte from the LCD and return it. 

#ifdef USE_LCD_RW 
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_LCD_RW 
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_LCD_RW 
output_low(LCD_RW); 
delay_cycles(1); 
#endif 

output_low(LCD_E); 

lcd_send_nibble(n >> 4); 
lcd_send_nibble(n & 0xf); 
} 

//---------------------------- 
void lcd_init(void) 
{ 
int8 i; 

output_low(LCD_RS); 

#ifdef USE_LCD_RW 
output_low(LCD_RW); 
#endif 

output_low(LCD_E); 

// 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 60 us, so in 
    // that case, lets just do a 5 ms delay 
    // after all four of them. 
    #ifndef USE_LCD_RW 
    delay_ms(5); 
    #endif 
   } 

lcd_xcoord = 1; 
} 

//---------------------------- 
// The x-coordinate can be 1 to 16. 
// The y coordinate is ignored.  
// This x,y interface is kept in order to be 
// consistent with other CCS LCD drivers. 
void lcd_gotoxy(int8 x, int8 y) 
{ 
int8 address; 

// Update the global x-coordinate variable with the 
// current x coordinate. 
lcd_xcoord = x; 

// Convert the x-coordinate from CCS format (1-16) to 
// the 0-15 format used by the LCD hardware. 
address = x - 1;  

// If the x-coordinate is within the 2nd half of the 
// LCD line, the address must be adjusted because 
// of the special architecture of the 8x2 LCD. 
if(address >= LCD_HALF_WIDTH)  
  {    
   address += (LCD_2ND_HALF_ADDRESS - LCD_HALF_WIDTH); 
  } 

lcd_send_byte(0, 0x80 | address); 
} 


//----------------------------- 
void lcd_putc(char c) 
{ 
 switch(c) 
   { 
    case '\f': 
      lcd_send_byte(0,1); 
      delay_ms(2); 
      lcd_xcoord = 1; 
      break; 
    
    case '\n': 
       lcd_gotoxy(1,1);  //  Goto start of line 1 
       break; 
    
    case '\b': 
       lcd_send_byte(0, 0x10); 
       lcd_xcoord--; 
       if(lcd_xcoord == LCD_HALF_WIDTH) 
          lcd_gotoxy(LCD_HALF_WIDTH, 1); 
       break; 
    
    default: 
       lcd_send_byte(1, c); 
       lcd_xcoord++; 
       if(lcd_xcoord == (LCD_HALF_WIDTH +1)) 
          lcd_gotoxy(LCD_HALF_WIDTH +1, 1); 
       break; 
   } 
} 

//------------------------------ 
#ifdef USE_LCD_RW 
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

Hope this solve your problem.
 

just to ask opinion

The file I posted previously is already setup for 16*1 with six wire interface. All you need to do is change the pin definitions at the beginning of the driver, if you are using the same ones, then no change is needed. You can cut and paste into notepad and then make any changes. Then save for instance as "FlexLcd.c" and not as a text file. You then need to copy this to the location where you keep the program you are working on. Then in your main program startup proceedure insert the line " #include FlexLcd.c ", without the quotes of course. You should then be able to use any of the lcd commands in your program.
e.g
lcd_goto(x,y);
lcd_init();
lcd_putc(" this is a test"); Etc Etc

Remember C is case sensitive, use upper/lowercase exactly as shown
Hope this helps
 

just to ask opinion - if the code is ok

finally i had managed to get the result..

2 cases already been done
* display simple word at LCD
* display temperature capture by LM35 sensor

the problem is basically on the lcd 16x1...totally can't be used...when i replace it with LCD 16x2 ...it yield a good result...

here is the simple code

LCD display

#include <16F877A.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)

#include "C:\Users\deli\Desktop\kli2\brum\Flexlcd2.c"

//==========================
void main()
{
lcd_init(); // Always call this first.

lcd_putc("\fHello World\n");
lcd_putc("Line Number 2");

while(1);
}


and the LCD driver

// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver. Change these
// pins to fit your own board.

#define LCD_DB4 PIN_D0
#define LCD_DB5 PIN_D1
#define LCD_DB6 PIN_D2
#define LCD_DB7 PIN_D3

#define LCD_E PIN_A1
#define LCD_RS PIN_A3
#define LCD_RW PIN_A2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW 1

//========================================

#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line


int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Func set: 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);
delay_us(2);
output_low(LCD_E);
}

//-----------------------------------
// 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_LCD_RW
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);
delay_cycles(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);

return(retval);
}
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
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_LCD_RW
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_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

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

// 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 60 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;

if(y != 1)
address = lcd_line_two;
else
address=0;

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
delay_ms(2);
break;

case '\n':
lcd_gotoxy(1,2);
break;

case '\b':
lcd_send_byte(0,0x10);
break;

default:
lcd_send_byte(1,c);
break;
}
}

//------------------------------
#ifdef USE_LCD_RW
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

For LM35 cases

#include <16F877A.H>
#device ADC=10
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)


#include "C:\Users\deli\Desktop\zoz2\brum\Flexlcd2.c"

//==========================


void main(void)
{
int16 temp_adc;
float temp;

setup_adc(ADC_CLOCK_DIV_8);
setup_adc_ports(PIN_A1);
set_adc_channel(1); //read analog input from channel 1



lcd_init();

lcd_putc("\ftemperature is:\n");

while(1)
{
temp_adc = read_adc();

temp = 5.00*temp_adc*100.00/1023.00;
lcd_gotoxy(1,2);
printf(lcd_putc,"%f",temp);
delay_ms(3000);
}

}


so, now the next step is to provide to control dc motor using PIC..aim to control the speed...

However, i managed to collect some mikro C code regarding the speed change...

Anyone know how to implement it in C languange...
hopefully add it at LM35 code that i given...

#define slow 32 //Duty cycle set for slow
#define medium 96 //Duty cycle set for medium
#define fast 230 //Duty cycle for fast
#define cel20 41 //20'C
#define cel50 102 //50'C

//I set range as:
//Less than 20'C : speed is slow
//From 20'C to 50'C : speed is medium
//Greater than 50'C : speed is fast

int ADVal; //Variable to store ADC result
unsigned char duty;

void main(void){
TRISC = 0;
PORTC = 0;
PWM1_Init(5000); //5khz pwm
PWM1_Set_Duty(medium); //50% duty cycle
PWM1_Start(); //Start PWM
while (1){
ADVal = ADC_Read(0);
if (ADVal < cel20){
duty = slow;
}
if ( (ADVal > cel20) & (ADVal < cel50) ){
duty = medium;
}
if (ADVal > cel50){
duty = fast;
}
PWM1_Set_Duty(duty); //Change duty cycle and adjust
delay_ms(100); //Wait for adjusting (Optional and may be left out)
}
}
 

Re: just to ask opinion - if the code is ok

Check out the "EX_PWM.c" file in the CCS example files.
 

just to ask opinion - if the code is ok

Most 16x1 displays are electrically configured as 2x8 and are driven as 2 separate 8 character lines, even though the display is just one line. The Lcd driver I posted is for this type of display. It may be that you have a true electrically 1x16, in which case it would not work correctly as shown. Stick with 2x16 if it is better for you.
 

just to ask opinion - if the code is ok

hi again...

how about the circuit connection...isn't just directly implement the Pwm pin towards DC motor ...no need any others element?...huhu...sorry for my weakness

Added after 5 minutes:

isn't ok for me to follow-up with this kind of schematic...? i download from other forum..



what is the function of Q2 2SJ48...isn't compulsory to use it?
 

just to ask opinion - if the code is ok

here is the simple code...that i made out based on the mikro C code given above..

isn't correct?...the compalation is good..but the truth is the circuit still not been build yet..since i will buy the transistor this evening...so hopefully someone can checked it....sorry for my weakness

#include <16F877A.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use Delay(clock=20000000)
#include "C:\Users\deli\Desktop\zoz2\brum\Flexlcd2.c"

#define cel20 set_pwm1_duty(30)
#define cel50 Set_pwm1_duty(125)
main()

{
int16 pwm_duty;
int16 temp_adc;
float temp;



setup_adc(ADC_CLOCK_DIV_8);
setup_adc_ports(PIN_A1);
set_adc_channel(1); //read analog input from channel 1
output_low(PIN_C2); // Set CCP1 output low

setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM

setup_timer_2(T2_DIV_BY_4, 249, 1); // 5khz

pwm_duty = 500L; // Set for 50% duty cycle

set_pwm1_duty(pwm_duty);

lcd_init();

lcd_putc("\ftemperature is:\n");
while(1);
{

temp_adc = read_adc();

temp = 5.00*temp_adc*100.00/1023.00;

if (temp < cel20){
set_pwm1_duty(25);
}
if ( (temp > cel20) & (temp < cel50) ){
set_pwm1_duty(120);
}
if (temp > cel50){
set_pwm1_duty(175);
}
set_pwm1_duty(temp); //Change duty cycle and adjust
//delay_ms(100); //Wait for adjusting (Optional and may be left out)

lcd_gotoxy(1,2);
printf(lcd_putc,"%f",temp);
delay_ms(3000);

}
}

Added after 1 hours 31 minutes:

here is a little adjustment...still...need someone to check it?...

#include <16F877A.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use Delay(clock=20000000)
#include "C:\Users\deli\Desktop\zoz2\brum\Flexlcd2.c"

#define cel20 30
#define cel50 125
#define medium 120
#define slow 25
#define fast 175
main()

{
int16 pwm_duty;
int16 temp_adc;
float temp;



setup_adc(ADC_CLOCK_DIV_8);
setup_adc_ports(PIN_A1);
set_adc_channel(1); //read analog input from channel 1
output_low(PIN_C2); // Set CCP1 output low

setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM

setup_timer_2(T2_DIV_BY_4, 249, 1); // 5khz

pwm_duty = 500L; // Set for 50% duty cycle

set_pwm1_duty(pwm_duty);

lcd_init();

lcd_putc("\ftemperature is:\n");
while(1);
{

temp_adc = read_adc();

temp = 5.00*temp_adc*100.00/1023.00;

if (temp < cel20){
temp=slow;
}
if ( (temp > cel20) & (temp < cel50) ){
temp=medium;
}
if (temp > cel50){
temp=fast;
}
set_pwm1_duty(temp); //Change duty cycle and adjust
//delay_ms(100); //Wait for adjusting (Optional and may be left out)

lcd_gotoxy(1,2);
printf(lcd_putc,"%f",temp);
delay_ms(3000);

}
}

Added after 2 minutes:

temp replace with temp_adc

sorry forget to replace it
 

just to ask opinion - if the code is ok

anyone??? please...really hope for ur help...
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top