|
|
View previous topic :: View next topic |
Author |
Message |
RWeiller
Joined: 15 May 2018 Posts: 3
|
Problem using PIC16LF1939 and LCD driver |
Posted: Tue May 15, 2018 5:47 pm |
|
|
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
|
|
Posted: Tue May 15, 2018 6:26 pm |
|
|
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
|
|
Posted: Tue May 15, 2018 6:46 pm |
|
|
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
|
|
Posted: Wed May 16, 2018 7:37 am |
|
|
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. |
|
|
RWeiller
Joined: 15 May 2018 Posts: 3
|
|
Posted: Wed May 16, 2018 1:25 pm |
|
|
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
|
|
Posted: Wed May 16, 2018 1:38 pm |
|
|
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
|
|
Posted: Thu May 17, 2018 12:06 am |
|
|
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. |
|
|
|
|
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
|