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

Problem using PIC16LF1939 and LCD driver

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
RWeiller



Joined: 15 May 2018
Posts: 3

View user's profile Send private message

Problem using PIC16LF1939 and LCD driver
PostPosted: Tue May 15, 2018 5:47 pm     Reply with quote

I'm developing a proprietary hardware, with the PIC16LF1939 and an LCD display. The LCD display works perfectly, but when I use the lcd_Symbol () function, some microcontroller pins stop working.
I already tried to reconfigure the TRIS register but with no results.

For the display I am using segments 1, 2, 3, 4, 5, 7, 12 and 15, in addition to COM0, COM1, COM2 and COM3.

The ccs version is: 5,008

On the hardware I am using the decoupling capacitors on the microcontroller and the voltage regulator.

Here's my code:


Code:

#include <16LF1939.h>                                 
#fuses INTRC_IO
#use delay (clock=32000000)
#include <header_mma.h>


#BYTE LCDSE0 = 0x798
#BYTE LCDSE1 = 0x799
#BYTE LCDSE2 = 0x79A
#BYTE ANSELA = 0x18C
#BYTE ANSELB = 0x18D
#BYTE ANSELD = 0x18F
#BYTE ANSELE = 0x190
#BYTE PORTC = 0x00E
   #BIT RC7 = PORTC.7
   #BIT RC6 = PORTC.6
   #BIT RC5 = PORTC.5
   #BIT RC4 = PORTC.4
   #BIT RC3 = PORTC.3
   #BIT RC2 = PORTC.2
   #BIT RC1 = PORTC.1
   #BIT RC0 = PORTC.0
#BYTE TRISD = 0x08F
#BYTE PORTD = 0x00F
   #BIT RD7 = PORTD.7
   #BIT RD6 = PORTD.6
   #BIT RD5 = PORTD.5
   #BIT RD4 = PORTD.4
   #BIT RD3 = PORTD.3
   #BIT RD2 = PORTD.2
   #BIT RD1 = PORTD.1
   #BIT RD0 = PORTD.0
#BYTE TRISE = 0x090
#BYTE PORTE = 0x010
   #BIT RE3 = PORTE.3
   #BIT RE2 = PORTE.2
   #BIT RE1 = PORTE.1
   #BIT RE0 = PORTE.0
#BYTE TRISB=0x08D
#BYTE PORTB=0x00D
   #BIT RB7 = PORTB.7
   #BIT RB6 = PORTB.6
   #BIT RB5 = PORTB.5
   #BIT RB4 = PORTB.4
   #BIT RB3 = PORTB.3
   #BIT RB2 = PORTB.2
   #BIT RB1 = PORTB.1
   #BIT RB0 = PORTB.0
#BYTE INTCON=0x00B
   #BIT GIE      = INTCON.7
   #BIT PEIE     = INTCON.6
   #BIT TMR0IE   = INTCON.5
   #BIT INTE     = INTCON.4
   #BIT IOCIE    = INTCON.3
   #BIT TMR0IF   = INTCON.2
   #BIT INTF     = INTCON.1
   #BIT IOCIF    = INTCON.0
#BYTE OPTION_REG=0x095
   #BIT WPUEN    = OPTION_REG.7
   #BIT INTEDG   = OPTION_REG.6
   #BIT TMROCS   = OPTION_REG.5
   #BIT TMROSE   = OPTION_REG.4
   #BIT PSA      = OPTION_REG.3
   #BIT PS2      = OPTION_REG.2
   #BIT PS1      = OPTION_REG.1
   #BIT PS0      = OPTION_REG.0
#BYTE WPUB=0x20D
   #BIT WPUB7    = WPUB.7
   #BIT WPUB6    = WPUB.6
   #BIT WPUB5    = WPUB.5
   #BIT WPUB4    = WPUB.4
   #BIT WPUB3    = WPUB.3
   #BIT WPUB2    = WPUB.2
   #BIT WPUB1    = WPUB.1
   #BIT WPUB0    = WPUB.0
#BYTE IOCBP=0x394
   #BIT IOCBP7    = IOCBP.7
   #BIT IOCBP6    = IOCBP.6
   #BIT IOCBP5    = IOCBP.5
   #BIT IOCBP4    = IOCBP.4
   #BIT IOCBP3    = IOCBP.3
   #BIT IOCBP2    = IOCBP.2
   #BIT IOCBP1    = IOCBP.1
   #BIT IOCBP0    = IOCBP.0
#BYTE IOCBN=0x395
   #BIT IOCBN7    = IOCBN.7
   #BIT IOCBN6    = IOCBN.6
   #BIT IOCBN5    = IOCBN.5
   #BIT IOCBN4    = IOCBN.4
   #BIT IOCBN3    = IOCBN.3
   #BIT IOCBN2    = IOCBN.2
   #BIT IOCBN1    = IOCBN.1
   #BIT IOCBN0    = IOCBN.0
#BYTE IOCBF=0x396
   #BIT IOCBF7    = IOCBF.7
   #BIT IOCBF6    = IOCBF.6
   #BIT IOCBF5    = IOCBF.5
   #BIT IOCBF4    = IOCBF.4
   #BIT IOCBF3    = IOCBF.3
   #BIT IOCBF2    = IOCBF.2
   #BIT IOCBF1    = IOCBF.1
   #BIT IOCBF0    = IOCBF.0


#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)

#define  I2C_WRITE_ADDR 0x3A
#define  I2C_READ_ADDR  0x3B

/////////////////////////////////////////////////////////////////////////////////////////
//                                 Configuração LCD                                   //
/////////////////////////////////////////////////////////////////////////////////////////
// Segmentos         A        B        C        D        E        F        G       DP

#define DIGITO1    COM3+1,  COM2+1,  COM1+1,  COM0+2,  COM1+2,  COM3+2,  COM2+2,  COM0+1
#define DIGITO2    COM3+4,  COM2+4,  COM1+4,  COM0+5,  COM1+5,  COM3+5,  COM2+5,  COM0+4
#define DIGITO3    COM3+7,  COM2+7,  COM1+7,  COM0+15, COM1+15, COM3+15, COM2+15, COM0+7
#define DIGITO4    COM3+3,  COM2+3,  COM1+3,  COM0+12, COM1+12, COM3+12, COM2+12, COM0+3
//
//         Caracter                 0    1    2    3    4    5    6    7    8    9
int8 const Mapa_de_Caracter[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xE6};

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

#define LedVerde     RC5
#define LedAm1Mais   RD4//RB2
#define LedAm2Mais   RD5//RB3
#define LedVm1Mais   RD6//RE0
#define LedVm2Mais   RD7//RE1
#define LedAm1Menos  RD3//RB1
#define LedAm2Menos  RD2//RB0
#define LedVm1Menos  RD1
#define LedVm2Menos  RC1

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


int8 RegulaAngulo=0;

int1 BotaoOk=0;


//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

int1 ext_ready(void)
{
   int ack;               
   i2c_start();           
   ack=i2c_write(I2C_WRITE_ADDR);     
   i2c_stop();             
   return !ack;           
}

int8 readreg(int8 address)
{
   int8 data;
   
   while(!ext_ready());
   i2c_start();                           
   i2c_write(I2C_WRITE_ADDR);           
   i2c_write(address);                   
   i2c_start(); 
   i2c_write(I2C_READ_ADDR);             
   data = i2c_read(0);
   i2c_stop();
   return data;
}

void writeReg(unsigned char address, unsigned char data)
{

   while(!ext_ready());
   i2c_Start();   
   i2c_write(I2C_WRITE_ADDR);
   i2c_write(address);   
   i2c_write(data); 
   i2c_stop();
}

void MMA8452_Standby (void)
{
   byte n;
   n = readreg(CTRL_REG1);
   writeReg(CTRL_REG1, n & ~ACTIVE_MASK);
}

void MMA8452_Active ()
{
   writeReg(CTRL_REG1, (readreg(CTRL_REG1) | ACTIVE_MASK));
}

void Display(int8 valor)
{
   int8 centena=0, dezena=0, unidade=0;
   
   centena = (valor%1000)/100;                                 
   dezena  = (valor%100)/10;                                   
   unidade = (valor%10);
   
   lcd_symbol(Mapa_de_Caracter[centena],DIGITO2);
   lcd_symbol(Mapa_de_Caracter[dezena],DIGITO3);
   lcd_symbol(Mapa_de_Caracter[unidade],DIGITO4); 
}

void ComparaAngulo(int16 ValorLido)
{
   float auxiliar=0;
   int16 Referencia=0;
   //int8 Erro=57;// 5 graus
   
   //auxiliar=RegulaAngulo*11.42;
   //Referencia=(int16)auxiliar;
   
   if((ValorLido>=0)&&(ValorLido<=1024))
   {
      auxiliar=(ValorLido*9)/102.4;
      Referencia=(int16)auxiliar;
   }else if((ValorLido<=4096)&&(ValorLido>=3072))
   {
      auxiliar=(((ValorLido-4096)*(-1))*9)/102.4;
      Referencia=(int16)auxiliar;
   }
   
   printf("Valor Lido: %0Lu",ValorLido);
   printf("  Angulo: %f",auxiliar);
   printf("  Referência: %0Lu\r\n",Referencia);
     
   
   if(Referencia>=(RegulaAngulo+20))  //teste 2 led vermelho Mais
   {
      LedVerde=0;
      LedAm1Mais=0;
      LedAm2Mais=0;
      LedVm1Mais=0;
      LedVm2Mais=0;
      LedAm1Menos=1;
      LedAm2Menos=1;
      LedVm1Menos=1;
      LedVm2Menos=1;
   }else if(Referencia<=(RegulaAngulo-20))  //teste 2 led Vermelho Menos
   {
      LedVerde=0;
      LedAm1Menos=0;
      LedAm2Menos=0;
      LedVm1Menos=0;
      LedVm2Menos=0;
      LedAm1Mais=1;
      LedAm2Mais=1;
      LedVm1Mais=1;
      LedVm2Mais=1;
   }else if((Referencia<=(RegulaAngulo+20))&&(Referencia>=(Referencia+15)))  //teste 1 led vermelho Mais
   {
      LedVerde=0;
      LedAm1Mais=0;
      LedAm2Mais=0;
      LedVm1Mais=0;
      LedVm2Mais=1;
      LedAm1Menos=1;
      LedAm2Menos=1;
      LedVm1Menos=1;
      LedVm2Menos=1;
   }else if((Referencia>=(RegulaAngulo-20))&&(Referencia<=(RegulaAngulo-15)))  //teste 1 led Vermelho Menos
   {
      LedVerde=0;
      LedAm1Menos=0;
      LedAm2Menos=0;
      LedVm1Menos=0;
      LedVm2Menos=1;
      LedAm1Mais=1;
      LedAm2Mais=1;
      LedVm1Mais=1;
      LedVm2Mais=1;
   }else if((Referencia<=(RegulaAngulo+15))&&(Referencia>=(Referencia+10)))  //teste 2 led amarelo Mais
   {
      LedVerde=0;
      LedAm1Mais=0;
      LedAm2Mais=0;
      LedVm1Mais=1;
      LedVm2Mais=1;
      LedAm1Menos=1;
      LedAm2Menos=1;
      LedVm1Menos=1;
      LedVm2Menos=1;
   }else if((Referencia>=(RegulaAngulo-15))&&(Referencia<=(RegulaAngulo-10)))  //teste 2 led amarelo Menos
   {
      LedVerde=0;
      LedAm1Menos=0;
      LedAm2Menos=0;
      LedVm1Menos=1;
      LedVm2Menos=1;
      LedAm1Mais=1;
      LedAm2Mais=1;
      LedVm1Mais=1;
      LedVm2Mais=1;
   }else if((Referencia>=(RegulaAngulo-10))&&(Referencia<=(RegulaAngulo-5)))  //teste 1 led amarelo Menos
   {
      LedVerde=0;
      LedAm1Menos=0;
      LedAm2Menos=1;
      LedVm1Menos=1;
      LedVm2Menos=1;
      LedAm1Mais=1;
      LedAm2Mais=1;
      LedVm1Mais=1;
      LedVm2Mais=1;
   }else if((Referencia<=(RegulaAngulo+10))&&(Referencia>=(RegulaAngulo+5)))  //teste 1 led amarelo Mais
   {
      LedVerde=0;
      LedAm1Mais=0;
      LedAm2Mais=1;
      LedVm1Mais=1;
      LedVm2Mais=1;
      LedAm1Menos=1;
      LedAm2Menos=1;
      LedVm1Menos=1;
      LedVm2Menos=1;
   }else if((Referencia>=(RegulaAngulo-5))&&(Referencia<=(RegulaAngulo+5))) // teste led verde
   {
      LedVerde=0;
      LedAm1Mais=1;
      LedAm2Mais=1;
      LedVm1Mais=1;
      LedVm2Mais=1;
      LedAm1Menos=1;
      LedAm2Menos=1;
      LedVm1Menos=1;
      LedVm2Menos=1;     
   }
}

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

void main(void)
{
   int16 x, y, z;
   int8 hix, lox, hiy, loy, hiz, loz;
   int8 data;
   //int8 i;
   set_tris_b (0xF0);
   output_b (0xFF);
   set_tris_c (0xDD);
   output_c (0xFF);
   set_tris_d (0x01);
   output_d (0xFF);
   set_tris_e (0x00);
   output_e (0xFF);
   
   ANSELA=ANSELB=ANSELD=ANSELE=0x00;
   
   WPUEN=0;
   WPUB=0xFF;
   IOCBP=0x00;
   IOCBN=0xC0;
   IOCBF=0x00;
   IOCIF=0;
   GIE=PEIE=IOCIE=1;
     
   setup_lcd( LCD_MUX14 | LCD_REF_ENABLED | LCD_B_HIGH_POWER , 2, 0x0090BE);    //0x0090BE
     
   lcd_symbol(BLANK,DIGITO1);
   lcd_symbol(BLANK,DIGITO2);
   lcd_symbol(BLANK,DIGITO3);
   lcd_symbol(BLANK,DIGITO4);   
   
   //setup_lcd( LCD_DISABLED, 0, 0x000000);
   // A partir daqui os LEDS não funcionam


   //setup_lcd( LCD_MUX14 | LCD_REF_ENABLED | LCD_B_HIGH_POWER, 0, 0x000000);
   //setup_lcd( LCD_MUX14 | LCD_REF_ENABLED | LCD_B_HIGH_POWER, 0, 0x0090BE);
   
      /*LCDSE0=LCDSE1=LCDSE2=0x00;
      set_tris_d (0x01);
      set_tris_c (0xDD);
      TRISD=0x01;
      ANSELA=ANSELB=ANSELD=ANSELE=0x00;delay_ms(10);
      LedVerde=0;
      LedAm1Mais=0;
      LedAm2Mais=0;
      LedVm1Mais=0;
      LedVm2Mais=0;
      LedAm1Menos=0;
      LedAm2Menos=0;
      LedVm1Menos=0;
      LedVm2Menos=0; */
      //RC5=RD4=RD5=RD6=RD7=RD3=RD2=RD1=RC1=0;
      //delay_ms(2000); //while(TRUE);
   
   printf("Inicio: Inclinometro \r\n");
 
   start:
   data=readreg(0x0d);
   printf("\n\data: %0u", data);
   if(data!=42) goto start;  //2A=42
   
   MMA8452_Standby();
   writeReg(CTRL_REG1,(readreg(CTRL_REG1)& ~FREAD_MASK));
   MMA8452_Active();
   delay_ms(100);
 
   while(TRUE)
   {
      hix=readreg(OUT_X_MSB_REG);
      lox=readreg(OUT_X_LSB_REG);
      x = make16(hix,lox);
      x=((x>>4)&0x0FFF);
     
      hiy=readreg(OUT_Y_MSB_REG);
      loy=readreg(OUT_Y_LSB_REG);
      y = make16(hiy,loy);
      y=((y>>4)&0x0FFF);//y=((y>>4)&0x07FF);
     
      hiz=readreg(OUT_Z_MSB_REG);
      loz=readreg(OUT_Z_LSB_REG);
      z = make16(hiz,loz);   
      z=((z>>4)&0x0FFF);
     
      //printf("X: %0Lu",x);  // printf("\r\n X: \fx: %0Lu \r\n",x); 
      //printf("   Y: %0Lu",y);
      //printf("   Z: %0Lu\r\n",z);
      delay_ms(1000);
     
      Display(RegulaAngulo);
      if(RegulaAngulo>=90){RegulaAngulo=0;}
      ComparaAngulo(y);
   } 
}

#INT_RB
void interrupcao(void)
{
   IOCIE=0;
   
   if(!RB6)
   {
      delay_ms(100);
      RegulaAngulo=RegulaAngulo+5;
   }else if(!RB7)
   {
      delay_ms(100);
      BotaoOk=1;
   }
   
   IOCBF=0x00;
   IOCIF=0;
   IOCIE=1;
}


Could someone give me some hint of what's wrong?

Thank you!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 15, 2018 6:26 pm     Reply with quote

Quote:
some microcontroller pins stop working.

List the pins that stop working. Also, list the ways that they don't work
for each pin.


ie, PIN_B0 doesn't work as an output.
PIN B5 doesn't work as an input.

Etc.
RWeiller



Joined: 15 May 2018
Posts: 3

View user's profile Send private message

PostPosted: Tue May 15, 2018 6:46 pm     Reply with quote

The pins that stop working are:
PIN_E1, PIN_B0, PIN_D2 ... D7.
They do not work as output.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Wed May 16, 2018 7:37 am     Reply with quote

There are several issues in the code, but I can't see anything that would cause bit I/O problems (except possibly the very early compiler version - this is before V5, was considered a 'working' release...).

There are spots in the maths that can't work. Look at the digit maths. Starting with an int8, but then feeding a 3 digit display. Duh!....

centena = (valor%1000)/100;

However he seems to limit the angle to 90,so probably will get away with this.

Then there is using a delay in the interrupt. This will result in large parts of the code having interrupts disabled. Not good.

The lack of comments on most of the code, make working out what is actually happening quite hard. Sad
RWeiller



Joined: 15 May 2018
Posts: 3

View user's profile Send private message

PostPosted: Wed May 16, 2018 1:25 pm     Reply with quote

Thanks for the help so far!

    The equation I will still change, but actually the display will only show the angle up to 90 degrees.

    The delay function in the interrupt routine I was doing some testing and forgot to remove it.

    Is there any way to get the lcd_symbol function algorithm?
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Wed May 16, 2018 1:38 pm     Reply with quote

After you compile, look at the .lst file. Gives the assembler code generated. It does nothing except write to the segment registers.
However your's is a very early V5 compiler (there were significant issues on what were effectively 'beta' versions at this point), but it looks as if the register writes are correct (on the nearest version I have 5.009).
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Thu May 17, 2018 12:06 am     Reply with quote

Not knowing what you are actually 'seeing', would INT_RB becoming disabled, give the behaviour you are seeing?.
There was an issue up to about 5.013, with the global interrupt becoming disabled when printf was used. Wherever you use printf, add 'enable_interrupts(GLOBAL);' on the next line.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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