Autor Tema: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232  (Leído 25849 veces)

0 Usuarios y 4 Visitantes están viendo este tema.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #15 en: 03 de Diciembre de 2010, 17:10:04 »
Gracias de nuevo.

Entonces si tengo algun bit que me avise cuando.. por ejemplo se acaba la conversion:
if( ADIF==1). Esto puedo tratarlo sin interrupciones no? tal y como hago a continuacion.

No se si te refieres a eso. Si es por la parte que pone "Using interruptions" esta entre /* */ como comentario.

  Las interrupciones las estás habilitando cuando pones GIE = 1; (Global Interrupt Enable);

  Claro, podés usar cualquier flag IF (ya sea ADIF, para el caso del conversor) o (SSPIF para el caso de SPI) sin necesidad de habilitar las interrupciones.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #16 en: 03 de Diciembre de 2010, 19:01:52 »
Gracias, arreglado! He seguido haciendo cosas y he separado los "setups" de las funciones leer, asi mucho mas claro. He retocado sobretodo la funcion del pot, juntando ADRESH y ADRESL en un mismo buffer. Pero me siguen saliendo errores...

-En el setup_adc el bit GO(GO =1, A/D conversion in progress) no me lo reconoce.. no se el porque.
-En el ejemplo de antes he visto que SSPBUF era un caracter, porque lo asignaba a la variable lectura, declarada como caracter ( Lo he cambiado pues)
- Las funciones para tx por el puerto rs232 no se si ya corren y si esta bien como le paso el parametro:

   UsartWriteText(&valor_potenciometro);
   UsartWriteText(&valor_sensor_temperatura);

Adjunto el codigo a continuacion. Gracias de antemano.
Código: [Seleccionar]
#include <htc.h>



/* =================================================================================
Definitions
    ================================================================================= */
#define PORTBIT(adr, bit) ( (unsigned)(&adr)*8 + (bit) )

#define Idle_Low 1 // No envia datos
#define Idle_High 2 // Envia datos

#define true 1
#define false 0

#define BAUD  9600 // Configuramos la velocidad, tanto puede ser 19200 o de 9600 kbaud/s pero hay q cambiarlo tb en la simulacion de proteus
#define PIC_CLK 4000000 // Clock de 4MHz (Cristal)

/* =================================================================================
Function prototypes
    ================================================================================= */
static void interrupt service_routine (void); // This is the interrupt service routine

void init_system (void);
void time_delay (unsigned int );
char output_logic(void);
char future_state_logic(void);

void setup_sensor(void);
void setup_adc(void);
void serial_setup(void);

void UsartWriteText(const unsigned char *txt);
void UsartWriteChar(unsigned char ch);
unsigned char getch(void);
unsigned char UsartReadChar_nonstop(void);
unsigned char getch_available(void);
void clear_usart_errors(void);
unsigned char read_spi (void);
unsigned char read_adc(void);



/* =================================================================================
Global variables 
  ================================================================================= */
static bit potenciometro @ PORTBIT(PORTA, 0); // Declaración del potenciometro
static bit sensor_temperatura @ PORTBIT(PORTB, 0);
//static bit sensor_datos_salida @ PORTBIT(PORTC, 7);  // SD0 disabled in master mode (configuración como entrada)
static bit LED @ PORTBIT(PORTB, 1);


static char present_state = Idle_Low; // state variable
static char future_state = Idle_Low; // state variable

static unsigned int valor_potenciometro;
char valor_sensor_temperatura;

static unsigned char caracter_recibido;

unsigned char dummy;
static unsigned int palabra_low;
static unsigned int palabra_high;

/* =================================================================================
Main function
  ================================================================================= */
void main(void){

valor_potenciometro=0;
valor_sensor_temperatura=0;
LED = 0;

init_system ();

setup_sensor();
setup_adc();
serial_setup();


while(1) {

valor_sensor_temperatura=read_spi(); // Las pongo aqui porque es donde hago la lectura de los datos.
valor_potenciometro=read_adc();

output_logic();
future_state_logic();
}

}

/* =================================================================================
Function definitions
  ================================================================================= */

//*****************************************************************************
//Future_state_logic routine
//*****************************************************************************
char future_state_logic(void){

char error = 0;

switch (present_state) {
case Idle_Low:
if ((valor_sensor_temperatura<20)||(valor_potenciometro<25)){ // Menor de 20ºC o la resistencia menos a 25Kohms
future_state = Idle_High;
}
else if (getch_available()==true) // Si hay un caracter disponible recibido por el puerto serie.
{
caracter_recibido=getch();
if(caracter_recibido=='a')
{
future_state = Idle_High;
LED=1;
error=0;
}
else{
future_state=Idle_Low;
LED=0;
error=1;
}
}

break;

case Idle_High:
if (TXIF==0){ // Buffer de transmision vacio
future_state = Idle_Low;
}
else{
error=1;
}
break;


default:
error = 1;
}
return (error);
}

//*****************************************************************************
//Output logic routine
//*****************************************************************************
char output_logic(void){
unsigned char error = 1;


switch (present_state) {

case Idle_Low:
LED = 0;
error = 0;
break;

case Idle_High:
if((valor_sensor_temperatura<20)||(valor_potenciometro<25))
{
UsartWriteText(&valor_potenciometro);
UsartWriteText(&valor_sensor_temperatura);
LED=1;
error=0;
}
else if (getch_available()==true) // Si hay un caracter disponible recibido por el puerto serie.
{
caracter_recibido=getch();
if(caracter_recibido=='a')
{
UsartWriteText(&valor_potenciometro);
UsartWriteText(&valor_sensor_temperatura);
LED=1;
error=0;
}
else
LED=0;
error=1;
}
else
error=1;
LED=0;

break;


default:
error = 1;
LED=0;
break;
}

return (error);
}

//*****************************************************************************
//Init operations 
//*****************************************************************************
void init_system (void)
{

TRISB=1; //LED. Todos los pines se comportaran como salidas menos RB0 2^0=1
TRISA=32; // SS( Select Slave) must have TRISA<5> bit set
TRISB=1; // SDI. El bit 0 a 1.Configurado en master mode (bit 1 cleared, en mode slave bit 1 set)
TRISC=128; // SDO. Tots els bits a 1 menys la sortida 7

}


//*****************************************************************************
//Time delay routine.   
//*****************************************************************************
void time_delay(unsigned int delay){

unsigned int i;
for(i = 0; i <= delay ;i++){
NOP();
}
}

//*****************************************************************************
// SERIAL SETUP 
//*****************************************************************************
void serial_setup(void){
#define SPBRG_VALUE ((PIC_CLK/(16UL*BAUD)) -1)


BRGH = 1;
BRG16 = 0;
SPBRG = SPBRG_VALUE;

SPEN=1; // Enable serial port
SYNC=0; // Asincrono

TXIE=0; // Desactivar interrupciones en tx
TXEN=1; // Enable the transmitter
TX9=0; // 8 bits transmission

RCIE=1; // Activar interrupciones en rx
RX9=0; // 8 bits reception
CREN=1; //Enable reception


#define clear_usart_errors_inline \
if (OERR)
{
TXEN=0; \
TXEN=1; \
CREN=0; \
CREN=1; \
}
if (FERR) \
{
dummy=RCREG; \
TXEN=0; \
TXEN=1; \
}

}


//*****************************************************************************
// Enviar datos ( un caracter)
//*****************************************************************************

void UsartWriteChar(unsigned char ch) {
   
while(TXIF!=0) // 0 = The EUSART transmit buffer is full
      continue;
TXREG = ch;

}
//*****************************************************************************
// Enviar datos (un buffer)
//*****************************************************************************
void UsartWriteText(const unsigned char *txt){

unsigned char i = 0;
while(txt[i]!='\0') {
UsartWriteChar(txt[i]);
i++;
}

}

//*****************************************************************************
//Leer datos ( un caracter)
//*****************************************************************************

unsigned char getch(void)
{
while(RCIF!=1){ //1 = The EUSART receive buffer, RCREG, is full
CLRWDT();
clear_usart_errors_inline;
}
return RCREG;
}

//*****************************************************************************
//Leer datos (un buffer)
//*****************************************************************************
unsigned char UsartReadChar_nonstop(void) {

if(!PIR1bits.RCIF) // TRMT1 is set when TSR is empty
      return 0;   

    return RCREG;
}


//*****************************************************************************
//Comprueba si aun faltan datos o no
//*****************************************************************************
unsigned char getch_available(void)
{
if(RCIF)
return true;
else
return false;
}


//*****************************************************************************
//Errores USART
//*****************************************************************************
void clear_usart_errors(void)
{
clear_usart_errors_inline;
}


//*****************************************************************************
//Leer entradas.
//*****************************************************************************

//*****************************************************************************
//Leer bytes recibidos del bus del modulo SPI
//*****************************************************************************

void setup_sensor(void)  // SPI Master mode:
{

SSPEN=1;    //Enables serial port and configures SCK, SDO, SDI and SS as serial port pins
BF=0;        //Receive not complete, SSPBUF is empty

//SCK is the clock output (Master Mode)
//Clock Polarity(Idle state of SCK)

SMP=1;      //Input data sampled at end of data output time
CKE=0;      //Transmit occurs on transition from Idle to active clock state

SSPM3=0;
SSPM2=0; //SPI Master mode, clock = FOSC/4
SSPM1=0;
SSPM0=0;

CKP=0; //Idle state for clock is a low level

SSPIF=0;   

}


void setup_adc(void)
{

ADCON1=14; // PCFG3=1,PCFG2=1,PCFG1=1,PCFG0=0. Todas las entradas digitales


CHS3=0;
CHS2=0; // Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
CHS1=0;
CHS0=0;

//Tiempo de adquisicion
ACQT2=0;
ACQT1=0;  // 2Tad (Tad=1us) Por tanto 2x1us =2us >= 1.65us( Tacq calculado teoricamente)
ACQT0=1;

ADCS2=1;
ADCS1=0;       // Idem a 4Tosc. 4*Tosc(1us) es el primer valor que hace que sea superior a 0.7us( el minimo)
ADCS0=0;


ADON=1; // A/D converter module is enabled

/* Configure A/D interrupt*/
ADIF=0;
ADIE=1;

//SALE ERROR EN ESTA INSTRUCCION Y EL BIT EXISTE!
//GO = 1; // A/D conversion in progress


}

//*****************************************************************************
//Leer entradas.
//*****************************************************************************

//*****************************************************************************
//LEER DATOS SENSOR
//*****************************************************************************
unsigned char read_spi (void)
{
if((BF==1)&&(SSPIF==1)){ //Receive complete, SSPBUF is full && The transmission/reception is complete (must be cleared in software)
SSPIF=0; ////Waiting to transmit/receive
BF=0;
return SSPBUF;
}
}

//*****************************************************************************
//LEER DATOS POTENCIOMETRO
//*****************************************************************************
unsigned char read_adc(void)
{
char buf[15];
int i=0;
int j=0;
int cont=0;

if( ADIF==1){ //An A/D conversion completed (must be cleared in software)
palabra_low= ADRESL;
palabra_high=ADRESH;
ADIF=0;
}   

for(i=0,i=7,i++)
{

if(palabra_low & 2^i)
buf[i] = '1';
else
    buf[i] = '0';
cont++;

if(cont==8)
j=8;
 
}               
             
for(j=8,j=15,j++)
{

if(palabra_high & 2^j)
buf[j] = '1';
else
  buf[j] = '0';
               
}   
return buf;
}

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #17 en: 03 de Diciembre de 2010, 21:05:33 »
Gracias, arreglado! He seguido haciendo cosas y he separado los "setups" de las funciones leer, asi mucho mas claro. He retocado sobretodo la funcion del pot, juntando ADRESH y ADRESL en un mismo buffer. Pero me siguen saliendo errores...

-En el setup_adc el bit GO(GO =1, A/D conversion in progress) no me lo reconoce.. no se el porque.


  En la versión que tengo yo (Hitech PIC18 9.51PL2 linux) este bit se llama GODONE. Para saber esto vas a tener que buscar el archivo de definiciones que tenga tu versión. En mi caso busqué en la carpeta "include" el archivo "pic18f4550.h"


-En el ejemplo de antes he visto que SSPBUF era un caracter, porque lo asignaba a la variable lectura, declarada como caracter ( Lo he cambiado pues)
- Las funciones para tx por el puerto rs232 no se si ya corren y si esta bien como le paso el parametro:

   UsartWriteText(&valor_potenciometro);
   UsartWriteText(&valor_sensor_temperatura);


  Yo para enviar sólo un char me hice la función putch(); y para enviar un string hice putst(); El uso que le doy es como te muestro a continuación

Código: C
  1. void main (void)
  2. {
  3.   unsigned char dato = 50;
  4.   unsigned char * palabra = "HOLA";
  5.  
  6.   putch(48);
  7.   putch('A');
  8.   putch(dato);
  9.  
  10.   putst("Hola Mundo");
  11.   putst(palabra)
  12. }
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #18 en: 04 de Diciembre de 2010, 12:58:37 »
He seguido toqueteando cosas. Gracias por el aporte anterior.

- Primero de todo, he visto que el bit GO/DONE  tal y como decias era GODONE=1; Lo he puesto pero me tira un warning: unused label "GODONE"

- He arreglado la funcion read_adc y me sale el error "illegal conversion of pointer to integer"

- En ambas funciones read_adc y read_sensor ---> illegal conversion of integer to pointer. No se porque no va! se queja con char y con int!


- En la funcion  char output_logic(void) hay cuando hago:  if((valor_sensor_temperatura<20)||(valor_potenciometro<25)) ya que 25 es un int y los dos valores son unsigned char.Transformo el valor del sensor o del pot a ASCII?

- En la funcion read_spi me tira un error "return at end of non-void function". Como retorno el caracter leido sino es con un return?

- Por ultimo la funcion putst.. no entiendo bien el codigo... no se porque hace if(*str==13) o if(*str==10). Creo que a mi estas lineas me sobran.

Adjunto el codigo, gracias de antemano:

Código: [Seleccionar]
#include <htc.h>

/* =================================================================================
Definitions
    ================================================================================= */
#define PORTBIT(adr, bit) ( (unsigned)(&adr)*8 + (bit) )

#define Idle_Low 1 // No envia datos
#define Idle_High 2 // Envia datos

#define true 1
#define false 0

#define BAUD  9600 // Configuramos la velocidad, tanto puede ser 19200 o de 9600 kbaud/s pero hay q cambiarlo tb en la simulacion de proteus
#define PIC_CLK 4000000 // Clock de 4MHz (Cristal)

/* =================================================================================
Function prototypes
    ================================================================================= */
static void interrupt service_routine (void); // This is the interrupt service routine

void init_system (void);
void time_delay (unsigned int );
char output_logic(void);
char future_state_logic(void);

void setup_sensor(void);
void setup_adc(void);
void serial_setup(void);

void putst(register const char *str);
void putch(unsigned char c);

unsigned char getch(void);
unsigned char UsartReadChar_nonstop(void);
unsigned char getch_available(void);
void clear_usart_errors(void);

unsigned char read_spi (void);
unsigned char read_adc(void);



/* =================================================================================
Global variables 
  ================================================================================= */
static bit potenciometro @ PORTBIT(PORTA, 0); // Declaración del potenciometro
static bit sensor_temperatura @ PORTBIT(PORTB, 0);
//static bit sensor_datos_salida @ PORTBIT(PORTC, 7);  // SD0 disabled in master mode (configuración como entrada)
static bit LED @ PORTBIT(PORTB, 1);


static char present_state = Idle_Low; // state variable
static char future_state = Idle_Low; // state variable

unsigned char * valor_potenciometro;
unsigned char * valor_sensor_temperatura;

unsigned char * buffer;

unsigned char high_result;
unsigned char low_result;

static unsigned char caracter_recibido;

unsigned char dummy;


/* =================================================================================
Main function
  ================================================================================= */
void main(void){

valor_potenciometro=0;
valor_sensor_temperatura=0;
LED = 0;

init_system ();

setup_sensor();
setup_adc();
serial_setup();


while(1) {

valor_sensor_temperatura=read_spi(); // Las pongo aqui porque es donde hago la lectura de los datos.
valor_potenciometro=read_adc();

output_logic();
future_state_logic();
}

}

/* =================================================================================
Function definitions
  ================================================================================= */

//*****************************************************************************
//Future_state_logic routine
//*****************************************************************************
char future_state_logic(void){

char error = 0;

switch (present_state) {
case Idle_Low:
if ((valor_sensor_temperatura<20)||(valor_potenciometro<25)){ // Menor de 20ºC o la resistencia menos a 25Kohms
future_state = Idle_High;
}
else if (getch_available()==true) // Si hay un caracter disponible recibido por el puerto serie.
{
caracter_recibido=getch();
if(caracter_recibido=='a')
{
future_state = Idle_High;
LED=1;
error=0;
}
else{
future_state=Idle_Low;
LED=0;
error=1;
}
}

break;

case Idle_High:
if (TXIF==0){ // Buffer de transmision vacio
future_state = Idle_Low;
}
else{
error=1;
}
break;


default:
error = 1;
}
return (error);
}

//*****************************************************************************
//Output logic routine
//*****************************************************************************
char output_logic(void){
unsigned char error = 1;


switch (present_state) {

case Idle_Low:
LED = 0;
error = 0;
break;

case Idle_High:
if((valor_sensor_temperatura<20)||(valor_potenciometro<25))
{

putst(valor_potenciometro);
putst(valor_sensor_temperatura);


LED=1;
error=0;
}
else if (getch_available()==true) // Si hay un caracter disponible recibido por el puerto serie.
{
caracter_recibido=getch();
if(caracter_recibido=='a')
{
putst(valor_potenciometro);
putst(valor_sensor_temperatura);
LED=1;
error=0;
}
else
LED=0;
error=1;
}
// else
error=1;
LED=0;

break;


default:
error = 1;
LED=0;
break;
}

return (error);
}

//*****************************************************************************
//Init operations 
//*****************************************************************************
void init_system (void)
{

TRISB=1; //LED. Todos los pines se comportaran como salidas menos RB0 2^0=1
TRISA=32; // SS( Select Slave) must have TRISA<5> bit set
TRISB=1; // SDI. El bit 0 a 1.Configurado en master mode (bit 1 cleared, en mode slave bit 1 set)
TRISC=128; // SDO. Tots els bits a 1 menys la sortida 7

}


//*****************************************************************************
//Time delay routine.   
//*****************************************************************************
void time_delay(unsigned int delay){

unsigned int i;
for(i = 0; i <= delay ;i++){
NOP();
}
}

//*****************************************************************************
// SERIAL SETUP 
//*****************************************************************************
void serial_setup(void){
#define SPBRG_VALUE ((PIC_CLK/(16UL*BAUD)) -1)


BRGH = 1;
BRG16 = 0;
SPBRG = SPBRG_VALUE;

SPEN=1; // Enable serial port
SYNC=0; // Asincrono

TXIE=0; // Desactivar interrupciones en tx
TXEN=1; // Enable the transmitter
TX9=0; // 8 bits transmission

RCIE=1; // Activar interrupciones en rx
RX9=0; // 8 bits reception
CREN=1; //Enable reception


#define clear_usart_errors_inline \
if (OERR)
{
TXEN=0; \
TXEN=1; \
CREN=0; \
CREN=1; \
}
if (FERR) \
{
dummy=RCREG; \
TXEN=0; \
TXEN=1; \
}

}


//*****************************************************************************
// Enviar datos ( un caracter)
//*****************************************************************************

void putch(unsigned char c)
{
while(!TXIF){
clear_usart_errors_inline;
CLRWDT();
}
TXREG=c;

}
//*****************************************************************************
// Enviar datos (un buffer)
//*****************************************************************************
void putst(register const char *str)
{
while((*str)!=0)
{
putch(*str);
if(*str==13)
putch(10);

if(*str==10)
putch(13);
str++;
}

}





//*****************************************************************************
//Leer datos ( un caracter)
//*****************************************************************************

unsigned char getch(void)
{
while(RCIF!=1){ //1 = The EUSART receive buffer, RCREG, is full
CLRWDT();
clear_usart_errors_inline;
}
return RCREG;
}

//*****************************************************************************
//Leer datos (un buffer)
//*****************************************************************************
unsigned char UsartReadChar_nonstop(void) {

if(!PIR1bits.RCIF) // TRMT1 is set when TSR is empty
      return 0;   

    return RCREG;
}


//*****************************************************************************
//Comprueba si aun faltan datos o no
//*****************************************************************************
unsigned char getch_available(void)
{
if(RCIF)
return true;
else
return false;
}


//*****************************************************************************
//Errores USART
//*****************************************************************************
void clear_usart_errors(void)
{
clear_usart_errors_inline;
}


//*****************************************************************************
//Leer entradas.
//*****************************************************************************

//*****************************************************************************
//Leer bytes recibidos del bus del modulo SPI
//*****************************************************************************

void setup_sensor(void)  // SPI Master mode:
{

SSPEN=1;    //Enables serial port and configures SCK, SDO, SDI and SS as serial port pins
BF=0;        //Receive not complete, SSPBUF is empty

//SCK is the clock output (Master Mode)
//Clock Polarity(Idle state of SCK)

SMP=1;      //Input data sampled at end of data output time
CKE=0;      //Transmit occurs on transition from Idle to active clock state

SSPM3=0;
SSPM2=0; //SPI Master mode, clock = FOSC/4
SSPM1=0;
SSPM0=0;

CKP=0; //Idle state for clock is a low level

SSPIF=0;   

}


void setup_adc(void)
{

ADCON1=14; // PCFG3=1,PCFG2=1,PCFG1=1,PCFG0=0. Todas las entradas digitales


CHS3=0;
CHS2=0; // Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
CHS1=0;
CHS0=0;

//Tiempo de adquisicion
ACQT2=0;
ACQT1=0;  // 2Tad (Tad=1us) Por tanto 2x1us =2us >= 1.65us( Tacq calculado teoricamente)
ACQT0=1;

ADCS2=1;
ADCS1=0;       // Idem a 4Tosc. 4*Tosc(1us) es el primer valor que hace que sea superior a 0.7us( el minimo)
ADCS0=0;


ADON=1; // A/D converter module is enabled

/* Configure A/D interrupt*/
ADIF=0;
ADIE=1;



}

//*****************************************************************************
//Leer entradas.
//*****************************************************************************

//*****************************************************************************
//LEER DATOS SENSOR
//*****************************************************************************
unsigned char read_spi (void)
{
if((BF==1)&&(SSPIF==1)){ //Receive complete, SSPBUF is full && The transmission/reception is complete (must be cleared in software)
SSPIF=0; ////Waiting to transmit/receive
BF=0;

}
return SSPBUF;
}

//*****************************************************************************
//LEER DATOS POTENCIOMETRO
//*****************************************************************************



unsigned char read_adc(void)
{

GODONE=1; //A/D conversion in progress

if( ADIF==1){ //An A/D conversion completed (must be cleared in software)
buffer = ADRESH<<8;
buffer = buffer+ADRESL;
ADIF=0;
}   

return buffer;
}
 
« Última modificación: 04 de Diciembre de 2010, 13:18:35 por edu1989 »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #19 en: 04 de Diciembre de 2010, 13:59:17 »
Compilé el programa y voy a tratar de detallar un poco los warning, solo que me va a llevar un tiempo, de hecho estoy escribiendo esto mientras tengo el entorno de programación abierto.


- En la funcion read_spi me tira un error "return at end of non-void function". Como retorno el caracter leido sino es con un return?

- Por ultimo la funcion putst.. no entiendo bien el codigo... no se porque hace if(*str==13) o if(*str==10). Creo que a mi estas lineas me sobran.


  En el caso de la función read_spi te emite un warning porque el return lo tenés puesto dentro del if. Si por algún motivo no se cumple dicha condición en tu función salís sin retornar nada y eso no puede ser ya que tu función tiene que devolver algo. Se puede solucionar poniendo el return fuera del if o sino agregando, por ejemplo, return 0 y que quede fuera del if.

algo asi...
Código: C
  1. unsigned char read_spi (void)
  2. {
  3.   if((BF==1)&&(SSPIF==1))
  4.   {                             //Receive complete, SSPBUF is full && The transmission/reception is complete  (must be cleared in software)
  5.     SSPIF=0; ////Waiting to transmit/receive
  6.     BF=0;
  7.     return SSPBUF;
  8.   }
  9.   return 0;         // este es el agregado para que no emita el warning, sino dejas aca el return SSPBUF
  10. }

  En el caso de la función putst, esos if están para detectar el "salto de línea" y al "retroceso de carro". O sea, para enviar como si fuera un "Enter"



- Primero de todo, he visto que el bit GO/DONE  tal y como decias era GODONE=1; Lo he puesto pero me tira un warning: unused label "GODONE"

- He arreglado la funcion read_adc y me sale el error "illegal conversion of pointer to integer"

- En ambas funciones read_adc y read_sensor ---> illegal conversion of integer to pointer. No se porque no va! se queja con char y con int!


  Respecto al GODONE, a mi no me emite ningún error;

  read_spi() devuelve char así que la variable que vayas a usar en la lectura de spi tiene que estar definida como char o unsigned char; tu error es que "valor_sensor_temperatura" lo tenés definido como puntero a char.
  Lo mismo vale para read_adc();


  Después de haber corregido lo anterior sigue habiendo errores. Uno es que superaste el tamaño del array. Cuando definís un array tené en cuenta que entre corchetes "[" y "]" va la cantidad de elementos del array, pero cuando usas una variable definida como array, entre los corchetes va el índice comenzando por 0 y no por 1.
Así, una variable definida como "char variable[15]" tiene 15 elementos que van desde vairable[0] hasta variable[14].

  También sigue habiendo errores de "Illegal conversion of integer to pointer" y es porque tenés definido a buf[15] como un puntero a char. Pero está variable no la podés escribir de la forma buf
  • = x. Nunca se puede escribir un puntero de esa forma.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #20 en: 04 de Diciembre de 2010, 23:16:13 »
  En los 16F usaba la función ITOA "Tnteger To ASCII" para poder pasar un número entero a su representación en texto. Esto es, por ejemplo, para un valor de 128 tener un string "128" y así poder usar la función putst y enviarlos por el RS232.
  Según el manual del PIC18 también tendría que tener dicha función pero no la pude encontrar, así que copie el código desde el compilador para los 16F y cambié tu programa para hacer uso de dicha función y ahora, simulado en proteus, estoy enviando el valor del pote. No hago la lectura del sensor porque el proteus no tiene dicho integrado.
  También cambié la rutina read_ADC que habías hecho porque le habías dejado un loop infinito.
  También cambié tu función "Future_state_logic()" ya que dentro de ella cambiabas la variable "future_state", pero nunca se le asignaba el nuevo valor a "present_state"

 mi versión de tu programa

Código: C
  1. #include <htc.h>
  2. //#include <stdlib.h>  // para poder usar la funcion itoa
  3.  
  4. #include "itoa.c"
  5.  
  6. /*      =================================================================================
  7.         Definitions
  8.         ================================================================================= */
  9. #define         PORTBIT(adr, bit) ( (unsigned)(&adr)*8 + (bit) )
  10.  
  11. #define         Idle_Low 1      // No envia datos
  12. #define         Idle_High 2 // Envia datos
  13.  
  14. #define true 1
  15. #define false 0
  16.  
  17. #define BAUD  9600                      // Configuramos la velocidad, tanto puede ser 19200 o de 9600 kbaud/s pero hay q cambiarlo tb en la simulacion de proteus      
  18. #define PIC_CLK 4000000         // Clock de 4MHz (Cristal)
  19.  
  20. /*      =================================================================================
  21.         Function prototypes
  22.         ================================================================================= */
  23. static void interrupt service_routine (void);   // This is the interrupt service routine
  24.  
  25. void init_system (void);
  26. void time_delay (unsigned int );
  27. char output_logic(void);
  28. char future_state_logic(void);
  29.  
  30. void setup_sensor(void);
  31. void setup_adc(void);
  32. void serial_setup(void);
  33.  
  34. void putst(register const char *str);
  35. void putch(unsigned char c);
  36.  
  37. unsigned char getch(void);
  38. unsigned char UsartReadChar_nonstop(void);
  39. unsigned char getch_available(void);
  40. void clear_usart_errors(void);
  41.  
  42. unsigned char read_spi (void);
  43. unsigned char read_adc(void);
  44.  
  45.  
  46.  
  47. /*      =================================================================================
  48.         Global variables  
  49.         ================================================================================= */
  50. static bit potenciometro @ PORTBIT(PORTA, 0);   // Declaración del potenciometro
  51. static bit sensor_temperatura @ PORTBIT(PORTB, 0);
  52. //static bit sensor_datos_salida @ PORTBIT(PORTC, 7);  // SD0 disabled in master mode (configuración como entrada)
  53. static bit LED @ PORTBIT(PORTB, 1);    
  54.  
  55.                                
  56. static char present_state = Idle_Low;           // state variable
  57. static char future_state = Idle_Low;            // state variable
  58.  
  59. unsigned char  valor_potenciometro;
  60. unsigned char  valor_sensor_temperatura;
  61.  
  62. unsigned char  buf[16];
  63.  
  64.  
  65. char * valor_pote_en_texto;           // un puntero para almacenar el numero en texto
  66. char * valor_sensor_en_texto;         // un puntero para almacenar el numero en texto
  67.  
  68. unsigned char high_result;
  69. unsigned char low_result;
  70.  
  71. static unsigned char caracter_recibido;
  72.  
  73. unsigned char dummy;
  74.  
  75.  
  76. /*      =================================================================================
  77.         Main function
  78.         ================================================================================= */
  79. void main(void)
  80. {
  81.   valor_potenciometro = 0;
  82.   valor_sensor_temperatura = 0;
  83.   LED = 0;     
  84.   init_system();
  85.   setup_sensor();
  86.   setup_adc();
  87.   serial_setup();      
  88.   while(1)
  89.   {
  90.     //valor_sensor_temperatura = read_spi();    // Las pongo aqui porque es donde hago la lectura de los datos.
  91.     valor_potenciometro = read_adc();
  92.    
  93.     valor_pote_en_texto = itoa (buf, valor_potenciometro, 10);
  94.  //   valor_sensor_en_texto = itoa (buf, valor_sensor_temperatura, 10);
  95.  
  96.     output_logic();
  97.     future_state_logic();
  98.   }            
  99. }      
  100.  
  101. /*      =================================================================================
  102.         Function definitions
  103.         ================================================================================= */
  104.  
  105. //*****************************************************************************
  106. //Future_state_logic routine
  107. //*****************************************************************************
  108. char future_state_logic(void)
  109. {
  110.   char error = 0;
  111.   switch (present_state)
  112.   {
  113.     case Idle_Low:                             
  114.                   if ((valor_sensor_temperatura < 20) || (valor_potenciometro < 25))
  115.                   { // Menor de 20ºC o la resistencia menos a 25Kohms
  116.                     //future_state = Idle_High;
  117.                     present_state = Idle_High;
  118.                   }
  119.                   else
  120.                   if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
  121.                   {
  122.                     caracter_recibido = getch();
  123.                     if (caracter_recibido == 'a')
  124.                     {
  125.                       //future_state = Idle_High;
  126.                       present_state = Idle_High;
  127.                       LED = 1;
  128.                       error = 0;
  129.                     }
  130.                     else
  131.                     {
  132.                       //future_state = Idle_Low;
  133.                       present_state = Idle_Low;
  134.                       LED = 0;
  135.                       error = 1;
  136.                     }
  137.                   }
  138.                   break;
  139.     case Idle_High:                                            
  140.                    if (TXIF == 0)
  141.                    { // Buffer de transmision vacio
  142.                      //future_state = Idle_Low;
  143.                      present_state = Idle_Low;
  144.                    }
  145.                    else
  146.                    {
  147.                      error = 1;
  148.                    }
  149.                    break;
  150.     default:
  151.                           error = 1;
  152.   }    
  153.   return (error);
  154. }
  155.  
  156. //*****************************************************************************
  157. //Output logic routine
  158. //*****************************************************************************
  159. char output_logic(void)
  160. {
  161.   unsigned char error = 1;
  162.   switch (present_state)
  163.   {
  164.     case Idle_Low:                             
  165.                    LED = 0;
  166.                    error = 0;
  167.                    break;
  168.     case Idle_High:                    
  169.                    if ((valor_sensor_temperatura < 20) || (valor_potenciometro < 25))
  170.                    {
  171.                      putst ("Valor del pote: ");
  172.                      putst (valor_pote_en_texto);
  173.                      putst ("\n");  //cambio de linea
  174.                      putst ("Valor del sensor: ");
  175.                      //putst (valor_sensor_en_texto);
  176.                      putst ("Suponemos un valor de 25 grados");
  177.                      putst ("\n");
  178.                      LED = 1;
  179.                      error = 0;
  180.                     }
  181.                     else
  182.                     if (getch_available() == true)
  183.                    // Si hay un caracter disponible recibido por el puerto serie.
  184.                    {
  185.                      caracter_recibido = getch();
  186.                      if (caracter_recibido == 'a')
  187.                      {
  188.                        putch (valor_potenciometro);
  189.                        putch (valor_sensor_temperatura);
  190.                        LED = 1;
  191.                        error = 0;
  192.                      }
  193.                      else
  194.                        LED = 0;
  195.                      error = 1;
  196.                    }
  197.                    //   else
  198.                    error = 1;
  199.                    LED = 0;    
  200.                    break;
  201.     default:
  202.                    error = 1;
  203.                    LED = 0;
  204.                    break;              
  205.   }
  206.   return (error);
  207. }
  208.  
  209. //*****************************************************************************
  210. //Init operations  
  211. //*****************************************************************************
  212. void init_system (void)
  213. {
  214.   TRISB = 1; //LED. Todos los pines se comportaran como salidas menos RB0 2^0=1
  215.   TRISA = 32; // SS( Select Slave) must have TRISA<5> bit set
  216.   TRISB = 1; // SDI. El bit 0 a 1.Configurado en master mode (bit 1 cleared, en mode slave bit 1 set)
  217.   TRISC = 128; // SDO. Tots els bits a 1 menys la sortida 7
  218. }
  219.  
  220.  
  221. //*****************************************************************************
  222. //Time delay routine.  
  223. //*****************************************************************************
  224. void time_delay(unsigned int delay)
  225. {
  226.   unsigned int i;
  227.        
  228.   for (i = 0; i <= delay; i++)
  229.   {    
  230.     NOP();
  231.   }
  232. }
  233.  
  234. //*****************************************************************************
  235. // SERIAL SETUP  
  236. //*****************************************************************************
  237. void serial_setup(void)
  238. {
  239.   #define SPBRG_VALUE ((PIC_CLK/(16UL*BAUD)) -1)
  240.   BRGH = 1;
  241.   BRG16 = 0;
  242.   SPBRG = SPBRG_VALUE;
  243.   SPEN = 1; // Enable serial port
  244.   SYNC = 0; // Asincrono
  245.   TXIE = 0; // Desactivar interrupciones en tx
  246.   TXEN = 1; // Enable the transmitter
  247.   TX9 = 0; // 8 bits transmission
  248.   RCIE = 1; // Activar interrupciones en rx
  249.   RX9 = 0; // 8 bits reception
  250.   CREN = 1; //Enable reception
  251.   #define clear_usart_errors_inline     if (OERR)\
  252.                                     {\
  253.                                       TXEN = 0;\
  254.                                       TXEN = 1;\
  255.                                       CREN = 0;\
  256.                                       CREN = 1;\
  257.                                     }\
  258.                                     if (FERR)\
  259.                                     {\
  260.                                       dummy = RCREG;\
  261.                                       TXEN = 0;\
  262.                                       TXEN = 1;\
  263.                                     }
  264. }
  265.  
  266.  
  267. //*****************************************************************************
  268. // Enviar datos ( un caracter)
  269. //*****************************************************************************
  270.  
  271. void putch(unsigned char c)
  272. {
  273.   while (!TXIF)
  274.   {
  275.     clear_usart_errors_inline;
  276.     CLRWDT();
  277.   }
  278.   TXREG = c;
  279. }
  280. //*****************************************************************************
  281. // Enviar datos (un buffer)
  282. //*****************************************************************************
  283. void putst(register const char *str)
  284. {
  285.   while ((*str) != 0)
  286.   {
  287.     putch (*str);
  288.     if (*str == 13) putch (10);
  289.     if (*str == 10) putch (13);
  290.     str++;
  291.   }
  292. }
  293.  
  294. //*****************************************************************************
  295. //Leer datos ( un caracter)
  296. //*****************************************************************************
  297.  
  298. unsigned char getch(void)
  299. {
  300.   while (RCIF != 1)
  301.   {                             //1 = The EUSART receive buffer, RCREG, is full
  302.     CLRWDT();
  303.     clear_usart_errors_inline;
  304.   }
  305.   return RCREG;
  306. }
  307.  
  308. //*****************************************************************************
  309. //Leer datos (un buffer)
  310. //*****************************************************************************
  311. unsigned char UsartReadChar_nonstop(void)
  312. {
  313.   if (!RCIF)    // TRMT1 is set when TSR is empty
  314.     return 0;  
  315.   return RCREG;
  316. }
  317.  
  318.  
  319. //*****************************************************************************
  320. //Comprueba si aun faltan datos o no
  321. //*****************************************************************************
  322. unsigned char getch_available(void)
  323. {
  324.   if (RCIF)
  325.     return true;
  326.   else
  327.     return false;
  328. }
  329.  
  330.  
  331. //*****************************************************************************
  332. //Errores USART
  333. //*****************************************************************************
  334. void clear_usart_errors(void)
  335. {
  336.   clear_usart_errors_inline;
  337. }
  338.  
  339.  
  340. //*****************************************************************************
  341. //Leer entradas.
  342. //*****************************************************************************
  343.  
  344. //*****************************************************************************
  345. //Leer bytes recibidos del bus del modulo SPI
  346. //*****************************************************************************
  347.  
  348. void setup_sensor(void)  // SPI Master mode:
  349. {
  350.   SSPEN = 1;            //Enables serial port and configures SCK, SDO, SDI and SS as serial port pins
  351.   BF = 0;                                                               //Receive not complete, SSPBUF is empty
  352.   //SCK is the clock output (Master Mode)
  353.   //Clock Polarity(Idle state of SCK)
  354.   SMP = 1;                                                       //Input data sampled at end of data output time
  355.   CKE = 0;                                                        //Transmit occurs on transition from Idle to active clock state
  356.   SSPM3 = 0;
  357.   SSPM2 = 0;                                                    //SPI Master mode, clock = FOSC/4      
  358.   SSPM1 = 0;
  359.   SSPM0 = 0;
  360.   CKP = 0;                                                              //Idle state for clock is a low level
  361.   SSPIF = 0;                                                   
  362. }
  363.  
  364. void setup_adc(void)
  365. {
  366.   ADCON1 = 14;          // PCFG3=1,PCFG2=1,PCFG1=1,PCFG0=0. Todas las entradas digitales
  367.   CHS3 = 0;
  368.   CHS2 = 0;                     // Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
  369.   CHS1 = 0;
  370.   CHS0 = 0;
  371.   //Tiempo de adquisicion
  372.   ACQT2 = 0;
  373.   ACQT1 = 0;            // 2Tad (Tad=1us) Por tanto 2x1us =2us >= 1.65us( Tacq calculado teoricamente)
  374.   ACQT0 = 1;
  375.   ADCS2 = 1;
  376.   ADCS1 = 0;    // Idem a 4Tosc. 4*Tosc(1us) es el primer valor que hace que sea superior a 0.7us( el minimo)
  377.   ADCS0 = 0;   
  378.   ADON = 1;             // A/D converter module is enabled
  379.   /* Configure A/D interrupt*/
  380.   ADIF = 0;
  381.   ADIE = 1;
  382. }
  383.  
  384. //*****************************************************************************
  385. //Leer entradas.
  386. //*****************************************************************************
  387.  
  388. //*****************************************************************************
  389. //LEER DATOS SENSOR
  390. //*****************************************************************************
  391. unsigned char read_spi (void)
  392. {
  393.   if ((BF == 1) && (SSPIF == 1))
  394.   {     //Receive complete, SSPBUF is full && The transmission/reception is complete (must be cleared in software)
  395.     SSPIF = 0; ////Waiting to transmit/receive
  396.     BF = 0;
  397.     return SSPBUF;
  398.   }
  399.   return 0;
  400. }
  401.  
  402. //*****************************************************************************
  403. //LEER DATOS POTENCIOMETRO
  404. //*****************************************************************************
  405. unsigned char read_adc(void)
  406. {
  407.   //Empezar a leer
  408.   GODONE=1; // A/D conversion in progress
  409.   while (ADIF == 0);
  410.   ADIF = 0;
  411.   return ((ADRESH << 8) + (ADRESL));
  412. }
  413.  
  414.     /*GUARDAR EL CONTENIDO DE HIGH_RESULT EN EL buf*/                
  415.     //Verificar si el bit 0 de high_result es 1 ó 0
  416. /*
  417.     if (high_result & 1) buf[0] = '1';
  418.     else
  419.       buf[0] = '0';
  420.     //Verificar si el bit 1 de high_result es 1 ó 0
  421.     if (high_result & 2) buf[1] = '1';
  422.     else
  423.       buf[1] = '0';
  424.     //Verificar si el bit 2 de high_result es 1 ó 0
  425.     if (high_result & 4) buf[2] = '1';
  426.     else
  427.       buf[2] = '0';
  428.     //Verificar si el bit 3 de high_result es 1 ó 0
  429.     if (high_result & 8) buf[3] = '1';
  430.     else
  431.       buf[3] = '0';
  432.     //Verificar si el bit 4 de high_result es 1 ó 0
  433.     if (high_result & 16) buf[4] = '1';
  434.     else
  435.       buf[4] = '0';
  436.     //Verificar si el bit 5 de high_result es 1 ó 0
  437.     if (high_result & 32) buf[5] = '1';
  438.     else
  439.      buf[5] = '0';
  440.     //Verificar si el bit 6 de high_result es 1 ó 0
  441.     if (high_result & 64) buf[6] = '1';
  442.     else
  443.       buf[6] = '0';
  444.     //Verificar si el bit 7 de high_result es 1 ó 0
  445.     if (high_result & 128) buf[7] = '1';
  446.     else
  447.        buf[7] = '0';
  448.  
  449. /*GUARDAR EL CONTENIDO DE Low_RESULT EN EL buf*/                
  450.              
  451.     //Verificar si el bit 0 de high_result es 1 ó 0
  452. /*
  453.     if (low_result & 1) buf[8] = '1';
  454.     else
  455.       buf[8] = '0';
  456.     //Verificar si el bit 1 de high_result es 1 ó 0
  457.     if(low_result & 2) buf[9] = '1';
  458.     else
  459.       buf[9] = '0';
  460.     //Verificar si el bit 2 de high_result es 1 ó 0
  461.     if (low_result & 4) buf[10] = '1';
  462.     else
  463.       buf[10] = '0';
  464.     //Verificar si el bit 3 de high_result es 1 ó 0
  465.     if (low_result & 8) buf[11] = '1';
  466.     else
  467.       buf[11] = '0';
  468.     //Verificar si el bit 4 de high_result es 1 ó 0
  469.     if (low_result & 16) buf[12] = '1';
  470.     else
  471.       buf[12] = '0';
  472.     //Verificar si el bit 5 de high_result es 1 ó 0
  473.     if (low_result & 32) buf[13] = '1';
  474.     else
  475.       buf[13] = '0';
  476.     //Verificar si el bit 6 de high_result es 1 ó 0
  477.     if (low_result & 64) buf[14] = '1';
  478.     else
  479.       buf[14] = '0';
  480.     //Verificar si el bit 7 de high_result es 1 ó 0
  481.     if(low_result & 128) buf[15] = '1';
  482.     else
  483.       buf[15] = '0';
  484. */

  y esto es el archivo itoa.c, que estoy incluyendo en mi versión del programa

Código: C
  1. #include        <stdlib.h>
  2.  
  3. char * utoa(char * buf, unsigned val, int base)
  4. {
  5.         unsigned        v;
  6.         char            c;
  7.  
  8.         v = val;
  9.         do {
  10.                 v /= base;
  11.                 buf++;
  12.         } while(v != 0);
  13.         *buf-- = 0;
  14.         do {
  15.                 c = val % base;
  16.                 val /= base;
  17.                 if(c >= 10)
  18.                         c += 'A'-'0'-10;
  19.                 c += '0';
  20.                 *buf-- = c;
  21.         } while(val != 0);
  22.         return buf;
  23. }
  24.        
  25. char * itoa(char * buf, int val, int base)
  26. {
  27.         char *  cp = buf;
  28.  
  29.         if(val < 0) {
  30.                 *buf++ = '-';
  31.                 val = -val;
  32.         }
  33.         utoa(buf, val, base);
  34.         return cp;
  35. }
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #21 en: 06 de Diciembre de 2010, 08:39:51 »
Muchisimas gracias, eres muy amable. Te lo agradezco mucho.

He probado el programa y no se que pasa que no puedo añadir el fichero itoa.c, me sale el siguiente error:
function "_utoa" redefined
function "_itoa" redefined

He hecho dos cosas y no han funcionado:
 -Crear un fichero itoa.c y añadirlo  a "Source files" con el codigo que has puesto antes y hacer un itoa.h (que lo añadia a itoa.c) con la declaracion:

Código: [Seleccionar]
char * utoa(char * buf, unsigned val, int base);
char * itoa(char * buf, int val, int base);

- Lo segundo que he hecho ha sido ponerlo todo en el mismo fichero (final.c) definiendo stdlib.h y sigue habiendo un error: conflicting functions...
________________________________________________________________________________________________________________________________

Por otro lado, como has hecho la simulacion de proteus? con el simulador de puerto serie y  el pote conectado y el led conectados al PIC?. El sensor de temperatura tambien aparece (TC77). Igualmente existe un debugger SPI que podria utilitzarlo no? Pongo el debugger o el sensor conectado al PIC?



Al terminal del PIC tambien se le puede escribir? Es que solo prové de recibir bien pero de enviar aun no he probado nada.

Saludoos y gracias de antemano

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #22 en: 06 de Diciembre de 2010, 10:03:38 »
Muchisimas gracias, eres muy amable. Te lo agradezco mucho.

He probado el programa y no se que pasa que no puedo añadir el fichero itoa.c, me sale el siguiente error:
function "_utoa" redefined
function "_itoa" redefined


  Tal vez sea  porque tu versión de compilador ya tenga dichas funciones. Revisa en la carpeta "include" que tiene que estar el archivo "stdlib.h" y mira su contenido a ver si ya tiene definidas ahí las funciones itoa y utoa. En mi caso en dicho archivo no tenía esas funciones.
  Si en tu caso las tiene, con que incluyas dicho archivo a tu código ya deberías poder usar las funciones. Osea, poner
"#include <stdlib.h>"


Por otro lado, como has hecho la simulacion de proteus? con el simulador de puerto serie y  el pote conectado y el led conectados al PIC?. El sensor de temperatura tambien aparece (TC77). Igualmente existe un debugger SPI que podria utilitzarlo no? Pongo el debugger o el sensor conectado al PIC?

Al terminal del PIC tambien se le puede escribir? Es que solo prové de recibir bien pero de enviar aun no he probado nada.


  Como te decía, el sensor no lo simulé porque no tiene dicho integrado. Utilicé el elemento "Virtual Terminal" conectado a los terminales TX y RX para poder ver la transmisión serial. El pote conectado al PIC.

  Gracias a esta prueba también encontré otros errores que corregí (pero me parece que dichas correcciones no están en el programita que te mandé), estos errores eran que tenías el puerto A configurado como salida y para poder usar el conversor AD tenés que configurarlo como entrada (al menos el puerto que quieras usar para el conversor) y también vi que la conversión estaba "justificada a la izquierda", yo ahora la dejé "justificada a la derecha", ésto último está en el datasheet.
 La diferencia entre ambas es la siguiente: para el valor 1111111111  (10 bits, todos en 1)

                ADRESH     ADRESL
izquierda: 11111111    11000000
derecha:   00000011   11111111

  También encontré otro error y es que uso la misma variable buf para convertir tanto el valor del pote como el del sensor y eso está mál. Habría que crear otra variable de similar a buf para usarla al convertir el valor del sensor.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #23 en: 06 de Diciembre de 2010, 10:52:01 »
Gracias de nuevo. He arreglado los errores menos el del justificado. Ese esta en el programita?
He probado la simulacion y me va enviando siempre los dos valores, he cambiado el valor de la resistencia y me va enviado que el valor es 192 siempre. Es un problema debido al justificado? La manera de variar el pot el cambiar la resistencia? recuerdo que habia un botoncito que te permitia cambiarlo durante la simulacion ( creo que era con el proteus.. a lo mejor me confundo de programa)

Por lo que respecta al sensor, lo que quieres decirme es que no lo encuentras en el proteus o que no esta directamente en el PIC? perdona pero no lo he entendido bien.

Edito: Me gustaría probar tambien si cuando envio el caracter a, me envia los datos.. como puedo hacerlo? tendria que conectar otro terminal no?
« Última modificación: 06 de Diciembre de 2010, 10:55:36 por edu1989 »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #24 en: 06 de Diciembre de 2010, 10:57:23 »
Gracias de nuevo. He arreglado los errores menos el del justificado. Ese esta en el programita?
He probado la simulacion y me va enviando siempre los dos valores, he cambiado el valor de la resistencia y me va enviado que el valor es 192 siempre. Es un problema debido al justificado? La manera de variar el pot el cambiar la resistencia? recuerdo que habia un botoncito que te permitia cambiarlo durante la simulacion ( creo que era con el proteus.. a lo mejor me confundo de programa)

Por lo que respecta al sensor, lo que quieres decirme es que no lo encuentras en el proteus o que no esta directamente en el PIC? perdona pero no lo he entendido bien.

  A también me pasaba que me enviaba siempre el mismo dato y por ello cambié el justificado. En la función "setup_adc" agregué ADFM = 1, con eso cambia el justificado.

  Para el pote busqué en resitors --> variable --> y allí algún POT que figure como ACTIVE y con ello te aparece un botoncito con el "+" y otro con el "-" en el pote y justamente con esos botoncitos cambias el valor.
  El sensor no está en el proteus, por eso no lo puedo simular.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #25 en: 06 de Diciembre de 2010, 11:39:39 »
Hombreee! ya funciona! que bieeen, muchisimas gracias!

Para comprobar lo de que cuando recibe un caracter me lo envia, tengo que conectar otro terminal no? En teoria la pata de rx ya esta al otro terminal..tendra que coger esa pata del PIC y conectarla al de tx de mi terminal, si?

Gracias de nuevo, amigo.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #26 en: 06 de Diciembre de 2010, 11:51:42 »
Hombreee! ya funciona! que bieeen, muchisimas gracias!

Para comprobar lo de que cuando recibe un caracter me lo envia, tengo que conectar otro terminal no? En teoria la pata de rx ya esta al otro terminal..tendra que coger esa pata del PIC y conectarla al de tx de mi terminal, si?

Gracias de nuevo, amigo.

 No, no es necesario conectar otro terminal. En el mismo que ya tenés conectado intentá escribir el caracter a enviar.
Te convendría modificar el programa para que no envié datos (así te queda libre la pantalla del termnal) constantemente, y recién los enviés cuando recibe algo a travez del terminal.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #27 en: 06 de Diciembre de 2010, 12:21:25 »
  Te dejo la nueva versión del programa. En la función "future_state_logic" comenté el if donde chequeabas si la temperatura < 20 o el pote < 25, para que no esté transmitiendo siempre.  También cambié la función "output_logic" ya que siempre que "present_state" se "Idle_High" vas a querer transmitir los datos.
  Cambié el TRISC, porque según el datasheet tanto el pin TX como el RX del uart deben ser configurados como entrada.
  Te dejo también una captura de la simulación.

Código: C
  1. #include <htc.h>
  2. #include <stdlib.h>  // para poder usar la funcion itoa
  3.  
  4.  
  5. /*      =================================================================================
  6.         Definitions
  7.         ================================================================================= */
  8. #define         PORTBIT(adr, bit) ( (unsigned)(&adr)*8 + (bit) )
  9.  
  10. #define         Idle_Low 1      // No envia datos
  11. #define         Idle_High 2 // Envia datos
  12.  
  13. #define true 1
  14. #define false 0
  15.  
  16. #define BAUD  9600                      // Configuramos la velocidad, tanto puede ser 19200 o de 9600 kbaud/s pero hay q cambiarlo tb en la simulacion de proteus      
  17. #define PIC_CLK 4000000         // Clock de 4MHz (Cristal)
  18.  
  19. /*      =================================================================================
  20.         Function prototypes
  21.         ================================================================================= */
  22. //static void interrupt service_routine (void); // This is the interrupt service routine
  23.  
  24. void init_system (void);
  25. void time_delay (unsigned int );
  26. char output_logic(void);
  27. char future_state_logic(void);
  28.  
  29. void setup_sensor(void);
  30. void setup_adc(void);
  31. void serial_setup(void);
  32.  
  33. void putst(const char *str);
  34. void putch(unsigned char c);
  35.  
  36. unsigned char getch(void);
  37. unsigned char UsartReadChar_nonstop(void);
  38. unsigned char getch_available(void);
  39. void clear_usart_errors(void);
  40.  
  41. unsigned char read_spi (void);
  42. unsigned int read_adc(void);
  43.  
  44.  
  45.  
  46. /*      =================================================================================
  47.         Global variables  
  48.         ================================================================================= */
  49. static bit potenciometro @ PORTBIT(PORTA, 0);   // Declaración del potenciometro
  50. static bit sensor_temperatura @ PORTBIT(PORTB, 0);
  51. //static bit sensor_datos_salida @ PORTBIT(PORTC, 7);  // SD0 disabled in master mode (configuración como entrada)
  52. static bit LED @ PORTBIT(PORTB, 1);    
  53.  
  54.                                
  55. static char present_state = Idle_Low;           // state variable
  56. static char future_state = Idle_Low;            // state variable
  57.  
  58. unsigned int  valor_potenciometro;
  59. unsigned char  valor_sensor_temperatura;
  60.  
  61. unsigned char pote_buf[6];
  62. unsigned char sensor_buf[10];
  63.  
  64.  
  65. char * valor_pote_en_texto;           // un puntero para almacenar el numero en texto
  66. char * valor_sensor_en_texto;         // un puntero para almacenar el numero en texto
  67.  
  68. //unsigned char high_result;
  69. //unsigned char low_result;
  70.  
  71. static unsigned char caracter_recibido;
  72.  
  73. unsigned char dummy;
  74.  
  75.  
  76. /*      =================================================================================
  77.         Main function
  78.         ================================================================================= */
  79. void main(void)
  80. {
  81.   valor_potenciometro = 0;
  82.   valor_sensor_temperatura = 0;
  83.   LED = 0;     
  84.   init_system();
  85.   setup_sensor();
  86.   setup_adc();
  87.   serial_setup();      
  88.   while(1)
  89.   {
  90.     //valor_sensor_temperatura = read_spi();  // Las pongo aqui porque es donde hago la lectura de los datos.
  91.     valor_potenciometro = read_adc();
  92.    
  93.     valor_pote_en_texto = itoa (pote_buf, valor_potenciometro, 10);
  94.     valor_sensor_en_texto = itoa (sensor_buf, valor_sensor_temperatura, 10);
  95.  
  96.     output_logic();
  97.     future_state_logic();
  98.   }            
  99. }      
  100.  
  101. /*      =================================================================================
  102.         Function definitions
  103.         ================================================================================= */
  104.  
  105. //*****************************************************************************
  106. //Future_state_logic routine
  107. //*****************************************************************************
  108. char future_state_logic(void)
  109. {
  110.   char error = 0;
  111.   switch (present_state)
  112.   {
  113.     case Idle_Low:
  114.                  /*                            
  115.                   if ((valor_sensor_temperatura < 20) || (valor_potenciometro < 25))
  116.                   { // Menor de 20ºC o la resistencia menos a 25Kohms
  117.                     //future_state = Idle_High;
  118.                     present_state = Idle_High;
  119.                   }
  120.                   else */
  121.                   if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
  122.                   {
  123.                     caracter_recibido = getch();
  124.                     if (caracter_recibido == 'a')
  125.                     {
  126.                       //future_state = Idle_High;
  127.                       present_state = Idle_High;
  128.                       LED = 1;
  129.                       error = 0;
  130.                     }
  131.                     else
  132.                     {
  133.                       //future_state = Idle_Low;
  134.                       present_state = Idle_Low;
  135.                       LED = 0;
  136.                       error = 1;
  137.                     }
  138.                   }
  139.                   break;
  140.     case Idle_High:                                            
  141.                    if (TXIF == 0)
  142.                    { // Buffer de transmision vacio
  143.                      //future_state = Idle_Low;
  144.                      present_state = Idle_Low;
  145.                    }
  146.                    else
  147.                    {
  148.                      error = 1;
  149.                    }
  150.                    break;
  151.     default:
  152.                           error = 1;
  153.   }    
  154.   return (error);
  155. }
  156.  
  157. //*****************************************************************************
  158. //Output logic routine
  159. //*****************************************************************************
  160. char output_logic(void)
  161. {
  162.   unsigned char error = 1;
  163.   switch (present_state)
  164.   {
  165.     case Idle_Low:                             
  166.                    LED = 0;
  167.                    error = 0;
  168.                    break;
  169.     case Idle_High:                    
  170.                    putst ("Valor del pote: ");
  171.                    putst (valor_pote_en_texto);
  172.                    putst ("\n");  //cambio de linea
  173.                    putst ("Valor del sensor: ");
  174.                    //putst (valor_sensor_en_texto);
  175.                    putst ("Suponemos un valor de 25 grados");
  176.                    putst ("\n");
  177.                    LED = 1;
  178.                    error = 0;
  179.                    break;
  180.     default:
  181.                    error = 1;
  182.                    LED = 0;
  183.                    break;              
  184.   }
  185.   return (error);
  186. }
  187.  
  188. //*****************************************************************************
  189. //Init operations  
  190. //*****************************************************************************
  191. void init_system (void)
  192. {
  193.   //TRISB = 1; //LED. Todos los pines se comportaran como salidas menos RB0 2^0=1
  194.   //TRISA = 32; // SS( Select Slave) must have TRISA<5> bit set
  195.   TRISA = 255;
  196.   TRISB = 1; // SDI. El bit 0 a 1.Configurado en master mode (bit 1 cleared, en mode slave bit 1 set)
  197.   TRISC = 192; // SDO. Tots els bits a 1 menys la sortida 7
  198. }
  199.  
  200.  
  201. //*****************************************************************************
  202. //Time delay routine.  
  203. //*****************************************************************************
  204. void time_delay(unsigned int delay)
  205. {
  206.   unsigned int i;
  207.        
  208.   for (i = 0; i <= delay; i++)
  209.   {    
  210.     NOP();
  211.   }
  212. }
  213.  
  214. //*****************************************************************************
  215. // SERIAL SETUP  
  216. //*****************************************************************************
  217. void serial_setup(void)
  218. {
  219.   #define SPBRG_VALUE ((PIC_CLK/(16UL*BAUD)) -1)
  220.   BRGH = 1;
  221.   BRG16 = 0;
  222.   SPBRG = SPBRG_VALUE;
  223.   SPEN = 1; // Enable serial port
  224.   SYNC = 0; // Asincrono
  225.   TXIE = 0; // Desactivar interrupciones en tx
  226.   TXEN = 1; // Enable the transmitter
  227.   TX9 = 0; // 8 bits transmission
  228.   RCIE = 1; // Activar interrupciones en rx
  229.   RX9 = 0; // 8 bits reception
  230.   CREN = 1; //Enable reception
  231.   #define clear_usart_errors_inline     if (OERR)\
  232.                                     {\
  233.                                       TXEN = 0;\
  234.                                       TXEN = 1;\
  235.                                       CREN = 0;\
  236.                                       CREN = 1;\
  237.                                     }\
  238.                                     if (FERR)\
  239.                                     {\
  240.                                       dummy = RCREG;\
  241.                                       TXEN = 0;\
  242.                                       TXEN = 1;\
  243.                                     }
  244. }
  245.  
  246.  
  247. //*****************************************************************************
  248. // Enviar datos ( un caracter)
  249. //*****************************************************************************
  250.  
  251. void putch(unsigned char c)
  252. {
  253.   while (!TXIF)
  254.   {
  255.     clear_usart_errors_inline;
  256.     CLRWDT();
  257.   }
  258.   TXREG = c;
  259. }
  260. //*****************************************************************************
  261. // Enviar datos (un buffer)
  262. //*****************************************************************************
  263. void putst(register const char *str)
  264. {
  265.   while ((*str) != 0)
  266.   {
  267.     putch (*str);
  268.     if (*str == 13) putch (10);
  269.     if (*str == 10) putch (13);
  270.     str++;
  271.   }
  272. }
  273.  
  274. //*****************************************************************************
  275. //Leer datos ( un caracter)
  276. //*****************************************************************************
  277.  
  278. unsigned char getch(void)
  279. {
  280.   while (RCIF != 1)
  281.   {                             //1 = The EUSART receive buffer, RCREG, is full
  282.     CLRWDT();
  283.     clear_usart_errors_inline;
  284.   }
  285.   return RCREG;
  286. }
  287.  
  288. //*****************************************************************************
  289. //Leer datos (un buffer)
  290. //*****************************************************************************
  291. unsigned char UsartReadChar_nonstop(void)
  292. {
  293.   if (!RCIF)    // TRMT1 is set when TSR is empty
  294.     return 0;  
  295.   return RCREG;
  296. }
  297.  
  298.  
  299. //*****************************************************************************
  300. //Comprueba si aun faltan datos o no
  301. //*****************************************************************************
  302. unsigned char getch_available(void)
  303. {
  304.   if (RCIF)
  305.     return true;
  306.   else
  307.     return false;
  308. }
  309.  
  310.  
  311. //*****************************************************************************
  312. //Errores USART
  313. //*****************************************************************************
  314. void clear_usart_errors(void)
  315. {
  316.   clear_usart_errors_inline;
  317. }
  318.  
  319.  
  320. //*****************************************************************************
  321. //Leer entradas.
  322. //*****************************************************************************
  323.  
  324. //*****************************************************************************
  325. //Leer bytes recibidos del bus del modulo SPI
  326. //*****************************************************************************
  327.  
  328. void setup_sensor(void)  // SPI Master mode:
  329. {
  330.   SSPEN = 1;            //Enables serial port and configures SCK, SDO, SDI and SS as serial port pins
  331.   BF = 0;                                                               //Receive not complete, SSPBUF is empty
  332.   //SCK is the clock output (Master Mode)
  333.   //Clock Polarity(Idle state of SCK)
  334.   SMP = 1;                                                       //Input data sampled at end of data output time
  335.   CKE = 0;                                                        //Transmit occurs on transition from Idle to active clock state
  336.   SSPM3 = 0;
  337.   SSPM2 = 0;                                                    //SPI Master mode, clock = FOSC/4      
  338.   SSPM1 = 0;
  339.   SSPM0 = 0;
  340.   CKP = 0;                                                              //Idle state for clock is a low level
  341.   SSPIF = 0;                                                   
  342. }
  343.  
  344. void setup_adc(void)
  345. {
  346.   ADFM = 1;
  347.   ADCON1 = 14;          // PCFG3=1,PCFG2=1,PCFG1=1,PCFG0=0. Todas las entradas digitales
  348.   CHS3 = 0;
  349.   CHS2 = 0;                     // Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
  350.   CHS1 = 0;
  351.   CHS0 = 0;
  352.   //Tiempo de adquisicion
  353.   ACQT2 = 0;
  354.   ACQT1 = 0;            // 2Tad (Tad=1us) Por tanto 2x1us =2us >= 1.65us( Tacq calculado teoricamente)
  355.   ACQT0 = 1;
  356.   ADCS2 = 1;
  357.   ADCS1 = 0;    // Idem a 4Tosc. 4*Tosc(1us) es el primer valor que hace que sea superior a 0.7us( el minimo)
  358.   ADCS0 = 0;   
  359.   ADON = 1;             // A/D converter module is enabled
  360.   /* Configure A/D interrupt*/
  361.   ADIF = 0;
  362.   //ADIE = 1;
  363. }
  364.  
  365. //*****************************************************************************
  366. //Leer entradas.
  367. //*****************************************************************************
  368.  
  369. //*****************************************************************************
  370. //LEER DATOS SENSOR
  371. //*****************************************************************************
  372. unsigned char read_spi (void)
  373. {
  374.   if ((BF == 1) && (SSPIF == 1))
  375.   {     //Receive complete, SSPBUF is full && The transmission/reception is complete (must be cleared in software)
  376.     SSPIF = 0; ////Waiting to transmit/receive
  377.     BF = 0;
  378.     return SSPBUF;
  379.   }
  380.   return 0;
  381. }
  382.  
  383. //*****************************************************************************
  384. //LEER DATOS POTENCIOMETRO
  385. //*****************************************************************************
  386. unsigned int read_adc(void)
  387. {
  388.   //Empezar a leer
  389.   GODONE = 1; // A/D conversion in progress
  390.   while (GODONE == 1);
  391.   ADIF = 0;
  392.   return ((ADRESH << 8) + (ADRESL));
  393. }

De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #28 en: 07 de Diciembre de 2010, 07:23:03 »
Gracias de nuevo. Ya me funciono! todo va viento en popa :)
Ahora mismo estoy centrado en el funcionamiento del sensor. He estado mirando el manual y explicaré un poco lo que he hecho:

1. Setup de todos los pines que hay que configurar ( eso ya estaba en la version anterior del programa)
2.Coneccion de pines:
- Serial Data Out (SDO)- RC7 ---> disabled in master mode. Por tanto no lo he declarado ya que en RC7 tengo la salida                   del terminal
- Serial Data Input(SDI)- RB0---> Lo he conectado pero no lo he configurado en el TRISB porque en el datasheet pone:
"Automatically controlled by the SPI module". Aunque si lo tengo declarado como que el sensor esta conectado al pin RB0 del puertoB
-Serial Clock (SCK). En este pin el datasheet distingui dos opciones depende del modo(Master o Slave). En mi caso(master), TRISB<1> bit clear
Y por ultimo el pin Select Slave(SS) que no lo tengo declarado porque solo se declara y conecta en modo Slave.

Os adjunto una imagen del proteus para que veais como lo tengo conectado.
Gracias de antemano.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #29 en: 07 de Diciembre de 2010, 09:53:38 »
Gracias de nuevo. Ya me funciono! todo va viento en popa :)
Ahora mismo estoy centrado en el funcionamiento del sensor. He estado mirando el manual y explicaré un poco lo que he hecho:

1. Setup de todos los pines que hay que configurar ( eso ya estaba en la version anterior del programa)
2.Coneccion de pines:
- Serial Data Out (SDO)- RC7 ---> disabled in master mode. Por tanto no lo he declarado ya que en RC7 tengo la salida                   del terminal
- Serial Data Input(SDI)- RB0---> Lo he conectado pero no lo he configurado en el TRISB porque en el datasheet pone:
"Automatically controlled by the SPI module". Aunque si lo tengo declarado como que el sensor esta conectado al pin RB0 del puertoB
-Serial Clock (SCK). En este pin el datasheet distingui dos opciones depende del modo(Master o Slave). En mi caso(master), TRISB<1> bit clear
Y por ultimo el pin Select Slave(SS) que no lo tengo declarado porque solo se declara y conecta en modo Slave.

Os adjunto una imagen del proteus para que veais como lo tengo conectado.
Gracias de antemano.

  Bien, lo que te falta es usar un pin (el que vos quieras) para controlar el pin CS del dispositivo spi (en este caso el TC77). Cuando hacés "1" el pin CS de x dispositivo, éste no puede ni recibir ni mandar información al bus spi. Cuando ponés a "0" el pin CS de x dispositivo es cuando podés trabajar con el dispositivo en cuestión.
  Esto sirve para tener varios dispositivos en un mismo bus spi, pero cada uno con un pin CS distinto.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas