F8EOZ » Microcontrôleur http://www.f8eoz.com Informatique - Electronique - Ham radio Thu, 11 May 2017 15:37:43 +0000 fr-FR hourly 1 http://wordpress.org/?v=3.5 PIC Microchip – Application du 16F88 – Le Bootloader http://www.f8eoz.com/?p=3904 http://www.f8eoz.com/?p=3904#comments Mon, 23 Nov 2015 11:41:18 +0000 admin http://www.f8eoz.com/?p=3904 chargePIC_1473Cet article s’inscrit dans le droit fil des précédents, l’utilisation et la programmation des microcontrôleurs. Le 16F88 à un avantage sur les microcontrôleurs que j’ai utilisés jusqu’ à présent, il dispose de la possibilité d’écriture de son propre programme (self-programming). Ce programme est chargé dans le PIC au moyen de deux autres programmes, l’un situé sur le PC, l’autre résident sur le PIC appelé Bootloader  qui communiquent entre-eux. Le programme résident nécessite d’être chargé une première fois, au moyen d’un programmateur.

1. Cahier des charges

1.1. Contraintes techniques

Si l’avantage de ce dispositif est de faciliter la mise au point des programmes en évitant de remettre sans cesse le microcontrôleur sur le banc du programmateur, il y a aussi des inconvénients.

Le premier tient au Bootloader lui-même. Le programme résident consomme un peu de l’espace mémoire du PIC et réduit d’autant l’espace disponible pour l’application. Les suivants sont inhérents à la technologie et au fonctionnement du PIC.

La configuration du microcontrôleur ne peut pas être changée dynamiquement ce qui implique de recharger le programme résident au moyen du programmateur lorsque la configuration ne correspond plus à l’usage.

La technique d’écriture en mémoire programme peut varier d’un microcontrôleur à l’autre. L’écriture en mémoire programme du 16F88 nécessite une phase d’effacement préalable (Erase). L’effacement est réalisé par bloc de 32 mots. Les 11 bits les plus forts de l’adresse pointent sur le bloc à effacer, les bits de poids faibles 4:0 sont ignorés. Quant à l’écriture, elle est réalisée en bloc de 4 mots. Un bloc à écrire consiste en 4 mots consécutifs dont les 2 bits 1:0 de poids faibles de l’adresse s’étendent de 00 à 11. Les mots sont placés en buffer d’écriture et l’opération d’écriture n’est effective qu’à l’application du mot 11. Cette séquence est réalisée automatiquement par le processeur. L’écriture en EEPROM se fait mot par mot de 8 bits sans effacement préalable. Tout ceci est fort bien expliqué dans la documentation technique du 16F88 de MICROCHIP au chapitre 3 « DATA EEPROM AND FLASH PROGRAM MEMORY ».

1.2. Solution

Le travail est réparti sur 2 programmes l’un sur le PIC, le Bootloader, appelé chargePIC16F88, l’autre sur le PC, appelé chargePIC.

1.2.1. Le Bootloader chargePIC16F88

Son rôle sera simplifié au maximum. Bien que son nom porte le suffixe 16F88, j’espère le généraliser à d’autres PIC du même type, mais c’est une autre histoire et je ne peux le vérifier sans faire de tests. A dessein, pour le rendre générique, il ne traite qu’une opération élémentaire à la fois envoyée par le PC :

  • connexion (login),
  • lecture d’un mot en mémoire programme,
  • lecture d’un mot en EEPROM,
  • effacement d’un bloc en mémoire (ici le terme bloc peut signifier 1 ou n mots selon le microcontrôleur),
  • écriture d’un mot en mémoire programme,
  • écriture d’un mot en EEPROM,
  • déconnexion (logout) et exécution de l’application.
Calcul

CRC (contrôle de redondance cyclique ou checksum) qui se résume à une addition et une opération logique. En cas d’erreur, l’opération est rejetée et un code est retourné au PC qui s’en arrange.

Configuration

La version proposée ici est une version basique avec oscillateur interne à 4MHz. qui utilise pour mes tests un minimum de composants. D’autres variantes avec oscillateurs externes seront disponibles en téléchargement.

Plan mémoire

Le Bootloader est réparti sur 2 segments mémoire :
l’un en tête, servant au reset et la redéfinition du plan mémoire pour l’application utilisateur (re-mapping),
l’autre, en fin de mémoire, le Bootloader proprement-dit.

Le Bootloader doit rester à l’abri de l’écriture. Pour les 16F88 ces segments sont calés sur des blocs de 32 mots au prix de la perte d’un peu de place.
Le plan mémoire ainsi défini pour le 16F88 et sa famille n’est pas figé pour s’adapter à d’autres microcontrôleurs et ne pas gaspiller la place mémoire. Au login, le PIC transmet au PC les propriétés du Bootloader.  Avec ces propriétés, le PC se construit  une image du plan mémoire.

Déclenchement

Au reset, à la mise sous tension, chargePIC16F88 attend un code de LOGIN. Au bout d’un temps réglable (login timeout), en l’absence de réception de ce code, LOGOUT/RUN est exécuté et l’application utilisateur est lancée. A réception du LOGIN le Bootloader retourne le code de LOGIN et les propriétés du Bootloader.  L’application hôte chargePIC est maintenant maître du PIC. Le Bootloader chargePIC16F88  se met en attente d’une commande de l’hôte.

1.2.2. L’application hôte chargePIC

Son rôle premier est de charger un fichier HEX (Intel) contenant les instructions de l’application utilisateur dans l’espace mémoire du PIC qui lui est réservée. Au prix d’un peu de code supplémentaire, je l’ai doté de fonctions de lecture pour faciliter le débogage et l’écriture séparée de l’EEPROM pour la mise à jour de paramètres. Pour atteindre ces buts, l’application dispose des fonctions suivantes :

  1. Se connecter au PIC et obtenir les propriétés du Bootloader
  2. Choisir dans une liste le µcontrôleur et ses propriétés,
  3. Charger le fichier HEX contenant l’application utilisateur, le traduire en liste d’instructions et en afficher le résultat
  4. Afficher le plan mémoire programme utilisateur et EEPROM
  5. Effacer écrire l’application utilisateur
  6. Relire vérifier l’écriture du programme utilisateur
  7. Lire la mémoire programme ou l’EEPROM
  8. Enregistrer l’historique du traitement dans un fichier journal (log)
  9.  Calculer SPBRG
  10. Calculer le délai de connexion

Le  logiciel dispose d’un catalogue des microcontrôleurs et de leurs propriétés qui pourra être enrichi.

L’application fonctionne sous Windows, testée sous Windows7 64 bits.

2. Choix des outils de développement

En tant qu’amateur j’utilise uniquement des outils gratuits ou des Open source.

2.1. Bootloader chargePIC16F88

Environnement de développement MICROCHIP: MPLAB IDE v8.92.
Langage de programmation: assembleur MPASMWIN v5.51 . Je reste fidèle à l’assembleur qui, pour moi, reste le moyen le plus simple et le plus clair d’obtenir la meilleure solution à ce type de problème.

2.2. Application hôte chargePIC

Environnement de développement MICROSOFT: IDE Microsoft Visual Studio 2015 pour Windows Desktop.
Langage de programmation: Microsoft Visual C# 2015 .

3. Choix du dispositif de communication

PC : Lignes de communication Emission/Réception : port série RS232.
Interface : Liaison série: asynchrone, convertisseur RS232 TTL MAX3232.
PIC : Lignes de communication Emission/Réception  UART: bornes TX et RX du PIC.

La trame UART est constituée des bits suivants :

  • un bit de start servant à la synchronisation du récepteur,
  • 8 bits de données,
  • pas de bit de parité,
  • un bit de stop.
Figure 1 - Diagramme fonctionnel

Figure 1 – Diagramme fonctionnel

4. Mise en oeuvre du Bootloader chargePIC16F88

La figure 1, ci-contre, montre le diagramme fonctionnel du dispositif. Comme vous pouvez le constater, il est le fils de usartELOADER décrit dans l’article précédent, implémenté de nouvelles fonctions. Le protocole de transmission a été revisité.

4.1. Initialisation

Le programme doit être chargé une première fois au moyen d’un programmateur. J’ai utilisé mon programmateur et l’excellent PICpgm. L’opération est sans souci. Le 16F88 s’insère sur le support ZIF de la même manière que le 16F84.

4.2. Test de bon fonctionnement

Le bootloader est fourni préchargé dans l’espace utilisateur avec un petit programme qui fait simplement clignoter une LED. Pour le faire fonctionner, connecter en série sur la broche 1 du PIC (port RA2) une résistance de 470 Ω et une LED. Sur le PC, activer chargePIC (qui sera décrit ci-après), cliquer sur Connecter (Login) puis sur Exécuter (Run). La LED doit clignoter, signe que tout va bien ! Ce petit programme sera naturellement détruit ensuite par le chargement de votre propre application.

4.3. Application utilisateur

Un exemple d’application est donné ci-dessous. Il faut veiller à rester dans les limites de la mémoire dédiée à l’application. Le logiciel chargePIC prévient tout effacement du Bootloader et signale les débordements.


__CONFIG    _CONFIG1, _INTRC_IO  & _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
            & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
__CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF

;-------------------------
; Programm Vector  Address
RESET_VECTOR	EQU	0x0000	; Address of RESET Vector
ISR_VECTOR      EQU	0x0004	; Address of Interrupt Vector
BANK0_RAM_DATA	EQU	0x0020	; 16 General Purpose registers (SRAM)
COMMON_RAM_DATA	EQU	0x0070	; 16 General Purpose registers (SRAM)
EEPROM_DATA     EQU	0x2100	; EEPROM address

;----------------------------------------------------------------------
; BOOTLOADER RESET SEGMENT RESERVED 32 WORDS
;----------------------------------------------------------------------
BLOADER_OFFSET    EQU 0x20

    ORG     RESET_VECTOR
    goto    RESET_VECTOR+BLOADER_OFFSET

; interrupt vector
    ORG     ISR_VECTOR
    goto    RESET_VECTOR+BLOADER_OFFSET+4

;----------------------------------------------------------------------
; END BOOTLOADER RESET SEGMENT RESERVED 32 WORDS
;----------------------------------------------------------------------

;----------------------------------------------------------------------
; USER APPLICATION SEGMENT
;----------------------------------------------------------------------

; Re-mapped Reset Vector
    ORG     RESET_VECTOR+BLOADER_OFFSET
UserReset
    goto    UserStart

; Re-mapped Interrupt Vector
    ORG     RESET_VECTOR+BLOADER_OFFSET+4
UserISR
    ;retfie
    goto    UserInterrupt

;----------------------------------------------------------------------
; USER PROGRAM STARTS HERE
;----------------------------------------------------------------------

UserStart
Main
#DEFINE LED    PORTA,2            ; LED

    banksel PORTA
    clrf    PORTA
    clrf    PORTB
    ; set up option register
    bsf     STATUS,RP0        ; Bank1
    movlw   B'00001000'
    ;         0-------  NOT RBPU: 0 = PORTB pull-ups are enabled by individual port latch values
    ;         -0------  INTEDG: 0 = Interrupt on rising edge of RB0/INT pin
    ;         --0-----  T0CS: 1 = Transition on GP2/T0CKI pin0=output
    ;         ---0----  T0SE: 1 = Increment on high-to-low transition on /T0CKI pin not used, MCLR and reset
    ;         ----1---  PSA: 1 = Prescaler is assigned to the WDT
    ;         -----000  PS2:PS0: 111= 1:128 prescaler
    movwf   OPTION_REG
    bcf     LED                ; TRISA output
    bcf     STATUS, RP0        ; Bank0

MainLoop
    bsf     LED                ; LED on
    call    delay
    bcf     LED                ; LED off
    call    delay
    nop
    nop

    goto    MainLoop    ; For Ever Loop------>

;-------------------------
; USER PROGRAM SUBROUTINES
;-------------------------
delay
    movlw   2
    movwf   cmpt3
delay3
    clrf    cmpt2
delay2
    clrf    cmpt1
delay1
    nop
    decfsz  cmpt1, f
    goto    delay1
    decfsz  cmpt2, f
    goto    delay2
    decfsz  cmpt3, f
    goto    delay3
    return

;------------------
; INTERRUPT MANAGER
;------------------
UserInterrupt
    ;save register
    movwf	ISRwreg  		; WREG
    swapf	STATUS,w		; STATUS without change Z
    movwf	ISRstatus		;
    ;restore register
UserInterrupt_end
    swapf	ISRstatus,w		; STATUS without change Z
    movwf   STATUS
    swapf   ISRwreg,f		        ; WREG without change Z
    swapf   ISRwreg,w
    retfie  				; return from interrupt set GIE

;----------------------------------------------------------------------
; EEPROM
;----------------------------------------------------------------------
	org 	EEPROM_DATA

;----------------------------------------
;              Month Day   Year  Vnum
EE_VERSION	DE D'11',D'20',D'15',1,0,0
EE_SETTING	DE "chargePIC_led: TEST ONE BLINK LED ON RA2 PORT"
;----------------------------------------------------------------------
; END USER APPLICATION SEGMENT
;----------------------------------------------------------------------

Download

Télécharger le programme source, le fichier .hex et tous les schémas.

5. L’application chargePIC

Comme indiqué dans le cahier des charges, c’est à chargePIC que revient le plus gros du travail.

Un mot sur la régionalisation. Visual studio offre une excellente prise en charge de la régionalisation. Le logiciel a été écrit pour être traduit. Il est fourni en 2 langues, français et anglais qu’il est possible de choisir dans l’onglet Setting, mais il est prévu pour supporter d’autres langues. Tous les textes sont mémorisés en anglais dans le fichier par défaut LocalStrings.resx  et traduit en français dans LocalStrings.fr-FR.resx. Comme d’habitude tous les sources seront disponibles en téléchargement. Pour les utilisateurs d’une autre langue, il suffit de créer son fichier LocalStrings.de-DE.resx  (Allemand par exemple) et de traduire les textes des boutons, labels, onglets, etc, de la fenêtre.  Il faut aussi modifier le constructeur de la classe HomeForm en y indiquant sa culture.

// Default language
if (settings.LanguageFrench)
Thread.CurrentThread.CurrentUICulture = FrenchCulture;
else
Thread.CurrentThread.CurrentUICulture = EnglishCulture;

Figure 2 - Fenêtre principale

Figure 2 – Fenêtre principale

5.1. Fenêtre principale MainForm

A l’ouverture, la première fenêtre, figure 2, affiche les éléments suivants:

- Le menu,
- La barre d’outils,
- Les propriétés du PIC en cours de programmation en hexadécimal et décimal,
- Les propriétés du Bootloader en hexadécimal et décimal,
- L’onglet Fichier Hex,
- Le journal (fichier log).

Le port par défaut est COM1, chez moi je n’ai que celui-là. Si vous en avez d’autres à vous de choisir dans la liste. Vérifier sur le journal que le port est bien ouvert.
Cliquer sur le bouton Login. Ceci a pour effet de charger les propriétés du Bootloader et de créer l’image mémoire.
Vérifier sur le journal que l’opération s’est bien passée.
Pour importer le fichier hex cliquer sur le bouton Importer fichier hex. L’onglet Fichier Hex  se divise en 3 parties:

  • à gauche la liste brute des articles du fichier hex,
  • au centre la liste des instructions après analyse du fichier hex,
  • à droite les valeurs de config1 et config2 et la plus haute adresse utilisée par le programme.

En cas de débordement sur le Bootloader un message erreur est écrit sur le Log.

Figure 3 - Mémoire programme

Figure 3 – Mémoire programme

5.2. Mémoire image

A ce stade du travail, les onglets Mémoire programme et EEPROM montrent l’état de la mémoire qui sera chargée dans le PIC. En rouge, l’espace protégé du Bootloader qui ne sera pas changé, en bleu, l’espace réservé à l’application utilisateur qui pourra être réécrit. La figure 3 ci-contre, montre en rouge,  le segment que j’ai appelé offset qui contient le vecteur de reset et de logout du Bootloader ainsi que les adresses qui redéfinissent le vecteur d’interruption et le vecteur de reset de l’application utilisateur. La figure 4 ci -dessous, montre la partie haute de la mémoire contenant le Bootloader proprement dit. La figure 5, montre l’EEPROM qui est exclusivement utilisée par l’application utilisateur. Cet espace étant en général utilisé pour conserver des paramètres de fonctionnements ou des résultats, cette fenêtre nous offrira un moyen de tracer nos programmes puisque chargePIC nous permet de le relire.

Figure 4 - Mémoire programme haute

Figure 4 – Mémoire programme haute

Figure 5 - EEPROM

Figure 5 – EEPROM

Download  Télécharger tous les programmes sources, hex, exe, et fichiers: Bootloader chargePIC16F88: avec petit programme démo. chargePIC16F88_led + chargePIC VISUAL C# 2010 projet complet avec sources et exe+Schémas Inkscape.

6. Utilisation de HI-TECH C Compiler

La version  picc_9_83 est disponible gratuitement sur le site de MICROCHIP  (choisir l’onglet Downloads Archive). L’installation est simple et rapide. Cocher la case version Lite pour une utilisation non professionnelle gratuite. Lorsque vous créez un projet qui utilise HI-TECH C et le Bootloader chargePIC16F88, il faut indiquer la taille de l’offset. Pour ce faire, quand le projet est créé, cliquer dans le menu sur Project>Build Options>Project. Choisir l’onglet Linker. Dans Linker options Codeoffset entrer 0×20 qui est la taille du premier bloc du Bootloader, voir Figure 6 ci-dessous. Cliquer sur OK pour terminer. Ci-dessous, le même programme écrit  et compilé avec HI-TECH C. Un petit coup d’oeil sur la map, figure 7 ci-dessous, pour voir que le vecteur de Reset et d’interruption ont été décalés de 0×20.

/*******************************************************************************
; File Name        : led16F88_test1.c
; Version          : 1.0
; Title:           : BLINK LED TEST and USART Bootloader
; Author           : F8EOZ Bernard DECAESTECKER http://f8eoz.com
; MCU              : Written and Tested on Microchip PIC 16F88 Microcontroller
; Compiler         : HI_TECH ANSI C Compiler V9.83
; IDE              : Microchip MPLAB IDE v8.92
; Programmer       : Home made
; Last Updated     : 17 December 2015
; *******************************************************************
; Hardware:
;  Tested with PIC16F88 at 4Mhz  internal oscillator.
;  USART use pin 8 as RX (RB2)
;  USART use pin 11 as TX (RB5)
; *******************************************************************
*/

#include    <pic.h>
#include    <htc.h>

//    __CONFIG    _CONFIG1, _INTRC_IO  & _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
//    __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF

#if defined(_16F88) || defined(_16F87)
    //1st: CONFIG1
    __CONFIG (FOSC_INTOSCCLK & CP_OFF & CCPMX_RB0 & DEBUG_OFF & WRT_OFF & CPD_OFF & LVP_OFF & BOREN_ON & MCLRE_ON & PWRTE_ON & WDTE_OFF & FOSC_INTOSCIO & IESO_OFF & FCMEN_OFF);
    //next: CONFIG2
    __CONFIG (IESO_OFF & FCMEN_OFF);
#else
    #error Must be compiled for 16F88, or 16F87
#endif

#ifndef _XTAL_FREQ
    // Unless already defined assume 4MHz system frequency
    // This definition is required to calibrate __delay_us() and __delay_ms()
    #define _XTAL_FREQ 4000000
#endif
#define LED        RA2    //bit 2 of PORTA
#define TRISLED    TRISA2 //bit 2 of PORTA

void interrupt tc_int(void)
{
    return;
}

void main()
{
    TRISLED = 0; //Output
    PORTA = 0b00000000;    // clrf    PORTA
    PORTB = 0b00000000;    // clrf    PORTB

    OPTION_REG = 0b00001000;
    //              0-------  NOT RBPU: 0 = PORTB pull-ups are enabled by individual port latch values
    //              -0------  INTEDG: 0 = Interrupt on rising edge of RB0/INT pin
    //              --0-----  T0CS: 1 = Transition on GP2/T0CKI pin0=output,
    //               ---0----  T0SE: 1 = Increment on high-to-low transition on /T0CKI pin not used, MCLR and reset
    //                ----1---  PSA: 1 = Prescaler is assigned to the WDT
    //              -----000  PS2:PS0: 111= 1:128 prescaler

    LED = 0;
    while(1)
    {
        LED = 1;  // LED ON
        __delay_ms(100);// delay for 100 milliseconds
        CLRWDT();
        LED = 0;  // LED OFF
        __delay_ms(100);// delay for 100 milliseconds
    }
}

Figure 6 - HI-TECH C Paramètre Offset

Figure 6 – HI-TECH C Paramètre Offset

Figure 7 - HI-TECH C map

Figure 7 – HI-TECH C map

Download  Télécharger tous les programmes sources, hex, exe, et fichiers: Bootloader chargePIC16F88: avec petit programme démo. chargePIC16F88_led + led16F88_test1.c HI-TECH C + chargePIC VISUAL C# 2010 projet complet avec sources et exe + Schémas Inkscape.
A suivre…

Index des articles de la catégorie microcontroleur

]]>
http://www.f8eoz.com/?feed=rss2&p=3904 0
PIC Microchip – Manipulateur électronique 16F628 CW Keyer et son interface de liaison série http://www.f8eoz.com/?p=3792 http://www.f8eoz.com/?p=3792#comments Mon, 21 Sep 2015 09:38:20 +0000 admin http://www.f8eoz.com/?p=3792 keyer16F628_1447Cet article est une application de l’UART, une des techniques de communication disponibles sur les PIC. USART, aussi appelé SCI, Interface de Communication Série est un dispositif qui peut être configuré en mode asynchrone full duplex ou en mode synchrone half duplex, maître ou esclave, pour communiquer avec des terminaux CRT, des ordinateurs personnels ou d’autres périphériques. Il s’agit dans ce projet d’établir une liaison entre mon ordinateur personnel et une machine construite autour d’un PIC disposant de l’USART.

1. Description du projet

1.1. Postulat de départ

Le manipulateur électronique décrit dans l’article précédent servira de base au projet. Je prévois de porter le programme du 12F675 avec un minimum de modifications vers un processeur disposant de l’USART et d’un peu plus de mémoire pour pouvoir y télécharger des messages à partir de mon ordinateur personnel. Mon choix s’est porté sur le 16F628 que j’avais en stock. En plus de l’USART, il dispose de 2K de mémoire FLASH, d’une EEPROM de 128 mots, de 1 ADC (pas directement voir ci-dessous). Je pourrais donc réutiliser le petit clavier de 9 touches. Il me faut réaliser une application hôte sur le PC qui commandera le PIC, et une interface, sur le PIC client. L’interface logicielle côté PIC devra être conçue comme un module indépendant réutilisable, utilisant un protocole de communication simple et un minimum de ressources.

1.2. Composants

1.2.1. Liaison série: asynchrone, convertisseur RS232 TTL MAX3232.

1.2.2. usartELoader: interface de chargement de l’EEPROM.
L’interface résidente sur le PIC est conçue comme un Bootloader. Le 16F628 ne disposant pas des possibilités d’écriture de son propre programme (self-programming), l’interface se limitera à l’écriture en EEPROM et à sa lecture pour en afficher le contenu.

Environnement de développement : MPLAB IDE v8.92.

Langage de programmation : assembleur MPASMWIN v5.51 pour obtenir un code compact. Moins de 170 mots mémoire, les quelques variables utilisées (moins de 10) sont temporaires et peuvent êtres redéfinies par l’application utilisateur.

Implantation : l’interface est logée en fin de mémoire.

Lignes de communication Emission/Réception : bornes TX et RX du PIC.

1.2.3. keyer16F628: manipulateur électronique.
Programme keyer12F675 porté sur le 16F628. Voir description dans l’article précedent.

1.2.4. keyerELoader: application hôte de gestion des messages préenregistrés du manipulateur électronique.

Environnement de développement et langage de programmation : IDE Microsoft Visual Studio C# 2010 Express.

Lignes de communication Emission/Réception : port série RS232.

2. Description fonctionnelle.

Le schéma figure 1 ci-dessous montre la distribution des composants de l’application.

Figure 1: keyer16F628 Schéma fonctionnel

Figure 1: keyer16F628 Schéma fonctionnel

3. Protocole de communication

L’interface usartELoader est munie d’un protocole de communication simple fonctionnant en half-duplex, l’émetteur attend toujours une réponse avant d’envoyer le message suivant.

Déclenchement: au reset, à la mise sous tension, usartELoader attend un code de LOGIN. Au bout d’un temps réglable (login timeout), en l’absence de réception de ce code, LOGOUT est exécuté et l’application utilisateur keyer16F628 est lancée. A réception du LOGIN le client renvoi le code et l’adresse d’implantation de usartELoader. L’application hôte keyerELoader est maintenant maître du PIC. UsartELoader se met en attente d’une commande de l’hôte.

Format de la trame de transmission:
une trame de transmission (ne pas confondre avec la trame  UART qui sera décrite plus loin) est composée de n bytes de 8 bits sous la forme qqbbbb,.. où qq= query code identifiant la trame et bb = byte de donnée ou d’adresse. Dans ce qui va suivre le sens de la transmission est vu du côté PIC: TX = émission du PIC vers l’hôte, RX = réception en provenance de l’hôte. La trame TX se termine par 0A (new line).

LOGIN:
Format RX: « L »
Description: au reset, à la mise sous tension, attente de ce code pendant le temps de connexion
Format TX: « L »aaaa0A
Description: LOGIN accepté , aaaa = 16 bits adresse d’implantation de usartELoader.

LOGOUT:
Format RX: « X »
Description: sortie de usartELoader et exécution de keyer16F628, généré au timeout ou envoyé par l’hôte.

WRITE EEPROM:
Format RX: « E »aaaaddddck
Description: demande d’écriture, aaaa = 16 bits adresse , dddd = 16 bits donnée, ck = 8 bits de poids faible de la somme de contrôle.

WRITE ACK:
Format TX: « K »0A
Description: accusé de réception de l’écriture.

DATA ERROR:
Format TX: « ! »0A
Description: erreur d’écriture.

CHEKSUM ERROR:
Format TX: « ? »0A
Description: erreur de la somme de contrôle.

BOUNDARY ERROR:
Format TX: « $ »0A
Description: erreur d’écriture hors limite.

PRINT EEPROM:
Format RX: « P »aaaa
Description: demande de la donnée située à l’adresse aaaa = 16 bits adresse.

PRINT EEPROM:
Format TX: « P »dddd0A
Description: donnée dddd à afficher.

4. Structure d’une trame UART

Notre trame UART est constituée des bits suivants :

  • un bit de start servant à la synchronisation du récepteur,
  • 8 bits de données,
  • pas de bit de parité,
  • un bit de stop.

5. Interface usartELoader

5.1. Description

Le module usartELoader, figure 2 ci-dessous, démarre à la mise sous tension, au reset du PIC. Une première boucle attend la réception de la trame de LOGIN. En cas de non réception dans le délai fixé (timeout) une trame de LOGOUT est générée. A réception, s’il s’agit d’une trame de LOGIN, usartELoader traite le LOGIN, enclenche sa boucle principale et se met sous contrôle du programme hôte keyerELoader. S’il s’agit d’une trame non identifiée, une trame de LOGOUT est générée.

Figure 2: usartELoader

Figure 2: usartELoader

5.2. Paramètres d’installation

L’interface usartELoader a besoin des paramètres suivants:

  • EEPROM_SIZE: taille de l’EEPROM,
  • FLASH_PROG_SIZE: taille la mémoire FLASH,

Dans le cas du 16F628 qui a 2K de mémoire FLASH et 128 mots d’EEPROM:

  • EEPROM_SIZE = 7F,
  • FLASH_PROG_SIZE = 7FF.
5.3. Paramètres du TIMER

Le délai de LOGIN est réglé par les paramètres suivants:

  • ELOADER_TIMER1_OVF: nombre de débordement de TIMER1,
  • ELOADER_TIMER1: Base de TIMER1,
  • ELOADER_T1CKPS  valeur du prédiviseur.

Avec un oscillateur XTAL = 4 MHz, le délai est fixé à 25 s environ avec les valeurs suivantes:

  • ELOADER_TIMER1_OVF = 200,
  • ELOADER_TIMER1 = 0,
  • ELOADER_T1CKPS  = 2.

Bien entendu, d’autres combinaisons sont possibles pour obtenir le même résultat. Le logiciel keyerELoader décrit plus loin, fournit les outils pour calculer différentes combinaisons de TIMER1, TIMER1_OVF, T1CKPS en fonction de la fréquence d’horloge et du délai souhaité. Ce délai pratique pour le test, s’ avère assez long à l’usage courant, il est intéressant de la réduire à moins de 10s environ.

5.4. Paramètres de l’UART

Ces paramètres servent à régler les 2 registres d’émission TXSTA et de réception RCSTA:

  • SPBRG_VALUE: Baud Rate (nombre de bits/s),
  • SPBRG_BRGH: Haute ou basse vitesse pour le calcul de SPBRG.

Avec un oscillateur XTAL = 4 MHz et une vitesse de 9600 Bauds les valeurs sont:

  • SPBRG_VALUE = 25,
  • SPBRG_BRGH = 1 Haute vitesse.

Le logiciel keyerELoader décrit plus loin, fournit les outils pour calculer différentes valeurs SPBRG et le taux d’erreur. Attention cependant à bien prendre en compte les ordres de grandeur du temps. Avec les valeurs choisies,
le temps d’émission d’une trame UART = (1s / 9600 bauds) * 10 bits = 1042 us, temps 1000 fois plus long que la durée du cycle de base d’une instruction
avec une horloge à 4MHz = 4/4 = 1 us.

6. Application keyerELoader

6.1. Description

L’application keyerELoader permet d’enregistrer les messages du manipulateur dans le PIC. Elle fournit en outre l’affichage de l’EEPROM et des outils pour aider à paramétrer usartELoader. Elle utilise pour la liaison série la classe SerialPort. Un bon exemple d’application de cette classe est donné sur le site Microsoft Most Valued Professionals par Noah Coad dans le SerialPortTerminal. Visual Studio offre la prise en charge de la localisation des applications Windows, ainsi une option de keyerELoader permet de choisir le français ou l’ anglais.

6.2. Fenêtre principale – Onglet Edition

La fenêtre principale, figure 3 ci-dessous, permet:

  • d’entrer les paramètres de transmission,
  • d’ouvrir le port,
  • de se connecter au PIC (LOGIN) ou de se déconnecter (LOGOUT),
  • de saisir l’indicatif, les messages et leur propriété,
  • d’envoyer les messages au PIC,
  • de visualiser l’EEPROM,
  • de suivre les opérations sur le journal (LOG).
Figure 3: keyerELoader - Fenêtre principale

Figure 3: keyerELoader – Fenêtre principale

6.3. Fenêtre principale – Onglet Paramètres

La fenêtre, figure 4 ci-dessous, présente tous les paramètres de l’application. L’application est livrée avec les valeurs par défaut liées au 16F628. Ces valeurs peuvent être adaptées à un autre PIC. Pour prendre en compte les changements, enregistrer, quitter l’application et relancer.

Adresse EEPROM de départ:
Indiquer ici, en hexadécimal, l’adresse à partir de laquelle l’indicatif et les messages seront enregistrés. Important: usartELoader enregistre l’indicatif et les messages dans un buffer de l’EEPROM qui peut être placé librement dans l’EEPROM, adresse et dimension maximale définies par le programme utilisateur. A l’intérieur de ce buffer, l’indicatif et les messages sont de longueur variable. Les données de l’EEPROM extérieure à ce buffer ne sont pas modifiées. Ceci permet de garder des informations propres à l’application utilisateur.

Taille maximale du buffer EEPROM:
Indiquer ici, la longueur maximale du buffer des messages réservé dans l’EEPROM. Description du buffer:

  • indicatif n bytes = aaaa…aa00 où aa = caractère de l’indicatif, 00 = fin,
  • message n bytes = 02iiaaaa…aa0002 = en-tête,  ii = identifiant du message, aa = caractère du message, 00 = fin.

Longueur maximale du message:
Indiquer ici, la longueur maximale du texte du message qui pourra être saisi. Quelle que soit la longueur maximale indiquée, la longueur totale des messages+caractères d’entête et de fin+indicatif <= Taille maximum du buffer de l’EEPROM.

Identifiant du message:
L’identifiant n’est autre que le numéro du bouton qui commande l’émission du message. Se reporter à l’article précédent manipulateur électronique 12F675.

Intervalle de temps du timer:
Temps en ms de rafraichissement de la liste des ports disponibles. Ne pas modifier sauf si dysfonctionnement.

Figure 4: keyerELoader - Paramètres

Figure 4: keyerELoader – Paramètres

6.4. Outils

Le chapitre outils du menu offre 2 calculateurs pour aider à paramétrer usartELoader: l’un pour la vitesse transmission, l’autre pour le délai d’attente  à la connexion (Login timeout).

6.4.1. Calculateur de SPBRG

La fenêtre, figure 5 ci-dessous, présente le calculateur. On se reportera utilement au document de MICROCHIP qui explique le calcul.

Paramètres:

  • fréquence de l’oscillateur en Hz: 4 MHz par défaut,
  • taux d’erreur accepté en %: 4 % maximum,
  • la case cochée sert à garder les derniers paramètres.

Le Tableau présente les combinaisons possibles sur 7 colonnes:

  • SPBRG (SPeed  Baud Rate Generator),
  • Débit calculé en basse vitesse en Baud,
  • Taux d’erreur,
  • Débit désiré en basse vitesse en Baud,
  • Débit calculé en haute vitesse en Baud,
  • Taux d’erreur,
  • Débit désiré en haute vitesse en Baud.
Figure 5: keyerELoader - Calculateur du SPBRG

Figure 5: keyerELoader – Calculateur du SPBRG

6.4.2. Calculateur de délai d’attente de connexion

La fenêtre, figure 6 ci-dessous, présente le calculateur.

Paramètres:

  • fréquence de l’oscillateur en Hz: 4 MHz par défaut,
  • délai en seconde: 100 s maximum,
  • la case cochée sert à garder les derniers paramètres.

Le Tableau présente les combinaisons possibles sur 4 colonnes:

  • Prédiviseur du TIMER1,
  • Base de comptage de TIMER1, le compteur est incrémenté à partir de cette valeur,
  • Nombre de débordements de TIMER1,
  • Délai en seconde.
Figure 6: keyerELoader - Calculateur du délai d'attente de connexion

Figure 6: keyerELoader – Calculateur du délai d’attente de connexion

 

7. Migration du code du PIC 12F675 vers le PIC 16F628

7.1. Description

Le code est installé dans la mémoire du 16F628 au-dessus du code de usartELoader comme le montre la figure 1. Un premier coup de compilateur déroule une longue liste d’erreurs. C’est impressionnant mais pas vraiment méchant. Voici dans l’ordre les adaptations réalisées:

  • assignation des PORTS,
  • reprogrammation de l’ADC,
  • gestion des interruptions.
7.2. Assignation des PORTS
Figure 7: assignation des ports

Figure 7: assignation des ports

Où l’on vérifie l’efficacité de nos définitions. La table figure 7, ci-contre, montre la projection du 12F675 vers le 16F628. Il faut noter que l’ ADC consomme 2 broches. Ont été ajoutés, les liaisons UART pour usartELoader. Cette partie du travail a été réalisé facilement  par l’utilisation des #define.

7.3. Reprogrammation de l’ADC

Le 16F628 ne dispose pas directement de l’ADC mais comme je disposais du 16F628, j’ai fait avec ce que j’avais. Dans sa note AN700 MICROCHIP décrit comment câbler et programmer le Delta Sigma ADC. J’ai repris trait pour trait son schéma, mot pour mot le code. Un bon exemple d’application de la note AN700 est donné sur le site de SPRUT à l’article « PIC-Lernbeispiel: ADC mit Komparator aufbauen ».

Figure 8: Extrait figure 1 note AN700 MICROCHIP

Figure 8: Extrait figure 1 note AN700 MICROCHIP

La figure 8, ci-contre, montre le diagramme du circuit qui, transposé sur le PIC nécessite 2 ports: AN et CMP et un intégrateur. C’est un peu plus lourd que le 12F675 et aussi 1000 fois plus lent. Pour obtenir un résultat sur 10 bits, avec le 12F675 nous sommes dans l’ordre de la us, ici nous sommes dans l’ordre de la ms. Mais pour un clavier manuel cela est acceptable.
Le code de la routine ADC du 12F6275 est chargé de fournir les registres ADRESH et ADRESL à la routine keystroke. Le travail a consisté à remplacer le code de la routine par celui de la note AN700, les registres ADRESL et ADRESH qui n’existent plus dans le 16F628 ont été simplement ajoutés dans la RAM pour conserver la compatibilité avec le programme. Les premiers essais ayant montré un fonctionnement aléatoire des touches j’ai ajouté un bout de code pour prélever une série d’échantillons et ne garder que le résultat le plus grand. Avec cette méthode, j’obtiens un fonctionnement plus sûr. Les résistances du clavier, figure 9 ci-dessous,  sont toujours dans le même rapport 3:1 mais leurs valeurs ont été adaptées. Après essais, j’ai opté pour  3K et 1K.

Figure 9: Clavier et intégrateur

Figure 9: Clavier et intégrateur

Méthode d’étalonnage

Comme pour le 12F675, de la précision de l’étalonnage du clavier dépendra le fonctionnement précis du clavier. Le clavier a été ré-étalonné. Cela est fait facilement en utilisant keyerELoader, l’EEPROM, à l’oreille par l’écoute du signal différent émis à la pression de chaque touche. Le programme enregistre en EEPROM les valeurs obtenues à chaque pression de touche (#define __ADRES_TRON). Commencer par attribuer dans la table ADC_Vth_TABLE à chaque touche un intervalle assez large. Lire ensuite le résultat dans l’EEPROM en utilisant KeyerELoader. Retoucher et réduire l’intervalle. Peaufiner jusqu’à obtenir un intervalle qui marche à tous les coups. Désactiver (#define    __ADRES_TRON). Voici les nouveaux paramètres:

; Fitted after real analyze

#define KPAD_00_MAX (1016+16)  ;key 0,0 (maximum maximorum)
#define KPAD_00_MIN (1016-4)   ;key 0,0
#define KPAD_10_MAX (757+5)    ;key 1,0
#define KPAD_10_MIN (757-5)    ;key 1,0
#define KPAD_20_MAX (605+5)    ;key 2,0
#define KPAD_20_MIN (605-5)    ;key 2,0
; Row 1
#define KPAD_01_MAX (502+6)    ;key 0,1
#define KPAD_01_MIN (502-6)    ;key 0,1
#define KPAD_11_MAX (438+5)    ;key 1,1
#define KPAD_11_MIN (438-5)    ;key 1,1
#define KPAD_21_MAX (385+5)    ;key 2,1
#define KPAD_21_MIN (385-5)    ;key 2,1
; Row 2
#define KPAD_02_MAX (345+5)    ;key 0,2
#define KPAD_02_MIN (345-5)    ;key 0,2
#define KPAD_12_MAX (308+7)    ;key 1,2
#define KPAD_12_MIN (308-8)    ;key 1,2
#define KPAD_22_MAX (287+5)    ;key 2,2
#define KPAD_22_MIN (287-5)    ;key 2,2

; NO KEY
#define KPAD_FF_MAX 256        ; no key
#define KPAD_FF_MIN 0          ; no key

On se reportera à l’article précédent du 12F6275. A ce stade le clavier ne sait pas encore quelle fonction activer. Une liste d’assignation lie la touche à sa fonction. Le clavier peut ainsi être personnalisé. En cas de changement d’assignation de touche de message il faut aussi modifier le paramètre Identifiant du Message dans keyerELoader (voir ci-dessus).

7.4. Schéma

La figure 10, ci-dessous, montre le circuit recâblé avec le 16F628. Le MAX3232 n’y est pas représenté. Voir au paragraphe 8, ci-dessous, la connexion.

Figure 10: Schéma CW Keyer 16F628 RS232

Figure 10: Schéma CW Keyer 16F628 RS232

Download  Télécharger tous les programmes sources, hex, exe, et fichiers: usartELoader: interface de liaison série EEPROM Loader avec petit programme démo. + keyer16F628+usartELoader: CW keyer avec liaison série + keyerELoader VISUAL C# 2010 projet complet avec sources et exe+Schémas Kicad+Schémas Inkscape.

Figure 11: module MAX3232 DB9

Figure 11: module MAX3232 DB9

8. Liaison RS232

L’interface PC est le convertisseur TTL/RS232 MAX3232. Comme le montre la photo qui introduit l’article, j’utilise un petit circuit pas plus grand qu’un timbre-poste acheté sur Ebay pour moins de 1 euro frais de port inclus. Ce circuit est livré complet, câblé, prêt à l’emploi, avec le MAX3232, une petite LED témoin, la prise DB9 et 4 fils de liaison à enficher d’une vingtaine de cm. Le circuit est sérigraphié. Relier RX à l’entrée RX du PIC, TX à TX du PIC, GND à la masse, VCC à VDD = 5V.

9. Tests – Réglages

Le circuit a été monté sur platine d’expérimentation comme le montre la figure 12 ci-dessous. Le clavier, est réduit à ses parties essentielles: ses résistances, et un fil muni d’une pointe de touche qui joue le rôle de bouton (voir figure 9). A noter la liaison simple au module MAX3232 qui est alimenté en 5V comme le PIC. Il est relié au PC par un câble direct, récupéré sur un vieux modem mais une connexion avec les 3 fils utiles (broches 2, 3, 5 de la DB9) peut être réalisée.

Figure 12: keyer16F628 sur platine d'expérimentation

Figure 12: keyer16F628 sur platine d’expérimentation

A suivre..

 

Index des articles de la catégorie microcontroleur

]]>
http://www.f8eoz.com/?feed=rss2&p=3792 1
PIC Microchip – Manipulateur électronique 12F675 CW Keyer http://www.f8eoz.com/?p=3613 http://www.f8eoz.com/?p=3613#comments Tue, 16 Jun 2015 14:41:57 +0000 admin http://www.f8eoz.com/?p=3613 PIC12F675Keyer_1352Depuis plusieurs semaines je parcours la documentation technique des petits processeurs 12F6xx de MICROCHIP. Petits, mais richement dotés à en juger par l’étendue de la documentation qui les accompagne. Poussé par le désir de ne pas en rester à la connaissance purement théorique du sujet et aussi par l’envie de « manger » un peu de code, j’ai cherché un projet qui pourrait me permettre de concrétiser mes acquis. Mon choix s’est porté rapidement sur un manipulateur électronique, petite machine utile à la station. Générer les DIT et les DAH c’est bien mais ce n’est pas tout, moyennant un peu de programmation, quelques fonctions fort utiles peuvent être implémentées. Il est agréable de pouvoir envoyer automatiquement les messages de base CQ CQ CQ DE F8EOZ…  et aussi CQ DX et un autre pour les CONTEST. Trois messages enregistrés d’une manière simple au choix de l’utilisateur devraient suffire. Pas besoin de dizaines de mémoires. Il est intéressant d’avoir une écoute locale que l’on peut activer/désactiver ce qui permet d’utiliser le manipulateur pour l’entraînement ou d’utiliser le sidetone de son TRX. Changer la vitesse facilement pour s’adapter à celle de son correspondant est nécessaire. Choisir le mode iambique A ou B pourquoi pas. Enfin une dernière possibilité utile pour régler son antenne, générer une tonalité continue ou à pulsations très rapides.  Toutes ces fonction accessibles rapidement et directement par boutons-poussoirs, pas de menus et sous-menus sélectionnés par paddle.

1. Description du projet

1.1. Logiciel

MPLAB IDE v8.92. J’utilise avec satisfaction cet environnement de développement MICROCHIP. A peu de frais, avec mon programmateur maison, il me permet de faire tous les tests de simulation et de débogage.

MPASMWIN v5.51. A priori, je pensais utiliser le langage C. D’une part, j’aurais quand même dû y broder un peu de code assembleur, d’autre part, la taille limitée de la mémoire 1 ou 2K, ont donné la préférence à l’assembleur. Le programme ne comprend pas de calculs compliqués et il n’y a qu’une bonne trentaine d’instructions assembleur à assimiler. Elles sont les mêmes que celles que j’ai utilisées pour le fréquencemètre.

1.2. Matériel

MCU. Les processeurs de la série 12F6 sont dotés de 6 ports mais pas des mêmes possibilités. Je tiens à garder le port GP3 en fonction MCLR (reset) ce qui me laisse 5 ports. Le postulat émis en introduction d’avoir accès aux fonctions directement par boutons-poussoirs m’oriente vers un petit clavier connecté à un port ADC. Je dispose du 12F675 et du 12F683. Je pense que 1K de mémoire devrait suffire à tenir le code du programme et les 128 bytes de l’EEPROM suffisent pour les messages. J’opte finalement pour le 12F675.

Clavier. Les touches de fonctions sont regroupées sur un petit clavier 3×3 réalisé ex nihilo. L’assignation des fonctions est libre et indépendante de la place physique des touches. Cela permet à chacun de choisir la disposition qui lui convient. (personnalisation). L’assignation est faite par des définitions qui font le lien entre le numéro de touche et la fonction.

Ecoute locale. Elle est réalisée par un petit buzzer connecté à un transistor servant de buffer.

Commande du TX. Elle est réalisé par un transistor.

La figure 1 ci-dessous montre le schéma du circuit.

Figure 1 - Schéma du circuit

Figure 1 – Schéma du circuit

2. Analyse fonctionnelle

2.1. Expression des besoins

En introduction, l’expression fonctionnelle du besoin a permis de définir les  fonctions que la machine devra réaliser. Je les rappelle:

  • Générer le code Morse en mode Iambique ou Droit,
  • Envoyer 3 messages au choix,
  • Incrémenter, décrémenter la vitesse,
  • Choisir le mode iambique A ou B,
  • Choisir l’utilisation de l’écoute locale, BUZZER ON/OFF,
  • Générer pour le réglage d’antenne un signal, TUNE Pulse ou Carrier.
2.2. Schéma fonctionnel

Le schéma figure 2 ci-dessous montre le diagramme fonctionnel du manipulateur.

Figure 2 - Diagramme fonctionnel du manipulateur électronique

Figure 2 – Diagramme fonctionnel du manipulateur électronique

Chacun des blocs mis en évidence fera l’objet d’une description des fonctions principales et des données qu’elles manipulent dans la suite de l’article.

2.2.1. Organes de sortie

Buzzer via un buffer.
Fonction : écoute locale sur option, message de service.

Commutateur Tx: commutateur à transistor.
Fonction : émission en code Morse via le Tx, des messages préenregistrés en clair, émission de la manipulation.

2.2.2. Organes d’entrée

Clef Morse: Iambique (choix du mode A ou B), Droite détectée au setup si le DAH est à la masse.
Fonction : manipulation du message, le DIT sert à avorter (abort) un message préenregistré en cours d’émission.

Clavier matriciel 3×3: organe de commande personnalisable, accessible pendant les temps morts c’est à dire quand la clef Morse reste inactive plus d’une seconde (paramètre).
Fonction: un bouton, une fonction, soit 9 fonctions.

Reset  bouton de reset.
Fonction : setup.

2.2.3. Flux de données

Message de service: c’est un message local court destiné à informer l’utilisateur que la commande a été comprise. Il s’agit en général d’un caractère émis en code Morse à la vitesse courante. Il est destiné uniquement au BUZZER même quand celui-ci est OFF. Il est stocké en RAM et personnalisable.

Message préenregistré: c’est un message destiné au TX et au BUZZER s’il est ON. Il est de longueur variable (0 à n caractères),  sa limite physique est celle de l’espace disponible dans l’EEPROM compte-tenu de la place prise par les autres messages. Il est muni de 2 propriétés: un identificateur symbolique qui correspond simplement au numéro du bouton qui le commande, un facteur de répétition personnalisable (0 à ∞). Il peut être interrompu par un DIT de la clef Morse. Il est rédigé en clair et transformé en code Morse par la machine. Il est diffusé à la vitesse courante de la machine.

Message manipulé: c’est le message généré par la clef Iambique ou Droite destiné au TX et au BUZZER s’il est ON. Avec la clef Iambique, quand les 2 paddles sont pincés, la répétition automatique des DIT et DAH est commandée en mode A ou en mode B.

2.2.4. Organes internes

Les organes internes de l’automate réalisent les fonctions techniques. Leur conception autonome facilite leur développement et leur mise au point. Ils peuvent ainsi être réutilisés.

KEY INTERFACE: traduit les appuis de la CLEF en DIT et DAH. Le type de clef Iambique ou Droite est déterminé automatiquement au Setup (DAH à la masse = clef  Droite). Le mode Iambique A ou B est sélectionnable par une touche du clavier fonctionnant en bascule. L’interface commande l’accès au clavier blocage/déblocage de manière asynchrone par l’interruption TIMER1.

MORSE PLAYER ou PLAYER: joue DIT,  DAH et espace entre les mots (GAP) à la demande de la CLEF ou de l’ENCODER. Autrement-dit, il commande les ports de sortie BUZZER et TX au niveau haut et bas à la vitesse courante.
Remarque: le signal PULSE n’est qu’une série de DIT qui se prolonge indéfiniment jusqu’à interruption, CARRIER est un signal continu qui se prolonge indéfiniment jusqu’à interruption.
L’ interrupteur BUZF autorise ou non la sortie BUZZER, l’interrupteur TXF autorise ou non la sortie TX.
Paramètre : unité de temps = durée d’un point à la vitesse courante.

MORSE TIMER: donne l’unité de temps en ms (le point) en fonction de la vitesse (nombre de mots/mn). L’unité de temps peut être incrémentée ou décrémentée par touches successives du clavier. La valeur par défaut est fixée à 12 mots/mn. La dernière valeur utilisée est conservée en EEPROM et reprise ensuite à chaque SETUP.

KEYPAD INTERFACE: gère le clavier matriciel 3×3. L’interface utilise l’ADC du MCU.
Paramètres: description du clavier (assignation des touches aux fonctions), table des seuils de tension analogique, numérique (intervalle numérique réservé à chaque touche).

ENCODER: traduit un caractère, lettre, chiffre, ponctuation, procédure, en code Morse à destination du PLAYER.
Trois entrées possibles : un message préenregistré de l’EEPROM, un message de service stocké en RAM, un message provenant du déroulement du programme.
Le message peut être interrompu par un appui et un relâchement de la clef DIT.
Paramètre: règles de traduction du caractère.

3. Méthode de développement

L’option MPLAB SIM du Debugger de MPLAB IDE permet de vérifier efficacement le bon fonctionnement du programme. Mais le test réel révèle toujours des défauts à corriger. La difficulté est de n’avoir aucun moyen de visualiser, ni de tracer le programme. Quoiqu’ en y réfléchissant, nous avons 2 moyens: nos oreilles et l’EEPROM. L’envoi vers le BUZZER de signaux Morse aux endroits à étudier permet de suivre le programme. L’enregistrement en EEPROM de données partielles permet aussi d’obtenir des indications. Il suffit de replacer le MCU sur le programmateur. PICPgm va relire le contenu de l’EEPROM et l’afficher. Ces traces seront naturellement provisoires (utilisation de define) et disparaissent dans la version Release. Cette observation conditionne la chronologie de développement. J’ai d’abord commencé par produire les sons, ensuite les messages et le reste a suivi.

4. Le clavier matriciel 3×3 touches

4.1. Conception

Je me suis fondé sur le document « Two-wire, four-by-four-key keyboard  interface saves power »   de « Stefano Salvatori, University of Rome, and Gabriele Di Nucci, EngSistemi, Rome, Italy » paru dans la rubrique designideas de EDN Network.

Figure 3 - Schéma du clavier matriciel 3x3

Figure 3 – Schéma du clavier matriciel 3×3

Le clavier figure 3, ci-dessus, est une matrice 3×3 dans la quelle il est possible de calculer la tension Vout lorsque l’un quelconque des boutons est pressé en appliquant l’équation:
V(x,y) = Vref . Rb/( xRa + yRb + Rb) (1).
L’équation (1) peut s’écrire sous forme d’un rapport de résistances:
V(x,y)/Vref = Rb/( xRa + yRb + Rb) (2).
Posons Rb=Ra/p, l’équation (2) peut s’écrire:
V(x,y)/Vref =  (Ra/p)/( xRa + y(Ra/p) + (Ra/p))
ou en multipliant par (p/Ra)/(p/Ra)
on obtient le rapport diviseur de tension quel que soit la touche pressée:
r(x,y) = V(x,y)/Vref = 1 / ( 1 + x.p + y)  (3)
dans laquelle p = Ra/Rb représente le rapport entre les résistances de lignes et de colonnes.
On observe facilement que le ratio Rb/Ra<3 donne des doublons et ne convient pas. En prenant une résolution ADC N=10 bits et en choisissant une tolérance T=0,01 pour les résistances Ra et Rb, il est possible de distinguer avec une bonne marge de sécurité 9 valeurs de tension.
J’ai choisi Ra=11K 1% et Rb=33K 1% simplement parce que je les avais en stock. D’autres combinaisons de rapport 1/3 sont possibles : Ra=1,3K et Rb=3,9K ou Ra=1,2K et Rb=3,6K par exemple. Ces dernières valeurs étant, par ailleurs, meilleures que celles que j’ai utilisées car je me suis rendu compte que la documentation MICROCHIP conseille de ne pas dépasser 10K en entrée de l’ADC. En effet, la résistance intervient dans le temps d’acquisition.
Il est maintenant très facile de calculer les valeurs numériques de chaque bouton dans l’intervalle [0, 1023]
AD RESULT = 1023. r(x,y) (4).
On constate un resserrement des valeurs les plus basses mais encore très acceptable. Enfin, cette expression montre que le résultat dépend essentiellement de la qualité des résistances. Dans la réalité, j’ai fixé une petite fenêtre d’examen autour de cette valeur qui laisse une marge d’erreur.
Ces valeurs sont reportées sur la figure ci-dessus.  Notre schéma maintenant complet, le clavier peut être programmé et fabriqué.

4.2. Mise en oeuvre de l’ADC

Le clavier est connecté à l’entrée AN0. Cette entrée est lue cycliquement. Le résultat est placé dans un registre ADRES de 10 bits donnant une valeur numérique de 0 à 1023 qui correspond au niveau de tension de la touche pressée. Le clavier n’est qu’un diviseur de la tension Vdd, tension de référence.
Sa mise en oeuvre passe par l’initialisation de quelques registres. Les chapitres 6 et 7 de la documentation technique du 12F675 décrivent le Comparateur et l’ADC.

Le registre ADCON0:
Tout est dit dans le diagramme 7-1 figure 4, ci-dessous, extrait de la documentation.

Figure 4 - A/D BLOCK DIAGRAM (MICROCHIP)

Figure 4 – A/D BLOCK DIAGRAM (MICROCHIP)

Le registre ADCON0 met ce circuit en état de fonctionnement. Voici sa définition et son initialisation dans le programme:

;----------------------------------------------------------------------
; ADC Config
#define ADC_CON b'10000001'
#define ADC_AN0 b'00000000'
#define ADC_AN1 b'00000100'
#define ADC_AN2 b'00001000'
#define ADC_AN3 b'00001100'
;         		  1-------  ADFM: 1=right justified result
;         		  -0------  VCFG: 0=Vdd is voltage reference
;         		  --xx----  not implemented
;         		  ----00--  00=select channel 00 (AN0=GP0)
;				      01 	= Channel 01 (AN1=GP1)
;				      10	= Channel 02 (AN2=GP2)
;					  11 	= Channel 03 (AN3=GP4)
;         		  ------0-  GO/NOT DONE Status bit: 0=A/D conversion not started
;         		  -------1  ADON: Conversion Status bit 1=A/D converter module is operating

#define ADC_AN_KPAD ADC_AN0 ; assign Keypad to Channel 00

	; set up A/D converter
	banksel ADCON0
    movlw   ADC_CON | ADC_AN_KPAD
    movwf   ADCON0

Le registre ANSEL:
Sa fonction est de désigner les ports qui sont affectés au convertisseur et de fixer la fréquence de conversion du cycle A/D.  Choisir la fréquence ad hoc, ni trop, ni trop peu. TAD = A/D clock period. Le minimum TAD requis est de 1.6us, paragraphe 7-1-4 de la documentation technique,  à 4MHz avec Fosc=8 le minimum TAD = 4MHz/8 = 2us. Les valeurs Fosc inférieures ne conviennent pas puisque TAD<1,6us. La table 7-1 , ci-dessous, extraite de la documentation, résume cela.

Figure 5 - TAD vs. DEVICE OPERATING MIFREQUENCIES (MICROCHIP)

Figure 5 – TAD vs. DEVICE OPERATING FREQUENCIES (MICROCHIP)

Note importante: placer un port en entrée analogique enlève automatiquement les résistances internes de pull-ups. Il faut donc utiliser des résistances externes.

En résumé, voici son initialisation dans le programme:


	; set up A/D converter
    banksel ANSEL
    movlw   b'00010001'
    ;         x-------  not implemented
    ;         -001----  ADCS A/D Conversion Clock: 001=Focs/8 Conversion Clock
    ;         -101----  ADCS A/D Conversion Clock: 001=Focs/16 Conversion Clock
    ;         ----0---  ANS3:ANS0: Analog Select bits 0=digital I/O, GP4, Tx output
    ;         -----0--  ANS3:ANS0: Analog Select bits 0=digital I/O, GP2, DIT paddle input
    ;         ------0-  ANS3:ANS0: Analog Select bits 0=digital I/O, GP1, DAH paddle input
    ;         -------1  ANS3:ANS0: Analog Select bits 1=analog  I/O, GP0, analog input
    movwf   ANSEL

Echantillonage – Calcul du temps d’acquisition minimum:
Un cycle d’échantillonnage comprend 2 phases:

  • le temps d’acquisition ou TACQ qui commence après que le canal a été choisi ou qu’un cycle s’achève et que le condensateur interne commence sa charge,
  • le temps de conversion qui commence à fin du TACQ et quand le GO bit=1, qui s’achève après 11 TAD.
Figure 6: ACQUISITION TIME  (MICROCHIP)

Figure 6: ACQUISITION TIME (MICROCHIP)

La résistance d’entrée intervient dans le calcul du temps de charge TC du condensateur interne et par conséquent du TACQ minimum. Avec une résistance de 10K en entrée le TACQ = 19.2us. Comme j’ai utilisé une résistance un peu plus élevée de 33K je calcule
TC = 120 pF(1K+7K+33K)ln0.0004885 = 37.5us
ce qui donne pour TACQ = 40us environ. En y ajoutant 11 * 2us nous obtenons environ 62us. Ce temps est largement inférieur à mon temps de réaction et d’appui sur les touches du clavier… L’équation encadrée, ci-dessus, extraite de la documentation, résume cela.

Le registre CMCON:
Puisque le module comparateur n’est pas utilisé, on choisit l’option « Comparator off ». Voici son initialisation dans le programme:


	; set up comparator
    banksel CMCON
    movlw   b'00000111'
    ;         x-------  not implemented
    ;         -0------  COUT: Comparator Output bit: 0 = VIN+ < VIN- When CINV = 0
    ;         --x-----  not implemented
    ;         ---0----  CINV: Comparator Output Inversion bit 0=non-inverted output
    ;         ----0---  CIS: Comparator Input Switch bit When CM2:CM0 = 110 or 101
    ;         -----111  CM2:CM0: Comparator Mode bits 111=comparator off
    movwf   CMCON

4.3. Programmation

Description du clavier:
La programmation du clavier figure 7, ci-dessous, est réalisée en se fixant 2 objectifs: rendre le module KEYPAD INTERFACE réutilisable pour un autre projet, rendre le clavier personnalisable.

Figure 7 - Agencement du clavier

Figure 7 – Agencement du clavier

Les touches sont numérotées de 0 à 8 en fonction de leur position x,y, les fonctions liées à ces touches sont assignées ensuite. Pour personnaliser le clavier il suffit de changer l’assignation. J’ai choisi de placer les touches d’envoi des messages sur la première colonne, il serait possible de les assigner à une autre colonne ou une ligne, par exemple. La programmation n’en serait nullement affectée. Voici sa description dans le programme:

; Definition
KPAD_00	EQU 0
KPAD_10	EQU 1
KPAD_20	EQU 2
KPAD_01	EQU 3
KPAD_11	EQU 4
KPAD_21	EQU 5
KPAD_02	EQU 6
KPAD_12	EQU 7
KPAD_22	EQU 8
KPAD_FF	EQU 0xFF ; no key
; Assign key 3x3 push button
; This allows one to change keypad layout without change algorithm
; My Layout:
;    (y2)
;    (y1)
;    (y0)
;  (x2)	   (x1)	   (x0)
KPAD_SEND0		EQU KPAD_22
KPAD_SEND1		EQU KPAD_21
KPAD_SEND2	 	EQU KPAD_20
KPAD_SPEED_UP	EQU KPAD_12
KPAD_SLOW_DOWN 	EQU KPAD_11
KPAD_BUZ	 	EQU KPAD_10
KPAD_TUNEC		EQU KPAD_02
KPAD_TUNEP		EQU KPAD_01
KPAD_MOD		EQU KPAD_00

Définition des seuils de tension:
A chaque touche correspond un niveau de tension et un seul. Mais comme rien n’est parfait, il faut attribuer à chaque touche une fenêtre de visée. J’ai défini 9 intervalles [min, max[ disjoints (pas de chevauchement). Pour faciliter la mise au point, les limites min et max sont des paramètres. Voici la description dans le programme:

; Fitted after real analyze

#define VTOLPLUS 10 ; tolerance
#define VTOLMINUS 1 ; tolerance
; Row 0 (3069=1023*3)
#define KPAD_00_MAX (1023+VTOLPLUS)		    ;key 0,0 (maximum maximorum)
#define KPAD_00_MIN (1023-VTOLMINUS)		;key 0,0
#define KPAD_10_MAX ((3069/4)+VTOLPLUS)		;key 1,0
#define KPAD_10_MIN ((3069/4)-VTOLMINUS)	;key 1,0
#define KPAD_20_MAX ((3069/5)+VTOLPLUS)		;key 2,0
#define KPAD_20_MIN ((3069/5)-VTOLMINUS)	;key 2,0
; Row 1
#define KPAD_01_MAX ((1023/2)+VTOLPLUS)		;key 0,1
#define KPAD_01_MIN ((1023/2)-VTOLMINUS)	;key 0,1
#define KPAD_11_MAX ((3069/7)+VTOLPLUS)		;key 1,1
#define KPAD_11_MIN ((3069/7)-VTOLMINUS)	;key 1,1
#define KPAD_21_MAX ((3069/8)+VTOLPLUS)		;key 2,1
#define KPAD_21_MIN ((3069/8)-VTOLMINUS)	;key 2,1
; Row 2
#define KPAD_02_MAX ((1023/3)+VTOLPLUS)		;key 0,2
#define KPAD_02_MIN ((1023/3)-VTOLMINUS)	;key 0,2
#define KPAD_12_MAX ((3069/10)+VTOLPLUS)	;key 1,2
#define KPAD_12_MIN ((3069/10)-VTOLMINUS)	;key 1,2
#define KPAD_22_MAX ((3069/11)+VTOLPLUS)	;key 2,2
#define KPAD_22_MIN ((3069/11)-VTOLMINUS)	;key 2,2
; NO KEY
#define KPAD_FF_MAX VTOLPLUS				; no key
#define KPAD_FF_MIN 0						; no key

Remarque: les calculs dans les définitions peuvent réserver des surprises, c'est pourquoi j'ai simplifié la formule en multipliant 1023 par le facteur 3.

Une façon simple de gérer une liste de données, moyennant quelques précautions dans l'implantation mémoire, est d'implémenter une "Lookup Table". Voici sa description dans le programme:

ADC_Vth_TABLE
	movlw 	HIGH(ADC_Vth_KEYPAD); PCLATH = HIGH bit address
	movwf 	PCLATH 				;
	movf	ADCVthPointer,W		; for PCL
	addwf	PCL ,F ; Jump to character pointed to in W register
ADC_Vth_KEYPAD ; maximum voltage threshold for keypad: analog to digital convert

	; real digit value saved into EEPROM for analyze (use __ADRES_TRON to get result)
	; 	(2)   (1)   (0)
	; 8---- 7---- 6---- (2)
	; 01 18 01 34 01 58
	; 5---- 4---- 3---- (1)
	; 01 82 01 B8 02 01
	; 2---- 1---- 0---- (0)
	; 02 69 03 01 03 FF

	; -------xy: digit maximum voltage threshold 	: digit minimum voltage threshold
	DT	KPAD_FF,(HIGH KPAD_FF_MAX),LOW (KPAD_FF_MAX),(HIGH KPAD_FF_MIN),LOW (KPAD_FF_MIN)
	DT	KPAD_22,(HIGH KPAD_22_MAX),LOW (KPAD_22_MAX),(HIGH KPAD_22_MIN),LOW (KPAD_22_MIN)
	DT	KPAD_12,(HIGH KPAD_12_MAX),LOW (KPAD_12_MAX),(HIGH KPAD_12_MIN),LOW (KPAD_12_MIN)
	DT	KPAD_02,(HIGH KPAD_02_MAX),LOW (KPAD_02_MAX),(HIGH KPAD_02_MIN),LOW (KPAD_02_MIN)
	DT	KPAD_21,(HIGH KPAD_21_MAX),LOW (KPAD_21_MAX),(HIGH KPAD_21_MIN),LOW (KPAD_21_MIN)
	DT	KPAD_11,(HIGH KPAD_11_MAX),LOW (KPAD_11_MAX),(HIGH KPAD_11_MIN),LOW (KPAD_11_MIN)
	DT	KPAD_01,(HIGH KPAD_01_MAX),LOW (KPAD_01_MAX),(HIGH KPAD_01_MIN),LOW (KPAD_01_MIN)
	DT	KPAD_20,(HIGH KPAD_20_MAX),LOW (KPAD_20_MAX),(HIGH KPAD_20_MIN),LOW (KPAD_20_MIN)
	DT	KPAD_10,(HIGH KPAD_10_MAX),LOW (KPAD_10_MAX),(HIGH KPAD_10_MIN),LOW (KPAD_10_MIN)
	DT	KPAD_00,(HIGH KPAD_00_MAX),LOW (KPAD_00_MAX),(HIGH KPAD_00_MIN),LOW (KPAD_00_MIN) 	; 5V
	; don't remove line below
	retlw 0xFF	; high value = end of table
	IF ((HIGH ($)) != (HIGH (ADC_Vth_KEYPAD)))
    	ERROR "ADC_Vth_KEYPAD CROSSES PAGE BOUNDARY!"
	ENDIF;

Algorithme Keystroke:
Keystroke, figure 8 ci-dessous, est l'algorithme principal de l'interface KEYPAD. Il lance le cycle ADC, récupère son résultat, sélectionne la touche frappée et lance la fonction liée à la touche.

Figure 8 - Algorithme Keystroke

Figure 8 – Algorithme Keystroke

Le code présenté ci-dessous est volontairement abrégé. Il ne montre pas le détail des fonctions liées à chaque touche ni la routine de comparaison CMP_A_B. On se reportera au programme source disponible en téléchargement.

;-------------------------------------
; KPAD_Keystroke process
; Scan ADC KPAD channel until find key
; Execute command associated with key
KPAD_Keystroke

KPAD_GetADRES
	movlw	ADC_CON | ADC_AN_KPAD	; select channel Keypad
	call	KPAD_GetADCvalue
	BANK1					; store ADC result into compare register A
    movf	ADRESL,W       	; 8 bits low
	BANK0
	movwf	CmpAL
	movf	ADRESH,W        ; 2 bits High
	movwf	CmpAH

	; point to first ADC table item
	movlw	ADC_Vth_KEYPAD - ADC_Vth_TABLE - 1 -3 -3 	; W = value relative address - 3
	movwf	ADCVthPointer		; Hold pevious line address

KPAD_Lookup	; read one table item
	incf	ADCVthPointer		; skip min value of previous table item
	incf	ADCVthPointer
	incf	ADCVthPointer		; point to current table item
	call	ADC_Vth_TABLE		; lookup voltage scale to find key pressed
	movwf   KeyPadXYtemp       	; hold KeyPadXY byte

	incf	ADCVthPointer,f		; Point to next byte
	call	ADC_Vth_TABLE
 	movwf   CmpBH       		; hold MAX value high byte into compare register B

	incf	ADCVthPointer,f		; Point to next byte
	call	ADC_Vth_TABLE
   	movwf   CmpBL	       		; hold MAX value low byte into compare register B

 	call	CMP_A_B				; compare ADC : MAX value
	btfss	UCON1,A_LT_B		; is ADC value < MAX table value ? 	goto	KPAD_Lookup			; no: NEXT item------>

	; value is < MAX: then look for MIN value 	incf	ADCVthPointer,f		; Point to next byte 	call	ADC_Vth_TABLE  	movwf   CmpBH       		; hold MIN value high byte into compare register B 	incf	ADCVthPointer,f		; Point to next byte 	call	ADC_Vth_TABLE    	movwf   CmpBL	       		; hold MIN value low byte into compare register B  	call	CMP_A_B				; compare ADC : MIN value 	btfsc	UCON1,A_EQ_B		; is ADC value = MIN table value 	goto	KPAD_GetKey_Found	; yes: Key found------>
	btfss	UCON1,A_GT_B		; is ADC value > MIN table value
	goto	KPAD_GetADRES		; no: value out of voltage span, read again------>

KPAD_GetKey_Found
 	movf	KeyPadXY,W			; Hold previous key
	movwf	KeyPadXYPre
 	movf	KeyPadXYtemp,W		; Hold new key
	movwf	KeyPadXY

;-------------------------------
; only for analyze and benchmark
KPAD_Report
	ifdef __ADRES_TRON
 		; Report ADRES value into EEPROM for analyse
		addwf	KeyPadXY,W		; pointer = 2*KeyPadXY
		btfsc	STATUS,C		; carry set if key 0xFF
		goto	KPAD_Report_End	; >>>no report
		sublw	LOW(EE_ADRESL0); pointer to LSB
		BANK1
		movwf	EEADR			; into EEADR
		movf	ADRESL,W		; ADC value LSB into EEDATA
		movwf	EEDATA
		call	WriteEEPROM		; write one byte to EEPROM
		BANK1
		decf	EEADR,f			; pointer to MSB
		BANK0
		movf	ADRESH,W		; ADC value MSB into EEDATA
		BANK1
		movwf	EEDATA
		call	WriteEEPROM		; write one byte to EEPROM
		BANK0
	endif
KPAD_Report_End
;--------------

	; switch case KeyPadXY
	;
	; case: NO KEY
	movfw	KeyPadXY
	xorlw	KPAD_FF		; Check if no key
	btfsc	STATUS, Z		; Z=0: no next key
	goto	KPAD_Keystroke_End	; Z=1: yes, end key ====>
	;
	; case: KEY = PREVIOUS KEY
	movfw	KeyPadXY
	xorwf	KeyPadXYPre,W	; Check if equal
	btfsc	STATUS, Z		; Z=0: no
	goto	KPAD_Keystroke_End	; end key ====>
	;
	; case: SEND0
	movfw	KeyPadXY
	xorlw	KPAD_SEND0	; Check if key Send0
	btfsc	STATUS, Z		; Z=0: no
	goto	KPAD_Keystroke_Sendn	; yes, ====>
	;
	; case: SEND1
	movfw	KeyPadXY
	xorlw	KPAD_SEND1	; Check if key Send1
	btfsc	STATUS, Z		; Z=0: no
	goto	KPAD_Keystroke_Sendn	; yes, ====>
	;
	; case: SEND2
	movfw	KeyPadXY
	xorlw	KPAD_SEND2	; Check if key Send2
	btfsc	STATUS, Z		; Z=0: no
	goto	KPAD_Keystroke_Sendn	; yes, ====>
	;
	; case: BUZZER
	movfw	KeyPadXY
	xorlw	KPAD_BUZ		; Check if key Buz
	btfsc	STATUS, Z		; Z=0: no
	goto	KPAD_Keystroke_Buz	; yes, ====>
	;
	; case: TUNEP
	movfw	KeyPadXY
	xorlw	KPAD_TUNEP	; Check if key Tune PULSE
	btfsc	STATUS, Z		; Z=0: no
	goto	KPAD_Keystroke_TunP	; yes, ====>
	;
	; case: TUNEC
	movfw	KeyPadXY
	xorlw	KPAD_TUNEC	; Check if key Tune CARRIER
	btfsc	STATUS, Z		; Z=0: no
	goto	KPAD_Keystroke_TunC	; yes, ====>
	;
	; case: MODEAB
	movfw	KeyPadXY
	xorlw	KPAD_MOD		; Check if key Mod
	btfsc	STATUS, Z		; Z=0: no
	goto	KPAD_Keystroke_Mod	; yes, ====>
	;
	; case: SPEED UP
	movfw	KeyPadXY
	xorlw	KPAD_SPEED_UP	; Check if key Speed up
	btfsc	STATUS, Z		; Z=0: no
	goto	KPAD_Keystroke_SpeedUp	; yes, ====>
	;
	; case: SLOW_DOWN
	movfw	KeyPadXY
	xorlw	KPAD_SLOW_DOWN; Check if key Slow down
	btfsc	STATUS, Z		; Z=0: no
	goto	KPAD_Keystroke_SlowDown	; yes, ====>
	;
KPAD_Keystroke_End ; End of keypad
	return	;>>>>>>>>>>>>>>>>END OF KEYPAD

; Send message #0,#1,#2 to Tx
;----------------------------
KPAD_Keystroke_Sendn
	...
	return	;>>>>>>>>>>>>>>>>END OF KEYPAD

; Side Tone Buzzer ON/OFF
; Only for TX message
; Not for service message
;------------------------
KPAD_Keystroke_Buz
	...
	return	;>>>>>>>>>>>>>>>>END OF KEYPAD

; Tune mode constant carrier
;---------------------------
KPAD_Keystroke_TunC
	...
	return	;>>>>>>>>>>>>>>>>END OF KEYPAD

; Tune mode pulse 50% duty cycle dits
;------------------------------------
KPAD_Keystroke_TunP
	...
	return	;>>>>>>>>>>>>>>>>END OF KEYPAD

; Toggle mode A or B
;-------------------
KPAD_Keystroke_Mod
	...
	return	;>>>>>>>>>>>>>>>>END OF KEYPAD

; Speed up
;---------
KPAD_Keystroke_SpeedUp
	...
	return	;>>>>>>>>>>>>>>>>END OF KEYPAD

; Slow down
;----------
KPAD_Keystroke_SlowDown
	...
	return	;>>>>>>>>>>>>>>>>END OF KEYPAD

;----------------------------------------------------------------------
; KPAD_GetADCvalue
; Convert analog voltage level to 10 bits number
; Input: WREG=AD config with channel number to read
; Output: 10 bit ADC value is read from the pin and returned justified right.
; Please refer data sheet Page 41 (Section 7.1.4) for the AD Conversion
; clock explanation.  The 10-BIT ADC in the PIC12F675 are request
; minimum Tad with 1.6uS, and the conversion time need 11 Tad, so the
; mininum conversion time is 1.6uS * 11Tad = 17.6uS.

KPAD_GetADCvalue
	movwf	ADCON0			; AD config channel ANx
KPAD_GetADCvalue_Go
	movlw	15 		; wait for Acquisition time
	call	Delay	; 15*5us=75us
	; A/D conversion cycle in progress
    bsf		ADCON0,GO_NOT_DONE	; Init GO_NOT_DONE
    btfsc	ADCON0,GO_NOT_DONE	;
    return

Réglages:
Pour m’assurer de la qualité de l’intervalle de mesure [min, max[ les résultats sont stockés provisoirement en EEPROM pour être visualisés a posteriori avec PICPgm. La section de code optionnelle encadrée par les étiquettes KPAD_Report et KPAD_Report_End disparaît en version Release. De même, le précieux espace réservé en EEPROM est récupéré en mettant en commentaire la définition     __ADRES_TRON . J'ai pu ainsi simplement vérifier que la théorie rejoignait la pratique.

Download  Télécharger le programme source, le fichier .hex et tous les schémas.

5. Encodeur morse – Gestion des messages

5.1. Messages préenregistrés

La quasi totalité de l'EEPROM est réservée à l'enregistrement des messages. Un indicatif et 3 messages peuvent être enregistrés. l'espace est distribué de manière dynamique. Chaque message de longueur variable s'insère dans la place restant disponible comme le montre l'extrait du programme ci-dessous.

;--------------
; MESSAGE BLOCK
;--------------
; Your call sign here
EE_CALLSIGN	; don't remove this label
;
	DE "F8EOZ" ; your call sign here CAPS LOCK ONLY
	DE _EOM ; end of call sign don't remove

;----------------------
; Prerecorded message#:
; A..Z CAPS LOCK ONLY
; @ alias for CALLSIGN
EE_MESSAGE ; don't remove this label
;
; message#0:
; CQ CQ CQ DE F8EOZ F8EOZ...
	DE _HOM,KPAD_SEND0,0x03 ; Head of message directive: message number (button assign), beacon time (0xFF=infinity)
	DE "CQ CQ CQ DE @ @ K "
	DE _EOM ; end of message#0
;
; message#1:
; CQ DX CQ DX CQ DX DE F8EOZ F8EOZ...
	DE _HOM,KPAD_SEND1,0x03 ; Head of message directive: message number (button assign), beacon time (0xFF=infinity)
	DE "CQ DX CQ DX CQ DX DE @ @ K "
	DE _EOM ; end of message#1
;
; message#2:
; CQ CQ F8EOZ F8EOZ TEST ...
	DE _HOM,KPAD_SEND2,0x03 ; Head of message directive: message number (button assign), beacon time (0xFF=infinity)
	DE "CQ CQ @ @ TEST "
	DE _EOM ; end of message#2
;----------------------------------------
;----------------------------------------
;----------------------------------------

L'indicatif: il est traité comme un texte pour être inséré dans les messages au moyen d'un alias. Il doit être placé après l'étiquette EE_CALLSIGN. La directive de fin de message _EOM le termine.

Les messages sont placés à la suite de l'indicatif après l'étiquette EE_MESSAGE.

Le message: se compose de 3 parties : l'entête, le texte du message, la fin.

L'entête:  comprend les données suivantes:

  • directive _HOM  (head of message),
  • le nom symbolique du bouton qui l'active,
  • le facteur de répétition (beacon time) [0, hFF] où FF = infini sachant qu’un message en cours peut toujours être interrompu par un DIT.

Le texte: c’est une chaîne de caractères ASCII et de codes procédure (prosign).
Caractère ASCII: [h20 (espace), h5A (Z)], portion de table comprenant les signes de ponctuation, les chiffres, les lettres majuscules. Les minuscules et tous les autres caractères ne sont pas utilisés.
Le caractère @ est utilisé comme alias de l’indicatif. L’encodeur le reconnaît et effectue son expansion.
Le caractère Espace est utilisé comme espace entre les mots (Word Gap).
Les codes de procédure sont situés dans l’intervalle [h80,hFF]. Les codes _AR,_BT,_SK peuvent être insérés simplement en fractionnant le texte. Exemple:

...	DE "TEXTE",_BT,"SUITE..."

La fin du message: directive _EOM (End of Message)

5.2. Messages de service

Le principe reste le même que les messages préenregistrés à la différence que les messages sont stockés dans une table de la RAM. Chaque message est placé derrière l’étiquette qui correspond à l’événement déclencheur.
Personnalisation : dans ma version, le message est constitué d’un seul caractère mais il pourrait être aussi un texte. Pour rendre muet le message il suffit de le remplacer par un espace. L’alias @ ne peut être utilisé. Voici la description de la table:

MSG_TABLE
	movlw 	HIGH(MSG_DATA) ; PCLATH = HIGH bit address
	movwf 	PCLATH 			;
	movf	TabPointer,W	; for PCL
	addwf	PCL ,F 			; Jump to character pointed to in W register
SERVICE_MESSAGE
;
; SERVICE MESSAGE
;
IAMBIC_MSG		; iambic key
	DT "I",_EOM
STRAIGHT_MSG	; straight key
	DT "S",_EOM
SPEED_UP_MSG	; signal for speed change up
	DT "U",_EOM
SLOW_DOWN_MSG	; signal for speed change down
	DT "D",_EOM
MOD_A_MSG		; signal for mode A change
	DT "A",_EOM
MOD_B_MSG		; signal for mode B change
	DT "B",_EOM
BUZ_MSG			; signal for sidetone buzzer on/off
	DT _AR,_EOM
ERROR_HM_NOT_FOUND	; signal for error header message not found
	DT _ERR,_EOM
;
	IF ((HIGH ($)) != (HIGH (SERVICE_MESSAGE)))
    	ERROR "MSG_TABLE CROSSES PAGE BOUNDARY!"
	ENDIF;

5.3. L’encodeur

Le diagramme figure 9 ci-dessous, montre le processus d’encodage.

Figure 9 - Diagramme du processus d'encodage

Figure 9 – Diagramme du processus d’encodage

Registres:

  • BitFrame: 8 bits comprenant le code Morse et une clé.
  • ControlTape: bande pilote de 8 bits qui commande de gauche à droite l’émission du code Morse (1= émission, 0=fin de code).
  • MorseCode: 8 bits de gauche à droite qui représente le code Morse (1 = DAH, 0=DIT).

ControlTape et MorseCode sont en correspondance biunivoque : ControlTape[b8]<->MorseCode[b8],…, ControlTape[b0]<->MorseCode[b0]

Entrée: un caractère ASCII ou un prosign.

Processus:

1) Transcodage:

  • Phase 1 : au moyen de la table RAM ENC_BIT_FRAME_TABLE, le caractère ASCII [h20,h5A] est transformé en BitFrame, le prosign passe ce premier filtre sans changement.
  • Phase 2 : Le prosign est transformé en Bit Frame. Les prosigns spéciaux passent ce second filtre sans changement.

2) Séparation:

Le BitFrame au moyen de sa clé, est divisé en 2 parties de 8 bits, MorseCode et ControlTape.

3) Encodage:

Enfin, l’encodage du signal morse est réalisé en faisant glisser vers la gauche la bande pilote (rotation gauche avec bit C) qui commande l’émission du signe Morse qui lui est relié.

Download  Télécharger le programme source, le fichier .hex et tous les schémas.

6. Le manipulateur électronique

La boucle principale du programme figure 10 ci-dessous, inclut l’interface de la clé Morse. Au démarrage ou au Reset, le Setup restaure  les dernières options de la machine à partir de l’EEPROM :

  • le registre UCON (User Control Register)
  • la vitesse de manipulation en mots/mn.

La détection du type de clé, Iambique ou Droite, est réalisée au Setup en examinant le port DAH. Voici la description du registre UCON.


;----- UCON Bits -----------------------------------------------------
IAMBIC_KEY 	EQU 0x00	; StraightKey=0 Iambic= 1
BUZE	 	EQU 0x01	; = 1 if side tone buzzer enable
TXF 		EQU 0x02	; Tx flag = 1 if message sending to Tx
MSGF		EQU 0x03	; msg flag = 1 if send message running
KPADF		EQU 0x04	; = 1 if keypad unlocked
MOD_B		EQU 0x05	; = 1 if keyer mode B, 0 mode A
BUZF		EQU 0x06	; buzzer flag = 1 if message sending to buzzer

;----- DEFAULT Options --------------------------------------------------
; Iambic Key + Buzzer on
#define UCON_DEFAULT (1<<IAMBIC_KEY) | (1<<BUZE) | (1<<BUZF)

L’accès au clavier est commandée de manière asynchrone par l’interruption TIMER1 (délai d’une seconde fixé par les paramètres TMR1_INIT  et TMR1_OVF_INIT) qui, elle même, est commandée par l’appui sur la clé du maniulateur.

Figure 10 - Boucle principale

Figure 10 – Boucle principale

Download  Télécharger le programme source, le fichier .hex et tous les schémas.

7. Réalisation

7.1. Clavier 3×3
Figure 11 - Clavier face avant

Figure 11 – Clavier face avant

Le circuit est réalisé  sur une plaque PCB FR4 pastillée étamée à trous métallisés double face de 5x7x0,16 cm. Le MCU et les composants qui l’entourent sont placés sur une seconde plaque identique, placée en dessous et qui s’enfiche à la première plaque. Il y a beaucoup de place. Les boutons poussoirs 6x6x9mm ont été achetés sur Ebay chez Electronics-Salon  qui propose des composants d’excellente qualité. L’utilisation d’une plaque double face est très pratique dans ce genre de circuit qui comprend surtout du fil! L’implantation des composants suit exactement le schéma théorique.

Vérification: avant de le connecter au MCU, s’assurer de son fonctionnement sous tension (problème de soudure). Pour ce faire, le relier seul à l’alimentation 5V, connecter le voltmètre à sa sortie, appuyer successivement sur chaque bouton et noter la tension.

Download  Télécharger le programme source, le fichier .hex et tous les schémas.

7.2. Carte principale
7.2.1. Prototype
Figure 12 - Prototype Carte principale

Figure 12 – Prototype Carte principale

Le prototype a été réalisé à l’aide du logiciel fritzing. C’est la première fois que je l’utilise. Sa prise en main est facile. Fritzing offre une protoboard dont les dimensions sont réglables. Je n’ai pas trouvé dans sa bibliothèque le 12F675. Qu’à cela ne tienne! l’éditeur de composants permet facilement de créer le sien à partir d’un modèle générique. Trois fichiers SVG sont nécessaires: breadbord.svg (platine d’essai), schematic.svg (schéma), pcb.svg (circuit imprimé). Si vous êtes curieux où si vous souhaitez peaufiner un peu, ces fichiers sont manipulables sous Inkscape. Attention cependant, au préalable, installer les polices de caractères OCR-A et Droid Sans qui sont utilisées par fritzing.

7.2.2. Carte câblée

Les 2 photos ci-dessous, montrent la carte principale cablée. Une diode de protection 1N4001 a été ajoutée en entrée du régulateur 5V. Le clavier s’embroche par dessus. L’ensemble est maintenu par des entretoises coupées dans de simples chevilles en plastique et 4 vis de 3mm provenant de la quincaillerie la plus proche.

Pour conclure, la mise en oeuvre du 12F675 est aisée mais n’oubliez pas: RTFM!

keyer12F675_1370

keyer12F675_1364

Download  Télécharger le programme source, le fichier .hex et tous les schémas et fichiers Inkscape et fritzing.

 

Références

Two-wire, four-by-four-key keyboard  interface saves power by Stefano Salvatori, University of Rome, and Gabriele Di Nucci, EngSistemi, Rome, Italy

Index des articles de la catégorie microcontroleur

]]>
http://www.f8eoz.com/?feed=rss2&p=3613 1
PIC Microchip – Adaptateur pour programmer la série des PIC 12F629/675/683 et 12F1822/1840 http://www.f8eoz.com/?p=3577 http://www.f8eoz.com/?p=3577#comments Mon, 06 Apr 2015 09:36:46 +0000 admin http://www.f8eoz.com/?p=3577
Figure 1 - Schéma de l'adaptateur 12F

Figure 1 – Schéma de l’adaptateur 12F

Le programmateur sur port parallèle a été réalisé initialement pour charger le firmware du fréquencemètre sur PIC 16F84. Le PIC s’insère dans le connecteur ZIF pour cette opération. Pour programmer la série des petits processeurs 12F il me faut maintenant un adaptateur ad hoc. C’est tout naturellement que l’adaptateur va s’insérer en lieu et place du 16F84. La figure 1 ci-contre montre le schéma de l’adaptateur. Les 5 connexions nécessaires à la programmation sont : Vdd (+5V), Vss (ground), Vpp (tension de programmation +13V), CLOCK, DATA. Pour s’assurer de la bonne connexion de l’adaptateur j’ai ajouté une petite LED et sa résistance de 1K sur Vdd.

1. Réalisation

Le circuit est réalisé  sur une plaque PCB FR4 pastillée étamée à trous métallisés double face de 4x6x0,16 cm. D’une face, figure 2 ci-dessous, sont soudées 2 barrettes sécables mâles droites de 4 pôles au pas de 2,54mm destinées à s’enficher sur le connecteurs ZIF sur les broches 4 à 7 et 12 à 15 du 16F84.

Figure 2 - Adaptateur face ZIF

Figure 2 – Adaptateur face ZIF

De l’autre face, figure 3 ci-dessous, sont soudées 2 barrettes de connexion sécables femelles rondes de 4 pôles au pas de 2.54mm destinées à recevoir le PIC 12F683 etc..

Figure 3 - Adaptateur face 12F...

Figure 3 – Adaptateur face 12F…

Comme vous pouvez le constater il reste beaucoup de place sur cette petite plaque qui pourra être utilisée pour s’adapter à une autre série de PIC. La dernière photo montre le programmateur en action muni de l’adaptateur.

Figure 4 - Programmateur + adaptateur 12F...

Figure 4 – Programmateur + adaptateur 12F…

2. Gestion de l’algorihme « Vpp before Vdd »

Pour programmer le 12F683, la tension Vpp doit être appliquée au moins  5us avant Vdd dans le cas de l’utilisation du mode INTOSC et du mode internal MCLR. Ce choix est fait en sélectionnant les bits du registre de configuration CONFIG. On se reportera utilement à la documentation de Microchip 41204G et particulièrement au chronogramme figure 3-1 du chapitre 3.

Mon programmateur a été conçu à l’origine pour le 16F84 du fréquencemètre et ne gère par cette séquence. Il est possible de programmer une première fois le 12F683. Il est ensuite impossible de le reprogrammer. Impossible me direz-vous ! Je ne connais pas ce mot (il me semble que quelqu’un à déjà dit cela avant moi…). En cherchant, j’ai trouvé une astuce pour reprogrammer le PIC sans changer de programmateur. Lorsque je mets sous tension mon programmateur portant le 12F683 qui a déjà été programmé dans le mode INTOSC et MCLRE_OFF, PICPgm regimbe et me dit qu’il ne connaît pas mon programmateur et du même coup ne peut identifier le PIC. Voilà comment je procède pour franchir l’obstacle. Tout en laissant connecté et sous tension mon programmateur, je fais croire à PICPgm que j’utilise un programmateur OLIMEX PIC-PG3 (28 pin – 40 pin) en le sélectionnant dans la liste des programmateurs disponibles. PICPgm se laisse faire et reconnaît le PIC. Je lance uniquement la séquence Erase. Bien entendu pas question d’aller plus loin, il refuse de charger le programme, mais cette étape est suffisante. Je sélectionne ensuite mon programmateur qui est bien reconnu ainsi que le PIC. Je peux exécuter le chargement du programme.

Bien entendu si on utilise l’option MCLR_ON, le 12F683 se reprogramme simplement comme d’habitude.

That’s all folks!

Download  Télécharger le fichier Inkscape du schéma.

Index des articles de la catégorie microcontroleur

]]>
http://www.f8eoz.com/?feed=rss2&p=3577 0
PIC Microchip – Installation de la nouvelle version WinPICPgm 1.8.3.0 http://www.f8eoz.com/?p=3560 http://www.f8eoz.com/?p=3560#comments Mon, 06 Apr 2015 08:07:48 +0000 admin http://www.f8eoz.com/?p=3560 PICPgm - Menu

PICPgm – Menu

On ne change pas une équipe qui gagne. Pour programmer les PIC je reste fidèle au duo programmateur sur port parallèle et WinPICPgm de Christian Stadler.  Jusqu’ici j’utilisais WinPICPgm sur un ordinateur fonctionnant sous W2K. Cet ordinateur portable que j’utilisais sans ménagement dans mon petit atelier depuis plus de 10 ans est au bout du rouleau. Il est temps de passer sur mon ordinateur principal plus récent. Une grande tour équipée de nombreux ports comme je l’aime, qui dispose encore d’un port parallèle fonctionnant sous W7 64 bits. Certes pas très esthétique mais efficace. J’en profite donc pour installer la dernière version de WinPICPgm. Comme son site web le présente à juste titre, il est « a free and simple PIC Development Programmer Software for Windows and Linux ». Son installation est simple est rapide. Son utilisation est toute aussi aisée. Voici la procédure :

  • télécharger la dernière version,
  • décompresser le fichier,
  • éxécuter winpicpgm_1.8.3.0.exe,
  • suivre la procédure d’installation.

1. Décrire le programmateur

Pour que le programmateur soit reconnu, s’il ne figure pas dans la liste de WinPICPgm, ajouter sa description dans le fichier pgmifcfg.xml confer l’article in situ.

2. Exécuter en tant qu’administrateur

A priori c’est terminé… Pas tout-à-fait peut-être? W7 peut vous demander d’élever vos droits. Si WinPICPgm demande que vous disposiez de droits d’administrateur alors que vous êtes déjà administrateur de l’ordinateur, cliquez avec le bouton droit sur l’icône du raccourci, puis cliquez sur Exécuter en tant qu’administrateur.
Si vous voulez éviter cela à chaque exécution du programme vous pouvez mémoriser ce droit, cliquez avec le bouton droit sur l’icône du raccourci, puis cliquez sur Propriétés, puis cliquez sur le bouton Avancé…, puis dans la fenêtre qui vient de s’ouvrir cocher la case Exécuter en tant qu’administrateur, puis  OK.

Bonne programmation!

PICPgm - Exécution avec droits d'administrateur

PICPgm – Exécution avec droits d’administrateur

Index des articles de la catégorie microcontroleur

]]>
http://www.f8eoz.com/?feed=rss2&p=3560 1
Atmel AVR – Installation des outils de développement logiciel et matériel http://www.f8eoz.com/?p=3491 http://www.f8eoz.com/?p=3491#comments Thu, 12 Mar 2015 15:07:12 +0000 admin http://www.f8eoz.com/?p=3491 ATMEGA8-16PU

« On ne connaît que les choses que l’on apprivoise. » Le petit prince – Antoine de Saint-Exupéry 1900-1944.

J’ai en réserve plusieurs projets à base de microcontrôleurs en lien avec l’émission-réception. Je relate dans cet article les étapes qui me permettent de dresser un atelier complet de développement et de faire mes premiers pas avec les microcontrôleurs AVR.

De ce premier contact avec AVR, les premiers mots qui me viennent à l’esprit sont: facilité, ouverture, gratuité. Facilité de mise en oeuvre, monde ouvert disposant d’une vaste bibliothèque de programmes et de nombreux outils open-source de développement gratuits dans différents langages. Un espace immense à explorer.

1. L’ oeuf ou la poule

Mon objectif est d’obtenir un atelier de développement complet à un coût très faible. De mon expérience avec les microcontrôleurs PIC, j’ en ai tiré que l’élément  critique de la chaîne était le programmateur et son logiciel associé. La programmation in-situ (In-System Programming ou ISP) facilite la mise au point des circuits. Le port USB s’impose comme un standard et remplace les autres ports externes de nos PC. Réaliser son programmateur, l’acheter? Les programmateurs ISP USB légers, bon marché, faciles à réaliser comme l’ USBtinyISP ou l’ USBasp sont conçus autour d’un microcontrôleur et d’un programme embarqué. Il me faudrait d’abord câbler un petit programmateur sur port parallèle pour télécharger le firmware dans le microcontrôleur du futur programmateur. Un coup d’oeil sur Ebay me fait opter pour l’achat. L’USBtinyISP avec un câble USB, et un cable ISP est disponible pour moins de 10 euros frais de port inclus.

Photo 1 - USBtinyISP

Photo 1 – USBtinyISP

2. Caractéristiques de l’ USBtinyISP

La photo 1 ci-contre montre ce petit programmateur qui se présente sous la forme d’un circuit de 27mm x 57 mm, construit autour du microcontrôleur AVR ATTINY2313A-PU. Son entrée est un connecteur USB (USB type B dans mon cas). En sortie, 2 connecteurs ISP , l’un de 6 broches, l’autre de 10. Un strap permet le choisir l’alimentation du circuit à programmer soit par le port USB, soit par une alimentation extérieure. Le strap est en place pour l’alimentation par le port USB. Le modèle Pocket AVR Programmer vendu par sparkfun et le modèle USBtinyISP AVR Programmer Kit vendu par adafruit industries sont les mêmes. Voici un schéma de l’ USBtinyISP dont il existe plusieurs variantes.

Remarque: la suite de l’article traite uniquement de  l’installation que j’ai réalisée sur Windows 7 64 bits.

3. Installation du driver de l’ USBtinyISP

C’est l’installation du driver qui m’a donné le plus de soucis. Quand on reçoit ce genre de circuit acheté sur Ebay, il est livré en général sans documentation ni aucun CD contenant les drivers. Il faut soit même chercher et croiser les doigts. Après plusieurs tentatives infructueuses, en fouillant le net j’ai trouvé une solution.

Ne pas brancher le programmateur tant que le driver n’est pas installé.

Etape 1 : télécharger et préparer le driver.

Télécharger les pilotes, le décompresser pour obtenir le répertoire pocketprog-driver.
Télécharger la dernière version des pilotes libusb-win32 depuis sourceforge, celle que j’ai téléchargée est la 1.2.6.0 du 17/01/2012, décompresser, pour obtenir le répertoire libusb-win32-bin-1.2.6.0.
Aller dans le répertoire libusb-win32-bin-1.2.6.0/bin/amd64.
Dans ce répertoire il y a 2 fichiers  libusb0.dll et libusb0.sys,
Renommer ces fichiers respectivement libusb0_x64.dll et libusb0_x64.sys.
Copier ces 2 fichiers dans le répertoire  pocketprog-driver, ils remplacent les 2 fichiers existants.

Photo 2 - Ajout du driver

Photo 2 – Ajout du driver

Etape 2 : installer le driver.

Ouvrir le menu Démarrer.
Clic droit sur Ordinateur.
Dans le menu, choisir Gérer.
Dans la fenêtre qui vient de s’ouvrir, colonne de gauche, cliquer sur gestionnaire de périphériques, vous obtenez dans la colonne du milieu un répertoire portant le nom de votre ordinateur avec  dessous la liste de tous les périphériques.
Clic droit en haut sur le nom de votre ordinateur, dans le petit menu qui vient de s’ouvrir cliquer sur Ajouter un matériel d’ancienne génération.
La fenêtre de l’assistant Ajout de nouveau matériel s’ouvre, cliquer sur suivant.
Dans la fenêtre qui vient de s’ouvrir choisir l’installation manuelle,
Une liste de matériel s’affiche, n’en sélectionner aucun, cliquer sur suivant,
Dans la fenêtre qui vient de s’ouvrir, cliquer sur le bouton installation à partir d’un disque.
Dans la fenêtre qui vient de s’ouvrir, sélectionner dans le répertoire  pocketprog-driver le fichier pocketprog.inf et cliquer sur OK.
Window vous prévient que le pilote n’est pas signé, continuer.
Dans la fenêtre suivante, cliquer sur suivant.
Un nouveau message d’avertissement de windows qui vous prévient que le pilote n’est pas signé, passer outre et continuer l’installation.
Une dernière fenêtre s’affiche qui indique que le pilote  AVR Pocket Programmer a été installé.
Cliquer sur Terminer.

Etape 3 : vérifier.

Dans la liste des périphériques on trouve maintenant une ligne LibUSB-Win32 Devices.
En cliquant dessus, s’affiche dessous la ligne AVR Pocket Programmer.
Clic droit sur cette ligne donne l’état du périphérique.

 4. Installation de WinAVR

WinAVR est un atelier complet de développement sous Windows regroupant tous les outils indispensables à la programmation C et assembleur, éditeur, débogueur, librairies. Il comprend aussi l’interface de programmation AVRdude qui permet le flashage du microcontrôleur en cours de programmation.
Télécharger la dernière version ici. La version que j’ai installée est la 2010-01-20. Suivre la procédure d’installation. Elle est rapide et sans problème.

Photo 3 - AVRdude options

Photo 3 – AVRdude options

5. Connexion de l’ USBtinyISP

Connecter le programmateur au PC à l’aide du câble USB,
Ne pas connecter pour l’ instant le cable ISP.
La LED verte du programmateur s’allume, le programmateur est alimenté.
Ouvrir une fenêtre d’invite de commande de façon suivante : dans le menu Démarrer, cliquer sur Tous les programmes, sur Accessoires, puis sur Invite de commandes.
Vérifier que AVRdude répond.
Dans la fenêtre  invite de commandes, taper avrdude.
Si tout va bien il répond en donnant la liste des options comme le montre la photo 3 ci-contre.
Vérifier que le programmateur communique avec le PC.
Dans la fenêtre  invite de commandes, taper
avrdude -c usbtiny -p m8
La petite LED rouge du programmateur cligne une fois.
La photo 4 ci-dessous montre le message qu’il faut obtenir. Cela indique que la connexion est bien établie mais que le dispositif, ici m8, pour ATMEGA8 n’est pas connecté. Normal puisqu’ aucun microcontrôleur à programmer n’est connecté à la ligne ISP. Bien entendu si vous compter utiliser un autre microcontrôleur, changer simplement le paramètre de l’option -p. La liste des dispositifs est donnée dans la documentation de avrdude. Mais le message obtenu sera le même.

Photo 4 - AVRdude -c usbtiny -p m8

Photo 4 – AVRdude -c usbtiny -p m8

6. Connexion de l’ USBtinyISP au dispositif à programmer

On se reportera utilement à la note AVR910 qui décrit le connecteur ISP.
Pour le test j’ai utilisé un ATMEGA8-16PU. Il s’agit de savoir si notre programmateur peut communiquer avec notre dispositif à programmer. Aucune alimentation n’est nécessaire, le dispositif à programmer est alimenté par le port USB via le programmateur. Aucun autre composant n’est utilisé. Pour ce faire :
Le programmateur reste connecté au PC via le port USB,
Sur une plaque d’essai, insérer le microcontrôleur,
Connecter le câble ISP 6 broches au programmateur,
Connecter l’autre extrémité du câble ISP au dispositif, les 6 lignes RST, VCC, GND, MOSI, MISO,  SCK, aux bornes de l’ATMEGA8 respectivement (1), (7), (8), (17), (18), (19) .
Pour avoir une connexion solide du connecteur ISP à la plaque d’essai, j’ai réalisé un petit adaptateur avec une chute de plaque veroboard et 4 morceaux de 3 pins de barrette sécable, 2 x 3 pins qui s’enfichent sur la prise ISP, 2 x3 pins qui s’enfichent sur la plaque d’essai, photo 5 ci-dessous.
Dans la fenêtre  invite de commandes, taper
avrdude -c usbtiny -p m8
La petite LED rouge du programmateur cligne une fois.
La photo 6 montre le message qu’il faut obtenir. Il indique que la connexion est bien établie.

Photo 5 - Connecteur ISP

Photo 5 – Connecteur ISP

Photo 6 - Flash

Photo 6 – Flash

7. Test de programmation

Il consiste à faire clignoter une LED. La fréquence de clignotement peut être modifiée en appuyant sur un bouton poussoir.

7.1. Matériel

Autour du microcontrôleur sont ajoutés 4 composants:
PORT B0, Une résistance de 330 ohms en série avec une LED dont la cathode est à la masse.
PORT B1, un bouton poussoir qui met le PORT à la masse quand on le presse.
En parallèle sur le bouton poussoir une capacité de 100 nF pour l’effet anti rebond.

Photo 7 - Dispositif de test de programmation

Photo 7 – Dispositif de test de programmation

7.2. Logiciel

Dans le répertoire WinAVR-20100110 cliquer sur Programmers Notepad
En haut dans la barre du menu, dans la liste déroulante choisir C/C++ .

Photo 8 - Programmation: choix du langage

Photo 8 – Programmation: choix du langage

Editer le programme

Vous trouverez en téléchargement le programme qui a servi aux tests. Il y en a aussi de multiples exemples du même genre sur le net. Si vous utilisez d’autres ports, il suffit de modifier le token-string de la macro define. (#define identifier token-string)
Dans votre répertoire de travail créer le répertoire LEDblink.
Enregistrer le programme en lui donnant le nom main.c .

Photo 9 - Programmation: éditer le programme

Photo 9 – Programmation: éditer le programme

Générer le MakeFile

Retourner dans le répertoire WinAVR-20100110 cliquer sur Mfile
Dans le menu de la fenêtre qui vient de s’ ouvrir, cliquer sur Makefile, puis sur MCU type, puis sur Atmega, et enfin choisir dans la liste atmega8.

Photo 10 - Programmation: générer le Makefile atmega8

Photo 10 – Programmation: générer le Makefile atmega8

De la même façon,  dans le menu cliquer sur Makefile, puis sur Port,  et enfin choisir dans la liste usb.

Photo 11 - Programmation: générer le Makefile port usb

Photo 11 – Programmation: générer le Makefile port usb

Toujours  dans le menu cliquer sur Makefile, puis Enable Editing of Makefile .
Dans le menu cliquer sur Makefile, puis sur Programmer,  cliquer sur le programmateur qui est déjà coché stk500v2, une ligne allumée en jaune s’affiche,  remplacer dans la ligne stk500v2 par usbtiny. Il faut faire comme cela parce que usbtiny n’est pas encore prévu dans la liste. Nous verrons au paragraphe suivant comment l’ajouter automatiquement.
Dans le menu cliquer sur File, puis sur Save as, sélectionner le répertoire LEDblink, ne pas changer le nom Makefile, cliquer sur Enregistrer.

Photo 12 - Programmation: générer le Makefile programmer usbtiny

Photo 12 – Programmation: générer le Makefile programmer usbtiny

8. mfile le générateur de Makefile pour AVR GCC

WinAVR est livré avec mfile.tcl un générateur de fichier Makefile. mfile.tcl est écrit en langage de script Tcl (Tool Command Language). WinAVR est fourni avec les outils Tcl et Tk qui interprètent ce fichier. mfile.tcl s’appuie sur le template makefile_template.
Puisque je vais travailler avec le même programmateur qui n’y est pas actuellement prévu, je vais modifier mfile.tcl pour l’y ajouter ainsi que les valeurs par défaut de makefile_template.
Pour ce faire, aller dans le répertoire WinAVR-2010110/mfile.
Dans ce répertoire se trouve les fichiers makefile_template et mfile.tcl. Commençons d’abord par faire une copie de sécurité de ces 2 fichiers.

8.1. Modifier mfile.tcl

Avec votre éditeur préféré, Notepad++ aller à  la ligne 711 dans la boucle foreach p ajouter usbtiny dans la liste déroulante. Sauvegarder.

Photo 13 - modification de mfile.tcl

Photo 13 – modification de mfile.tcl

8.2. Modifier makefile_template

Toujours avec votre éditeur préféré, Notepad++ aller à  la ligne 277 AVRDUDE_PROGRAMMER remplacer stk500v2 par usbtiny.
Aller à la ligne 280 AVRDUDE_PORT = com1
Mettre cette ligne en commentaire # AVRDUDE_PORT = com1
Sous cette ligne ajouter AVRDUDE_PORT = usb
Vous pouvez, si vous le souhaitez, y ajouter des commentaires comme je l’ai fait.
Sauvegarder.

Photo 14 - modification de makefile_template

Photo 14 – modification de makefile_template

Download  Télécharger tous les fichiers.

Références

SparkFun Electronics
NewbieHack.com
AVR910: In-System Programming
megaAVR Microcontrollers – Atmel Corporation
Tcl (Tool Command Language)

Index des articles de la catégorie microcontroleur

]]>
http://www.f8eoz.com/?feed=rss2&p=3491 0
Fréquencemètre à microcontrôleur PIC – Révision 1 http://www.f8eoz.com/?p=3203 http://www.f8eoz.com/?p=3203#comments Wed, 30 Jul 2014 16:24:58 +0000 admin http://www.f8eoz.com/?p=3203 Figure 1 - Le circuit câblé

Figure 1 – Le circuit câblé

J’ai réalisé une version plus compacte du fréquencemètre à insérer dans le boîtier du transceiver que je suis en train de construire. Le circuit figure 1 est câblé sur une plaque d’époxy FR4 pastillée, étamée double face de 5×7 cm. L’afficheur LCD est enfiché sur cette plaque. Quatre vis sont prévues pour le fixer sur le panneau avant du futur boîtier. Le firmware fcounter14 n’a pas été modifié il est disponible en téléchargement en version source et Hexa. L’utilisation des boutons-poussoirs évite toute modification du firmware (voir description), le fréquencemètre est utilisable dans différentes configurations matérielles:

  • choix du mode: avec ou sans IF, LO+IF, LO-IF, IF-LO, (avec LO = ocillateur local, IF = fréquence intermédiaire),
  • valeur de la fréquence IF.

Le  PIC16F84 et a été flashé avec mon programmateur. Au cours de cet exercice de soudure j’ai noté 2 erreurs sur le schéma initial que j’ai corrigées:

  • R5 = 470 Ω et non 22 kΩ,
  • R6 = 22 kΩ et non 27 kΩ.

J’ai aussi ajouté une résistance de 75 Ω pour le rétroéclairage de l’afficheur. Voici le schéma corrigé disponible en téléchargement révision 1:

Figure 2 - Schéma du fréquencemètre révision 1

Figure 2 – Schéma du fréquencemètre révision 1

Il faut noter aussi que je n’ai pas câblé sur ce circuit toute la partie concernant le régulateur 5V bien qu’il figure sur le schéma. J’évite ainsi la redondance du circuit d’alimentation. La tension de 5V est fournie par une alimentation solide et bien filtrée, montée sur un circuit séparé qui alimente aussi le VFO.

IMG_1665

IMG_1664

IMG_1663

Index des articles de la catégorie microcontroleur

]]>
http://www.f8eoz.com/?feed=rss2&p=3203 7
Fréquencemètre à microcontrôleur PIC – Réalisation http://www.f8eoz.com/?p=847 http://www.f8eoz.com/?p=847#comments Mon, 09 Jan 2012 18:12:17 +0000 admin http://www.f8eoz.com/?p=847 Le circuit imprimé
Le circuit imprimé a été monté sur plaque époxy à pastilles. Sa réalisation ne pose pas de problème particulier. Je n’ai pas poussé la miniaturisation. On pourrait faire plus petit en superposant l’afficheur au circuit imprimé.

Circuit imprimé vu de dessus

La face avant présente l’interrupteur on/off, la prise BNC d’entrée, les boutons de setup. La face arrière présente la fiche pour l’adaptateur secteur.

Circuit imprimé vu de dessous

Le circuit peut être, soit alimenté par pile pour être portable, soit par adaptateur secteur en utilisation de laboratoire. Remarquez les entretoises qui ne sont que de simples chevilles bon marché, coupées à dimension!

Le boîtier
La coque du boîtier a été réalisé avec de la tôle d’alu de 10/10. Les parties internes latérales sont des morceaux d’alu de 15/10. Les faces avant et arrière sont 2 plaques d’époxy cuivrées. L’ensemble est tenu par de simples vis à tôle.

Boîtier

Télécharger le fichier Kicad du schèma .
Télécharger les fichiers source et hexa du fréquencemètre .

Liens

Fréquencemètre à microcontrôleur PIC
Fréquencemètre à microcontrôleur PIC – Description
Fréquencemètre à microcontrôleur PIC – Structure du programme
Fréquencemètre à microcontrôleur PIC – Mesure
Fréquencemètre à microcontrôleur PIC – Commande de l’afficheur LCD
Fréquencemètre à microcontrôleur PIC – Réalisation

]]>
http://www.f8eoz.com/?feed=rss2&p=847 4
Fréquencemètre à microcontrôleur PIC – Commande de l’afficheur LCD http://www.f8eoz.com/?p=813 http://www.f8eoz.com/?p=813#comments Mon, 09 Jan 2012 15:21:37 +0000 admin http://www.f8eoz.com/?p=813 L’afficheur est commandé par le HD44780 LCD controller. Pour le commander nous disposons des bornes suivantes:
RS = 0 instruction input, 1 data input,
R/W = 0 write to LCD, 1 read from LCD,
E = enable signal,
DB0 à DB7 = data bus line 0 (LSB) to line 7 (MSB).
L’afficheur comprend 2 lignes de 16 caractères:
- ligne 0 de 0×00 à 0x0F,
- ligne 1 de 0×40 à 0x4F.

L’afficheur peut être utilisé en mode 8 bits (8-bit interface) ou en mode 4 bits (8-bit interface). Dans ce dernier cas, seules les lignes DB4 à DB7 sont utilisées. Le quartet (nibble) de poids fort et écrit puis le quartet de poids faible. C’est cette dernière méthode qui est utilisée ici.

J’ai construit le module d’affichage pour qu’il soit entièrement réutilisable par une autre application. Il comprend un ensemble de routines utilisées au travers de macros. Il comprend les éléments suivants:

Définitions:

#define DECIMALPOINT    '.'            ; decimal symbol : dot, comma, …
#define Number_notLeadingZero     LCDOption,0x07    ; 1 = not leading zero
; NUMBER_FORMAT code
#define    END_FORMAT       0xFF
#define    DOT_FORMAT       0x2E
#define    NINE_FORMAT    0x39
#define    ZERO_FORMAT    0x5A

Variables:

    LCD_TEMP:1    ; LCD subroutines internal use
    LCDOption:1   ; internal register don't use
    LCDIndex:1    ; general purpose index

Macros:
IR_WRITE    commande d’écriture d’instruction

BF_READ    commande de lecture du busy flag

DR_WRITE    commande d’écriture de data

DR_READ    commande de lecture de data

LCDDisplay_NumberF  <MSB_nombre>,  <adresseFormat> afficher un nombre avec format

LCDDisplay_Textl  <adresseTexte> afficher un texte

CURSOR_POS    placer le curseur à la position indiquée dans le registre W

CURSOR_POS l   <position> placer le curseur à la position indiquée en paramètre

LCDSet_Display_Control  contrôle de l’afficheur: curseur ou non, clignotement

SET_NOT_LEADING_ZERO afficher les zéros

Tables:
TABLE_TEXT textes à afficher.
NUMBER_FORMAT format des nombres à afficher.
Attention à l’implantation de ces tables qui modifient PCL, registre de 8 bits, qui est l’adresse basse du compteur ordinal. Ces 2 tables de moins de 256 octets ont été placées pour cela à partir de l’adresse 0×01.

Description de TABLE_TEXT
La première instruction de la table modifie PCL.
Chaque texte commence par une étiquette, se termine par le retour de zéro binaire sous forme:

ETIQUETTE_TEXTE
   DT   "TEXTE"
   RETLW 0

Ci-dessous TABLE_TEXT de notre programme.

;*****************************************************************************
; Text to display
; Relative character address is in W
;*****************************************************************************
TABLE_TEXT
    addwf    PCL ,F ; Jump to character pointed in W register
MOD_0
    DT   "NO IF"  ; Note the zero termination.
    retlw    0
MOD_1
    DT   "LO+IF"  ; Note the zero termination.
    retlw    0
MOD_2
    DT   "LO-IF"  ; Note the zero termination.
    retlw    0
MOD_3
    DT   "IF-LO"  ; Note the zero termination.
    retlw    0
MODE_LABEL
    DT    "MODE:"
    retlw    0
IF_LABEL
    DT    "IF:"
    retlw    0
UNDERFLOW_ERROR
    DT    "Underflow Error"
    retlw    0
MHz_UNIT
    DT    "MHz"
    retlw    0
TABLE_TEXT_END
    retlw    0
;
    IF ( (TABLE_TEXT & 0x0FF) >= (TABLE_TEXT_END & 0x0FF) )
        MESSG   "==============Warning - User Defined: Table 'TABLE_TEXT' crosses page boundary in computed jump=============="
    ENDIF

Afficher un texte
L’affichage d’un texte se résume à une seule ligne qui utilise la macro LCDDisplay_Textl. Par exemple pour afficher l’unité de la fréquence:
LCDDisplay_Textl    MHz_UNIT

Cas particulier de la traduction d’un code en texte
Ce cas se pose ici pour l’option MODE du setup qui propose 4 valeurs de 0 à 3. On affiche le code et sa traduction litérale. Ce problème se règle simplement en définissant une table intermédiaire ici appelée MOD_x (placé ici sous TABLE_TEXT) qui retourne l’adresse du texte à afficher dans le registre W. Le texte est affiché directement par la routine (et non la macro) LCDDisplayText de la façon suivante:

    movf    MODindex, w      ; get address from TABLE_TEXT
    call    MOD_x            ; return address MODE option text from TABLE_TEXT in W
    call    LCDDisplayText   ; display text

Table intermédiaire MOD_x:

MOD_x    ; MODindex is in W. Return TABLE_TEXT address into W register
    addwf    PCL ,F ; Jump to character pointed to in W register
    retlw    MOD_0 - TABLE_TEXT - 1
    retlw    MOD_1 - TABLE_TEXT - 1
    retlw    MOD_2 - TABLE_TEXT - 1
    retlw    MOD_3 - TABLE_TEXT - 1

Description de NUMBER_FORMAT
La première instruction de la table modifie PCL.
Chaque format commence par une étiquette, se termine par le retour de oxFF sous forme:

ETIQUETTE_FORMAT
   DT   "FORMAT"
   RETLW 0xFF

Description du format
Le format sert à supprimer les zéros non significatifs, à indiquer la position du point décimal, à insérer des espaces pour séparer les milliers.
Z = supprime un zéro non significatif (leading zero). Dès qu’un chiffre différent de zéro est atteint ce code devient inactif.
. = point décimal, insère le caractère défini par DECIMALPOINT et inactive Z.
9 = insère le chiffre quel que soit sa valeur et inactive Z.
espace (valeur par défaut) = insère un espace.
L’affichage du nombre commence par la gauche (MSB) et s’arrête au dernier 9 s’il existe ou sinon au dernier Z. Le nombre doit être sous forme Décimal Codé Binaire étendu ( pas de nombre en ASCII).

Ci-dessous NUMBER_FORMAT de notre programme.

;*****************************************************************************
; Number format
; Relative format code address is in W
;*****************************************************************************
NUMBER_FORMAT
    addwf    PCL ,F ; Jump to character pointed in W register
FORMAT_MHz
    DT   "Z Z99.999 999"  ; Note the FF termination.
    retlw    0xFF
FORMAT_IF
    DT   "99.999"  ; Note the FF termination.
    retlw    0xFF
FORMAT_MOD
    DT   "9"  ; Note the FF termination.
    retlw    0xFF
NUMBER_FORMAT_END
    retlw    0xFF
;
    IF ( (NUMBER_FORMAT & 0x0FF) >= (NUMBER_FORMAT_END & 0x0FF) )
        MESSG   "==============Warning - User Defined: Table 'NUMBER_FORMAT' crosses page boundary in computed jump=============="
    ENDIF

Ci-dessous la routine d’affichage d’un nombre.

;*****************************************************************************
; Display a number at cursor position using a table NUMBER_FORMAT
; Format sample: ZZZ Z9 or 99 or 9.999 or 9 999 999 ....
; Start address character must be in FSR
; Start address table NUMBER_FORMAT must be in W
; Number_notLeadingZero = 0 => Leading zeros are not displayed
; Number_notLeadingZero = 1 => zero is not Leading zero
;_______________________________________________________
; ASCII value    x30 x31 x32 x33 x34 x35 x36 x37 x38 x39
; number           0   1   2   3   4   5   6   7   8   9
;_______________________________________________________
;*****************************************************************************
LCDDisplayNumberF
    movwf    LCDIndex                ; Holds format address in table NUMBER_FORMAT
    clrf     LCDOption
LCDDisplayNumberFLoop
    ; is leading Zero ?
    movfw    LCDIndex
    call     NUMBER_FORMAT
    xorlw    0x5A                    ; Check if "Z" format
    btfsc    STATUS, Z
    goto     Z_format                ; yes, ====>
    ; is nine ?
    movfw    LCDIndex
    call     NUMBER_FORMAT
    xorlw    0x39                    ; Check if "9" format
    btfsc    STATUS, Z
    goto     nine_format             ; yes, ====>
    ; is dot ?
    movfw    LCDIndex
    call     NUMBER_FORMAT
    xorlw    0x2E                    ; Check if "." format
    btfsc    STATUS, Z
    goto     dot_format              ; yes, ====>
    ; is end ?
    movfw    LCDIndex
    call     NUMBER_FORMAT
    xorlw    0xFF                    ; Check if at end of format
    btfsc    STATUS, Z
    goto     LCDDisplayNumberFEnd    ; yes, end =====================>

space_format    ; default
    btfss    Number_notLeadingZero   ; is a number 1 to 9 already displayed ?
    goto     nextIndexFormat         ; no, no space to insert
    movlw    ' '                     ; yes, insert a space
    call     LCDputChar4             ; Display character
    goto     nextIndexFormat
dot_format
    SET_NOT_LEADING_ZERO             ; to avoid future Z format
    movlw    DECIMALPOINT            ; insert decimal point
    call     LCDputChar4             ; Display character
    goto     nextIndexFormat
nine_format
    SET_NOT_LEADING_ZERO             ; to avoid future Z format
    goto     displayASCII
Z_format
    btfsc    Number_notLeadingZero   ; is a number 1 to 9 already displayed ?
    goto     displayASCII            ; yes, display digit

    movf     INDF, f                 ; INDF -> INDF, set STATUS bit Z
    btfsc    STATUS, Z
    goto     nextDigit               ; yes digit = 0, leading zero not displayed
    SET_NOT_LEADING_ZERO             ; no, display digit and avoid future Z format
displayASCII
    movf     INDF,W                  ; Digit -> W
    iorlw    030h                    ; ASCII value mask
    call     LCDputChar4             ; Display character
nextDigit
    incf     FSR, f
    nextIndexFormat
    incf     LCDIndex,f              ; Point to next character
    goto     LCDDisplayNumberFLoop
LCDDisplayNumberFEnd

return

Afficher un nombre
L’affichage d’un nombre se résume à une seule ligne qui utilise la macro LCDDisplay_NumberF, par exemple pour afficher la fréquence mesurée:
LCDDisplay_NumberF BCD9, FORMAT_MHz

Télécharger le fichier Kicad du schèma .
Télécharger les fichiers source et hexa du fréquencemètre .

Liens

Fréquencemètre à microcontrôleur PIC
Fréquencemètre à microcontrôleur PIC – Description
Fréquencemètre à microcontrôleur PIC – Structure du programme
Fréquencemètre à microcontrôleur PIC – Mesure
Fréquencemètre à microcontrôleur PIC – Commande de l’afficheur LCD
Fréquencemètre à microcontrôleur PIC – Réalisation

]]>
http://www.f8eoz.com/?feed=rss2&p=813 0
Fréquencemètre à microcontrôleur PIC – Mesure http://www.f8eoz.com/?p=767 http://www.f8eoz.com/?p=767#comments Sat, 07 Jan 2012 12:21:56 +0000 admin http://www.f8eoz.com/?p=767 La routine de mesure  est le coeur du fréquencemètre. A chaque boucle du programme elle est appelée 2 fois:
- pour l’auto calibrage,
- pour la mesure réelle.

Description de la routine de mesure
La fréquence à mesurer est appliquée sur RA4/T0CKI. La routine est chargée de relever à chaque cycle le compteur TMR0. La représentation d’une fréquence  maximum de 50 MHz nécessite en binaire, 25 bits, il faut donc utiliser 4 compteurs  de 8 bits soit 32 bits. Comme TMR0   est limité à 8 bits, elle détecte le débordement de TMR0 en comparant sa valeur avec la valeur stockée au cycle précédent TMR0_old. Quand TMR0 < TMR0_old, elle reporte la retenue aux niveaux supérieurs. La durée d’un cycle de la routine de mesure est de 25 us avec un PIC 16F84 à 4 MHz. J’ai choisi cette durée qui est sous-multiple de 275 us, durée de l’auto calibrage, et de 500 ms durée de la mesure réelle.
Paramètres:
gateLow = nombre de cycles bas,
gateHigh = nombre de cycles haut,
Durée de la mesure = gateHigh x gateLow x 25us
Compteur Binary Frequency Counter = BFC3 (32 bits), BFC2, BFC1, BFC0 (LSB)
TMR0_old = valeur de TMR0 du cycle précédent, initialisée à zéro.

Auto calibrage
Il permet de régler le prescaler pour la mesure réelle. L’auto calibrage consiste à effectuer une mesure pendant 275us avec le prescaler = 256. A l’issue de cette mesure, nous obtenons dans le compteur BFC0 une approximation de la gamme de fréquence en MHz.
1 MHz x 275us / 256 = 1,07 => BFC0 = 1
2 MHz x 275us / 256 = 2,14 => BFC0 = 2
3 MHz x 275us / 256 = 3,22 => BFC0 = 3

10 MHz x 275us / 256 = 10,74 => BFC0 = 10

20 MHz x 275us / 256 = 21,48 => BFC0 = 21

50 MHz x 275us / 256 = 53,71 => BFC0 = 53
Remarque: compte-tenu de la durée de mesure de 275us et le la valeur du prescaler de 256, les fréquences <  1 x 256 / 275 soit 0,930908 MHz donneront BFC0 = 0.
Vous pouvez vérifier le résultat de l’auto calibrage sur l’afficheur. Dans le programme source rechercher la ligne ;#define    AUTORANGE_TEST. Cette ligne est inactivée en commentaire. Rendez cette ligne active. Ré assemblez et vérifiez en connectant au fréquencemètre un VFO par exemple.

Calcul du pré diviseur (prescaler PS)
Le calcul est effectué simplement en examinant le bit de poids fort de BFC0 de la façon suivante:
bit 7 = 1 | 128 à 255 MHz et au dessus inutilisé
bit 6 = 1 | 064 à 128 MHz inutilisé
bit 5 = 1 | 032 à 064 MHz | PS = 5 | 64:1
bit 4 = 1 | 016 à 032 MHz | PS = 4 | 32:1
bit 3 = 1 | 008 à 016 MHz | PS = 3 | 16:1
bit 2 = 1 | 004 à 008 MHz | PS = 2 | 8: 1
bit 1 = 1 | 002 à 004 MHz | PS = 1 | 4:1
bit 0 = 1 | 000 à 002 MHz | PS = 1 | 4:1
Remarque: je n’ai pas utilisé la valeur PS=0. En effet, lors de mes essais avec cette valeur, j’obtenais une mesure erronée que je ne m’explique pas. Si un lecteur à la solution je suis preneur!

Vérifions la mesure maximum possible pour chaque gamme de fréquence, pour une durée de mesure de 500 ms:
64 MHz = 64 000 000 x 0,5 / 64 = 500 000 =   07 A1 20 (16)
32 MHz = 32 000 000 x 0,5 / 32 = 500 000 =   07 A1 20 (16)
16 MHz = 16 000 000 x 0,5 / 16 = 500 000 =   07 A1 20 (16)
08 MHz = 08 000 000 x 0,5 / 08 = 500 000 =   07 A1 20 (16)
04 MHz = 04 000 000 x 0,5 / 04 = 500 000 =   07 A1 20 (16)

Mesure réelle
Après l’auto calibrage, la mesure réelle est faite pendant 500 ms. Le résultat est ensuite multiplié une première fois par 2 (simple décalage à gauche avec report du bit de retenu) pour obtenir une valeur rapportée à une seconde. Ce résultat et encore multiplié par 2, autant de fois que l’indique le prescaler pour obtenir la valeur définitive de la fréquence en Hz. A cette valeur est éventuellement ajoutée ou ôtée IF selon l’option MODE du setup. La valeur binaire obtenue et ensuite transformée en décimal codé binaire dans BCD9 (MSB) à BCD0 (LSB) puis affichée.

Limites et précision
Avec une durée de mesure de 500 ms, la plus petite fréquence mesurable serait théoriquement de 2 Hz. Toutefois avec PS minimum = 4, la fréquence minimum mesurable = 1 x 4 / 0.5 = 8 Hz.
Précision:
- gamme 04 MHz = 008 Hz,
- gamme 08 MHz = 016 Hz,
- gamme 16 MHz = 032 Hz,
- gamme 32 MHz = 064 Hz,
- gamme 64 MHz = 128 Hz.

Modification de la durée du cycle de base de la routine de mesure
Avec une fréquence d’horloge de 10 MHz la routine ne doit pas être modifiée. Vous pouvez modifier les paramètres gateLow et gateHigh pour obtenir une durée proche de 256 us pour l’auto calibrage et une durée exacte de 500 ms pour la mesure réelle. Ainsi avec un quartz de 10 MHz, si le cycle de base = 10 us au lieu de 25 us, vous pouvez choisir 26 x 10 us = 260 us (> 256 us) pour l’auto calibrage et 200 x 250 x 10 us = 500 000 us =  500 ms pour la mesure réelle.

Si cela n’est pas suffisant il faut adapter la routine. Pour cela il faut distinguer les instructions nécessaires et suffisantes de celles qui sont là pour faire perdre du temps (nop en général). Voici la formule du cycle de base de notre routine:
cycle de base = 4p + (10+a)np + (3+b)p(n-1) + 2p + (3+c)(p-1) + 2 + 3

n = gateLow,
p = gateHigh,
a = temps perdu,
b = temps perdu,
c = temps perdu,
Les valeurs fixes 4, 10, 2, 3 sont la durée des instructions nécessaires avec une horloge de 4 MHz.

Avec ces valeurs pour obtenir un cycle de base de 25 us, poser n = 1 et p = 1, il vient:
cycle de base = 25 us = 4 + (10 + a) + 0 + 2 + 0 + 2 + 3 => a = 4,
poser n = 2 et p = 1, il vient
2 cycles de base = 50 us = 4 + (10 + 4)2 + (3 + b)1 + 2 + 0 + 2 + 3 => b = 8,
poser n = 1 et p = 2, il vient
2 cycles de base = 50 us = 4×2 + (10 + 4)2 + 0 + 2×2 + (3+ c) + 2 + 3 => c = 2, d’où
cycle de base = 4p + (10+4)np + (3+8)p(n-1) + 2p + (3+2)(p-1) + 2 + 3.
C’est la formule qui est utilisée dans ce programme.
a est obtenu avec 4 instructions nop, b avec 8 nop, c avec un goto supplémentaire.

Supposons par exemple une fréquence d’ horloge qui diviserait par 4 la durée des instructions et un  cycle de base = 8 us, durée choisie car sous-multiple de 256 et 500000 qui peut être obtenu en faisant gateLow = 250 et gateHigh = 250 (chaque compteur est limité à 255).
Cycle de base = 8 us = p + (2.5 + a)np + (0.75 + b)p(n-1) + 0.5p + (0.75+c)(p-1) + 0.5 + 0.75,
avec n = 1 p = 1, il vient
cycle de base = 8us = 1 + (2.5 + a) + 0 + 0.5 + 0 + 0.5 + 0.75 => a = 2.75,
avec n = 2 et p = 1, il vient
2 cycles de base = 16 us = 1 +(2.5 + 2.75)2 + (0.75 + b) + 0.5 + 0 + 0.5 + 0.75 = b = 2,
avec n = 1 et p = 2, il vient
2 cycles de base = 16 us = 2 +(2.5 + 2.75)2 + 0 + 0.5×2 + (0.75+c) + 0.5 + 0.75 => c = 0.5, d’où
cycle de base = 8us = p + (2.5 + 2.75)np + (0.75 + 2)p(n-1) + 0.5p + (0.75+0.5)(p-1) + 0.5 + 0.75.
Avec ces valeurs pour l’auto calibrage = 256 us = 32 x 8 us, n = 32 et p = 1,  il vient
32 cycles de base = 1 + (2.5 + 2.75)32 + (0.75 + 2)31 + 0.5 + 0 + 0.5 + 0.75 = 256 us C.Q.F.D.
La mesure réelle = 500 ms = 62500 x 8 us, n = 250 et p = 250,  il vient
62500 cycles de base = 250 + (2.5 + 2.75)62500 + (0.75 + 2)250×249 + 0.5×250 + (0.75+0.5)249 + 0.5 + 0.75 = 500 000 us C.Q.F.D.
a pourrait être obtenu avec 11 nop, b avec 8 nop, c en laissant le même goto supplémentaire.

Dans le Debugger de MPLAB, il y a un excellent outil qui s’appelle StopWatch qui permet de connaître la durée exacte de notre routine. Indiquer au préalable la valeur de la fréquence horloge en choisissant Setting dans le menu du Debugger.

Ci-dessous la routine de mesure qui finalement contient peu d’instructions.

;********************************************************************************
; Parameters : gate time high = p, gate time low = n
; Gate time = 4p + (10+4)np + (3+8)p(n-1) + 2p + (3+2)(p-1) + 2 + 3
; One step = 25 us with XTAL = 4 MHz
; 275 us = 1 x 11 x 25 us => p = 1, n = 11
; 500 ms = 100 x 200 x 0.025 ms => p = 100, n = 200
;********************************************************************************
Measure
    BANK1
    movwf    OPTION_REG     ;
    BANK0
    clrf    BFC0-1         ; clear 16 bits counter
    clrf    BFC0-2         ; clear 24 bits counter
    clrf    BFC0-3         ; clear 32 bits counter

    bcf     PORTA,0x03
    movf    gateHigh,w
    movwf   countHigh
    clrf    TMR0_old
    clrf    TMR0
    COUNT_START    ; start count
M05 movfw   gateLow         ; |
    movwf   countLow        ; | = 4p
    goto    M20             ; |
M10 ; c
    goto M05                ; = 2(p-1)
    ; b = 8 nop
M15 nop                     ; |
    nop                     ; |
    nop                     ; |
    nop                     ; |  = 8p(n-1)
    nop                     ; |
    nop                     ; |
    nop                     ; |
    nop                     ; |

M20 movf    TMR0,w         ; TMR0 rollover ?    ; |
    subwf   TMR0_old,f     ; TMR0_old - TMR0    ; |
    btfss   STATUS,Z       ; 0 = no change      ; |
    goto    M25                                 ; |
    nop                                         ; |
    nop                                         ; |
    nop                                         ; |
    goto    M30                                 ; |
M25 btfsc   STATUS,C    ; TMR0 < TMR0_old ?     ; | = (10+4)np
    incf    BFC0-1,f    ; 16 bits counter       ; |
    btfsc   STATUS,Z                            ; |
    incf    BFC0-2,f    ; 24 bits counter       ; |
M30 movwf   TMR0_old                            ; |
    ; a = 4 nop
    nop                                         ; |
    nop                                         ; |
    nop                                         ; |
    nop                                         ; |

    decfsz  countLow,f          ; = 2p
    goto    M15                 ; = 3p(n-1)
    decfsz  countHigh,f         ; = 2
    goto    M10                 ; = 3(p-1)
    COUNT_STOP                  ; = 3
    ; last value
    movf    TMR0,w       ; test for TMR0 rollover
    movwf   BFC0         ; save 8 bits counter
    subwf   TMR0_old,f
    btfsc   STATUS,Z     ; rollover ?
    goto    M_35         ; no
    btfsc   STATUS,C
    incf    BFC0-1,f     ; 16 bits counter
    btfsc   STATUS,Z
    incf    BFC0-2,f     ; 24 bits counter
M_35
    retlw   0x00

Télécharger le fichier Kicad du schèma .
Télécharger les fichiers source et hexa du fréquencemètre .

Liens

Fréquencemètre à microcontrôleur PIC
Fréquencemètre à microcontrôleur PIC – Description
Fréquencemètre à microcontrôleur PIC – Structure du programme
Fréquencemètre à microcontrôleur PIC – Mesure
Fréquencemètre à microcontrôleur PIC – Commande de l’afficheur LCD
Fréquencemètre à microcontrôleur PIC – Réalisation

]]>
http://www.f8eoz.com/?feed=rss2&p=767 1