Autor Tema: transmisión serie pic16f876  (Leído 2418 veces)

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

Desconectado laurabec

  • PIC10
  • *
  • Mensajes: 14
transmisión serie pic16f876
« en: 23 de Agosto de 2004, 04:45:00 »
wenas!!! soy nuevisima en esto de los pic y tengo que conseguir q se comunique en serie con el pc (q envia y recibe con Builder c++ modo consola) . no se si tengo mal la aplicación builder o he configurado mal el pic.......el caso es q esto no va. le importaria a alguien exarle un vistazo a mi codigo y decirme q es lo q me falla?? muxisimas gracias de antemano!!!

;************************************************************
; Programa para mostrar la funcionalidad de USART.
;
; Puerto B conectado a 8 LEDs.
; Cuando el PIC16F876 recive una palabra a traves de USART,
; el valor es mostrado en los LEDs y retransmitido hacia el host.
; 9600 baudios, 1 bit de stop y sin paridad
;

   list p=16f876   
      
   include <P16f876.INC>


PORTB EQU 0x06
PORTC EQU 0X07
TRISB EQU 0x86
TRISC EQU 0x87
SPBRG EQU 0x99
TXSTA EQU  0x98
RCSTA EQU 0x18
PIR1 EQU 0x0C
PIE1 EQU 0x8C
INTCON EQU 0x0B
STATUS EQU 0x03
RCREG EQU 0x1A
TXREG EQU 0x19

PDel0 EQU 0x22
PDel1 EQU 0x23
PDel2 EQU 0x24

;************************************************************
; Vectores de reset y de interrupción

   org   0x00   ; vector de reset
    goto   Start

   org   0x04   ; vector de interrupcion
   goto   IntVector

;************************************************************


   org   0x05   
Start
   clrf    PORTB
   clrf    PORTC
   bsf   RCSTA,SPEN   ; Se activa la USART

   bsf    STATUS,5   ; Cambia al banco 1
   clrf   TRISB       ; Configura el puerto B como salidas
   movlw   b"10011111"   ;RC7/Rx entrada,
   movwf   TRISC       ;RC6/Tx   salida y RC5 Salida.

   movlw   .25      ; 9600 baud @4MHz
   movwf   SPBRG
   movlw b"10100100"    ; Habilita la transmision
   movwf TXSTA        ; Asíncrono, alta velocidad, reloj interno
   
   bcf STATUS,5      ; Cambia al banco 0
   
   movlw b"10010000"    ;Habilita puerto serie y recepción contínua
   movwf RCSTA

   
   bcf   PIR1,RCIF   ; Buffer de recepción de USART vacío

   bsf    STATUS,5
   bsf   PIE1,RCIE   ; Habilita la interrupción de transmisión de USART
   bcf    STATUS,5
   
   movlw   b"11000000"   ;Habilitacion para las
   movwf   INTCON      ;interrupciones generales y perifericas

;************************************************************
; Main loop

Main
   goto   Main      ;espera aqui hasta que salte la interrupción

;************************************************************
; rutina de interrupción

IntVector
   

   btfss   PIR1,RCIF   ; Testeamos si se produce una interrupción en USART
            ; Indica si la transferencia se ha completado
   goto   OtherInt   ; No, se produce otro tipo de interrupción

   movlw   06h      
   andwf   RCSTA,W      ; Chequeamos los bits  FERR y OERR de RCSTA para ver
            ; si se ha producido algún error durante la recepción
   btfss   STATUS,Z   ; Chequeamos el bit de error de STATUS
   goto   RcvError   ; Error encontrado

   movf   RCREG,W      ; Toma datos entrantes
   movwf   PORTB      ; Muestra el resultado en el puertoB
   call DEMORA
   ;movwf   TXREG      ; Transmisión
   clrf    PORTB      ;Borra el dato en PortB
   goto   ISREnd      
   
RcvError
   bcf   RCSTA,CREN   ; Deshabilita recepción contínua y borra el error
   bsf   RCSTA,CREN   ; Habilita de nuevo recepción contínua
   movlw   0FFh      ; Ilumina todos los leds
   movwf   PORTB   
   goto   ISREnd   

OtherInt
   goto   $   

ISREnd
   
   retfie
DEMORA  movlw     .14       ; 1 set numero de repeticion  (C)
        movwf     PDel0     ; 1 |
PLoop0  movlw     .72       ; 1 set numero de repeticion  (B)
        movwf     PDel1     ; 1 |
PLoop1  movlw     .247      ; 1 set numero de repeticion  (A)
        movwf     PDel2     ; 1 |
PLoop2  nop             ; 1 clear watchdog
        decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
        goto      PLoop0    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  nop              ; 1 ciclo delay
        return              ; 2+2 Fin.

   end


Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: transmisión serie pic16f876
« Respuesta #1 en: 23 de Agosto de 2004, 05:13:00 »
  Pues el codigo está bien, se ve en los LEDs no lo he comprovado si es el número o no pero si se ve un cambio, para recibir el dato en el PC he tenido que cambiar de sitio la instrucción de enviar y si me llega al hyperterminal.


así ha quedado todo:


;************************************************************
; Programa para mostrar la funcionalidad de USART.
;
; Puerto B conectado a 8 LEDs.
; Cuando el PIC16F876 recive una palabra a traves de USART,
; el valor es mostrado en los LEDs y retransmitido hacia el host.
; 9600 baudios, 1 bit de stop y sin paridad
;
   
   list p=16f876
   
   include <P16f876.INC>


   
PDel0 EQU 0x22
PDel1 EQU 0x23
PDel2 EQU 0x24

;************************************************************
; Vectores de reset y de interrupción
   
   org 0x00 ; vector de reset
   goto Start
   
   org 0x04 ; vector de interrupcion
   goto IntVector

;************************************************************


   org 0x05
Start
   clrf PORTB
   clrf PORTC
   bsf RCSTA,SPEN ; Se activa la USART
   
   bsf STATUS,5 ; Cambia al banco 1
   clrf TRISB ; Configura el puerto B como salidas
   movlw b"10011111" ;RC7/Rx entrada,
   movwf TRISC ;RC6/Tx salida y RC5 Salida.
   
   movlw .25 ; 9600 baud @4MHz
   movwf SPBRG
   movlw b"10100100" ; Habilita la transmision
   movwf TXSTA ; Asíncrono, alta velocidad, reloj interno
   
   bcf STATUS,5 ; Cambia al banco 0
   
   movlw b"10010000" ;Habilita puerto serie y recepción contínua
   movwf RCSTA
   
   
   bcf PIR1,RCIF ; Buffer de recepción de USART vacío
   
   bsf STATUS,5
   bsf PIE1,RCIE ; Habilita la interrupción de transmisión de USART
   bcf STATUS,5
   
   movlw b"11000000" ;Habilitacion para las
   movwf INTCON ;interrupciones generales y perifericas

;************************************************************
; Main loop

Main
   goto Main ;espera aqui hasta que salte la interrupción

;************************************************************
; rutina de interrupción

IntVector


   btfss PIR1,RCIF ; Testeamos si se produce una interrupción en USART
   ; Indica si la transferencia se ha completado
   goto OtherInt ; No, se produce otro tipo de interrupción
   
   movlw 06h
   andwf RCSTA,W ; Chequeamos los bits FERR y OERR de RCSTA para ver
   ; si se ha producido algún error durante la recepción
   btfss STATUS,Z ; Chequeamos el bit de error de STATUS
   goto RcvError ; Error encontrado
   
   movf RCREG,W ; Toma datos entrantes
   movwf PORTB ; Muestra el resultado en el puertoB
   movwf TXREG ; Transmisión
   call DEMORA

   clrf PORTB ;Borra el dato en PortB
   goto ISREnd

RcvError
   bcf RCSTA,CREN ; Deshabilita recepción contínua y borra el error
   bsf RCSTA,CREN ; Habilita de nuevo recepción contínua
   movlw 0FFh ; Ilumina todos los leds
   movwf PORTB
   goto ISREnd

OtherInt
   goto $

ISREnd

   retfie
DEMORA movlw .14 ; 1 set numero de repeticion (C)
   movwf PDel0 ; 1 |
PLoop0 movlw .72 ; 1 set numero de repeticion (B)
   movwf PDel1 ; 1 |
PLoop1 movlw .247 ; 1 set numero de repeticion (A)
   movwf PDel2 ; 1 |
PLoop2 nop ; 1 clear watchdog
   decfsz PDel2, 1 ; 1 + (1) es el tiempo 0 ? (A)
   goto PLoop2 ; 2 no, loop
   decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (B)
   goto PLoop1 ; 2 no, loop
   decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (C)
   goto PLoop0 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 nop ; 1 ciclo delay
   return ; 2+2 Fin.

   end


Si no te funciona comentanos que es lo que te hace a ti, ah!!!  si pones el include del PIC No hace falta definir los registros internos, veras que en el codigo lo he borrado y PORTB etc... lo compila igualmente
- T0ni0 -
30RCF112

Desconectado laurabec

  • PIC10
  • *
  • Mensajes: 14
RE: transmisión serie pic16f876
« Respuesta #2 en: 23 de Agosto de 2004, 06:14:00 »
muxas gracias por mirarlo! alimentado sí que está. igual es q tengo mal lo de C++...........¿cómo puedo probarlo sin hacer uso del Builder? añado el código x si es cosa de ésto........gracias!
//---------------------------------------------------------------------------

#include <vcl.h>
#include <iostream.h>
#pragma hdrstop

#define NOMBRE1 "COM1"
#define NOMBRE2 "COM2"


//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
        char datos [1000];
        DWORD escritos;
        BOOL finalizado = false;
        OVERLAPPED over;
        //Abrimos puerto
        HANDLE puerto = CreateFile(NOMBRE2,GENERIC_WRITE,0, NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
        if(puerto== INVALID_HANDLE_VALUE){
                DWORD e=GetLastError();
                return e;
                }
        over.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
        if (over.hEvent == NULL)
                {
                        cout<<"No se accede a recurso de S.O "<<endl;
                        return -1;
                }

                //Configuración del puerto de TRANSMISIÓN
        DCB midcb;
        DWORD e1=GetCommState(puerto, &midcb);
        if(e1==0){
                DWORD e=GetLastError();
                CloseHandle(puerto);
                return e1;
        }
        midcb.BaudRate=CBR_9600;
        midcb.fParity = TRUE;
        midcb.Parity=EVENPARITY;
        midcb.StopBits=ONESTOPBIT;
        midcb.ByteSize=8;
        e1=SetCommState(puerto,&midcb);
        if(e1==0){
                CloseHandle(puerto);
                DWORD e2=GetLastError();
                return e2;
        }
              //Escribimos los datos
        BOOL recibido=WriteFile(puerto,"HOLA",4, &escritos, &over);
        if (recibido == 0)
        {
        do {
                BOOL berror = GetOverlappedResult(puerto, &over, &escritos, false);
                DWORD error = GetLastError();
                if (berror == 0)
                {
                        if ((error == ERROR_IO_INCOMPLETE) || (error != ERROR_IO_PENDING))
                        {
                                cout << "La operación de escritura asíncrona no ha finalizado aún "<<endl;
                        }
                        else
                        {
                                cout << "Error en el proceso de I/O "<<endl;
                                return -2;
                        }

                }
                else
                        {
                                cout << "Operación finalizada correctamente "<<endl;
                                finalizado = true;
                                CloseHandle(over.hEvent);
                        }
        } while (finalizado == false);
        }

                //Liberamos el puerto de lectura
        CloseHandle(puerto);
        return 0;
}
//---------------------------------------------------------------------------
 

Desconectado laurabec

  • PIC10
  • *
  • Mensajes: 14
RE: transmisión serie pic16f876
« Respuesta #3 en: 23 de Agosto de 2004, 06:17:00 »
se me olvido decir que a mi no me hace na! no se enciende ni un led..........en fin!!muxas gracias

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: transmisión serie pic16f876
« Respuesta #4 en: 23 de Agosto de 2004, 06:41:00 »
No puedo probar este código.

Lo primero comprobar el hardware, utilizas una placa de evaluación o una hecha por ti?

Probar comunicación serie del PC (ya sea tu código o utilizando Hyperterminal de windows) probar que envia y recibe

luego lo pruebas todo junto ok?
- T0ni0 -
30RCF112

Desconectado laurabec

  • PIC10
  • *
  • Mensajes: 14
RE: transmisión serie pic16f876
« Respuesta #5 en: 23 de Agosto de 2004, 09:21:00 »
la placa la hice yo...........según un esquema al igual al q hay en esta dirección http://informatica.uv.es/iiguia/SBM/lsbm_p5.pdf.
las conexiones ya las comprobe y si q están bien!!!
mañ pruebo con lo del hiperterminal y os cuento! muxas gracias por todo!!

Desconectado laurabec

  • PIC10
  • *
  • Mensajes: 14
RE: transmisión serie pic16f876
« Respuesta #6 en: 23 de Agosto de 2004, 09:24:00 »
jooooooooor! el esquema viene en esta dirección!
http://informatica.uv.es/iiguia/SBM/lsbm_p4.pdf
es q ando a uvas!

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: transmisión serie pic16f876
« Respuesta #7 en: 23 de Agosto de 2004, 09:36:00 »
Antes de todo, he visto el esquema de la rs-232, en el PIN 5 de DB9 tienes que ponerla a masa y luego hacer un puente entre el pin 7 y 8.

Con esto lo vuelves a probar, muchas veces solo con el puenta ya puede ser que no te funcione nada ok?
- T0ni0 -
30RCF112

Desconectado gabotronic

  • PIC12
  • **
  • Mensajes: 57
RE: transmisión serie pic16f876
« Respuesta #8 en: 26 de Agosto de 2004, 06:41:00 »
Perdon por la intromision, pero se asume que esta por intermedio un max232 o algo por el estilo no?

Saludos

Desconectado laurabec

  • PIC10
  • *
  • Mensajes: 14
RE: transmisión serie pic16f876
« Respuesta #9 en: 26 de Agosto de 2004, 06:44:00 »
sí claro, utilizo un max232 con un esquema como el de la pag q puse! gracias por entremeterte xq esto no va ni xa atras ni xa alante!

Desconectado elabuelillo

  • PIC10
  • *
  • Mensajes: 1
RE: transmisión serie pic16f876
« Respuesta #10 en: 10 de Noviembre de 2004, 17:13:00 »

Hola,

estoy empezando a manejar la comunicacion serie con el 16f876 y tampoco soy capaz de comunicarme con él. Utilizo un programa de Vbasic que ya he probado con el 16f84a y funcionaba perfectamente. El mismo programa no es capaz de enviar ni un byte al pic. Me podeis dar alguna pista de que estaria haciendo mal.
Os paso la parte de codigo de visual.¿quizá hay otra version más nueva del MScomm?

Private Sub cmdEnviar_Click()
   
   a = CByte(opcion)
   byte0 = Chr$(a)
   B = CByte(vel)
   byte1 = Chr$(B)
   C = CByte(angulo)
   byte2 = Chr$(C)
   d = CByte(0)
   byte3 = Chr$(d)
   
 
   comTelefono.PortOpen = True
   comTelefono.Output = byte0
   
   comTelefono.PortOpen = False
   "Retardo
   "comTelefono.PortOpen = True
   "comTelefono.Output = byte1
   "comTelefono.PortOpen = False
   "Retardo
   "comTelefono.PortOpen = True
   "comTelefono.Output = byte2
   "comTelefono.PortOpen = False
   "Retardo
   "comTelefono.PortOpen = True
   "comTelefono.Output = byte3
   "Retardo
   "comTelefono.PortOpen = False
   
     
End Sub


En mi PC solo pude comunicar a 4800 bps cosa que no se puede hacer con el 16f876 con 4Mhz. Tambien he visto en vuestros programas que utilizais .25 para el SPBRG a 9600 y 4Mhz, según el catálogo que tengo este parámetro es para 2400 baudios para ese reloj.