Muy buenas de nuevo
He conseguido progresar un poco en mi código C18. Os recuerdo que mi propósito era transmitir el valor de la potencia leida en la entrada del ADC de mi PICDEM por medio de elevar al cuadrado el valor de ese nivel de voltage para una impedancia de un ohmio. Todo ha ido muy bien en la simulación con MPLAB. Cuál es mi sorpresa que cuando le cargo mi firmware al PIC y lo comunico con el HyperTerminal de Windows, recibo una cantidad de valores erróneos sorprendente. Ni un solo número decimal. Por ello pensé en testear con el osciloscopio en la salida serie RS232 del PICDEM HPC explorer board. Cuál fué mi sorpresa al ver que la comunicación serie era demasiado rápida. Lo comparé con un demo que tengo y así era. Mi propósito es transmitir a 9600 baudios e incluso he intentado bajar la frecuencia de oscilación del PIC pero nada. Así que creo que tengo un problema con los tiempos del Timer1. Hasta ahora no he encontrado el error. Creo que la ecuacón que utilizo es correcta porque la simulación fué de lujo. Así que me pongo en vuestras manos, vuestros consejos siempre fueron brillantes. Como podéis ver en la última parte del código, utilizo un switch para transmitir al USART la representación del valor de la potencia que he hallado previamente, para ello considero el valor de cada número decimal entre 0 y 10, y su correspondiente valor ASCII, siendo el #48 el valor decimal correspondiente para el número cero. No me pongo más pesado, dado que me consta que hacéis estupendos análisis de códigos, así que ahí va el mío.
Un coordial saludo de un Andaluz en la tierra de Los Escarabajos.
#include <stdio.h>
#include <math.h>
#include "p18cxxx.h"
#include "p18f8722.h"
#include <adc.h>
#include <stdlib.h>
#include <timers.h>
#include <usart.h>
#define __18F8722_H
/* Xtal frequency */
#define XTAL 16000000L
#define ON 1
#define OFF 0
#define WDTCON WDTCONbits.SWDTEN
#define TX1IF PIR1bits.TX1IF
#define RC1IF PIR1bits.RC1IF
#define TMR1IF PIR1bits.TMR1IF
#define RC0 PORTCbits.RC0
#define ADG0 ADCON0bits.GO
#define BRG16 BAUDCONbits.BRG16
#define BRGH TXSTAbits.BRGH
#define SYNC TXSTA2bits.SYNC
#define SPEN RCSTAbits.SPEN
#define CREN RCSTAbits.CREN
#define SREN RCSTAbits.SREN
#define TX1IE PIE1bits.TX1IE
#define RC1IE PIE1bits.RC1IE
#define TX9 TXSTAbits.TX9
#define RX9 RCSTAbits.RX9
#define TXEN TXSTA2bits.TXEN
#define RD0 LATDbits.LATD0
#define RD1 LATDbits.LATD1
#define RD2 LATDbits.LATD2
#define RD3 LATDbits.LATD3
#define RD4 LATDbits.LATD4
#define RD5 LATDbits.LATD5
#define RD6 LATDbits.LATD6
#define RD7 LATDbits.LATD7
#define HEIGHT 4
#define TRUE 0
#define UPDATES_PER_SECOND 1L
#define TMR1H_RESET ((65542L-((XTAL/32L)/UPDATES_PER_SECOND)) >>

#define TMR1L_RESET ((65542L-((XTAL/32L)/UPDATES_PER_SECOND)) & 0xff)
/* NOTE: 65542 instead of 65536 for 6 cycles it takes to recognize TMR0
* 32=4 Instruction cycles per CLK * 8 (Preescaler value)
* overflow and reload TMR1H/TMR1L:
* while (!TMR1IF)
*
* TMR1H= TMR1H_RESET;
* TMR1L= TMR1L_RESET;
* becomes
* Lxx:
* BTFSS 0x0C, 0
* GOTO Lxx
* MOVLW xxxx
* MOVWF TMR1H
* MOVLW yyyy
* MOVWF TMR1L
*/
void putch1(char letter);
short FilterLowPass(short);
void delay(int loop_count);
#define num 2
void serial_setup(void)
{
/*
* Comms setup:9600/f=16 MHZ -> BRGH=0;SPBRGX=25
*/
WDTCON=OFF; //watchdog disable
SPBRG1=25;
BRG16= 0;
BRGH=0; //low data rate for sending--EUSART
SYNC=0; //asynchronous
SPEN=1; //enable serial port pins
CREN=1; //enable recepton
SREN=0; //no effect
TX1IE=0; //disable tx interrups
RC1IE=0; //disable rx interrups
TX9=0; //8-bit transmission
RX9=0; //8-bit reception
TXEN=0; //reset transmitter
TXEN=1; //enable the transmitter
}
unsigned char i, j;
unsigned char z, m, n;
unsigned int adcv[30],out;
unsigned int ArrNum[HEIGHT], Arr[HEIGHT];
unsigned int sum, ssum, summ, ssumm;
unsigned int numl, numL, numh, numH, numHh, numLl;
unsigned char pos, post;
int loop_count;
int loop;
long int number;
void main(void)
{
// Query for direct boot entry
if (!PORTBbits.RB0) // used to pass the control to bootloader
{
_asm
clrf STKPTR, 0
goto 0x0004
_endasm
}
TRISC=0x80; // PORT C output Except RX (RC7) serial_setup();
ADCON2= 0b10001001;
/*1....... = right justified in ADRESH:ADRESL */
/*.0...... = unused */
/*..001... = 2 adquisition time A/D
/*.....001 = A/D conversion clock = Fosc/8 */
ADCON1= 0b00001110;
/*00...... = unused */
/*..00.... = voltage reference: +AVdd, -AVss */
/*....1110 = only NA0 is analog, Vref+=AVdd, Vref-=ground(AVss)*/
ADCON0= 0b00000001;
/*00...... = unused*/
/*..0000.. = channel 0 (AN0 on RA0) */
/*......0. = A/D conversion not in progress */
/*.......1 = ADC on */
T1CON = 0b11001001;
/*1....... = mode enable bit in one 16-bit operations */
/*.1...... = device clock derived from Timer1 oscilator */
/*..00.... = 1:1 prescalar */
/*....1... = Oscillator is enabled */
/*.....0.. = !T1SYNC (ignored if TMR1CS is 0) */
/*......0. = TMR1CS = internal clock (Fosc/4) */
/*.......1 = TMR1ON (timer1 enabled) */
serial_setup();
LED_Init(); // Setup and update LEDs
LED_update();
while(1)
{
TMR1H = TMR1H_RESET;
TMR1L = TMR1L_RESET;
TMR1IF = OFF;
RC0=0; //LED off
for(i=0;i<30;i++) adcv
=0;
i=0;
RD0= 0;
RD1= 0;
RD2= 0;
RD3= 0;
RD4= 0;
RD5= 0;
RD6= 0;
RD7= 0;
while (!TMR1IF)
{
TMR1H = TMR1H_RESET;
TMR1L = TMR1L_RESET;
TMR1IF = OFF;
ADG0 = ON;
while (ADG0); /*wait for ADC conversion */
adcv = (ADRESH<<
+ADRESL;
sum=0;
summ=0;
for(j=0;j<3;j++)
{
out=0;
out = FilterLowPass(adcv[j]);
sum+= out;
}
sum=sum/3;
printf("\n\n binary, hexadecimal and decimal voltage resolution %b,%x, %u \n", sum, sum, sum);
sum=sum>>2; //valour betwen (0,65025) (aprox. in hundredth of volt with 2% error)
sum= pow(sum, num);
//sum=0xFFFF; //claibrate resolution betwen (0, 65535) decimal value
ssum=sum;
printf("binary power value %b\n", sum);
printf("hexadecimal power value %x\n", sum);
summ=sum/650; //valour betwen (0,65025) (aprox. in hundredth of volt with 2% error) to represent in (0, 255) decimal for 8 bits
printf("Power value = %u, %u watts\n",sum/650,sum%100); //resolution (0, 100) watts
if((summ&0x01)!= TRUE) // show binary value of power response result
{
RD0= 1;
}
if((summ&0x02)!= TRUE)
{
RD1= 1;
}
if((summ&0x04)!= TRUE)
{
RD2= 1;
}
if((summ&0x08)!= TRUE)
{
RD3= 1;
}
if((summ&0x10)!= TRUE)
{
RD4= 1;
}
if((summ&0x20)!= TRUE)
{
RD5= 1;
}
if((summ&0x40)!= TRUE)
{
RD6= 1;
}
if((summ&0x80)!= TRUE)
{
RD7= 1;
}
printf("LED1 --> %b | LED2 --> %b | LED3 --> %b | LED4 --> %b | LED5 --> %b | LED6 --> %b | LED7 --> %b\n", RD0, RD1, RD2, RD3, RD4, RD5, RD6, RD7);
numHh=ssum/650; //valour betwen (0,100) (aprox. in hundredth of watts with 2% error) to transmit by USART
numLl=ssum%100;
numH=numHh/10;
numh=numHh-(numH*10);
numL=numLl/10;
numl=numLl-(numL*10);
printf("Power value %d %d,%d %d\n",numH,numh, numL, numl);
ArrNum[1]=numH;
ArrNum[2]=numh;
ArrNum[3]=numL;
ArrNum[4]=numl;
n=1;
ssumm=0;
for(pos=1; pos<6; pos++)
{
m= pos;
switch(m)
{
case 1:
Arr[n]= ArrNum[pos];
ssumm= 48 + Arr[n];
putch1((char) ssumm);
break;
case 2:
Arr[n]= ArrNum[pos];
ssumm= 48 + Arr[n];
putch1((char) ssumm);
break;
case 3:
ssumm= 46;
putch1((char) ssumm);
n= n-1;
break;
case 4:
post= pos-1;
Arr[n]= ArrNum[post];
ssumm= 48 + Arr[n];
putch1((char) ssumm);
break;
case 5:
post= pos-1;
Arr[n]= ArrNum[post];
ssumm= 48 + Arr[n];
putch1((char) ssumm);
break;
} n=n+1; if(n>HEIGHT) n=1;
}
for(j=0; j<10; j++)
{
printf("\n");
putch1((char)32); //spaces betwen measurement
}
i=i+1; if(i>30) i=0; //actualize index
} //while(!t...
} /* while(1) */
} /*main() */
//writes a character to the serial port
void putch1(char letter)
{
while(!TX1IF);
TXREG1=letter;
loop_count= 100;
for(loop=1;loop<=loop_count;loop++);
}
//gets a character from the serial port without timeout
unsigned char getch(void)
{
while(!RC1IF);
return RCREG1;
}
//int atoi(char s[])
//{
// int m, n;
//
// n=0;
// for(m=0; s[m] >= '0' && s[m]<= '9'; ++m)
// n=10*n+(s-'0');
// return n;
//}
//void delay(loop_count)
//{
// int loop;
// for(loop=1;loop<=loop_count;loop++);
//}
//