#include <stdlib.h> // para poder usar la funcion itoa
#include <htc.h>
__CONFIG(1, 0x0018);
__CONFIG(2, 0x0039);
__CONFIG(3, 0x01FF );
__CONFIG(4, 0x29FF);
__CONFIG(5, 0xC00F);
__CONFIG(6, 0xE00F);
__CONFIG(7, 0x000F);
/* =================================================================================
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 4800 // 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 5000000 // Clock de 5MHz (Cristal)
#define CS RB2
/* =================================================================================
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(PORTD, 0);
char present_state = Idle_Low; // state variable
char future_state = Idle_Low; // state variable
unsigned int valor_potenciometro;
unsigned int valor_sensor_temperatura;
unsigned char pote_buf[6];
unsigned char sensor_buf[10];
char * valor_pote_en_texto; // un puntero para almacenar el numero en texto
char * valor_sensor_en_texto; // un puntero para almacenar el numero en texto
char byte_alto, byte_bajo;
unsigned char caracter_recibido;
unsigned char dummy;
/* =================================================================================
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(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 int read_adc(void);
/* =================================================================================
Main function
================================================================================= */
void main(void)
{
valor_potenciometro = 0;
valor_sensor_temperatura = 0;
LED = 0;
init_system();
setup_sensor();
setup_adc();
serial_setup();
time_delay(30000);
while(1)
{
CS = 0;
byte_alto = read_spi();
byte_bajo = read_spi();
CS = 1;
valor_sensor_temperatura = (byte_alto << 8) + byte_bajo;
valor_sensor_temperatura = valor_sensor_temperatura >> 7;
//valor_sensor_temperatura = read_spi(); // Las pongo aqui porque es donde hago la lectura de los datos.
valor_potenciometro = read_adc();
valor_pote_en_texto = itoa (pote_buf, valor_potenciometro, 10);
valor_sensor_en_texto = itoa (sensor_buf, valor_sensor_temperatura, 10);
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 < 5) || (valor_potenciometro <=0))
{ // Menor de 20ºC o la resistencia menos a 25Kohms
//future_state = Idle_High;
present_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')
{
present_state = Idle_High;
}
else
{
present_state = Idle_Low;
error = 1;
}
}
break;
case Idle_High:
if (TXIF == 0)
{ // Buffer de transmision vacio
//future_state = Idle_Low;
present_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:
putst ("\n");
putst ("Valor del pote: ");
putst (valor_pote_en_texto);
putst ("\n"); //cambio de linea
putst ("Valor del sensor: ");
putst (valor_sensor_en_texto);
//putst ("Suponemos un valor de 25 grados");
putst ("\n");
LED = 1;
error = 0;
break;
default:
error = 1;
LED = 0;
break;
}
return (error);
}
//*****************************************************************************
//Init operations
//*****************************************************************************
void init_system (void)
{
//Primary oscillator
SCS1=0;
SCS0=0;
TRISA = 255;
CS = 1;
TRISB = 1; // SDI. El bit 0 a 1.Configurado en master mode (bit 1 cleared, en mode slave bit 1 set)
TRISC = 192; // RC7 i RC6 a 1
TRISD=0;
}
//*****************************************************************************
//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 (!RCIF)
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 = 0; //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)
{
ADFM = 1;
ADCON1 = 14; // PCFG3=1,PCFG2=1,PCFG1=1,PCFG0=0. Todas las entradas digitales
// Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
CHS3 = 0;
CHS2 = 0;
CHS1 = 0;
CHS0 = 0;
//Tiempo de adquisicion
ACQT2 = 0;
ACQT1 = 1;
ACQT0 = 0;
// Tiempo de conversion
ADCS2 = 1;
ADCS1 = 0; // Idem a 4Tosc. 4*Tosc(1/5Mhz = 0.2us) es el primer valor que hace que sea superior a 0.7us( el minimo) (100)
ADCS0 = 0;
ADON = 1; // A/D converter module is enabled
/* Configure A/D interrupt*/
ADIF = 0;
}
//*****************************************************************************
//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;
}
*/
TRISC7 = 1; // así pongo en alta impedancia el pin SDO
SSPBUF = 16;
while (SSPIF == 0);
SSPIF = 0;
return SSPBUF;
}
//*****************************************************************************
//LEER DATOS POTENCIOMETRO
//*****************************************************************************
unsigned int read_adc(void)
{
//Empezar a leer
GODONE = 1; // A/D conversion in progress
while (GODONE == 1);
ADIF = 0;
return ((ADRESH << 8) + (ADRESL));
}
Gracias de antemano. Cualquier pequeña idea es bienvenida!
Gracias! He probado de cambiar la palabra de configuracion 1 tal y como has dicho y sigue sin funcionar. Ahora en el proteus cuando le pongo el .hex con las palabras de configuracion, ya no se queja pero siguen saliendo los errores del adc:
ADC conversion clock period(2,0832e-08) violates the minimum required TAD time
ADC conversion clock period(2e-07) violates the minimum required TAD time
Simulation is not running in real time due to excessive CPU load
Eso es lo que sale...
Gracias de antemano, a ver si encontramos la solucion.. yo seguire probando cosas.
P.D: Adjunto el archivo del hyperterminal.
#include <stdlib.h> // para poder usar la funcion itoa
#include <htc.h>
__CONFIG(1, 0x3CE0); // Cambiar
__CONFIG(2, 0x0039);
__CONFIG(3, 0x01FF );
__CONFIG(4, 0x29FF);
__CONFIG(5, 0xC00F);
__CONFIG(6, 0xE00F);
__CONFIG(7, 0x000F);
/* =================================================================================
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 20000000 // Clock de 20MHz
#define CS RB2
/* =================================================================================
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(PORTD, 0);
char present_state = Idle_Low; // state variable
char future_state = Idle_Low; // state variable
unsigned int valor_potenciometro;
unsigned int valor_sensor_temperatura;
unsigned char pote_buf[6];
unsigned char sensor_buf[10];
char * valor_pote_en_texto; // un puntero para almacenar el numero en texto
char * valor_sensor_en_texto; // un puntero para almacenar el numero en texto
char byte_alto, byte_bajo;
unsigned char caracter_recibido;
unsigned char dummy;
/* =================================================================================
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(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 int read_adc(void);
/* =================================================================================
Main function
================================================================================= */
void main(void)
{
valor_potenciometro = 0;
valor_sensor_temperatura = 0;
LED = 0;
init_system();
setup_sensor();
setup_adc();
serial_setup();
time_delay(30000);
while(1)
{
CS = 0;
byte_alto = read_spi();
byte_bajo = read_spi();
CS = 1;
valor_sensor_temperatura = (byte_alto << 8) + byte_bajo;
valor_sensor_temperatura = valor_sensor_temperatura >> 7;
//valor_sensor_temperatura = read_spi(); // Las pongo aqui porque es donde hago la lectura de los datos.
valor_potenciometro = read_adc();
valor_pote_en_texto = itoa (pote_buf, valor_potenciometro, 10);
valor_sensor_en_texto = itoa (sensor_buf, valor_sensor_temperatura, 10);
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 < 10) || (valor_potenciometro < 1))
{ // Menor de 20ºC o la resistencia menos a 25Kohms
//future_state = Idle_High;
present_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')
{
present_state = Idle_High;
}
else
{
present_state = Idle_Low;
error = 1;
}
}
break;
case Idle_High:
if (TXIF == 0)
{ // Buffer de transmision vacio
//future_state = Idle_Low;
present_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:
putst ("\n");
putst ("Valor del pote: ");
putst (valor_pote_en_texto);
putst ("\n"); //cambio de linea
putst ("Valor del sensor: ");
putst (valor_sensor_en_texto);
//putst ("Suponemos un valor de 25 grados");
putst ("\n");
LED = 1;
error = 0;
break;
default:
error = 1;
LED = 0;
break;
}
return (error);
}
//*****************************************************************************
//Init operations
//*****************************************************************************
void init_system (void)
{
//Primary oscillator
// SCS1=0;
// SCS0=0;
TRISA = 255;
CS = 1;
TRISB = 1; // SDI. El bit 0 a 1.Configurado en master mode (bit 1 cleared, en mode slave bit 1 set)
TRISC = 192; // RC7 i RC6 a 1
TRISD=0;
}
//*****************************************************************************
//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 (!RCIF)
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 = 0; //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)
{
ADFM = 1;
ADCON1 = 14; // PCFG3=1,PCFG2=1,PCFG1=1,PCFG0=0. Todas las entradas digitales
// Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
CHS3 = 0;
CHS2 = 0;
CHS1 = 0;
CHS0 = 0;
//Tiempo de adquisicion 010
ACQT2 = 0;
ACQT1 = 1; //4Tad
ACQT0 = 0;
// Tiempo de conversion
ADCS2 = 1;
ADCS1 = 1; // 16Tosc Idem a 4Tosc. 4*Tosc(1/5Mhz = 0.2us) es el primer valor que hace que sea superior a 0.7us( el minimo) (100)
ADCS0 = 0;
ADON = 1; // A/D converter module is enabled
/* Configure A/D interrupt*/
ADIF = 0;
}
//*****************************************************************************
//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;
}
*/
TRISC7 = 1; // así pongo en alta impedancia el pin SDO
SSPBUF = 16;
while (SSPIF == 0);
SSPIF = 0;
return SSPBUF;
}
//*****************************************************************************
//LEER DATOS POTENCIOMETRO
//*****************************************************************************
unsigned int read_adc(void)
{
//Empezar a leer
GODONE = 1; // A/D conversion in progress
while (GODONE == 1);
ADIF = 0;
return ((ADRESH << 8) + (ADRESL));
}
No se porque no funciona nada ahora.. he probado lo que dices ( estoy con el sensor solo) y no funciona.
Explico exactamente que es lo que ocurre ( estoy sin palabra de configuracion).
El led se enciende y sale todo el rato como si estuviera tx pero cuando abro el vterm envia una serie de 0 ( imagino que es el tiempo que tarda en coger los datos) y para. Se puede leer bien y cuando tecleo "a" sale el valor correcto y actual del sensor.
El led no para de parpadear.. no se el porque pero esta como enviando cosas...
Edito1: Acabo de volver a poner la parte del adc y no lee bien el dato. Todo el rato sale 0...
Estoy alucinando.. el programa esta tal cual lo teniamos, he quitado la palabra d configuracion y tendria que funcionar. Solo hemos tocado los tiempos del adc y hemos seguido lo que dice en el manual...
Estas seguro que los bits no implementados se asignan como "1" y no es un "0"?
#include <stdlib.h> // para poder usar la funcion itoa
#include <htc.h>
/*
__CONFIG(1, 0x30E0); // Cambiar
__CONFIG(2, 0x0039);
__CONFIG(3, 0x01FF );
__CONFIG(4, 0x29FF);
__CONFIG(5, 0xC00F);
__CONFIG(6, 0xE00F);
__CONFIG(7, 0x000F);
*/
/* =================================================================================
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 20000000 // Clock de 20MHz
#define CS RB2
/* =================================================================================
Global variables
================================================================================= */
static bit LED @ PORTBIT(PORTD, 0);
char present_state = Idle_Low; // state variable
char future_state = Idle_Low; // state variable
unsigned int valor_potenciometro;
unsigned int valor_sensor_temperatura;
unsigned char pote_buf[6];
unsigned char sensor_buf[10];
char * valor_pote_en_texto; // un puntero para almacenar el numero en texto
char * valor_sensor_en_texto; // un puntero para almacenar el numero en texto
char byte_alto, byte_bajo;
unsigned char caracter_recibido;
unsigned char dummy;
/* =================================================================================
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(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 int read_adc(void);
/* =================================================================================
Main function
================================================================================= */
void main(void)
{
valor_potenciometro = 30;
valor_sensor_temperatura = 0;
LED = 0;
init_system();
setup_sensor();
setup_adc();
serial_setup();
time_delay(30000000);
while(1)
{
CS = 0;
byte_alto = read_spi();
byte_bajo = read_spi();
CS = 1;
valor_sensor_temperatura = (byte_alto << 8) + byte_bajo;
valor_sensor_temperatura = valor_sensor_temperatura >> 7;
valor_potenciometro = 128;
// valor_potenciometro = read_adc();
valor_pote_en_texto = itoa (pote_buf, valor_potenciometro, 10);
valor_sensor_en_texto = itoa (sensor_buf, valor_sensor_temperatura, 10);
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 < 10) || (valor_potenciometro < 25))
// if (valor_sensor_temperatura < 10)
{ // Menor de 20ºC o la resistencia menos a 25Kohms
//future_state = Idle_High;
present_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')
{
present_state = Idle_High;
}
else
{
present_state = Idle_Low;
error = 1;
}
}
break;
case Idle_High:
if (TXIF == 0) // Buffer de transmision vacio
{
//future_state = Idle_Low;
present_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:
putst ("\n");
putst ("Valor del pote: ");
putst (valor_pote_en_texto);
putst ("\n"); //cambio de linea
putst ("Valor del sensor: ");
putst (valor_sensor_en_texto);
putst ("\n");
LED = 1;
error = 0;
break;
default:
error = 1;
LED = 0;
break;
}
return (error);
}
//*****************************************************************************
//Init operations
//*****************************************************************************
void init_system (void)
{
//Primary oscillator
SCS1=0;
SCS0=0;
TRISA = 255;
CS = 1;
TRISB = 1; // SDI. El bit 0 a 1.Configurado en master mode (bit 1 cleared, en mode slave bit 1 set)
TRISC = 192; // RC7 i RC6 a 1
TRISD=0;
}
//*****************************************************************************
//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 (!RCIF)
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 = 0; //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)
{
ADFM = 1;
ADCON1 = 14; // PCFG3=1,PCFG2=1,PCFG1=1,PCFG0=0. Todas las entradas digitales
// Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
CHS3 = 0;
CHS2 = 0;
CHS1 = 0;
CHS0 = 0;
//Tiempo de adquisicion 010
ACQT2 = 0;
ACQT1 = 1; //4Tad
ACQT0 = 0;
// Tiempo de conversion
ADCS2 = 1;
ADCS1 = 0; // 16Tosc Idem a 4Tosc. 4*Tosc(1/5Mhz = 0.2us) es el primer valor que hace que sea superior a 0.7us( el minimo) (100)
ADCS0 = 1;
ADON = 1; // A/D converter module is enabled
/* Configure A/D interrupt*/
ADIF = 0;
}
//*****************************************************************************
//Leer entradas.
//*****************************************************************************
//*****************************************************************************
//LEER DATOS SENSOR
//*****************************************************************************
unsigned char read_spi (void)
{
TRISC7 = 1; // así pongo en alta impedancia el pin SDO
SSPBUF = 16;
while (SSPIF == 0);
SSPIF = 0;
return SSPBUF;
}
//*****************************************************************************
//LEER DATOS POTENCIOMETRO
//*****************************************************************************
unsigned int read_adc(void)
{
//Empezar a leer
GODONE = 1; // A/D conversion in progress
while (GODONE == 1);
ADIF = 0;
return ((ADRESH << 8) + (ADRESL));
}
A mi sin la palabra de configuracion no me iba bien ayer.. puedes adjuntarme todo el codigo? he cambiado muchas cosas y tengo el codigo un poco revuelto.
Muchas gracias!
Sigue sin funcionarme en el proteus.. a ti te va en el proteus?
Por otro lado, porque usas las palabras de configuracion si dijimos que el fichero estaba mal..?
Edito: He grabado el programa en el PIC y durante un rato envia caracteres raros, despues empieza a enviar los datos bien ( pote y sensor) a mucha velocidad y envia mal los datos del sensor, pone temp 168
A veces me he fijado que pone una temp de 19 grados que puede ser perfectamente. Pero esto va cambiando y va haciendo burradas 511 160 y pico.. creo que el tiempo que tiene para leer no es suficiente. Es como si fuera mas rapido lo otro y solo diera los valores correctos cada un tiempo.
Gracias!
Y a este ultimo problema.. como hay que hacerle frente? porque seria otra vez volver a cambiar la freq...
El proteus te funciona?
Podriamos probar de meterle un delay ( no se exactamente donde) para que tenga tiempo de leer bien. No se si en la misma funcion o en el main.. alguna idea?
Te adjunto mi simulacion de proteus y prueba a ver si te funciona.. porque a mi no.
He grabado el PIC otra vez y el pote funciona perfecto pero el sensor no, muestra todo el rato 168 podria ser que fuessen 16.8ºC?
Lo que falla tambien es que envia los datos siempre, sin seguir ningun criterio.
Por otra parte si ahora cambio a 5MHz para hacerlo mas parecido a cuando lo haciamos con 4MHz y funcionaba.. dices que solo he de cambiar PIC_CLK y los tiempos del conversor pero tambien tendre q cambiar la palabra de configuracion no?
#include <stdlib.h>
#include <stdio.h>
void
main (void)
{
char * buf;
float input = 12.34;
int status;
buf = ftoa(input, &status);
printf("The buffer holds %s\n", buf);
}
valor_sensor_temperatura = (byte_alto << 8) + byte_bajo;
valor_sensor_temperatura = valor_sensor_temperatura >> 7;
valor_sensor_en_texto=ftoa(valor_sensor_temperatura,&status);
Ya funciona! volvi a armar el proteus y todo va bien.
Respecto a cuando grabo en el PIC, antes has dicho que ya lo estaba haciendo bien:
Recrodá que según el programa, si la temperatura (o el dato tomado desde el sensor) era inferior a 20, se enviaban constantemente los datos. O sea que estaría bien.[
Eso significa que el valor 168 es 16.8 no? voy a ver si lo arreglo para que pueda verse la ",". Imagino que sera cambiar el tipu de datos a float no?
Edito: He cambiado la variable a float --> float valor_sensor_temperatura;
Y ahora necesito otra funcion ( que no sea itoa) para pasar de float a string. He mirado y la funcion es ftoa. La implementacion de ftoa es segun este ejemplo:Código: [Seleccionar]#include <stdlib.h>
#include <stdio.h>
void
main (void)
{
char * buf;
float input = 12.34;
int status;
buf = ftoa(input, &status);
printf("The buffer holds %s\n", buf);
}
Y por tanto la declaracion es char * ftoa (float f, int * status)
Cuando hago el cambio me salen errores en el codigo en las lineas:Código: [Seleccionar]valor_sensor_temperatura = (byte_alto << 8) + byte_bajo;
valor_sensor_temperatura = valor_sensor_temperatura >> 7;
Y en la linea de la funcion ftoaCódigo: [Seleccionar]valor_sensor_en_texto=ftoa(valor_sensor_temperatura,&status);
He declarado status como int como se dice en el ejemplo pero no entiendo muy bien lo que es. Voy a seguir mirando
Ese 168 es problema del tiempo de adquisicion de datos del sensor. Nada mas.
El programa ahora funciona perfecto, lo unico que no muestra bien es cuando le envio el caracter "a" para que me envie los dos datos, el dato del pote esta Ok pero el dato del sensor siempre es 0. Luego si hago cumplir la condicion me dice la temp adequada del sensor..
Creo que en el caso de que se enviase un caracter ( en nuestro caso "a"), tendriamos que leer dentro de esa pequeña parte del codigo el dato que hay del sensor.
ats0=1<cr>
ats512=4<cr>
ats502=1<cr>
ats536=1<cr>
at+btk="XXXX"<cr>
at&w<cr>
atz<cr>
// Establecer connexion con comandos AT
putst ("AT");
putst ("\n");
//Comprovar que reciba "OK"
putst ("ATS0=1")
putst ("\n");
//Comprovar que reciba "OK"
putst ("ATS512=4")
putst ("\n");
//Comprovar que reciba "OK"
putst ("ATS502=1")
putst ("\n");
//Comprovar que reciba "OK"
putst ("ATS536=1")
putst ("\n");
//Comprovar que reciba "OK"
putst ("AT+BTK="1234"")
putst ("\n");
//Comprovar que reciba "OK"
putst ("AT&W")
putst ("\n");
//Comprovar que reciba "OK"
putst ("ATZ")
putst ("\n");
//Comprovar que reciba "OK"
Si se recibe el mensaje siguiente, empieza el programa:PAIR 1 008098E6A5F4
PAIR 0 008098E6A5F4
CONNECT 008098E6A5F4,1101 A
Establecer connexion con comandos AT
================================================================================= */
//Primer comando AT
putst ("AT");
putst ("\n");
//Comprovar que reciba "OK"
if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
{
comando_recibido1 = getch(); // Cambiar getch por una funcion que lea mas de 1 caracter
while (comando_recibido1!="OK"){
error_comando=0;
}
if(comando_recibido1=="OK")
error_comando=1;
}
//Segundo comando AT
if (error_comando==1)
{
error_comando=0;
putst ("ATS0=1");
putst ("\n");
if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
{
comando_recibido2 = getch(); // Cambiar getch por una funcion que lea mas de 1 caracter
while (comando_recibido2!="OK")
error_comando=0;
if(comando_recibido2=="OK")
error_comando=1;
}
}
//Tercer comando AT
if (error_comando==1)
{
error_comando=0;
putst ("ATS512=4");
putst ("\n");
if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
{
comando_recibido3 = getch(); // Cambiar getch por una funcion que lea mas de 1 caracter
while (comando_recibido3!="OK")
error_comando=0;
if(comando_recibido3=="OK")
error_comando=1;
}
}
//Quarto comando AT
if (error_comando==1)
{
error_comando=0;
putst ("ATS502=1");
putst ("\n");
if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
{
comando_recibido4 = getch(); // Cambiar getch por una funcion que lea mas de 1 caracter
while (comando_recibido4!="OK")
error_comando=0;
if(comando_recibido4=="OK")
error_comando=1;
}
}
//Quinto comando AT
if (error_comando==1)
{
error_comando=0;
putst ("ATS536=1");
putst ("\n");
if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
{
comando_recibido5 = getch(); // Cambiar getch por una funcion que lea mas de 1 caracter
while (comando_recibido5!="OK")
error_comando=0;
if(comando_recibido5=="OK")
error_comando=1;
}
}
//Sexto comando AT
if (error_comando==1)
{
error_comando=0;
putst ("AT+BTK=1234");
putst ("\n");
if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
{
comando_recibido6 = getch(); // Cambiar getch por una funcion que lea mas de 1 caracter
while (comando_recibido6!="OK")
error_comando=0;
if(comando_recibido6=="OK")
error_comando=1;
}
}
//Septimo comando AT
if (error_comando==1)
{
error_comando=0;
putst ("AT&W");
putst ("\n");
if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
{
comando_recibido7 = getch(); // Cambiar getch por una funcion que lea mas de 1 caracter
while (comando_recibido7!="OK")
error_comando=0;
if(comando_recibido7=="OK")
error_comando=1;
}
}
//Octavo comando AT
if (error_comando==1)
{
error_comando=0;
putst ("ATZ");
putst ("\n");
if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
{
comando_recibido8 = getch(); // Cambiar getch por una funcion que lea mas de 1 caracter
while (comando_recibido8!="OK")
error_comando=0;
if(comando_recibido8=="OK")
error_comando=1;
}
}
#include <string.h>
int
strcmp(register const char * s1, register const char * s2)
{
register signed char r;
while(!(r = (unsigned char)*s1 - (unsigned char)*s2++) && *s1++)
continue;
return r;
}
//Segundo comando AT
if (error_comando==0)
{
error_comando=1;
putst ("ATS0=1/n");
if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
{
comando_recibido2 = getch(); // Cambiar getch por una funcion que lea mas de 1 caracter
while (strcmp(comando_recibido2, comando_recibido_ideal)!= 1 ){
error_comando=1;
}
if(strcmp(comando_recibido2, comando_recibido_ideal) == 1 )
error_comando=0;
}
int error_comando=1;
char comando_recibido_ideal[] = "OK";
char comando_recibido1;
char comando_recibido2;
char comando_recibido3;
char comando_recibido4;
char comando_recibido5;
char comando_recibido6;
char comando_recibido7;
char comando_recibido8;
unsigned char UsartReadChar_nonstop(void)
{
if (!RCIF) // TRMT1 is set when TSR is empty
return 0;
return RCREG;
}