Autor Tema: pic18f8722 in serial communication with host  (Leído 9020 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7918
Re: pic18f8722 in serial communication with host
« Respuesta #15 en: 11 de Abril de 2007, 15:18:53 »
Hola Shagui.
Estas seguro que lo que aqui pones configura la comunicacion correctamente a 9600bps ??
Código: [Seleccionar]
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

}

Para asegurarte lee bien la hoja de datos de tu micro y calcula el valor del registro SPBRG1 segun el valor del cristal que tiene el micro.
Yo en CCS no me preocupo de como debo poner estos registros, el lo hace solo.

Marcos
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado shagui

  • PIC10
  • *
  • Mensajes: 12
Re: pic18f8722 in serial communication with host
« Respuesta #16 en: 13 de Abril de 2007, 16:35:37 »
Muy buenas de nuevo

 Gracias por contestar tan pronto a mi auxilio. Respecto a tus iniciativas para comprobar la velocidad para la comunicación serie, te respondo que según el data sheet, éste valor para el registro SPBRG es el adecuado para el tiempo impuesto para el oscilador y una transmision de simbolos a 9600 baudios.

 Hoy mísmo he estado de nuevo programando el chip, he hecho algunos cambios para la transmitisión serie. Antes utilizaba una función putch1, la cual definía al final del código, mientras que ahora uso una función de la librería USART para escribir los caracteres en éste puerto. Claro está, el resultado que obtuve fué el mísmo, me puse a trastear el código y a hacer inventos. Tras varias modificaciones me dí cuenta que la única función que transmite cosas en mi código son los printf que utilizo. No sé como darle explicación a ésto. La historia es que si quito todos los printf, no logro recibir nada por el Hyperterminal del Windows, en cambio si pongo un printf ( otra causa es que si estos printf están dentro de loops como un bucle for tampoco transmite nada) dentro del bucle infinito  while empiezo a recibir una cantidad enorme de carácteres en el Hyperterminal  :shock: . Así que así está la situación ahora. Por supuesto como los printf solo eran señalizaciones que me servían durante el periodo de diseño de éste programa, los he inhabilitado. Así que ahora me pregunto:

-¿Por qué el EUSART1 Transmit Register llamado TXREG1, el cuál utilizo en la función putch1, o la mísma función void --> puts1USART (PARAM_SCLASS char *data); de la librería USART del C18, no envía los caracteres que recibe ese registro desde mi código?



PD: Para ver la forma en que utilizo esta función de librería comentada, tan solo hace falta sustituir cada función putch1 del main por: puts1USART(&ssumm);

    También quiero decir que al simular el código con MPLABSIM, recibo el mísmo resultado que obtenía con mi función putch:

-¿Por qué en la situación en la que estoy, cuando me dispongo a simular el código en MPLABSIM, si borro todos los printf me contesta la pantalla:  No stimulus file attached to ADRESL for A/D, y en cambio cuando le dejo todos los printf que podeis ver en el código del post anterior, la simulación funciona de forma tan sorprendente cojonuda para un principiante como yo?  ¡¡ además cuando simulo con los printf me funciona la transmisión del registro TXREG1, o la función de librería ahora, y sin los printf me sale ese error comentado pero nada en la SIM UART!!

 Creo que me estoy volviendo loco de leer y leer y decir claro si yo lo hago así... y de preguntarme por que? y por que? hasta  a veces dudo de la máquina. :?
Please, echen una manita a este primo que vino a ésta tierra de ingleses, ya los conoceis, pocos servicios humanitarios y muchos impuestos.

Un coordial saludo

 

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7918
Re: pic18f8722 in serial communication with host
« Respuesta #17 en: 13 de Abril de 2007, 16:55:10 »
La pregunta es:

Como transmite la funcion printf()??

Que diferencia hay respecto a las funciones creadas??

Seguramente alli esta la respuesta, ya que si usas el registro txreg1 seguramente estas usando interrupciones, y si no borras el flag de transmicion o lees si ya transmitio seguramente estas echando ruido al port.

No conozco de C18, pero creo que por alli debes buscar... :mrgreen: :mrgreen: :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado shagui

  • PIC10
  • *
  • Mensajes: 12
Re: pic18f8722 in serial communication with host
« Respuesta #18 en: 14 de Abril de 2007, 21:32:35 »
Muy Buenas

  Después de analizar palmo a palmo el código, me doy cuenta que no tan solo los printf son los que transmiten al transmit register sino que además sin ellos, mi codigo no funciona ni en la simulación donde me dice que: ADC-W0001:   Tad time is less than 0.70us
                                                                                     ADC-W0008: No stimulus file attached to ADRESL for A/D.

 NI TAMPOCO FUNCIONA CUANDO LO PROGRAMO CON MPLAB ICD2. Puedo comprobarlo porque los LEDs de la placa solo se encienden cuando hay algún printf escrito en el programa. Os paso el código en el cual utilizo funciones de C18 para la USART.

#include <stdio.h>
#include <math.h>
#include "p18cxxx.h"
#include "p18f8722.h"
#include <adc.h>
#include <stdlib.h>
#include <timers.h>
#include <usart.h>
#include "Timer.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 TX9D   TXSTA1bits.TX9D
#define   RX9      RCSTAbits.RX9
#define TXEN   TXSTA2bits.TXEN
#define TMR0IF   INTCONbits.TMR0IF
#define TMR0IE   INTCONbits.TMR0IE
#define GIE      INTCONbits.GIE   
#define PEIE   INTCONbits.PEIE
#define CSRC   TXSTAbits.CSRC
#define SENDB   TXSTAbits.SENDB
#define TRMT   TXSTAbits.TRMT

#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)) >> 8)
#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);
void Transmit(unsigned char Value_To_Be_Transmitted);

#define num 2

void serial_setup(void)
{
   /*
    * Comms setup:9600/f=16 MHZ -> BRGH=0;SPBRGX=25
    */

   GIE=1;                           //enable Global Interrupt
   PEIE=0;                           //disable Peripheral Interrupt
   CSRC=0;                           //don´t care for asynchronous mode
   SENDB=1;                        //Send Sync Break on next transmission (cleared by hardware upon completion)
   TMR0IE=0;                        // enable TMR0 Overflow Interrupt Enable bit
   WDTCON=OFF;                        //watchdog disable
   SPBRG1=25;
   BRG16=0;                        //8-bit Baud Rate Generator – SPBRGx only (Compatible mode), SPBRGHx value ignored   
   BRGH=0;                           //low data rate for sending--EUSART
   SYNC=0;                           //asynchronous
   SPEN=1;                           //enable serial port pins
   CREN=1;                           //enable reception
   SREN=0;                           //no effect
   TX1IE=1;                        //enable 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
//   TX9D=0;                           //don´t used register for 8-bit transmission

//   SPBRG = 25;          // Speed transmission 9600 BAUD   
//   TXSTA = 0x24;      // 8-bit transmission | Transmit enable | Asynchronous mode | High speed | TSR full
//   RCSTA = 0x80;      // Serial port enabled and only transmitting Tx


}

   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 = 0b11111001;
         /*1....... = mode enable bit in one 16-bit operations */
         /*.1...... = device clock derived from Timer1 oscilator */
         /*..11.... = 1:8 prescalar */
         /*....1... = Oscillator is enabled */
         /*.....0.. = !T1SYNC (ignored if TMR1CS is 0) */
         /*......0. = TMR1CS = internal clock (Fosc/4) */
         /*.......1 = TMR1ON (timer1 enabled) */


   serial_setup();
   TimerInit();
   LATD = 0xFF;      // Initialize LEDs
   TRISD = 0;

   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<<8)+ADRESL;
               sum=0;
               summ=0;
               for(j=0;j<1;j++)
               {               
               out=0;
               out = FilterLowPass(adcv[j]);
               sum+= out;
               }
               //sum=sum/30;

         //      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;
               
         //      printf("   ");


               for(pos=1; pos<6; pos++)
               {
                  m= pos;
                  ssumm=0;
         
                        switch(m)
                  {
                        case 1:

                           Arr[n]= ArrNum[pos];
                           ssumm= 48 + Arr[n];
                        
                           if (TimerIsOverflowEvent())
                           {
                            Transmit(ssumm);
                           }
                            else
                           {
                           n=n-1;
                           pos=pos-1;
                           }
                           break;
                           
                  
                        case 2:
                              
                           Arr[n]= ArrNum[pos];
                           ssumm= 48 + Arr[n];   
                           
                           if (TimerIsOverflowEvent())
                           {
                            Transmit(ssumm);
                           }
                            else
                           {
                           n=n-1;
                           pos=pos-1;
                           }
                           break;

                        case 3:
   
                           ssumm= 46;
                  
                           if (TimerIsOverflowEvent())
                           {
                            Transmit(ssumm);
                           }
                               else
                           {
                           n=n-1;
                           pos=pos-1;
                           }
                                    n= n-1;
                           break;

                        case 4:

                           post= pos-1;
                           Arr[n]= ArrNum[post];
                           ssumm= 48 + Arr[n];
                                                      
                           if (TimerIsOverflowEvent())
                           {
                            Transmit(ssumm);
                           }
                            else
                           {
                           n=n-1;
                           pos=pos-1;
                           }
                           break;      

                        case 5:      

                           post= pos-1;
                           Arr[n]= ArrNum[post];
                           ssumm= 48 + Arr[n];   
                        
                           if (TimerIsOverflowEvent())
                           {
                            Transmit(ssumm);
                           }
                            else
                           {
                           n=n-1;
                           pos=pos-1;
                           }
                            break;

                  }   n=n+1; if(n>HEIGHT) n=1;
               }

               for(j=0; j<10; j++)
               {
               
                  if(TimerIsOverflowEvent())
                  {
                         Transmit(32);
                  }
                   else
                  {
                         j=j-1;
                  }
               }

               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++);
//}
//

void Transmit(unsigned char Value_To_Be_Transmitted)
{
   while(!(TRMT));      // Are we transmitting ?
   //TXREG1 = (Value_To_Be_Transmitted);      // Send a char
   puts1USART(&Value_To_Be_Transmitted);
   //Write1USART(Value_To_Be_Transmitted); Called to restore the transmitted value
   //   loop_count= 1000;
   //   for(loop=1;loop<=loop_count;loop++);

}

Desconectado shagui

  • PIC10
  • *
  • Mensajes: 12
Re: pic18f8722 in serial communication with host
« Respuesta #19 en: 14 de Abril de 2007, 21:35:12 »
Se me olvidaba, al ser un serial communicaction estoy utilizando el TIMER0 con interrupciones para controlar la transmision, aquí va el código:

 
#include   <P18cxxx.H>         // Hardware specific header



#define   TIMER_PERIOD_MS      8               // Period in milliseconds
#define   TIMER_FOSC            4000000L         // Frequency of the processor clock
//#define   TIMER_FOSC         19660000L         // Frequency of the processor clock
#define   TIMER_PRESCALE      4               // The desired prescale


#if    TIMER_PRESCALE == 0
   #define   TIMER_PRESCALE_VALUE   2
#elif    TIMER_PRESCALE == 1
   #define   TIMER_PRESCALE_VALUE   4
#elif   TIMER_PRESCALE == 2
   #define   TIMER_PRESCALE_VALUE   8
#elif   TIMER_PRESCALE == 3
   #define   TIMER_PRESCALE_VALUE   16
#elif   TIMER_PRESCALE == 4
   #define   TIMER_PRESCALE_VALUE   32
#elif    TIMER_PRESCALE == 5
   #define   TIMER_PRESCALE_VALUE   64
#elif   TIMER_PRESCALE == 6
   #define   TIMER_PRESCALE_VALUE   128
#elif   TIMER_PRESCALE == 7
   #define   TIMER_PRESCALE_VALUE   256
#else
   #define   TIMER_PRESCALE_VALUE   1
   #define   TIMER_PRESCALE   8
#endif


void TimerInit(void)
{   
   T0CON = 0xC0 | TIMER_PRESCALE;

   TMR0L = 255L - ((TIMER_PERIOD_MS * TIMER_FOSC) / 1000L / 4 / TIMER_PRESCALE_VALUE);
   
   INTCONbits.TMR0IF = 0;

}


unsigned char TimerIsOverflowEvent(void)
{
   static unsigned char temp;
   
   if (INTCONbits.TMR0IF==1)
   {
      temp = 256L - ((TIMER_PERIOD_MS * TIMER_FOSC) / 1000L / 4 / TIMER_PRESCALE_VALUE);
      TMR0L += temp;

      INTCONbits.TMR0IF = 0;
      //PIR1bits.TX1IF=PIR1bits.TX1IF+1;
      //TXSTAbits.TRMT=TXSTAbits.TRMT+1;
      return(1);
   }

   return(0);
}

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: pic18f8722 in serial communication with host
« Respuesta #20 en: 17 de Abril de 2007, 12:03:19 »
Shaqui, aquí estoy , perdón la demora pero realmente ando muy ocupado en mi vida real.  :lol:

Dime , que es lo que no puedes hacer

1) Simular un estimulo al A/D ?
2) Hacer andar el ICD2 ?

Luego revisamos el código, pero comencemos por lo primero.

Saludos
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)