samedi 31 mars 2012

lecture d'un clavier sur entrée en logique TTL

Suite au résultat positif de lecture de plusieurs boutons sur une 1 entrée en logique TTL, (voir projet PocketSimon), J'ai décidé de vérifier s'il était possible de lire un keypad de 16 touches avec cette méthode. J'ai donc fait le montage suivant

Ce qu'on aperçoit à gauche du montage est un affichage binaire de 1 octet que je me suis fait. C'est un petit outil de dévellopement utile qui n'utilise que 2 sortie TTL du MCU, 1 DATA et 1 CLOCK et une très courte routine d'affichage. Dans ce cas ci je m'en suis servis pour afficher la valeur du compte de délais de charge du condensateur pour chaque touches du clavier.
Ce projet n'est alimenté que par le 5Volt fournis par le PICKIT 2.

résultat des tests

Voici le schémas du circuit et le code utilisé.

; test le principe de lecture de plusieurs boutons par la mesure
; du temps de charge d'un condensateur.
#include <P10F202.INC>
__CONFIG _WDTE_OFF & _CP_OFF & _MCLRE_OFF

#define DISP_CLK GPIO, GP1
#define DISP_DAT GPIO, GP0
#define BTN_INP GPIO, GP2

;;;;;;;;;;; constantes ;;;;;;;;;;;

OPTION_CFG EQU B'01000001'
TMR0_CNT EQU ~.250

;;;;;;;;;;;;;;;; macros ;;;;;;;;;;;;;;;;;

clamp_on macro ;; court-circuite le condensateur sur GP1
movlw B'1000'
TRIS GPIO
bcf BTN_INP
endm

clamp_off macro ;; enlève le court-circuit et met GP1 en mot input
movlw B'1100'
TRIS GPIO
endm

cpr macro r1, r2 ; copie le registre r1 dans r2
movfw r1
movwf r2
endm

ldr macro reg, const ; initialise le registre avec une constante
if const==0
clrf reg
else
movlw const
movwf reg
endif
endm

init_delay_cntr macro msec
ldr delay_cntr, low (~msec)
ldr delay_cntr+1, high (~msec)
endm


;;;;;;;;;;;; variables ;;;;;;;;;;;;;;;
cblock 8
charge_delay : 1 ; compteur du délais de charge du condensateur
delay_cntr : 2 ; compteur pour la routine delay_ms
display_val : 1 ; valeur à afficher
bit_cntr : 1 ; compteur de bit pour display
endc

;;; début du code ;;;;;;;;;
org 0
movlw OSCCAL
goto initialization

;;;; delay_ms ;;;;;;;;;
;; delais en milisecondes
;; entrée: delay_cntr = nombre de millisecondes
delay_ms
ldr TMR0, TMR0_CNT
movlw OPTION_CFG
option
movfw TMR0
skpz
goto $-2
incfsz delay_cntr
goto delay_ms
incfsz delay_cntr+1
goto delay_ms
return

;;;;; display ;;;;;;;;;;;;;;
;;; affiche une valeur en binaire sur le dbg_display
;;; entrée: display_val contient la valeur à afficher
display
ldr bit_cntr, 8
display01
bcf DISP_CLK
bcf DISP_DAT
rlf display_val,F
skpnc
bsf DISP_DAT
bsf DISP_CLK
decfsz bit_cntr
goto display01
return

;;;;;;;;;;;; read_buttons ;;;;;;;;
;;; lecture des boutons
;;; sortie: charge_delay contient le compte
read_buttons
clrf charge_delay
clamp_off
btfsc BTN_INP
goto sortie
incfsz charge_delay
goto $-3
sortie
clamp_on
return


initialization
movlw OPTION_CFG
bcf OSCCAL, 0
option
clamp_off

main
init_delay_cntr .500
call delay_ms ; attend 20 milliseconde entre chaque lecture
call read_buttons ; lecture des boutons
cpr charge_delay, display_val ; copie la valeur pour affichage
call display ; affiche la value
goto main
end


résultats
boutonlecture
14
28
312
A16
417
521
625
B28
730
834
938
C41
*43
047
#50
D54
Il n'y a qu'un digit de différence entre la lecture de A et de 4. Pour que cette méthode soit fiable il faut une alimentation régulé et stable et il serait préférable que les résistances R5 à R7 soit de 12Kohm plutôt que 10Kohm pour augmenter l'écart entre les boutons A et4.

Aucun commentaire:

Enregistrer un commentaire