Problemas com RS232 + 16F876 + get_string

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Problemas com RS232 + 16F876 + get_string

Mensagempor __JEREK__ » 31 Out 2006 06:25

Bom dia galera, estou tendo problemas com a função get_string do CCS (versão 3.43) e até agora não consegui resolver.

O que estou tentando é usar o exemplo do CCS para escrever uma string (ou seja uma palavra inteira) e não consegui porque parece que o PIC 16F876 parece ficar resetando.

quando eu ligo o PIC aparece a mensagem no hyperterminal "Enter a string of text. The maximum number of characters is 50" quer dizer que posso digitar até 50 caracteres, mas quando eu escrevo 3 ou 4 caracteres ele mostra a mensagem inicial novamente "Enter a string of text. The maximum number of characters is 50" quer dizer só pode estar resetando. depois disso se vc escreve 1 caractere ele aparece a mensagem novamente, as vezes eu consigo escrever 3 ou 4 caracteres e apertar enter e ele funciona como deveria ser (aparecer a mensagem STATISTICS) mas na proxima vez já da erro.

veja a figura:

Imagem


o código é esse, é um exemplo do CCS:
Código: Selecionar todos
/*
#if defined(__PCB__)
#include <16c56.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)  // Jumpers: 11 to 17, 12 to 18
*/
//#elif defined(__PCM__)
#include <16F876.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12

#fuses XT//,NOBROWNOUT//,NOWDT,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NODEBUG,NOWRT

//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12
/*
#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12
#endif
*/

#include <string.h>
#include <input.c>

#define  STRING_SIZE    51             // The number of characters allowed to input

//int ttrtrtr = 250;
// This function cleans up the string. It removes all
// punctuation and all multiple spaces. It also removes
// any leading and trailing spaces.
void clean_up_str(char *str)   {
   char separators[8];
   char *ptr, *clean_str;

   strcpy(separators," ,;.\"!?");      // initialize variables
   clean_str=str;

   do
   {
      ptr = strpbrk(str,separators);   // search for punctuation or space
      if(ptr == str)                   // if first char is punct or space
      {
         ++str;                        // simply go to next char
      }
      else if(ptr == 0)                // if search returns end of str
      {
         while(*str != 0)              // loop until end of string
            *clean_str++ = *str++;     // copy characters to remove punct and spaces
         if(*--clean_str == ' ')       // if the last char is a space
            *clean_str = 0;            // remove it and terminate the string
         else
            *++clean_str = 0;          // otherwise just terminate the string
      }
      else                             // if somewhere in middle of string
      {
         while(ptr != str)             // loop until pointers match up
            *clean_str++ = *str++;     // copy chars to remove punct and spaces
         *clean_str++ = ' ';           // then add a space
      }
   } while(ptr != 0);                  // loop until through string
}


// This function return the number of words in the string.
// The words must be separated by a single space.
int get_num_words(char *str)   {
   int retval;

   retval=0;                           // initialize variable
   while(*str!=0)                      // loop through all of string
   {
      str = strchr(str,' ');           // find first space

      retval++;                        // increment counter
      if(*str == 0)                    // if at the end, quit
         break;
      else                             // otherwise increment pointer
         str++;
  }
   return(retval);
}


// This function returns the number of words in the string
// excluding any repeated words.  The words must be separated
// by a single space.
int get_num_unique_words(char *str)   {
   int retval, i;
   char temp_str[STRING_SIZE], space[2];
   char *word, *srch_string, *srch_word;

   strcpy(temp_str,str);               // copy the string to temp string
   strcpy(space," ");                  // initialize local variables
   retval=0;
   srch_string=temp_str;

   word=strtok(temp_str,space);        // find next word
   while(word!=0)                      // loop until all words looked at
   {
      retval++;

      srch_string+= strlen(word)+1;    // points to next word after 0 in temp

      srch_word=temp_str;
      while(srch_word!=0)              // loop while not end of words
      {
         srch_word=strstr(srch_string,word); // ptr points to found word or 0

         if(srch_word!=0)              // if 0, no matches found.  Otherwise..
         {
            i = srch_word + strlen(word);    // i=end of found word
            while(srch_word<i)         // insert spaces where the
               *srch_word++=' ';       // word was so no checking twice

            clean_up_str(srch_string); // remove the spaces (remove the double word)
         }
      }
      word=strtok(0,space);            // go to next word
   }
   return(retval);
}


// this function return the number of numbers in the string passed
// into it.  For example: 123 would return 3 because there are 3 numbers.
int get_num_numbers(char *str)   {
   int retval;

   retval=0;                           // initialize varialbes
   while(*str!=0)                      // loop until all characters checked
   {
      if(isdigit(*str++))              // if the character is a number
         retval++;                     // increment the counter
   }
   return(retval);
}


// this function allows users to enter in text, and then it calculates
// some statistics including the number of words, the number of unique
// words and the number of numbers in the user entered text.
void main()   {
   char input_str[STRING_SIZE];

   while(TRUE)
   {
      printf("\n\rEnter a string of text.  The maximum number of characters is %U.\n\r", STRING_SIZE-1);
      get_string(input_str,STRING_SIZE);     // gets the string

      clean_up_str(input_str);               // removes all punctuation and extra spaces

      printf("\n\n\rSTATISTICS:\n\r");
      printf("You entered %U word(s).\n\r", get_num_words(input_str));
      printf("You entered %U unique word(s).\n\r", get_num_unique_words(input_str));
      printf("You entered %U number(s).\n\r", get_num_numbers(input_str));
   }
}


as unicas alterações que fiz foi o valor do cristal (que estava 20MHz no exemplo) e o microcontrolador (que estava como 16F877).

já le todos os posts no forum antigo e ainda não consegui fazer funcionar. Algumas tentativas foram:

*Mudar a velocidade do Baud rate (não fez diferença)
*Habilitar "Ecoar localmente caracteres digitados" não funcionou
*colocar fuses (não funcionou)

qualquer ajuda seria bem vinda!!!
Valeu!!!
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor Anderson_Arantes » 31 Out 2006 07:20

Começando pela parte física, já experimentou remover o MCU e pôr em curto os pinos C6 e C7, digitar caracteres no hyperterminal e observar se ecoam? Vc pode até o momento somente ter certeza que o sentido MCU -> PC funciona e o contrário?
Anderson_Arantes
Bit
 
Mensagens: 42
Registrado em: 13 Out 2006 15:58
Localização: Rio de Janeiro

Mensagempor Anderson_Arantes » 31 Out 2006 07:26

Ainda na parte física. Repita o teste sugerido anteriormente mas desta vez ponha em curto os pinos 2 e 3 do conector DB-9 do cabo serial. A outra extremidade fixada na saída serial do PC. digite caracteres no hiperterminal e observe se ecoam. Isso assegurará a integridade das conexões do cabo. OK?
Anderson_Arantes
Bit
 
Mensagens: 42
Registrado em: 13 Out 2006 15:58
Localização: Rio de Janeiro

Mensagempor __JEREK__ » 31 Out 2006 07:32

Anderson, obrigado pela resposta!!!

Liguei as pontas RX TX depois do MAX232 o que eu digito aparece na tela. Acho que isso indica que esta funcionando bem até o PIC, não é???

Obrigado!!!
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor __JEREK__ » 31 Out 2006 07:39

Anderson_Arantes escreveu:Ainda na parte física. Repita o teste sugerido anteriormente mas desta vez ponha em curto os pinos 2 e 3 do conector DB-9 do cabo serial. A outra extremidade fixada na saída serial do PC. digite caracteres no hiperterminal e observe se ecoam. Isso assegurará a integridade das conexões do cabo. OK?


não tinha visto que você digitou isso, mas acho que vc queria dizer para testar o cabo, não foi?? Bom se foi isso eu fiz o que lhe disse, testei colocando em curto depois do MAX232 que fica depois do cabo, quando desconecto o cabo do max232 o que eu digito não aparece na tela.
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor andre_luis » 31 Out 2006 07:55

Uma pequena observação :

Voce está definindo o oscilador como HS, mas está usando um cristal de 4MHz.

Não deveria definir como XT ?

+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor __JEREK__ » 31 Out 2006 08:17

Oi Andre, blz??

é que antes eu não estava definindo nenhum fuse, não funcionava ai tentei testar os fuses um a um para ver se era alguma coisa que estava fazendo resetar tipo watchdog, cristal (no desesper hehehe). acabei postando sem apagar essa parte mas o programa esta funcionando sem fuse, nesse exemplo eu realmente esqueci de apagar.

será que tenho que colocar fuse?? deveria funcionar sem fuse não é??

obrigado!!!
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor andre_luis » 31 Out 2006 10:17

Poisé rapaz, nem sei qual é o default...

Mas, olha, a minha opiniao a respeito dessas bibliotecas da microchip, é que elas são lentas, e as vezes travam outros processos. Eu sugiro que voce tente implementar essa funcao, mas com a filosofia 'multitarefa', ou seja, não fica muito tempo dentro da mesma rotina.

Eu digo isso, pois já resolvi um problema de envio de strings, criando minha propria funcao, à base de putc().

+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor __JEREK__ » 31 Out 2006 12:24

andre_teprom escreveu:Eu digo isso, pois já resolvi um problema de envio de strings, criando minha propria funcao, à base de putc().


Ei andré, eu lembro que você falou isso no outro forum, quando eu perguntei a primeira vez

andre_teprom escreveu: Esse get_string() não é função da bibioteca STRING, entao nao da pra avaliar sem ver a implementacao desta funcao. Suponho que voce utilize nela o getc()...correto ?

Outra dica: Eu nao uso printf(); na verdade eu criei uma função com putc() intercalados por delay() de alguns milisegundos. Só assim funciona confiavel 100% das vezes.

Pode ser que esteja ocorrendo algo parecido na entrada de dados, como um problema de Debounce, onde o get_string() esteja recebendo o mesmo dado mais de 1 vez.


foi nesse post:
http://www.asm51.eng.br/forum/topic.asp?ARCHIVE=&whichpage=1&TOPIC_ID=14284

vou ver o que mais da para testar com putc() e implementar algo na "unha", se alguem tiver mais alguma dica eu agradeço!!!
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor otavio luiz » 31 Out 2006 12:44

Só uma idéia de bobo, essa função que voce usa, não utiliza o hadware do pic para fazer a comunicação né, se não me engano, ela é implementa por software voce pode então mudar o pino de entrada do pic que esta usando. Explicando quando um caracter é recebido, o hardware pode estar gerando erroneamente uma int mas voce não tem trata int mas mesmo assim é enviado para o vetor de reset e o prog para e reinicializa. Acho que vale a pena tentar outra coisa, voce não tem cristal de 20mhz?
Lembre-se, zona de Fresnel não é nenhuma franquia de puteiro.
Avatar do usuário
otavio luiz
Byte
 
Mensagens: 257
Registrado em: 11 Out 2006 13:56
Localização: Barretos - SP, terra de Peão

Mensagempor __JEREK__ » 31 Out 2006 14:32

OI Otávio, sim a função é por software (eu acho).

Realmente eu não tinha usado outro pino porque estou usando uma placa daquelas que já vem para programar e testar, mas vou dar um jeito de fazer como sugerio. O cristal eu só tenho de 4MHz, realmente o programa original é em 20MHz. Você acha que faz diferênça???

Valeu Otavio, obrigado pela dica!!!
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor __JEREK__ » 01 Nov 2006 10:12

tentei fazer um novo programa utilizando a função getc() ou getchar() para saber de pelo menos caracter por caracter ele consegue receber mas mesmo assim não tive sucesso. O programa sai do loop while e envia a mensagem inicial do programa, o que indica que o PIC esta resetando de alguma forma.

Tentei usar RESTART_WDT no rs232 mas tambem não fez efeito.

Código: Selecionar todos
#include <16F876.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
//#fuses XT,NOLVP,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,RESTART_WDT)  // Jumpers: 8 to 11, 7 to 12

short int conta=0;

void main()
{
   char teste='@';
   
   printf("\n\r+------------------------------------------------------------------+");
   printf("\n\rTeste de RS232 N003");

   do {
        printf("\r\nValor atual: %c\r\n",teste);
      delay_ms(250);
          printf("\n\rAperte uma letra: ");
   
      teste = getc();
   
      delay_ms(250);
          printf("\r\nA letra foi %c\r\n",teste);
      delay_ms(250);
   
     } while(1);
}



A figura abaixo mostra o que esta acontecendo, quando eu aperto a letra 2 ou 3 vezes o PIC envia a mensagem inicial que esta antes do laço while.

Imagem

Aceito sugestões!!! :roll: :roll: :roll:
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor andre_luis » 01 Nov 2006 10:18

Este delay de 250ms, não é muito alto não ?
Nao poderia ser na faixa de alguns milisegundos ?
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor __JEREK__ » 01 Nov 2006 10:43

Oi andre, sim esta alto, é que estava tentando colocar varios delays para ver se era o tempo que estava muito curto.

Quando coloquei delay_ms(5); parece que dá menos erros, tipo reseta a cada 5 letras digitadas, ai fui aumentando...

acabei esquecendo em 250, mas mesmo com valores como 1, 5, 7, 10 ainda reseta o PIC.

Valeu!!!
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor Jorge_Francisco » 01 Nov 2006 10:53

Se está configurado NOWDT pra que colocar RESTART_WDT?
Coloque:

#use rs232(baud=38400 ,xmit=pin_c6,rcv=pin_c7).


Acho que não resolve,seu problema deve estar em algum ruido,sei lá.Mais tarde escrevo um programa aqui!!!
Avatar do usuário
Jorge_Francisco
Dword
 
Mensagens: 1009
Registrado em: 12 Out 2006 09:53
Localização: Rio de Janeiro

Próximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x