|
|
View previous topic :: View next topic |
Author |
Message |
sergio1234
Joined: 06 Jan 2006 Posts: 17 Location: Argentina
|
Trouble using LCD controller of PIC16LF1947 |
Posted: Wed Aug 21, 2013 2:50 pm |
|
|
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
|
|
Posted: Wed Aug 21, 2013 4:39 pm |
|
|
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
|
|
Posted: Wed Aug 21, 2013 8:31 pm |
|
|
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
|
|
Posted: Wed Aug 21, 2013 8:34 pm |
|
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Aug 21, 2013 9:48 pm |
|
|
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
|
|
Posted: Thu Aug 22, 2013 10:50 am |
|
|
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
|
|
Posted: Thu Aug 22, 2013 8:30 pm |
|
|
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
|
|
Posted: Thu Aug 22, 2013 10:37 pm |
|
|
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
|
|
Posted: Fri Aug 23, 2013 1:11 pm |
|
|
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
|
|
Posted: Tue Aug 27, 2013 3:22 pm |
|
|
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: 1934 Location: Norman, OK
|
|
Posted: Tue Aug 27, 2013 4:05 pm |
|
|
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
|
lcd_symbol solution for use in pic16f1646 |
Posted: Thu Jan 30, 2014 12:34 pm |
|
|
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
|
Definitely this setting to internal LCD works. |
Posted: Mon Feb 24, 2014 1:50 am |
|
|
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: 19512
|
|
Posted: Mon Feb 24, 2014 2:14 am |
|
|
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
|
Sorry, I say administrator. |
Posted: Mon Feb 24, 2014 5:47 am |
|
|
They can take notice administrator,
I think is important, for the forum????? |
|
|
|
|
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
|