16F84 et le port rs232
Répondre à la discussion
Affichage des résultats 1 à 4 sur 4

16F84 et le port rs232



  1. #1
    inviteeda80a3d

    je recherche de petits exemples de gestion du port série avec un pic 16f84
    Je sais utiliser le port série en Delphi
    exemple1: commander une sortie du pic (allumer 1 led) à partir du pc
    exemple2: lire l'état d'un port (inter ON ou OFF)
    Faut-il un max 232 entre le pic et le pc
    merci
    André

    -----

  2. #2
    Antoine

    Salut !

    Oui je pense qu'il faut un MAX232, puisque le rs232 c'est du NRZ (+12 -12) et que le pic fonctionne en TTL (0 +5)....

    Voili voilou

    @++

  3. #3
    inviteeda80a3d

    merci de la réponse où peut-on trouver de petits exemples car j'en ai trouvé pour une direction pc 16f mais pas 16f vers pc

  4. #4
    Bigonoff

    Salut
    -------

    Voici un exemple d'utilisation d'une liaison série pour carte ISO 7816.
    La différence est que la ligne émission/réception est unique, mais c'est très simple de dédoubler.
    Pour plus d'infos, tu peux regarder dans mon cours-part1 disponible sur mon site :www.abcelectronique.com/bigonoff

    A+
    Bigonoff

    ;***************************** ****************************** ***********
    ; Ce fichier est la base de départ pour la gestion d'une carte *
    ; répondant à la norme ISO7816. *
    ; *
    ;***************************** ****************************** ***********
    ; *
    ; NOM: ISO7816 *
    ; Date: 10/03/2001 *
    ; Version: 1.0 *
    ; Circuit: Carte pour serrure codée *
    ; Auteur: Bigonoff *
    ; *
    ;***************************** ****************************** ***********
    ; *
    ; Fichier requis: P16F84.inc *
    ; *
    ;***************************** ****************************** ***********
    ; *
    ; - MCLR Commande de reset de la carte Entrée *
    ; - RB7 DATA - données mode série Bi-directionnel *
    ; *
    ;***************************** ****************************** ***********


    LIST p=16F84 ; Définition de processeur
    #include <p16F84.inc> ; Définitions des constantes

    __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC

    ; Code protection OFF
    ; Timer reset sur power on en service
    ; Watch-dog hors service
    ; Oscillateur quartz grande vitesse

    ;***************************** ****************************** **********
    ; ASSIGNATIONS *
    ;***************************** ****************************** **********

    OPTIONVAL EQU 0x08 ; Valeur registre option
    ; Résistance pull-up ON
    ; Préscaler timer à 1

    ;***************************** ****************************** **********
    ; DEFINE *
    ;***************************** ****************************** **********

    #DEFINE SERIAL PORTB , 7 ; connection port série

    ;***************************** ****************************** **********
    ; MACRO *
    ;***************************** ****************************** **********

    BANK0 macro
    bcf STATUS , RP0 ; passer banque0
    endm

    BANK1 macro
    bsf STATUS , RP0 ; passer banque1
    endm

    WRITEE macro addwrite ; la donnée se trouve dans W
    movwf EEDATA ; placer data dans registre
    movlw addwrite ; charger adresse d'écriture
    movwf EEADR ; placer dans registre
    bcf INTCON , GIE ; interdire interruptions
    bsf STATUS , RP0 ; passer en banque1
    bcf EECON1 , EEIF ; effacer flag de fin d'écriture
    bsf EECON1 , WREN ; autoriser accès écriture
    movlw 0x55 ; charger 0x55
    movwf EECON2 ; envoyer commande
    movlw 0xAA ; charger 0xAA
    movwf EECON2 ; envoyer commande
    bsf EECON1 , WR ; lancer cycle d'écriture
    bcf EECON1 , WREN ; verrouiller prochaine écriture
    bsf INTCON , GIE ; réautoriser interruptions
    bcf STATUS , RP0 ; repasser en banque0
    endm

    ;***************************** ****************************** **********
    ; DECLARATIONS DE VARIABLES *
    ;***************************** ****************************** **********

    CBLOCK 0x00C ; début de la zone variables
    Ser_Ins ; instruction ISO7816
    Ser_P1 ; paramètre 1 ISO7816
    Ser_P2 ; paramètre 2 ISO7816
    Ser_Len ; longueur data ISO7816
    local1 : 1 ; variable locale 1
    local2 : 1 ; variable locale 2
    local3 : 1 ; variable locale 3
    local4 : 1 ; variable locale 4

    temp_sauvw : 1 ; sauvegarde de W pour temp
    ENDC ; Fin de la zone

    ; routine ATR
    ; -----------
    #DEFINE cmpt1 local1 ; compteur d'octets pour ATR

    ; sous-routine send et receive
    ; ----------------------------
    #DEFINE caract local2 ; caractère à envoyer
    #DEFINE parite local3 ; bit de parité
    #DEFINE cmptbts local4 ; compteur de bits

    ; pour STATUS
    ; -----------
    #DEFINE status2 local1 ; octet 2 du status

    ; pour instruction 25
    ; -------------------
    #DEFINE cmpt2 local1 ; compteur d'octets

    ;***************************** ****************************** **********
    ; DECLARATIONS DE LA ZONE EEPROM *
    ;***************************** ****************************** **********
    org 0x2100 ; adresse début zone eeprom

    ATR DE 0x07 ; Réponse à l'ATR
    DE 0xAB ; B7 01 BB AB 07
    DE 0xBB
    DE 0x01
    DE 0xB7


    ;***************************** ****************************** **********
    ; INITIALISATIONS *
    ;***************************** ****************************** **********
    org 0x000 ; Adresse de départ après reset
    init
    BANK1 ; passer banque1
    movlw OPTIONVAL ; charger masque
    movwf OPTION_REG ; initialiser registre option
    BANK0 ; passer banque0

    ;***************************** ****************************** **********
    ; PROGRAMME PRINCIPAL *
    ;***************************** ****************************** **********

    start
    ; on commence par attendre un peu
    ; -------------------------------

    call temp_1bd ; attendre 1 bit et demi

    ;============================= ============================== ==========
    ; ENVOI DE L'ATR =
    ;============================= ============================== ==========
    ;---------------------------------------------------------------------
    ; Envoi d'un ATR fictif : l'ATR est dans les 5 octets de 0x04 à
    ; 0x00 de l'eeprom interne. L'ATR est écris en sens inverse
    ;---------------------------------------------------------------------

    movlw 0x5 ; pour 5 octets
    movwf cmpt1 ; dans compteur de boucles = adresse

    ATR_loop
    decf cmpt1 , w ; adresse à lire = compteur de boucles-1
    call Rd_eeprom ; Lire un octet eeprom interne
    call Send ; Envoyer sur le décodeur
    decfsz cmpt1 , f ; décrémenter compteur
    goto ATR_loop ; pas fini, suivant

    ;============================= ============================== ==========
    ; ENVOI DU STATUS STANDARD =
    ;============================= ============================== ==========
    ;---------------------------------------------------------------------
    ; Envoie le status standard, dans ce cas on a pris 0x80 0X00
    ;---------------------------------------------------------------------
    Statstd
    movlw 0x80 ; prendre 1er octet status
    call Send ; l'envoyer
    clrw ; effacer w
    call Send ; envoyer 00
    goto classe ; et traiter classe

    ;============================= ============================== ==========
    ; ENVOI D'UN STATUS SPECIFIQUE =
    ;============================= ============================== ==========
    ;---------------------------------------------------------------------
    ; Envoie d'abord l'octet contenu dans w, puis l'octet contenu dans
    ; status2
    ;---------------------------------------------------------------------
    Statxx
    call Send ; on envoie valeur
    movf status2 , w ; charger byte à envoyer
    call Send ; on envoie 2ème octet du status

    ;============================= ============================== ==========
    ; LECTURE DE LA CLASSE =
    ;============================= ============================== ==========
    ;---------------------------------------------------------------------
    ; on considère dans cet exemple qu'il n'y a qu'une seule classe
    ; valide. on attend l'arrivée de la classe et on ne la traite pas
    ;---------------------------------------------------------------------
    classe
    call Receive ; Lire le byte venant du maître

    ;============================= ============================== ==========
    ; LECTURE DE INS,P1,P2,LEN =
    ;============================= ============================== ==========
    ;---------------------------------------------------------------------
    ; INS sera placé dans la variable Ser_ins
    ; P1 sera placé dans Ser_P1 et P2 dans Ser_P2
    ; La longueur du champs de data sera dans Ser_len
    ;---------------------------------------------------------------------

    movlw Ser_Ins ; pointer sur emplacement instruction
    movwf FSR ; initialiser pointeur indirection
    read_loop
    call Receive ; Lire un octet
    movwf INDF ; sauver dans emplacement prévu
    incf FSR , f ; pointer sur suivant
    btfss FSR , 0x4 ; Tester si adresse 0x10 atteinte
    goto read_loop ; non, octet suivant

    ;============================= ============================== ==========
    ; SWITCH SUIVANT INSTRUCTION RECUE =
    ;============================= ============================== ==========
    ;---------------------------------------------------------------------
    ; Nous allons imaginer que nous allons réagir à une instruction 0x25
    ; Toute autre instruction sera considérée comme incorrecte
    ; Dans le cas d'une instruction incorrecte, nous reverrons un status
    ; 0x60 0x40
    ;---------------------------------------------------------------------

    ; tester instruction reçue
    ; ------------------------
    movf Ser_Ins , w ; charger instruction reçue
    sublw 0x25 ; comparer avec 0x25
    btfsc STATUS , Z ; tester si identique
    goto Ins25 ; oui, traiter instruction 25

    ; traiter instruction incorrecte
    ; ------------------------------
    movlw 0x40 ; charger octet2 status à envoyer
    movwf status2 ; placer dans variable
    movlw 0x60 ; charger octet 1 status
    goto Statxx ; envoyer status

    ;============================= ============================== ==========
    ; TRAITER INSTRUCTION 25
    ;============================= ============================== ==========
    ;---------------------------------------------------------------------
    ; On va traiter cette instruction bidon de la manière suivante :
    ; 1) Comme dans toute instruction, on renvoie la commande reçue
    ; 2) L'instruction renvoie la somme de P1 et de P2.
    ; 3) La trame d'envoi est complété par des 0xFF pour atteindre une
    ; longueur totale de data identique à Ser_Len
    ; 4) Ensuite le status standard est envoyé
    ;---------------------------------------------------------------------
    Ins25
    ; envoyer écho de la commande
    ; ---------------------------
    movf Ser_Ins , w ; charger commande reçue
    call Send ; renvoyer en écho

    ; renvoyer P1 + P2
    ; ----------------
    movf Ser_P1 , w ; charger P1
    addwf Ser_P2 , w ; + P2
    call Send ; envoyer résultat

    ; Tester longueur de la réponse
    ; -----------------------------
    decf Ser_Len , f ; car déjà résultat envoyé
    btfsc STATUS , Z ; tester si complet
    goto Statstd ; oui, envoyer status standard

    ; compléter avec des 0xFF
    ; -----------------------
    Insloop
    movlw 0xFF ; valeur à envoyer
    call Send ; envoyer 0xFF
    decfsz Ser_Len , f ; décrémenter compteur de boucles
    goto Insloop ; pas fini, suivant

    ; envoyer status standard
    ; -----------------------
    goto Statstd ; envoyer status standard


    ;***************************** ****************************** **********
    ; TEMPORISATION *
    ;***************************** ****************************** **********
    ;---------------------------------------------------------------------
    ; temp_1bd: initialise tmr0 pour que la temporisation soit égale à
    ; l'équivalent d'un bit et demi, soit 46+93 incrémentations
    ; de tmr0 - le temps nécessaire pour arriver dans la routine
    ; temp_1b : Attend que l'écart entre la précédente tempo et la tempo
    ; actuelle soit de 1 bit, soit 93 instructions
    ;---------------------------------------------------------------------

    temp_1bd
    movlw -40 ; préparer valeur tmr0
    movwf TMR0 ; initialiser tmr0
    call temp_suite ; et attendre 1/2 bit

    temp_1b
    movlw -93 ; écart entre 2 bits
    addwf TMR0 , f ; ajouter à la valeur actuelle

    temp_suite
    bcf INTCON , T0IF ; effacer flag
    temp_wait
    btfss INTCON , T0IF ; attendre débordement timer
    goto temp_wait ; pas fini, attendre
    return ; et sortir

    ;***************************** ****************************** **********
    ; Lecture d'un octet en eeprom interne *
    ;***************************** ****************************** **********
    ;---------------------------------------------------------------------
    ; Lecture d'un octet de l'eeprom interne. L'adresse est passée dans w
    ; l'octet lu est retourné dans W
    ;---------------------------------------------------------------------
    Rd_eeprom
    movwf EEADR ; adresse à lire dans registre EEADR
    bsf STATUS , RP0 ; passer en banque1
    bsf EECON1 , RD ; lancer la lecture EEPROM
    bcf STATUS , RP0 ; repasser en banque0
    movf EEDATA , w ; charger valeur lue dans W
    return ; retour

    ;***************************** ****************************** **********
    ; Envoi d'un octet vers le lecteur de carte *
    ;***************************** ****************************** **********
    ;---------------------------------------------------------------------
    ; envoie l'octet contenu dans le registre w vers le lecteur de carte
    ;---------------------------------------------------------------------
    Send
    movwf caract ; Sauver caractère à envoyer
    call temp_1bd ; attendre 1 bit et demi
    BANK1 ; passer banque1
    bcf SERIAL ; port série en sortie
    BANK0 ; repasser banque0

    ; envoyer start-bit
    ; -----------------
    bcf SERIAL ; envoyer 0 : start-bit
    clrf parite ; effacer bit de parité

    movlw 8 ; pour 8 bits à envoyer
    movwf cmptbts ; dans compteur de bits
    call temp_1b ; attente entre 2 bits


    ; envoyer 8 bits de data
    ; ----------------------
    Send_loop
    rrf caract , f ; décaler caractère, b0 dans carry
    rrf caract , w ; carry dans b7 de w
    andlw 0x80 ; garder bit à envoyer en position b7
    xorwf parite , f ; positionner parité
    xorwf PORTB , w ; Garder 1 si changement sur SERIAL
    xorwf PORTB , f ; si oui, inverser RB7
    call temp_1b ; attente entre 2 bits
    decfsz cmptbts , f ; décrémenter compteur de bits
    goto Send_loop ; pas dernier, suivant

    ; envoyer parité
    ; --------------
    movf parite , w ; charger parité paire calculée
    xorwf PORTB , w ; Si serial différent de bit à envoyer
    xorwf PORTB , f ; alors inverser RB7
    call temp_1b ; attendre fin de parité

    ; envoyer 2 stop-bits
    ; -------------------
    BANK1 ; passer banque1
    bsf SERIAL ; repasser en entrée (et niveau haut)
    BANK0 ; passer banque0
    call temp_1b ; attendre temps entre 2 bits
    call temp_1b ; attendre temps entre 2 bits
    return ; et retour

    ;***************************** ****************************** **********
    ; Réception d'un octet provenant du maitre *
    ;***************************** ****************************** **********
    ;---------------------------------------------------------------------
    ; Caractère lu dans W. La parité pas n'est pas vérifiée
    ;---------------------------------------------------------------------
    Receive
    ; attendre début start-bit
    ; ------------------------

    btfsc SERIAL ; Tester si start bit arrivé
    goto Receive ; non, attendre

    ; se positionner sur le milieu du 1er bit utile
    ; ---------------------------------------------

    call temp_1bd ; attendre 1bit et demi

    ; réception du caractère
    ; ----------------------

    movlw 0x8 ; pour 8 bits
    movwf cmptbts ; dans compteur de bits

    Recloop
    bcf STATUS , C ; Carry = 0
    btfsc SERIAL ; tester si bit = 0
    bsf STATUS , C ; Carry = bit reçu
    rrf caract , f ; faire entrer le bit par la gauche
    call temp_1b ; attendre milieu caractère suivant
    decfsz cmptbts , f ; décrémenter compteur de bits
    goto Recloop ; pas dernier, suivant


    ; on pointe maintenant sur moitié du bit de parité
    ; reste donc à attendre au moins 1.5 bits
    ; ------------------------------------------------

    call temp_1bd ; Attendre 1,5 bit
    movf caract , w ; charger caractère lu
    return ; et retour


    END ; directive fin de programme
    Vive l'Internet libre

  5. A voir en vidéo sur Futura

Discussions similaires

  1. probleme activation port 16f84
    Par orphe2000 dans le forum Électronique
    Réponses: 14
    Dernier message: 24/06/2007, 21h55
  2. Émetteur/Récepteur liaison wireless sur port série RS232
    Par invite9766527f dans le forum Électronique
    Réponses: 3
    Dernier message: 28/02/2006, 22h52
  3. tension de sortie du port serie rs232
    Par invitee335123b dans le forum Électronique
    Réponses: 13
    Dernier message: 19/02/2006, 20h52
  4. Port d'E/S d'un pic 16F84
    Par WhiteBird dans le forum Électronique
    Réponses: 8
    Dernier message: 03/01/2006, 09h18
  5. temps de réaction des port sur 16f84
    Par maho dans le forum Électronique
    Réponses: 8
    Dernier message: 08/07/2004, 21h40
Découvrez nos comparatifs produits sur l'informatique et les technologies.