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 support@ccsinfo.com

Trouble using LCD controller of PIC16LF1947
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
sergio1234



Joined: 06 Jan 2006
Posts: 17
Location: Argentina

View user's profile Send private message

Trouble using LCD controller of PIC16LF1947
PostPosted: Wed Aug 21, 2013 2:50 pm     Reply with quote

I am trying to program the PIC16LF1947 LCD controller, with the CCS PCWH compiler v5.011 (the last version)

Until now I didn't obtain any result

The function setup_lcd(LCD_MUX14 | LCD_HALT_IDLE, 2); doesn't write anything on the LCD registers

With the debugger I always see all the LCD registers in 00 in the LCD peripherals tab

Inclusive when I write any value manually in the LCD registers in the SFR Tab nothing is write and it returns allways 00

Code:

LCDCON     791   000X0000   0x00
LCDPS      792   00000000   0x00
LCDREF     793   000X000X   0x00
LCDCST     794   XXXXX000   0x00
LCDRL      795   0000X000   0x00
LCDSE0     798   00000000   0x00
LCDSE1     799   00000000   0x00
LCDSE2     79A   00000000   0x00
LCDSE3     79B   00000000   0x00
LCDSE4     79C   00000000   0x00
LCDSE5     79D   XX000000   0x00
LCDDATA0   7A0   00000000   0x00
LCDDATA1   7A1   00000000   0x00
LCDDATA2   7A2   00000000   0x00
LCDDATA3   7A3   00000000   0x00
LCDDATA4   7A4   00000000   0x00
LCDDATA5   7A5   00000000   0x00
LCDDATA6   7A6   00000000   0x00
LCDDATA7   7A7   00000000   0x00
LCDDATA8   7A8   00000000   0x00
LCDDATA9   7A9   00000000   0x00
LCDDATA10  7AA   00000000   0x00
LCDDATA11  7AB   00000000   0x00
LCDDATA12  7AC   00000000   0x00
LCDDATA13  7AD   00000000   0x00
LCDDATA14  7AE   XX000000   0x00
LCDDATA15  7AF   00000000   0x00
LCDDATA16  7B0   00000000   0x00
LCDDATA17  7B1   XX000000   0x00
LCDDATA18  7B2   00000000   0x00
LCDDATA19  7B3   00000000   0x00
LCDDATA20  7B4   XX000000   0x00
LCDDATA21  7B5   00000000   0x00
LCDDATA22  7B6   00000000   0x00
LCDDATA23  7B7   XX000000   0x00


I don't see activity in the LCD PINS

Neither I am able to change the LCD registers with the #byte instruction

What am I making bad?

My code:

Code:

#include <16LF1947.h>
#device ADC=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O



#device ICD=TRUE
#use delay(internal=4000000)
#define AD_BAT   PIN_A0
#define Enable_BAT   PIN_A3

#define Bot_Der   PIN_B0
#define Bot_Izq   PIN_B5

#define ISP_Clk   PIN_B6
#define ISP_Dat   PIN_B7

#define Tx   PIN_C6
#define Rx   PIN_C7

#use rs232(baud=9600,parity=N,xmit=Tx,rcv=Rx,bits=8,stream=PORT1)

#define LED PIN_A3
#define DELAY 100
#use FIXED_IO( A_outputs=PIN_A3 )


Code:

#include <TC2_Disp.h>

//-------------------------------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////
//                                 LCD Configuration                                   //
/////////////////////////////////////////////////////////////////////////////////////////
// Digit segments    A        B        C        D        E        F        G        DP
//                   b7       b6       b5       b4       b3       b2       b1       b0
#define DIGIT4    COM1+26, COM1+17, COM2+17, COM3+26, COM2+25, COM1+25, COM2+26, COM3+17
#define DIGIT3    COM1+24, COM1+16, COM2+16, COM3+24, COM2+23, COM1+23, COM2+24, COM3+16
#define DIGIT2    COM1+22, COM1+19, COM2+19, COM3+22, COM2+21, COM1+21, COM2+22, COM3+19
#define DIGIT1    COM1+20, COM1+18, COM2+18, COM3+20, COM2+28, COM1+28, COM2+20, COM3+18
//
//         character         0    1    2    3    4    5    6    7    8    9
byte const Digit_Map[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xE6};

#define BLANK 0
#define DASH 11
//-------------------------------------------------------------------------------------------------------


byte lcd_pos;

void lcd_putc(char c) {
   byte segments;

   if(c=='\f')
     lcd_pos=0;
   else {
      if((c>='0')&&(c<='9'))
         segments=Digit_Map[c-'0'];
      else
         segments=BLANK;
      switch(lcd_pos) {
        case 1 : lcd_symbol(segments,DIGIT4); break; // fill 1000s place
        case 2 : lcd_symbol(segments,DIGIT3); break; // fill  100s place
        case 3 : lcd_symbol(segments,DIGIT2); break; // fill   10s place
        case 4 : lcd_symbol(segments,DIGIT1); break; // fill    1s place
      }
   }
   lcd_pos++;
}

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

void setup_lcd_segments(int8 se5, int8 se4, int8 se3, int8 se2, int8 se1, int8 se0)
{
#byte LCDSE0 = 0x798 
#byte LCDSE1 = 0x799
#byte LCDSE2 = 0x79A
#byte LCDSE3 = 0x79B
#byte LCDSE4 = 0x79C
#byte LCDSE5 = 0x79D

LCDSE0 = se0;
LCDSE1 = se1;
LCDSE2 = se2;
LCDSE3 = se3;
LCDSE4 = se4;
LCDSE5 = se5;
}


void main() {
   long number = 0;
   setup_oscillator( OSC_4MHZ );



setup_lcd(LCD_MUX14 | LCD_HALT_IDLE, 2);

// Enable the segments that are connected to the LCD.
// This function loads the Segment Enable registers
// with the bitmasks specified below.  The segments
// are determined by looking at the schematic of the
// PIC to LCD connections. In each byte, a '1' means
// the segment is Enabled ("On").  A '0' means it's Off.
// This function must be called after the setup_lcd() function.
setup_lcd_segments(0x00,   // Segs 41-40 = off
                   0x00,   // Segs 39-34 = off, 33-32 = On
                   0x00,   // Segs 31-24 = off
                   0xFF,   // Segs 23-21 = On, 20-16 = on
                   0xFF,   // Segs 15-8 = on
                   0xFF);  // Segs 7-0 = on



   while(true){

 
      printf(lcd_putc,"\f%4lu",number);
      if(number++==10000)
        number=0;
   
   
      output_toggle(LED);
      delay_ms(DELAY);
     
     
   }

}


Thanks for your help
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 21, 2013 4:39 pm     Reply with quote

Did you buy the 16LF1947 LCD board ? If so, post a link to the website
for the board.

If you built the board yourself, post a link to the schematic for the board.
sergio1234



Joined: 06 Jan 2006
Posts: 17
Location: Argentina

View user's profile Send private message

PostPosted: Wed Aug 21, 2013 8:31 pm     Reply with quote

Thanks for your soon answer

I built my own board

I know that the #define DIGITx must be modified to match the schematics

But First i need to put in service the LCD controller

Here the schematics

[img]http://imgur.com/YJTAVTy[/img]

Thanks again for your help
sergio1234



Joined: 06 Jan 2006
Posts: 17
Location: Argentina

View user's profile Send private message

PostPosted: Wed Aug 21, 2013 8:34 pm     Reply with quote

PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 21, 2013 9:48 pm     Reply with quote

Please post a link to the data sheet for the PZDTP1816P lcd.
Google doesn't find anything.
sergio1234



Joined: 06 Jan 2006
Posts: 17
Location: Argentina

View user's profile Send private message

PostPosted: Thu Aug 22, 2013 10:50 am     Reply with quote

Thanks for your help

The display is custom, here the link to download the datasheet:

http://rapidshare.com/files/1872990618/PZDTP1816P.pdf

This display is close similar (with another segment distribution) to another that we already used with an MSP430 for 3 years

However I believe that the problem that we have doesn't have to do with the display type that we are using

The problem that we have is with the CCS compiler + ICDU64, the LCD registers of the PIC16LF1947 are not writing , the registers always has value 00, either if i Write them programmatically or using the SFR Tab in the debugger

Thanks for your comments
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 22, 2013 8:30 pm     Reply with quote

Quote:

The function setup_lcd(LCD_MUX14 | LCD_HALT_IDLE, 2); doesn't write anything on the LCD registers

With the debugger I always see all the LCD registers in 00 in the LCD peripherals tab

I think it must be some debugger problem, because the .LST file shows
that vs. 5.011 generates code that writes to the LCD registers:

LST file in symbolic mode:
Code:

0249:  MOVLW  C3
024A:  MOVLB  0F
024B:  MOVWF  LCDCON
024C:  MOVLW  21
024D:  MOVWF  LCDPS
024E:  CLRF   LCDREF
024F:  CLRF   LCDRL

LST file in CCS (address) mode:
Code:

........... setup_lcd(LCD_MUX14 | LCD_HALT_IDLE, 2); 
0249:  MOVLW  C3
024A:  MOVLB  0F  // Bank 0x0F
024B:  MOVWF  11  // Register 0xF91 = 0xC3
024C:  MOVLW  21
024D:  MOVWF  12  // Register 0xF92 = 0x21
024E:  CLRF   13  // Register 0xF93 = 0x00
024F:  CLRF   15  // Register 0xF95 = 0x00
sergio1234



Joined: 06 Jan 2006
Posts: 17
Location: Argentina

View user's profile Send private message

PostPosted: Thu Aug 22, 2013 10:37 pm     Reply with quote

Thanks for your help

I don't find to be a debugger problem, with an oscilloscope I don't see any activity on the LCD pins

I have made debugging in ASM view

MOVLW C3 //Load C3 on WREG
MOVLB 0F //Load 0F on BSR
MOVWF 11 // should write C3 on LCDCON (address 791) but doesn't write anything

Please Pay attention to the LST in CCS (address) Mode on your example, the comments point to wrong addresses

Code:

........... setup_lcd(LCD_MUX14 | LCD_HALT_IDLE, 2); 
0249:  MOVLW  C3
024A:  MOVLB  0F  // Bank 0x0F
024B:  MOVWF  11  // Register 0xF91 = 0xC3 (Must be 791 not F91)
024C:  MOVLW  21
024D:  MOVWF  12  // Register 0xF92 = 0x21 (Must be 792 not F92)
024E:  CLRF   13  // Register 0xF93 = 0x00 (Must be 793 not F93)
024F:  CLRF   15  // Register 0xF95 = 0x00 (Must be 794 not F94)



Will some problem exist and CCS are writing and reading on the mistaken register address? (Fxx instead of 7xx)

Thanks for your comments
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 23, 2013 1:11 pm     Reply with quote

You are right about the high nybble of the register address. It's not the
same as the bank address. I assumed that it was true and typed it in.
But that's not the problem.

You believe that nothing is being written to the LCDCON register. Let's
write a very simple program to test that.

In the program below, the ICD is not used as a debugger. The line for
#device ICD=TRUE is removed. The ICD is only used as a programmer.
Instead, RS-232 is used to display the output and the register contents.
I hope you have RS-232 working on your board (with Max232 chip, etc).
Compile this program, run it, and see what is displayed. If you are
using MPLAB, make sure that you compile the program in "Release" mode.

I assume that your board is using a Vdd voltage of +3.3v, because
you are using the "LF" version of the PIC. For that reason, I set
the brownout voltage to 2.5v. It's important to use Brownout. It keeps
the PIC in reset until the Vdd voltage reaches the correct level.
Code:

#include <16LF1947.h>
#fuses INTRC_IO, NOWDT, BORV25, NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#byte LCDCON = getenv("SFR:LCDCON")

//=========================================
void main()
{
printf("Start \n\r");

printf("LCDCON address from getenv: %lx \n\r", getenv("SFR:LCDCON"));
printf("Initial value of LCDCON: %x \n\r", LCDCON);
printf("Value of LCD_MUX14 constant is: %lx \n\r", LCD_MUX14);

setup_lcd(LCD_MUX14, 0, 1);

printf("Value of LCDCON after calling setup_lcd: %x \n\r", LCDCON);

printf("Done \n\r");     
while(1);
}


I compiled this with vs. 5.011 and ran it in MPLAB simulator. It worked fine.
sergio1234



Joined: 06 Jan 2006
Posts: 17
Location: Argentina

View user's profile Send private message

PostPosted: Tue Aug 27, 2013 3:22 pm     Reply with quote

Thank you Very much.

Thanks to your example I could continue working, and I reached the following conclusions.

The CCS compiler together with the ICDU 64 write correctly the registers of the LCD Controller (as a programmer).

The CCS debugger together with the ICDU64 reads wrong values for the LCD controller registers (always 00).

Your example of the UART is a good workaround for this problem.

I also found that they are a bug with the following values in the 16LF1947.h file provided by CCS on the LCD section:

#define COM0 0
#define COM1 48, must be 24
#define COM2 96, must be 48
#define COM3 144, must be 72

Thanks again
dyeatman



Joined: 06 Sep 2003
Posts: 1924
Location: Norman, OK

View user's profile Send private message

PostPosted: Tue Aug 27, 2013 4:05 pm     Reply with quote

Please send a message to CCS and let them know.
_________________
Google and Forum Search are some of your best tools!!!!
cosmo



Joined: 30 Jan 2014
Posts: 3
Location: España

View user's profile Send private message

lcd_symbol solution for use in pic16f1646
PostPosted: Thu Jan 30, 2014 12:34 pm     Reply with quote

I have the same problem with the configuration of the pic16f1946 and lcd_symbol command.
Reviewing the lst file. It can be seen that in writing LCDDATX record does not correspond to the segment.
I found a solution and now in the lst you can see that if you type in the appropriate register.

For this you have to change the way you configure the segments.
instance.

Code:

#define DIGIT1 COM0+SEG0,  COM2+SEG31,


The file 16f1946.h must be modified as follows.

Code:

// Constants used in lcd_symbol() are:
#define COM0 0
#define COM1 24     
#define COM2 48     
#define COM3 72
#define SEG0   0 
#define SEG1   1
#define SEG2   2
#define SEG3   3
#define SEG4   4
#define SEG5   5 
#define SEG6   6
#define SEG7   7
#define SEG8   8
#define SEG9   9
#define SEG10  10
#define SEG11  11
#define SEG12  12
#define SEG13  13
#define SEG14  14
#define SEG15  15
#define SEG16  16
#define SEG17  17
#define SEG18  18
#define SEG19  19
#define SEG20  20
#define SEG21  21
#define SEG22  22
#define SEG23  23

#define SEG24  96
#define SEG25  97 
#define SEG26  98 
#define SEG27  99 
#define SEG28  100 
#define SEG29  101 
#define SEG30  102 
#define SEG31  103
#define SEG32  104 
#define SEG33  105
#define SEG34  106
#define SEG35  107
#define SEG36  108
#define SEG37  109
#define SEG38  110
#define SEG39  111
#define SEG40  112
#define SEG41  113
#define SEG42  114
#define SEG43  115
#define SEG44  116
#define SEG45  117


In my case to set the segments I have used.

Code:

setup_lcd( LCD_MUX14 | LCD_A_LOW_POWER | LCD_TIMER1, 5, 0b11111111110011001111110010100111,0xFCFC);     //FFCCFCA7


I have implemented this function to clear the lcd, the compiler says "code has no effect". Although I think works?
Code:

void clear_lcd(void){   
 
  int16 i,j;
  i=getenv("SFR:LCDDATA0");
  j=getenv("SFR:LCDDATA23"); 
 
   for (i ; i < j ; i++){   
   *i = 0x00;   
   }
}



I have not tested for pic16f946, but the solution should look like.
cosmo



Joined: 30 Jan 2014
Posts: 3
Location: España

View user's profile Send private message

Definitely this setting to internal LCD works.
PostPosted: Mon Feb 24, 2014 1:50 am     Reply with quote

They can take notice administrator, I tried this.

I created separate file with the new definitions.
I add to the top of the program:
Code:

// Constants used in lcd_symbol() are:

#define CM0 0
#define CM1 24     
#define CM2 48     
#define CM3 72   

#define SG0   0
#define SG1   1
#define SG2   2
#define SG3   3
#define SG4   4
#define SG5   5 
#define SG6   6
#define SG7   7
#define SG8   8
#define SG9   9
#define SG10  10
#define SG11  11
#define SG12  12
#define SG13  13
#define SG14  14
#define SG15  15
#define SG16  16
#define SG17  17
#define SG18  18
#define SG19  19
#define SG20  20
#define SG21  21
#define SG22  22
#define SG23  23

#define SG24  96
#define SG25  97 
#define SG26  98 
#define SG27  99 
#define SG28  100 
#define SG29  101 
#define SG30  102 
#define SG31  103
#define SG32  104 
#define SG33  105
#define SG34  106
#define SG35  107
#define SG36  108
#define SG37  109
#define SG38  110
#define SG39  111
#define SG40  112
#define SG41  113
#define SG42  114
#define SG43  115
#define SG44  116
#define SG45  117


The config from the internal lcd register.
Code:

setup_lcd(LCD_MUX14 | LCD_TYPE_A | LCD_REF_ENABLED | LCD_A_MED_POWER |
            LCD_B_MED_POWER | LCD_LFINTOSC ,
            8 ,                                                            //Preescaler
            // segments   31-0             ,    45-32
            0b10100111111110001100111111111111,0b011111000011100 );       //


I used to writing in a digit.

Code:

#define DIGIT1    CM0+SG22, CM0+SG23, CM2+SG23, CM3+SG22, CM2+SG22, CM1+SG22, CM1+SG23

lcd_symbol( bufLCDTem [0], DIGIT1);
Ttelmah



Joined: 11 Mar 2010
Posts: 19381

View user's profile Send private message

PostPosted: Mon Feb 24, 2014 2:14 am     Reply with quote

Report it to CCS.

Read the top of the forum:

"CCS does not monitor this forum on a regular basis."
cosmo



Joined: 30 Jan 2014
Posts: 3
Location: España

View user's profile Send private message

Sorry, I say administrator.
PostPosted: Mon Feb 24, 2014 5:47 am     Reply with quote

They can take notice administrator,
I think is important, for the forum?????
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  Next
Page 1 of 2

 
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