|
|
View previous topic :: View next topic |
Author |
Message |
xTeox
Joined: 27 Aug 2009 Posts: 10
|
Problem with PRINTF and/or FPRINTF on a PIC18F4550 |
Posted: Thu Aug 27, 2009 11:26 am |
|
|
Hi! I'm trying do send some chars by USART, but I'm getting a strange behavior when it runs the code.
The criteria is to send one description of a menu that will be works on a console or hyperterminal and, after, the options of the menu. But every time I stack two printf or fprintf and run the program at a PIC simulation board, it just doesn't work. The LCD gains black block characters and the communication doesn't do nothing. It's like a crash, otherwise the code is compiled as normal.
Here is piece of the code, if anyone could help I should thank ya very much:
Code: | #include <CONFIG>
#include <VARS>
#include <COAD>
void main(void) {
config();
// printf(LCD_putc, "At:"); << Here the LCD works
// printf(LCD_putc, "def"); << After here and under it crashes... but this isn't the point... the actual problem is under
// printf(LCD_putc, "asa");
// printf(LCD_putc, "123");
//fprintf(USART, "Escolha a opcao do menu:\n\r"); << IF TWO OF THESE ARE ONE AFTER OTHER, IT CRASHES... SEE MORE UNDER
#ignore_warnings 203
while(1) {
#ignore_warnings NONE
if (kbhit() && USART_Rx() == 'a')
saida = menu();
USART_Tx(atenuacao(Read_ADC(), saida));
}
} |
In COAD:
Code: | int menu (void) {
unsigned int i = 0;
//fprintf(USART, "Escolha a opcao do menu:\n\r"); << IF I PUT THIS STRECH IT CRASHES LIKE I'VE COMMENTED
do {
if (++i==10) i=0;
fprintf(USART, "%u - %u db\n\r", i, opcs[i]);
} while(i);
#ignore_warnings 201
while (!(kbhit() && ((opc = USART_Rx()) >= 48 && opc <= 57 || opc >= 0 && opc <= 9)));
#ignore_warnings NONE
return tabela(opc);
} |
The configs are all rigths:
Code: | #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, stream=USART) |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 27, 2009 11:40 am |
|
|
It would be easier for us to solve if you would post a complete, compilable
test program, with the #include for the PIC, the #fuses, #use delay(),
etc., and all necessary variable declarations. It would also be easier
if you would remove all the #ignore warnings statements. Make it easy
for us to read the code. Make the program as short as possible.
Also, post your compiler version. |
|
|
xTeox
Joined: 27 Aug 2009 Posts: 10
|
|
Posted: Thu Aug 27, 2009 12:45 pm |
|
|
Sorry... here they are:
MAIN.C
Code: | #include <CONFIG>
#include <VARS>
#include <COAD>
void main(void) {
config();
while(1) {
if (kbhit() && USART_Rx() == 'a')
saida = menu();
USART_Tx(atenuacao(Read_ADC(), saida));
}
} |
CONFIG
Code: | #ifndef __CONFIG__
#define __CONFIG__
#include <CONFIG.h>
void config (void) {
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
LCD_inicia();
}
#endif |
CONFIG.H
Code: | #ifndef _CONFIG_H_
#define _CONFIG_H_
#include <18F4550.h>
// CONFIGURAÇÕES /////////////////
#device adc = 8 // Número de bits utilizado na conversão de [spam]ógico para digital [até 16]
#FUSES NOWDT // Desabilita o temporizador Watch Dog
#FUSES INTRC // Oscilador Interno RC
#FUSES NOPROTECT // Desabilita a proteção de leitura do código
#FUSES NOBROWNOUT // Desabilita o resete Brownout
#FUSES NOPUT // Desabilita o Temporazidor Power Up
#FUSES NOCPD // Desabilita a proteção da EE (EEPROM)
#FUSES NODEBUG // Desabilita o modo de debugação para ICD
#FUSES NOLVP // Desabilita a Programação por Baixa Voltagem em B3 (PIC16) ou B5 (PIC18)
#FUSES NOWRT // Desabilita a proteção de gravação de dados na memória do programa
#FUSES NOWRTD // Desabilita a proteção de gravação de dados na EEPROM
#FUSES IESO // Habilita a chave de modo interno-externo
#FUSES FCMEN // Habiita o monitoramento anti-falha do clock
#FUSES NOWRTC // Desabilita a proteção contra gravação do registro
#FUSES NOEBTR // Desabilita a proteção na memória de leitura em tabelas
#FUSES NOWRTB // Desabilita a proteção contra gravação do bloco de inicialização
#FUSES NOEBTRB // Desabilita a proteção contra leitura do bloco de inicialização
#FUSES NOCPB // Desabilita a proteção do código do bloco de inicialização
#FUSES NOXINST // Desabilita os modos: conjunto de extensão prolongado e endereçamento indexado (modo Legacy)
#FUSES PLL1 // Desabilita o PLL PreScaler
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#use delay(clock=8000000) // Clock de 8 MHz
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, stream=USART)
// Comunicação serial RS232:
// |- Velocidade de comunicação em 9600 bits/seg
// |- Pino transmissor definido em C6
// |- Pino receptor definido em C7
// |- 8 bits de comunicação
// |- Sem paridade de bits
// '- Stream chamada "USART"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <USART>
#include <LCD>
#endif |
USART
Code: | #ifndef __USART__
#define __USART__
#include <USART.h>
//////////////////////////////////////////////////////////////
char USART_Rx() { //
return fgetc(USART); //
} //
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
void USART_Tx (int _numero) { //
static int stock; //
if (stock != _numero) { //
stock = _numero; //
fprintf(USART, "Atenuado: %u\n\r", _numero); //
} //
delay_ms(100); //
} //
//////////////////////////////////////////////////////////////
#endif |
USART.H
Code: | #ifndef _USART_H_
#define _USART_H_
////////////////////////////////////////////////////////////////
char USART_Rx ();
void USART_Tx (int _numero);
////////////////////////////////////////////////////////////////
#endif |
LCD
Code: | #ifndef __LCD__
#define __LCD__
#include <LCD.h>
//////////////////////////////////////////////////////////////
void LCD_inicia() { //
int i; //
LCD_comando_escrever(); //
LCD_pino_RS(0); //
LCD_pino_EN(0); //
delay_ms(15); //
for (i=1; i<=3; ++i) { //
LCD_envia_nibble(3); //
delay_ms(5); //
} //
LCD_envia_nibble(2); //
for (i=0; i<=3; ++i) //
LCD_envia_byte(0, LCD_inicia_string[i]); //
delay_ms(2); //
} //
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
void LCD_goto (int _x, int _y) { //
if (_x > 1) _x = LCD_linha_2; //
else _x = 0; //
_x += _y-1; //
LCD_envia_byte(0, 0x80 | _x); //
} //
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
char LCD_getc (int _x, int _y) { //
char _char; //
LCD_goto(_x, _y); //
while (bit_test(LCD_ler_byte(), 7)); //
LCD_pino_RS(1); //
_char = LCD_ler_byte(); //
LCD_pino_RS(0); //
return _char; //
} //
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
void LCD_putc (char _char) { //
switch(_char) { //
case '\f' : LCD_envia_byte(0, 1); //
delay_ms(2); break; //
case '\n' : LCD_goto(2, 1); break; //
case '\b' : LCD_envia_byte(0, 0x10); break; //
default : LCD_envia_byte(1, _char); break; //
} //
} //
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
char LCD_ler_byte() { //
int _MSB, _LSB; //
LCD_comando_ler(); //
LCD_pino_EN(1); //
delay_cycles(1); //
_MSB = LCD_pino_DT; //
LCD_pino_EN(0); //
delay_cycles(1); //
LCD_pino_EN(1); //
delay_us(1); //
_LSB = LCD_pino_DT; //
LCD_pino_EN(0); //
LCD_comando_escrever(); //
return ((_MSB << 4) | _LSB); //
} //
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
void LCD_envia_nibble (byte _nibble) { //
LCD_pino_DT(_nibble); //
delay_cycles(1); //
LCD_pino_EN(1); //
delay_us(2); //
LCD_pino_EN(0); //
} //
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
void LCD_envia_byte (int _RS, byte _byte) { //
LCD_pino_RS(0); //
while (bit_test(LCD_ler_byte(), 7)); //
LCD_pino_RS(_RS); //
delay_cycles(1); //
LCD_pino_EN(0); //
LCD_envia_nibble(_byte >> 4); //
LCD_envia_nibble(_byte & 0xF); //
} //
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
void LCD_comando_ler() { //
LCD_pino_EN(0); //
LCD_pino_RS(0); //
LCD_pino_DT(0xF0); //
} //
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
void LCD_comando_escrever() { //
LCD_pino_EN(0); //
LCD_pino_RS(0); //
LCD_pino_DT(0x00); //
} //
//////////////////////////////////////////////////////////////
#endif |
LCD.H
Code: | #ifndef _LCD_H_
#define _LCD_H_
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void LCD_pino_EN (boolean _bit) { output_bit(PIN_E1, _bit); }
void LCD_pino_RS (boolean _bit) { output_bit(PIN_E2, _bit); }
void LCD_pino_DT (byte _byte) { output_D (_byte << 4); }
#define LCD_tipo 2
#define LCD_linha_2 0x40
const int LCD_inicia_string[4] = {0x20 | (LCD_tipo << 2), 0xc, 1, 6};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void LCD_inicia ();
void LCD_goto (int _x, int _y);
char LCD_getc (int _x, int _y);
void LCD_putc (char _char);
char LCD_ler_byte ();
void LCD_envia_nibble (byte _nibble);
void LCD_envia_byte (boolean _RS, byte _byte);
void LCD_comando_ler ();
void LCD_comando_escrever ();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif |
VARS
Code: | #ifndef __VARS__
#define __VARS__
#include <VARS.txt>
#endif |
VARS.TXT
Code: | #ifndef __VARS_TXT__
#define __VARS_TXT__
// VARIÁVEIS /////////////////////////
//
int saida = 40; //
unsigned int opcs[] = {100, //
10, //
20, //
30, //
40, //
50, //
60, //
70, //
80, //
90}; //
//
#endif |
COAD
Code: | #ifndef __COAD__
#define __COAD__
#include <COAD.h>
////////////////////////////////////////////////////////////////
int atenuacao (int entrada, int saida) {
return saida - entrada;
}
////////////////////////////////////////////////////////////////
int menu (void) {
unsigned int i = 0;
//fprintf(USART, "Escolha a opcao do menu:\n\r"); <<<<<<<<<<<<<<<< HERE >>>>>>>>>>>>>>>>
do {
if (++i==10) i=0;
fprintf(USART, "%u - %u db\n\r", i, opcs[i]);
} while(i);
while (!(kbhit() && ((opc = USART_Rx()) >= 48 && opc <= 57 || opc >= 0 && opc <= 9)));
return tabela(opc);
}
////////////////////////////////////////////////////////////////
int tabela (int opc) {
switch (opc) {
case 0 :
case '0': return opcs[0];
case 1 :
case '1': return opcs[1];
case 2 :
case '2': return opcs[2];
case 3 :
case '3': return opcs[3];
case 4 :
case '4': return opcs[4];
case 5 :
case '5': return opcs[5];
case 6 :
case '6': return opcs[6];
case 7 :
case '7': return opcs[7];
case 8 :
case '8': return opcs[8];
case 9 :
case '9': return opcs[9];
default: return 40;
}
}
////////////////////////////////////////////////////////////////
#endif |
COAD.H
Code: | #ifndef _COAD_H_
#define _COAD_H_
////////////////////////////////////////////////////////////////
static char opc;
////////////////////////////////////////////////////////////////
int atenuacao (int entrada, int saida);
int menu (void);
int tabela (char opc);
////////////////////////////////////////////////////////////////
#endif |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 27, 2009 1:00 pm |
|
|
It seems that you have a problem with lcd_putc() or with fprintf().
So make a simple test program to look at these problems.
First try it with your LCD driver. If it fails, then use the Flex driver
from the CCS code library. Example:
Code: | #include <18F4550.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS, stream=USART)
#include "flex_lcd.c"
//======================================
void main(void)
{
lcd_init();
printf(lcd_putc, "At:"); // Here the LCD works
printf(lcd_putc, "def"); // After here it crashes
printf(lcd_putc, "asa");
printf(lcd_putc, "123");
fprintf(USART, "Escolha a opcao do menu:\n\r");
while(1);
} |
Also, post your compiler version. |
|
|
xTeox
Joined: 27 Aug 2009 Posts: 10
|
|
Posted: Thu Aug 27, 2009 1:12 pm |
|
|
Sorry, but the LCD problem is another thing to fix after the RS232...
On the LCD, it doesn't work if I unify the printf's into only one, like:
Code: | printf(lcd_putc, "Atenuado:"); |
Seems that if I try to send more than three characters at one time, it crashes exactly like the RS232 problem has I mentioned before...
But the actual problem is for RS232... on the "COAD" there is a line specified with "<< HERE >>" text.
If you can help me with this you will be so much useful as can be with LCD...
PS.: I don't know this file "flex_lcd.c" that you mentioned... it doesn't exist in my PC.
Thx 'till now! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 27, 2009 1:18 pm |
|
|
Post a very small test program that shows the problem. Example:
Code: | #include <18F4550.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS, stream=USART)
//======================================
void main(void)
{
fprintf(USART, "Escolha a opcao do menu:\n\r");
while(1);
} |
1. Explain what you mean by "it crashes".
2. Post your compiler version. |
|
|
xTeox
Joined: 27 Aug 2009 Posts: 10
|
|
Posted: Thu Aug 27, 2009 1:52 pm |
|
|
I'm compiling using CCS C 4.020 PCWH Compiler integrated with MPLAB IDE 8.33 and programming using PICkit 2 v2.61.
Crashes, I mean, the PIC doesn't do nothing. It freezes. The LCD comes black characteres and the communication on RS232 by any interface (like hyperterminal) simply doesn't occur.
Here is a sample code that crashes for LCD:
Code: | #include <18F4550.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=8000000)
#include <LCD>
void main(void) {
LCD_inicia();
printf(lcd_putc, "Atenuado:");
while(1);
} |
Doing some tests, I found the point of the error, but I don't solved yet.
The problem is at the function "LCD_inicia()"... it crashes even the LCD test than the communication test.
Something that I've configured wrong, evidentiality.
I've did that code of "LCD" file basing in a example of the compiler CCS.
If there is a error code that you saw in "LCD", just tell me please.
The includes is in previous replies.
Tx 4'll till nw
Last edited by xTeox on Thu Aug 27, 2009 2:00 pm; edited 1 time in total |
|
|
xTeox
Joined: 27 Aug 2009 Posts: 10
|
|
Posted: Thu Aug 27, 2009 1:57 pm |
|
|
On the entry code, if I retire the comment of the function "LCD_inicia()", it will just crashes.
Code: | #include <18F4550.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=USART)
#include <USART>
int opcs[] = {0,10,20,30,40,50,60,70,80,90};
int saida = 40;
#include <COAD>
#include <LCD>
void main(void) {
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
//LCD_inicia();
while(1) {
if (kbhit() && USART_Rx() == 'a')
saida = menu();
USART_Tx(atenuacao(Read_ADC(), saida));
}
} |
Code: | int menu (void) {
unsigned int i = 0;
fprintf(USART, "Escolha a opcao do menu:\n\r");
do {
if (++i==10) i=0;
fprintf(USART, "%u - %u db\n\r", i, opcs[i]);
} while(i);
#ignore_warnings 201
while (!(kbhit() && ((opc = USART_Rx()) >= 48 && opc <= 57 || opc >= 0 && opc <= 9)));
#ignore_warnings NONE
return tabela(opc);
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 27, 2009 2:21 pm |
|
|
Your code is complicated because you have many indirections. This
makes your code more difficult to understand and debug quickly. You
could write it in a lot more simple way. For example, you have this code:
Code: |
if (kbhit() && USART_Rx() == 'a')
saida = menu();
|
It could be written like this:
Code: |
if (fgetc() == 'a')
saida = menu();
|
This new code waits until a character is received. It then reads it.
It then compares it to 'a'. If it equals 'a', then it calls the menu() function
and puts the result in 'saida'.
Also, your code has delays and printf statements that could block
your other code from reading the UART's receiver quickly enough.
It's possible that you are getting an overrun error in the UART
receiver. This could cause your program to lock up (freeze).
Add the ERRORS parameter to your #use rs232() statement, as shown
below. If the program doesn't freeze, then the problem was caused by
an overrun error.
Quote: | #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, stream=USART, ERRORS) |
|
|
|
xTeox
Joined: 27 Aug 2009 Posts: 10
|
|
Posted: Thu Aug 27, 2009 2:29 pm |
|
|
I cannot use to read the pressed key by using "get" because I cannot stop the program. This is the because I've used "kbhit".
On my concentration, my way is the better way (to me) to separe every part of the entire code.
The addition of "ERROR" on RS232 doens't work. It's still crashing.
Anyway, I'm pretty sure that the problem is on the file "LCD" and "LCD.H". |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 27, 2009 2:38 pm |
|
|
But in your previous comment you said for me to ignore the LCD
problem and only to help you on the fprintf problem:
Quote: |
If you can help me with this you will be so much useful as can be with LCD... |
So, as before, I suggest that you use the Flex LCD driver.
http://www.ccsinfo.com/forum/viewtopic.php?t=24661 |
|
|
xTeox
Joined: 27 Aug 2009 Posts: 10
|
|
Posted: Fri Aug 28, 2009 5:32 am |
|
|
Yes... I did... but as soon I've found the source of the errors... is in the LCD file... without the LCD my communication works properly... there's something wrong in the function "LCD_inicia()"... or maybe in the constants... the pins are rights... but the logic (of the LCD, off course), I've based on the example from the CCS compiler...
So... I guess there's nothing wrong in the communication...
I'll read the link that u forwarded...
Tx 4 ur helping me till now... |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Aug 28, 2009 5:49 am |
|
|
Quote: | I'm compiling using CCS C 4.020 PCWH Compiler | This is where I stopped reading.
v3.249 was a stable version. Then the v4 releases came and it took to about v4.060 to become more or less stable. Using any version in between is a waste of time; the code will not compile or will behave with strange errors. See also the sticky thread on top of this forum.
Revert to v3.249 or upgrade to a newer version. |
|
|
xTeox
Joined: 27 Aug 2009 Posts: 10
|
|
Posted: Fri Aug 28, 2009 6:42 am |
|
|
Tx ∞one...
I've found the solution... the problem is really in the LCD file... the logic isn't wrong... but, comparing mine and the example of the link, I've saw one mistake I did: as my LCD configuration doesn't use any pin to RW, because it's grounded, I don't need some specifications given from it... like:
Code: | while (bit_test(LCD_ler_byte(), 7)); | ...and some delays...
Removing them all, it works properly...
Tx again!!!
If I have any new problem, off course I'll ask your help, PCM Programmer!!...
Have a nice weekend! |
|
|
|
|
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
|