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

LCD Do not initialize using PORTs A and E.
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

LCD Do not initialize using PORTs A and E.
PostPosted: Sat Sep 02, 2017 9:01 am     Reply with quote

Hello friends. I have a didatica board for studies that uses as configuration RS-> RE0, E-> RA5, D4-> RA4, D5-> RA3, D6-> RA2, D7-> RA1 to initialize the LCD.

CCS by default sets PORT_D in library #include <lcd.c>, it is easy to switch to PORT_B inserted in the #define directive use_portb_lcd true.
I made this code in the attempt to use the PORTs_A, E., but does not initialize the LCD. The ADCON1 recorder of the PIC 16F877A comes standard with all the bits zeroed, I believe it is necessary to configure the pins of the PIC as a digital output to use the LCD.

Please help me find the error?
Code:

#include <16F877a.h>
#device ADC = 10 // 8-bit converter
#fuses hs, nowdt, nolvp
#use delay (clock = 20M)
#define use_porta_lcd true
#define use_porte_lcd true
#include <lcd.c>
#use fast_io (a)
#use fast_io (e)
#byte ADCON1 = 0x9F // register address ADCON1

Void main (void)
{
    SETUP_ADC_PORTS (AN0);
    Set_tris_a (0b00000001); // the first pin Analogic
    Set_tris_e (0x11111110);
    ADCON1 = 0b00001110;
    Init_lcd ();
    Printf (lcd_txt, "PIC and LCD");
    Dealy_ms (3000);

}
temtronic



Joined: 01 Jul 2010
Posts: 9250
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Sep 02, 2017 9:55 am     Reply with quote

this...
Quote:
Dealy_ms (3000);

is incorrect, compiler should complain about it....

Also If I recall correctly, the LCD.c driver requires that ALL lines connected to the LCD module be from ONE port, you've 'split' them...

It would be best to use the 'flex_lcd.c' driver, where you CAN 'split' the pins any way you want.

And with ANY I/O pin that has multiple uses, you should disable all peripherals associated with that pin (ADC, comparators, etc.).

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Sat Sep 02, 2017 11:30 am     Reply with quote

Just to add to this. It is essential to read what the drivers say.

The #define use_porta_lcd true

Says to use port access for the LCD (so all the bits on one port), and put it on porta.

Similarly the next line says to use porte the same way....

Honestly, flex_lcd is the easier driver to setup, _but read what it says and set the pins up in the order you want_.

Think about it. How is the compiler meant to know what connects where on the two ports you are trying to use?.

As a comment, why are you accessing ADCON. Just use the compiler's instruction setup_adc. Much less likely to be wrong. You are currently setting the ADC to use Fosc/2, which has a maximum supported processor speed of 1.25Mhz. It is not going to give anything even remotely close to a correct reading...

setup_adc(ADC_CLOCK_DIV_32);
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Thanks Friends.
PostPosted: Tue Sep 12, 2017 10:16 am     Reply with quote

Now it worked with these settings. I am using the ports configured for the LCD and also the analog input on Port_a and E.
Code:

#define LCD_DB4   PIN_A4 // Pinos bloco dados LCD deve ser definidos antes da biblioteca <lcd4bitsMicrostronic.c>
#define LCD_DB5   PIN_A3
#define LCD_DB6   PIN_A2
#define LCD_DB7   PIN_A1
#define LCD_RS     PIN_E0
#define LCD_E       PIN_A5
#include <lcd4bitsMicrostronic.c> // 'flex_lcd.c' driver

void main(){
   set_tris_a(0b00000001);
   set_tris_e(0x02);
   set_tris_d(0x0F);
   set_tris_c(0x07); 
   setup_adc_ports(an0);
   setup_adc(ADC_CLOCK_INTERNAL );
   set_adc_channel(0);
   enable_interrupts(int_ad);
   enable_interrupts(global);

   lcd_init();                       
   kbd_init();                       
   lcd_putc("SENHA:\n"); // Escreve no LCD
}
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

PostPosted: Tue Sep 12, 2017 10:35 am     Reply with quote

Ttelmah thank you friend: sorry I did not understand your question I'm starting to learn programming now, I have a lot of doubts on how to do it.
Quote:

As a comment, why are you accessing ADCON. Just use the compiler's instruction setup_adc. Much less likely to be wrong. You are currently setting the ADC to use Fosc/2, which has a maximum supported processor speed of 1.25Mhz. It is not going to give anything even remotely close to a correct reading...
setup_adc(ADC_CLOCK_DIV_32);

But at first I accessed the ADCON1 to configure only the TRIS A1, A2, A3, A4, A5 for LCD, and A0 as analog. I did another test removing ADCON1 from the program, but I had to keep the command set_tris_a (0b00000001); because in it the LCD is not initializing.

This is my full program test:

Code:
#include <16f877a.h>
#device ADC = 10
#fuses hs, nowdt, nolvp, put, brownout
#use delay (clock=20M)
#use fast_io(a)
#use fast_io(e)
//#use fast_io(d)// para sensor temperatura

#define LCD_DB4   PIN_A4 // Pino bloco dados 4 no pino microcontrolador
#define LCD_DB5   PIN_A3
#define LCD_DB6   PIN_A2
#define LCD_DB7   PIN_A1
#define LCD_RS    PIN_E0
#define LCD_E     PIN_A5
#include <lcd4bitsMicrostronic.c>

//***Variaveis

//#byte ADCON1 = 0x9F
//int16 valor;

//int  a = 25, b = 15;

void main()
{
  //long data;
  float temp, tensao, dados;
  //ADCON1 = 0b00001110;
  set_tris_a(0b00000001);
  set_tris_e(0xFE); // 0b11111100
  set_tris_d(0x00);//11110000
  output_d(0x00);
 
  SETUP_ADC(ADC_CLOCK_INTERNAL);
  SETUP_ADC_PORTS(AN0);
  SET_ADC_CHANNEL(0);
 
  lcd_init();
 
  while(1)
  {
     
      dados =  (float) (READ_ADC());
      delay_ms(50);
      tensao = (5000.0*dados)/1024; // tensao em milivolts
      temp = tensao/10; 
      //printf(lcd_putc,"\fVolt = %.1fmv", tensao);
      //printf(lcd_putc,"\nTemp =%.1fGr ",temperatura);
      delay_ms(1500);
     
      if( temp<100)
      {
         output_high(pin_D4);
         printf(lcd_putc,"\fTemperat Boa");
         lcd_gotoxy(5,2);
         printf(lcd_putc,"\%.1fGraus ",   Temp);
         delay_ms(100);
      }
      else
      {
         output_low(pin_D4);
      }
       if( temp>100&&temp<200)
      {
         output_high(pin_D5);
         printf(lcd_putc,"\fTemperat Media");
         printf(lcd_putc,"\n%.1fGraus ",Temp );   
      }
      else
      {
         output_low(pin_D5);
      }
     
       if( temp>200&& temp<300)
      {
         output_high(pin_D6);
         printf(lcd_putc,"\fTemperat Alta");
         printf(lcd_putc,"\n%.1fGraus ",Temp ); 
      }
      else
      {
         output_low(pin_D6);
      }
     
       if( temp>300&&temp<=500)
      {
         output_high(pin_D7);
         printf(lcd_putc,"\fTemperat Extrema");
         printf(lcd_putc,"\n%.1fGraus ",Temp );
      }
      else
      {
         output_low(pin_D7);
      }
     
       
  }
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Tue Sep 12, 2017 1:12 pm     Reply with quote

If you use flex_lcd, you don't have to configure TRIS. The standard CCS LCD driver directly accesses the port, and requires the TRIS setup. As you have found you don't need the ADCON setting, just the TRIS.
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Keypad keyboard does not generate numbers correctly.
PostPosted: Sun Sep 17, 2017 11:22 am     Reply with quote

Ttelmah thank you friend.

Now I have another problem. I used a flex library for the keypad. But when typing on the keypad the numbers do not match, for example the number one never appears even by pressing the 1 key, on the contrary 4 appears in another one pressed 5 appears and in the place of the number 6 appears the 9 or # is very confused. Crying or Very sad
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Sun Sep 17, 2017 12:13 pm     Reply with quote

If the keys are coming up incorrectly, then the physical connections you have do not match the pins you are specifying in the driver....
Remember also the row pins do need pull-ups. Either programmed in the chip or physical resistors.
temtronic



Joined: 01 Jul 2010
Posts: 9250
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Sep 17, 2017 12:40 pm     Reply with quote

Mr t is spot on !

Sounds like you have the ROWs not connected correctly.

Row 1 has 1,2,3
Row 2 has 4,5,6
Row 3 has 7,8,9
Row 4 has *,0,#

Col 1 has 1,4,7,*
Col 2 has 2,5,8,0
Col 3 has 3,6,9,#

That's providing you follow the 'convention' that the #1 key (top left) of a KPD is the starting point. Nothing says you have to though.

Jay
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

keyboard scan by interruption timer0
PostPosted: Tue Sep 19, 2017 12:32 pm     Reply with quote

Many thanks for the help, friends !! No, but it seems to be the deboucyng effect, since I have corrected all the connections and even then the same key continues to generate several different numbers.

I am trying to make a program that sweeps the keyboard by interrupting the zero timer, because from what I researched it inhibits the deboucing effect !! This is program: This generates this error: "Expecting LVALUE such as a variable name or * expression" in all the lines with: Led1 = 0x01; and all lines with col0 = 0x01;
col1 = 0x00;
col2 = 0x01;
Can you help me friends!!
Code:

#include <16f877a.h>
#fuses hs, nowdt, nolvp, put, brownout
#use delay (clock=20M)
#use fast_io(a)
#use fast_io(e)

#define LCD_DB4   PIN_A4
#define LCD_DB5   PIN_A3
#define LCD_DB6   PIN_A2
#define LCD_DB7   PIN_A1
#define LCD_RS     PIN_E0
#define LCD_E       PIN_A5
#include <lcd4bitsMicrostronic.c>


#define col0 PIN_C0
#define col1 PIN_C1
#define col2 PIN_C2
#define row0 PIN_D0
#define row1 PIN_D1
#define row2 PIN_D2
#define row3 PIN_D3

#define Led1 PIN_D4
       

char control = 0x01;
char cont = 0x00;

//** interrupt timer directive

#int_timer0   

//** Interrupt function due to TIMER0 overflow

void varre()
{
   SET_TIMER0(0); //  256-0 = 250*0,2us*256(prescaler)= 13ms
   cont++;
}

//void pulse function, the led flashes the number of times the key is pressed.. The value of number is the value assigned to the pulse when the line and column of the keypad

void pulse (char number)
{   
 char i;
 
 for (i=0; i<number; i++)
     {
         Led1 = 0x01;
         delay_ms (400);
         Led1 = 0x00;
         delay_ms (400);
     }
}

// Home of main

void main(void)
{
    setup_timer_0(rtcc_internal|rtcc_div_256);
    enable_interrupts(global);
    SET_TIMER0(0);
                                     
if (cont == 256)    //Has the timer popped?
  {
    cont==0x00;
 
    if(col0 && control == 0x01) 
    {                           
      control = 0x02;   // active control = 02 to exit this loop if
      col0 = 0x00;   //we want to turn column 1 on low level after pressing a button
      col1 = 0x01;
      col2 = 0x01;
      if (!row0) pulse(1);        // if it is line A, it will flash LED 1 time..pull (1)
      else if (!row1) pulse (4);  // if it is line B, it will flash LED 4 time..pull (4)
      else if (!row2) pulse (7);  // if it is line C, it will flash LED 7 time..pull (7)
      else if (!row3) pulse (11); // // if it is line D, it will flash LED 11 time..pull (11)
    }

    else if(col1 && control == 0x02)
    {                               
      control = 0x03;                 
      col0 = 0x01;
      col1 = 0x00;
      col2 = 0x01;
      if (!row0) pulse(2);             
      else if (!row1) pulse (5);   
      else if (!row2) pulse (8);   
      else if (!row3) pulse (10);   
    }

    else if(col2 && control == 0x03) 
    {                               
      control = 0x01;               
      col0 = 0x01;
      col1 = 0x01;
      col2 = 0x00;
      if (!row0) pulse(3);
      else if (!row1) pulse (6);
      else if (!row2) pulse (9);
      else if (!row3) pulse (12);
     
    }
  }// End if keyboard scan
}// End main
temtronic



Joined: 01 Jul 2010
Posts: 9250
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Sep 19, 2017 2:36 pm     Reply with quote

1st problem.
You're using fast_io() but NOT configuring the tris registers, at least not that I can see in your program. Perhaps your LCD driver sets them? But we can't tell....

Have to ask why don't you use the flex_kbd driver? It works, even on an 18F46K22 running at 64MHz attached on a 20 year old breadboard!!

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 19, 2017 5:42 pm     Reply with quote

Jack,
You need to do a lot of basic computer study. You're trying to do
programming without knowing the basics. This results in disaster.
Example:
Code:

char cont = 0x00;

if (cont == 256) 

A char in CCS is an unsigned 8-bit number. It can only have
a value from 0 to 255. It can't ever be 256. Furthermore, Timer0 is
8 bits in the 16F877A. It can only count from 0 to 255. At 255, it rolls
over and starts counting up from 0 again.

Now let's look your next mistake:
Code:
if(col0 && control == 0x01) 

The && operator is a TRUE/FALSE operator. You're using it as if it's a
bitwise ANDing operator, and that is not the case. The bitwise ANDing
operator is a single ampersand: &

This is all basic bonehead C knowledge. You can't just jump into C
without learning all this stuff and whole lot more. You can't write PIC
code in C without carefully reading and remembering the PIC data sheet.

And then your posted complaint is:
Quote:
Expecting LVALUE such as a variable name or * expression" in all the lines with: Led1 = 0x01; and all lines with col0 = 0x01;

You have got these defined as constants:
Code:
#define col0 PIN_C0
#define col1 PIN_C1
#define col2 PIN_C2

PIN_C0, etc., are just numbers. Look in the 16F877A.h file. It lists what
they are. i.e.:
Code:
#define PIN_C0  56
#define PIN_C1  57
#define PIN_C2  58

So in your program you are doing this:
Code:
col1 = 0x00;
col2 = 0x01;

So you're trying to do this:
Code:

57 = 0x00;
58 = 0x01;

You have got to spend a lot more time learning how computers work and
how to program them before you can write code.
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Thank temtronic
PostPosted: Tue Sep 19, 2017 8:59 pm     Reply with quote

Thank you friend temtronic. I really wondered how to set up the TRIS. I'm starting to learn to program now and study alone for it so many doubts and mistakes. Yes I used the Flex kdb driver file. But I am trying to develop this code by scan to test, because my keypad has generated different numbers when triggering the same keys and with this I want to try to dim the debaucing effect by using the scan by the overflow of timer0. I will correct the program by setting the tris. Thank you very much.
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Thank you PCM programmer
PostPosted: Tue Sep 19, 2017 9:18 pm     Reply with quote

thanks friend PCM programmer for the clarifications and tips I'm starting to learn how to program now, so I have a lot of questions and mistakes. I have followed C programming manuals, CCS and PIC datasheet, but the content is quite extensive and complex and I have a long way to go to learn. I'm studying the few months. And I've dedicated myself. I'm sorry for the basic mistakes you've made, but I hope you understand that every initial apprenticeship is like that, with lots of mistakes. Thanks for the valuable tips. I will make the corrections and I know new doubts I will have.

Ok I understood your explanation and I open and saw file #include <16f877a.h>

So to make the column go to logical level zero the correct one is to use the command output_low (col0); and all other rows and columns correct?
I did not understand why CCS is assigned a constant to pins, registers and et all.
#define PIN_C0 56
#define PIN_C1 57
#define PIN_C2 58

Programming in the Mikroc the command col1 = 0x00;
is correct, that is, it compiles without any errors.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 19, 2017 10:25 pm     Reply with quote

jacktaylor wrote:

So to make the column go to logical level zero the correct one is to use
the command output_low (col0); and all other rows and columns correct?
Yes.

jacktaylor wrote:

I did not understand why CCS is assigned a constant to pins, registers
#define PIN_C0 56
#define PIN_C1 57
#define PIN_C2 58

The number encodes the Port address and the bit position.
For example, 58 is the code for pin C2.

58 is 0x3A in hex, and 0b00111010 in binary.

The bottom 3 bits (010) are the bit number, and the upper 5 bits are
the port address. Below, you can see that the Port address is 7 and
the bit position is 2.
Code:

Binary 00111 010
Decimal  7    2

Look at the 16F877A data sheet, at this table:
Quote:
FIGURE 2-3: PIC16F876A/877A REGISTER FILE MAP

It lists the memory address of PortC as 7. Bit position 2 corresponds to
Pin C2 on Port C.

The compiler uses these encoded Port/Bit position values with these functions:
output_low()
output_high()
output_float()
output_toggle()
etc.
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, 4  Next
Page 1 of 4

 
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