CAPACIMETRE NUMERIQUE
basé sur un ATmega8

Je vous ai déjà parlé ici de ces puissants microcontrôleurs RISC que sont les AVR ATMEGA8-16.

Voici ma première réalisation avec l'un d'eux, afin de me familiariser avec le langage assembleur AVR.
Moi qui connaissais bien les PIC, je n'ai eu aucune difficulté à migrer vers ces nouveaux circuits que je trouve plus performants, mais dont l'architecture et les ressources restent assez semblables.

Vous trouverez dans le soft que je fournis:
  • des routines permettant de piloter un afficheur LCD 1x16c ou 2x16c.
  • des routines d'affichage d'un octet et d'un mot de 16bits.
  • des routines de gestion des interruptions et des timers.
  • une routine périodemètre.
  • une routine de MULTIPLICATION 8 bits x 16 bits résultat sur 24 bits (en complément de celle implantée dans la puce qui est de 8b*8b->16b).
  • une routine de DIVISION 24 bits par 8 bits, résultat sur 24 bits.

1 Le schéma:

Le condensateur à mesurer est connecté sur un NE555 (voir sa doc) qui fonctionne en oscillateur (utilisation très classique)
L'ATmega8 mesure la fréquence (plus exactement la période).

2 L'appareil monté

Voici le Capacimètre en train de mesurer un condensateur de 1nF (le petit bleu, flou, à droite)

L'ajustable de gauche permet de régler le contraste de l'afficheur Celui de droite sert pour étalonner (il suffit de connecter une capa dont la valeur est connue avec précision, par exemple un condensateur à 0.5% ou plus simplement un condensateur préalablement mesuré avec un autre capacimètre... c'est le cas de mon 1nF)


Le capacimètre peut mesurer des valeurs de 1pF à 1uF
L'échelle est ajustée automatiquement, ainsi que l'unité affichée (pF ; nF ; uF) On pourrait facilement le modifier pour monter plus haut, mais ça ne m'intéresse pas ! (je lui demande juste de mesurer mes petit CMS lorsque je renverse la boîte!)

Le connecteur en haut du circuit sert à programmer le microcontrôleur "in situ" en quelques secondes, avec le programmateur décrit sur ce site. De quoi apporter toutes les modifs que vous voulez. Vous pouvez même en faire autre chose qu'un capacimètre !

Le zéro est automatique à la mise sous tension (SANS CONDO CONNECTE donc); Le petit switch permet de forcer cette mise à zéro.

Remarque: J'ai utilisé quelques straps zéro ohms au format de résistances.

3 Le firmware en assembleur AVR

boite code source:
CODE SOURCE en assembleur AVR
  1. ;=======================================================================
  2. ; Fichier : capacimetre.asm
  3. ; Titre: Capacimetre numerique ATMEGA8 - NE555 - Afficheur LCD 2x16
  4. ; Version: 1.0
  5. ; Auteur: Fred
  6. ; Date: 05/12/2005
  7. ;
  8. ;
  9. ;=======================================================================
  10.  
  11. ;Declaration des Variables
  12. ;Declaration des Vecteurs d'interruptions
  13. ;Routines de traitement des interruptions
  14. ;Programme de RESET
  15. ;PROGRAMME PRINCIPAL
  16. ;PROCEDURES
  17.  
  18. ;mul16_8 MULTIPLICATION 8 bits x 16 bits resultat sur 24 bits
  19. ;div24_8 DIVISION 24 bits par 8 bits, resultat sur 24 bits
  20.  
  21.  
  22. .include "m8def.inc" ; nom du fichiers de references des registres (ATMEGA 8)
  23.  
  24.  
  25. ;------------------------------------------------------------------------
  26. ;Declaration des Variables
  27. ;------------------------------------------------------------------------
  28. .def gamme=r2
  29. .def type_aff=r3
  30.  
  31. .def SAUVREG = r16 ; registre de sauvegarde de SREG
  32. .def a=r17
  33. .def AA=r18
  34. .def BB=r19
  35. .def AL=r18 ;idem AA volontairement
  36. .def AH=r19 ;idem BB volontairement
  37.  
  38. ;registres [20..25] pour les variables locales
  39.  
  40. .DSEG
  41. dtlcd: .BYTE 1
  42. bitn: .BYTE 1
  43. aff1: .BYTE 1
  44. aff2: .BYTE 1
  45. aff3: .BYTE 1
  46. aff4: .BYTE 1
  47. aff5: .BYTE 1
  48. dividende: .BYTE 3
  49. nbr: .BYTE 2
  50. periode: .BYTE 2
  51. offset: .BYTE 1
  52. numerateur: .BYTE 1
  53. denominateur: .BYTE 1
  54.  
  55. ;------------------------------------------------------------------------
  56. ;Declaration des Vecteurs d'interruptions
  57. ;------------------------------------------------------------------------
  58.  
  59. .CSEG
  60. .ORG 0x0000 ;debut zone memoire programme
  61. rjmp RESET ;RESET
  62. rjmp EXT_INT0 ;Interruption externe INT0
  63. rjmp EXT_INT1 ;Interruption externe INT1
  64. rjmp TIM2_COMP ;Interrution comparaison reussie TIMER2
  65. rjmp TIM2_OVF ;Interrution debordement compteur TIMER2
  66. rjmp TIM1_CAPT ;Interrution entree capture TIMER1
  67. rjmp TIM1_COMPA ;Interrution comparateurA TIMER1
  68. rjmp TIM1_COMPB ;Interrution comparateurB TIMER1
  69. rjmp TIM1_OVF ;Interrution debordement compteur TIMER1
  70. rjmp TIM0_OVF ;Interrution debordement compteur TIMER0
  71. rjmp SPI_STC ;Interrution transmissions SPI terminee
  72. rjmp UART_RXC ;Interrution reception UART termine RX
  73. rjmp UART_DRE ;Interrution UART vide
  74. rjmp UART_TXC ;Interrution emission UART termine TX
  75. rjmp ADC_ok ;Interrution Conversion A/D terminee
  76. rjmp EE_RDY ;Interrution EEPROM prete
  77. rjmp ANA_COMP ;Interrution comparaison analogique effectuee
  78.  
  79. ;------------------------------------------------------------------------
  80. ;Routines de traitement des interruptions
  81. ;------------------------------------------------------------------------
  82. EXT_INT0: reti
  83. ;------------------------------------------------------------------------
  84. EXT_INT1: reti
  85. ;------------------------------------------------------------------------
  86. TIM2_COMP: reti
  87. ;------------------------------------------------------------------------
  88. TIM2_OVF: reti
  89. ;------------------------------------------------------------------------
  90.  
  91. ;The Input Capture is updated with the counter (TCNT1) value each time an event occurs
  92. ;on the ICP1 pin (par le signal dont on veut mesurer la periode))
  93. ;TCNT1 est incremente par l'horloge / prescaler
  94.  
  95. TIM1_CAPT: in sauvreg,sreg
  96. push sauvreg
  97. push a
  98. cli
  99.  
  100. in a,ICR1L ;lit le registre de capture
  101. sts periode+0,a
  102.  
  103. in a,ICR1H
  104. sts periode+1,a
  105.  
  106. clr a
  107. out TCNT1H,a ;raz TCNT1, registre de comptage
  108. out TCNT1L,a
  109. sbic portb,0
  110.  
  111. sei
  112. pop a
  113. pop sauvreg
  114. out sreg,sauvreg
  115. reti
  116. ;------------------------------------------------------------------------
  117. TIM1_COMPA: reti
  118. ;------------------------------------------------------------------------
  119. TIM1_COMPB: reti
  120. ;------------------------------------------------------------------------
  121. ;si debordement de la mesure
  122. TIM1_OVF: in sauvreg,sreg
  123. push sauvreg
  124. push a
  125. sbi portd,6
  126. ldi a,2
  127. mov gamme,a
  128. pop a
  129. pop sauvreg
  130. out sreg,sauvreg
  131. reti
  132. ;------------------------------------------------------------------------
  133. TIM0_OVF: reti
  134. ;------------------------------------------------------------------------
  135. SPI_STC: reti
  136. ;------------------------------------------------------------------------
  137. UART_RXC: reti
  138. ;------------------------------------------------------------------------
  139. UART_DRE: reti
  140. ;------------------------------------------------------------------------
  141. EE_RDY: reti
  142. ;------------------------------------------------------------------------
  143. ANA_COMP: reti
  144. ;------------------------------------------------------------------------
  145. ADC_ok: reti
  146. ;------------------------------------------------------------------------
  147. UART_TXC: reti
  148. ;------------------------------------------------------------------------
  149. UART_RXC1: reti
  150. ;------------------------------------------------------------------------
  151.  
  152.  
  153. ;------------------------------------------------------------------------
  154. ;Programme de RESET
  155. ;------------------------------------------------------------------------
  156.  
  157.  
  158. RESET: ldi a,low(RAMEND)
  159. out SPL,a ; Initialisation de la pile a
  160. ldi a,high(RAMEND) ; l'adresse haute de la SRAM
  161. out SPH,a
  162.  
  163. ldi a,0b11111110 ; PB0 (=ICP1) en entree
  164. out ddrb,a
  165.  
  166. ldi a,0b01111111 ; PD7(switch) en entree
  167. out ddrd,a
  168. ldi a,0b10000000 ; R de tirage validee pour PD7
  169. out portd,a
  170.  
  171.  
  172. ldi a,0b11111111
  173. out ddrc,a
  174. clr a
  175. out portc,a ; sorties = 0
  176.  
  177. ; wdr
  178. ; ldi a,0b00001111 ; wachtdog enable; delai = 2s (voir p:82)
  179. ; out wdtcr,a
  180.  
  181. wdr
  182. ldi a,0b00011111
  183. out wdtcr,a
  184. ldi a,0b00010111
  185. out wdtcr,a ; disable le wachtdog. (voir p:83)
  186.  
  187. ldi a,1
  188. mov gamme,a
  189.  
  190. ldi a,5
  191. mov type_aff,a
  192.  
  193. ; ldi a,0b01000000 ; enable INT0(externe) sur front montant
  194. ; out GICR,a ; General Interrupt Control Register
  195.  
  196. ;------------------------------------------------------------------------
  197. ;TIMSK
  198. ;Timer Interrupt Mask; voir pdf p:70
  199. ;bit7 (OCIE2)
  200. ;bit6 (TOIE2)
  201. ;bit5 (TICIE1) Timer/Counter1, Input Capture Interrupt Enable
  202. ;bit4 (OCIE1A) Timer/Counter1, Output Compare A Match Interrupt Enable
  203. ;bit3 (OCIE1B) Timer/Counter1, Output Compare B Match Interrupt Enable
  204. ;bit2 (TOIE1) Timer/Counter1, Overflow Interrupt Enable
  205. ;bit1 inutilise
  206. ;bit0 (TOIE0) Timer/Counter0 Overflow Interrupt Enable
  207.  
  208. ; 76543210
  209. ldi a,0b00101110 ;TICIE1 =1
  210. out TIMSK,a
  211. ;------------------------------------------------------------------------
  212. ;TCCR1B
  213. ;definit le mode de fonctionnement du Timer1 avec utilisation de la fonction 'capture' sur pin ICP1
  214. ;voir Tavernier p:94-95 ;et p:81-82 du datasheet.pdf
  215.  
  216. ;bit7 (ICNC1): enable/disable reducteur de bruit
  217. ;bit6 (ICES1)=1: transfert du registre de comptage TCNT1 dans le registre de capture ICR1 sur front montant du pin ICP
  218. ;bit5 : inutilise
  219. ;bit4 : inutilise
  220. ;bit3 (WGM12 ou CTC1): raz registre de comptage (TCNT1) apres comparaison
  221. ;bits2,1,0: taux de predivision applique a l'horloge systeme. voir Tavernier p:95
  222.  
  223. mov a,gamme
  224. cpi a,1
  225. breq gam1a
  226. cpi a,2
  227. breq gam2a
  228.  
  229. ;------------------------------------------------------------------------
  230.  
  231. ; 76543210
  232. gam1a: ldi a,0b11000001 ; horloge/1 ;(/1 pour gamme 10nF)
  233. rjmp suite0
  234. ;------------------------------------------------------------------------
  235. ; 76543210
  236. gam2a: ldi a,0b11000011 ; horloge/64 ;(/64 pour gamme 1uF)
  237.  
  238. suite0: out TCCR1B,a
  239. ;------------------------------------------------------------------------
  240. ;MCUCR bits[1,0]
  241. ;ISC11 ISC10 Description
  242. ;0 0 The low level of INT1 generates an interrupt request.
  243. ;0 1 Any logical change on INT1 generates an interrupt request.
  244. ;1 0 The falling edge of INT1 generates an interrupt request.
  245. ;1 1 The rising edge of INT1 generates an interrupt request.
  246.  
  247. ldi a,0b00000011 ;enable INT0(externe) sur front montant
  248. out MCUCR,a ;voir p:65 du datasheet.pdf et Tavernier p:30
  249.  
  250. ;------------------------------------------------------------------------
  251.  
  252.  
  253. initvar: clr a
  254. sts aff1,a
  255. sts aff2,a
  256. sts aff3,a
  257. sts aff4,a
  258. sts aff5,a
  259.  
  260. ldi a,28
  261.  
  262. sts offset,a
  263. ldi a,1
  264. sts numerateur,a
  265. ldi a,1
  266. sts denominateur,a
  267.  
  268. wdr ; raz Watchdog
  269. ; ldi a,$01
  270. ; out timsk,a ; Validation de l'interruption.
  271. ; ldi a,156 ; chargement de la valeur 156
  272. ; out tcnt0,a ; dans le registre du compteur
  273. ; ldi a,$04 ;
  274. ; out tccr0,a ; Selection de la frequence de pre-division
  275.  
  276. ;------------------------------------------------------------------------
  277. ;zone de tests de procedures
  278.  
  279.  
  280. ;r20,21,22 doivent contenir le dividende (r20=LSB)
  281. ;r23 doit contenir le diviseur
  282. ;resultat (Quotient) dans r20 (LSB) et r21 et r22
  283. ;reste dans r24
  284.  
  285. ; ldi r20,LOW(123)
  286. ; ldi r21,HIGH(123)
  287. ; ldi r22,0
  288. ; ldi r23,246
  289. ; rcall Div24_8
  290. ;
  291. ; ldi r20,LOW(65535)
  292. ; ldi r21,HIGH(65535)
  293. ; ldi a,255
  294. ; rcall mul16_8
  295.  
  296. ; ldi r20,LOW(15000)
  297. ; ldi r21,HIGH(15000)
  298. ; rjmp gam1c
  299.  
  300. ;------------------------------------------------------------------------
  301.  
  302. ;PROGRAMME PRINCIPAL
  303. wdr
  304.  
  305.  
  306. ;cli ;arret des interruptions (interdite pendant l'affichage qui utilise une tempo)
  307. clr a
  308. sts periode+0,a
  309. sts periode+1,a
  310.  
  311. zero: rcall dspclr ;efface LCD
  312. rcall home
  313. rcall fset
  314. rcall setmod0
  315. rcall dsp10
  316.  
  317. ldi a,1
  318. mov gamme,a
  319.  
  320. ldi a,0
  321. rcall ddras
  322. ldi a,'i'
  323. rcall ecrire
  324.  
  325. rcall tp100ms
  326.  
  327. rcall mesure
  328. ;doit-on paser en gamme1 ?
  329. ; lds a,periode+1
  330. ; cpi a,10
  331. ; brsh suite3
  332. ; ldi a,1
  333. ; mov gamme,a
  334.  
  335. ;ajustement de l'offset
  336. suite3: lds a,periode+0
  337. sts offset,a
  338.  
  339. rcall tp100ms
  340.  
  341. bcl0: wdr
  342. ;cli ;arret des interruptions
  343. ldi a,0
  344. rcall ddras
  345.  
  346. lds r20,periode+0
  347. lds r21,periode+1
  348.  
  349. cbi portd,6
  350.  
  351. sbis pind,7
  352. rjmp zero
  353.  
  354. mov a,gamme
  355. cpi a,1
  356. breq gam1b
  357. cpi a,2
  358. breq gam2b
  359.  
  360.  
  361. gam1b: ldi a,0b11000001 ; horloge/1 ;(/1 pour gamme 10nF)
  362. out TCCR1B,a
  363. ldi a,100 ;(100 pour gamme 10nF)
  364. sts numerateur,a
  365. ldi a,27 ;( 27 pour gamme 10nF)
  366. sts denominateur,a
  367. rjmp saut01
  368.  
  369. gam2b: ldi a,0b11000011 ; horloge/64 ;(/64 pour gamme 1uF)
  370. out TCCR1B,a
  371. ldi a,24 ;( 24 pour gamme 1uF)
  372. sts numerateur,a
  373. ldi a,100 ;(100 pour gamme 1uF)
  374. sts denominateur,a
  375. rjmp saut01
  376.  
  377. saut01: lds a,offset ;charge l'offset dans 'a'
  378. ldi AA,2 ;ajustement qui augmente la justesse
  379. add a,AA
  380.  
  381. clr r22
  382. cp r20,a ;teste si l'offset n'est pas superieur a la mesure (poids faible)
  383. brcc saut02 ;non
  384. cpi r21,0 ;oui, r21=0 ?
  385. brne saut02 ;non
  386.  
  387. clr r20 ;oui, on affichera zero
  388. clr r21
  389. ldi a,1
  390. mov gamme,a
  391. rjmp saut03
  392.  
  393. saut02: sub r20,a ;retranche l'offset a la valeur de la mesure dans r20
  394. sbci r21,0 ;report de la retenue sur l'octet de poids fort
  395.  
  396. lds a,numerateur
  397. rcall mul16_8
  398.  
  399.  
  400. ;r20,21,22 doivent contenir le dividende (r20=LSB)
  401. ;r23 doit contenir le diviseur
  402. ;resultat (Quotient) dans r20 (LSB) et r21 et r22
  403. ;reste dans r24
  404.  
  405. lds r23,denominateur
  406. rcall div24_8
  407.  
  408. cpi r22,0 ;test si resultat sur plus de deux octets: on passe alors en gamme2
  409. breq saut4
  410. ldi a,2
  411. mov gamme,a
  412. ldi a,0b11000011 ; horloge/64 ;(/64 pour gamme 1uF)
  413. out TCCR1B,a
  414. rjmp saut5
  415.  
  416. ;ici r20, r21 contiennent la valeur a afficher
  417. ;----------------------------------
  418. ;determination de la tranche d'affichage (types T1 a T5)
  419. saut4: mov a,gamme
  420. cpi a,1
  421. breq gam1c ;traitement different suivant la gamme de mesure
  422. cpi a,2
  423. breq gam2c
  424.  
  425. ;traitement pour la gamme1
  426. gam1c: ldi a,1
  427. cpi r21,HIGH(999) ;rd-k
  428. brlo suite10 ;si r21>=999
  429. ldi a,2
  430. cpi r21,HIGH(9999)
  431. brlo suite10
  432. ldi a,3
  433. rjmp suite10
  434.  
  435. ;----------------------------------
  436. ;traitement pour la gamme2
  437. gam2c: ldi a,4
  438. cpi r21,HIGH(9999) ;rd-k
  439. brlo suite10 ;si r21>=999
  440. ldi a,5
  441. rjmp suite10
  442. ;----------------------------------
  443. suite10: mov type_aff,a
  444.  
  445. saut03: rcall affnb
  446. rcall affiphy5
  447.  
  448. saut5: rcall tp100ms
  449.  
  450. ; lds a,mesflags
  451. ; sbrc a,0 ;saute l'ins suivante si bit0 =0
  452. ; rcall depass
  453. ; cbi portd,6 ;LED
  454.  
  455. rcall mesure
  456.  
  457. rjmp bcl0
  458.  
  459. ;------------------------------------------------------------------------
  460. ;PROCEDURES
  461. ;------------------------------------------------------------------------
  462.  
  463. mesure: sei ;enable interruptions
  464. rcall tp100ms
  465. rcall tp100ms
  466. rcall tp100ms
  467.  
  468. ;cli ;arret des interruptions
  469. ret
  470. ;------------------------------------------------------------------------
  471. depass: ldi a,'-'
  472. rcall ecrire
  473. ret
  474.  
  475.  
  476. ;========================================================================
  477. ; PROCEDURES D'AFFICHAGE PHYSIQUE SUR LE LCD
  478. ;========================================================================
  479.  
  480.  
  481. ;FUNCTION SET
  482.  
  483. fset: cbi portc,2 ;E=0
  484. cbi portc,3 ;R/S=0
  485.  
  486. ldi a,56 ;movlw .56 ;(32+16+8)
  487. sts dtlcd,a ;movwf dtlcd
  488.  
  489. rcall dt_out ;transmission serie vers 4015 -> DATA // LCD
  490. rcall impuls
  491. ret
  492.  
  493. ;----------------------------------------------------------------------
  494. ;DISPLAY CLEAR
  495. dspclr: cbi portc,2 ;E=0
  496. cbi portc,3 ;R/S=0
  497.  
  498. ldi a,1
  499. sts dtlcd,a
  500. rcall dt_out
  501. rcall impuls
  502. ret
  503. ;----------------------------------------------------------------------
  504. ;RETURN HOME
  505. home: clr a
  506. out portc,a ;clrf portc
  507. ldi a,2 ;movlw .2
  508. sts dtlcd,a
  509. rcall dt_out
  510. rcall impuls
  511. ret
  512.  
  513. ;----------------------------------------------------------------------
  514. ;ENTRY MODE SET 0
  515. ;le curseur se deplace
  516. setmod0: cbi portc,2 ;E=0
  517. cbi portc,3 ;R/S=0
  518. ldi a,6 ;( 4+2 sens inverse si 4+0 )
  519. sts dtlcd,a
  520. rcall dt_out
  521. rcall impuls
  522. ret
  523.  
  524.  
  525. ;----------------------------------------------------------------------
  526. ;DISPLAY ON OFF
  527. dsp10: cbi portc,2 ;E=0
  528. cbi portc,3 ;R/S=0
  529. ldi a,12 ;( 8+4 )
  530. sts dtlcd,a
  531. rcall dt_out
  532. rcall impuls
  533. ret
  534. ;----------------------------------------------------------------------
  535. ;DDRAM ADRESS SET (A)
  536. ;a doit contenir l'adresse (position d'affichage. voir doc)
  537. .def b=R20
  538. ddras: cbi portc,2 ;E=0
  539. cbi portc,3 ;R/S=0
  540. ldi b,128 ;addlw .128
  541. add a,b
  542. sts dtlcd,a
  543. rcall dt_out
  544. rcall impuls
  545. ret
  546.  
  547. ;----------------------------------------------------------------------
  548. ;ECRIRE
  549. ;a doit contenir la valeur ASCII du caractere a afficher
  550. ecrire: wdr
  551. cbi portc,2 ;E=0
  552. sbi portc,3 ;R/S=1
  553. sts dtlcd,a
  554. rcall dt_out
  555. sbi portc,2 ;impuls E a 1 avec RS=1
  556. rcall tp1ms
  557. ; rcall tp1ms
  558. sbi portc,2 ;fin impulsion
  559. rcall tp1ms
  560. ; rcall tp1ms
  561. ret
  562.  
  563. ;----------------------------------------------------------------------
  564. ;impulsion E a 1 avec RS=0
  565. impuls: wdr
  566. cbi portc,3 ;R/S=0
  567. sbi portc,2 ;impulsion E a 1
  568. rcall tp1ms
  569. ; rcall tp1ms
  570. cbi portc,2 ;fin impulsion
  571. rcall tp1ms
  572. ; rcall tp1ms
  573. ret
  574.  
  575. ;----------------------------------------------------------------------
  576. ;SORTIE DATA (8 bits) en serie sur PA0 vers CD4015. PA1=Clock 4015
  577.  
  578. .def n=r20
  579. dt_out: ldi n,8
  580. lds a,dtlcd
  581. dtbcl: rol a ;bit de poids fort -> dans c ;rlf dtlcd,f
  582. cbi portc,0 ;bcf portc,0 ;bit = 0 (a priori)
  583. brcc dt_out1 ;btfsc STATUS,0 ;test carry
  584. sbi portc,0 ;bsf portc,0 ;non, bit = 0
  585. dt_out1: sbi portc,1 ;clock 4015
  586. rcall tp1ms
  587. ; rcall tp1ms
  588. cbi portc,1 ;fin clock
  589. rcall tp1ms
  590. ; rcall tp1ms
  591. dec n ;decfsz n,f
  592. cpi n,0
  593. brne dtbcl
  594. ret
  595.  
  596. ;-----------------------------------------------------------------------
  597. ;decompose un octet [0..255] -> notation BCD dans variables aff1..4
  598. ;unites -> aff1
  599. ;dizaines -> aff2
  600. ;centaines -> aff3
  601. ;milliers (en fait toujours zero) -> aff4
  602. ;a doit contenir l'octet a afficher
  603. ;ex: a=184
  604.  
  605. affi_a: mov AA,a
  606. rcall cvBDU ;BB=18 et AA=4 ; fractionne les unites et les dizaines
  607. sts aff1,AA ;aff1=4
  608. mov AA,BB ;AA=18
  609. rcall cvBDU ;BB=1 et AA=8 ; si les dizaines sont > 9, fractionne en dizaines et centaines
  610. sts aff2,AA ;aff2=8
  611. sts aff3,BB ;aff3=1
  612. ldi a,0
  613. sts aff4,a ;affiche toujours zero
  614. ret
  615.  
  616. ;------------------------------------------------------------------------
  617. ;CONVERSION BINAIRE --> BCD
  618. ;nombre a convertir dans AA
  619. ;resultat dans BB (dizaines) et dans AA (unites)
  620. ;ex: AA=237 -> BB=23 et AA=7
  621. ;ex2 a=84 -> BB=8 et AA=4
  622.  
  623. cvBDU: clr BB
  624. conv2: cpi AA,10 ;AA:=AA-10
  625. brcs conv3 ;9 passages au max si nb <= 99
  626. subi AA,10
  627. inc BB
  628. rjmp conv2
  629. conv3: ret
  630.  
  631. ;------------------------------------------------------------------------
  632. ;CONVERSION BINAIRE 2 octets -> Affi5,4,3,2,1
  633. ;r20,21 doivent contenir le nombre a convertir. r20=poids faible
  634.  
  635. ;ex: nb1,0 = 6215 =24*256 + 71
  636. ;r20 =71
  637. ;r21= 24
  638.  
  639. affnb: clr r22 ;dividende
  640. ldi r23,10 ;diviseur
  641.  
  642. ldi r26,LOW(aff1) ;registre x
  643. ldi r27,HIGH(aff1) ;registre x
  644.  
  645. ldi AA,5 ;compteur de boucle
  646.  
  647. affnb1: rcall Div24_8 ;(ne touche pas r26)
  648. st x+,r24 ;reste de la division par 10
  649.  
  650. dec AA
  651. brne affnb1
  652.  
  653. ret
  654.  
  655.  
  656. ;------------------------------------------------------------------------
  657.  
  658. affdeci: push BB
  659. rcall cvBDU
  660. sts aff1,AA
  661. sts aff2,BB
  662.  
  663. pop AA ;voir push BB plus haut
  664. rcall cvBDU
  665. sts aff3,AA
  666. sts aff4,BB
  667. ret
  668.  
  669. ;------------------------------------------------------------------------
  670. ;affichage physique de 5 chiffres
  671. ;Types_aff: (Gamme-Type)
  672. ;G1-T1 -> 2.7pF 15.6pF on est en gamme1 On affiche tout avec un point
  673. ;G1-T2 -> 102pF 335pF on est en gamme1 On n'affiche pas le point ni le premier digit
  674. ;G1-T3 -> 1.518nF 4.725nF on est en gamme1. On n'affiche pas le 1er digit. le point est deplace
  675. ;G2-T4 -> 22.31nF on est en gamme2 On n'affiche pas le 1er digit. le point est deplace
  676. ;G2-T5 -> 101.2nF on est en gamme2
  677.  
  678. affiphy5: lds a,aff5 ;positionne z si nul
  679. ; cpi a,0
  680. ; breq affi4 ;pour ne pas afficher le zeros non significatif
  681. ldi b,48 ;code ASCII de zero
  682. add a,b
  683. rcall ecrire
  684.  
  685. mov a,type_aff
  686. cpi a,3 ;pour T3 afficher le point
  687. breq affi4b
  688. cpi a,5 ;pour T5 afficher le point
  689. breq affi4b
  690. rjmp affi4 ;
  691.  
  692. affi4b: ldi a,'.'
  693. rcall ecrire
  694.  
  695. affi4: lds a,aff4
  696. ldi b,48 ;code ASCII de zero
  697. add a,b
  698. rcall ecrire
  699.  
  700.  
  701. affi3: lds a,aff3
  702. ldi b,48 ;code ASCII de zero
  703. add a,b
  704. rcall ecrire
  705.  
  706. mov a,type_aff
  707. cpi a,5 ;pour T5 ne pas afficher la suite
  708. breq affi0
  709.  
  710. affi2: lds a,aff2
  711. ldi b,48 ;code ASCII de zero
  712. add a,b
  713. rcall ecrire
  714.  
  715. mov a,type_aff
  716. cpi a,2
  717. breq affi0
  718. cpi a,3
  719. breq affi0
  720.  
  721. ldi a,'.'
  722. rcall ecrire
  723.  
  724. affi1: lds a,aff1
  725. ldi b,48 ;code ASCII de zero
  726. add a,b
  727. rcall ecrire
  728.  
  729. affi0: mov a,type_aff ;REMARQUE: choix de type "case of"
  730. cpi a,1
  731. breq aff_p
  732. cpi a,2
  733. breq aff_p
  734. cpi a,3
  735. breq aff_n
  736. cpi a,4
  737. breq aff_n
  738. cpi a,5
  739. breq aff_u
  740.  
  741. aff_p: ldi a,'p'
  742. rjmp suite1
  743.  
  744. aff_n: ldi a,'n'
  745. rjmp suite1
  746.  
  747. aff_u: ldi a,'u'
  748. rjmp suite1
  749.  
  750. suite1: rcall ecrire
  751.  
  752. ldi a,'F'
  753. rcall ecrire
  754.  
  755. ldi a,' '
  756. rcall ecrire
  757.  
  758. ldi a,' '
  759. rcall ecrire
  760.  
  761. rjmp finaff
  762.  
  763.  
  764. finaff: ret
  765.  
  766. ;----------------------------------------------------------------------
  767. ;mul16_8 ;mutiplication 8 bits x 16 bits resultat sur 24 bits
  768. ;multiplie r20(poids faible),r21(poids fort) par 'a'
  769. ;produit dans r22,r21,r20
  770.  
  771. .def produit0=r20 ;produit poids faible
  772. .def produit1=r21 ;produit
  773. .def produit2=r22 ;produit poids fort
  774. .def n1=r23
  775.  
  776. mul16_8: ldi n1,17 ;compteur de boucle
  777.  
  778. mul16_81: ror produit2
  779. ror produit1
  780. ror produit0
  781.  
  782. brcc mul16_82 ;lecture d'un bit de r20 ; test de ce bit
  783. add produit2,a ;si c' est un '1' on ajoute 'a' a A2
  784.  
  785. mul16_82: dec n1
  786. brne mul16_81
  787.  
  788. ret
  789.  
  790. ;----------------------------------------------------------------------
  791. ;DIVISION 24 bits par 8 bits, resultat sur 24 bits
  792. ;note; le quotient est stocke dans le dividende; permet de decaller les deux a la fois
  793.  
  794.  
  795. ;r20,21,22 doivent contenir le dividende (r20=LSB)
  796. ;r23 doit contenir le diviseur
  797. ;resultat (Quotient) dans r20 (LSB) et r21 et r22
  798. ;reste dans r24
  799. ;le bit T=1 indique un debordement
  800.  
  801. .def Dividend0=r20 ;pour la routine Div24_8
  802. .def Dividend1=r21 ;pour la routine Div24_8
  803. .def Dividend2=r22 ;pour la routine Div24_8
  804. .def Diviseur =r23 ;pour la routine Div24_8.
  805. .def Aux0=r24 ;pour la routine Div24_8
  806. .def Aux1=r25
  807. .def n1=r17
  808.  
  809. div24_8: ldi n1,24
  810. clr Aux0 ;clrf Aux+0
  811.  
  812. div24_80: lsl Dividend0
  813. rol Dividend1
  814. rol Dividend2
  815.  
  816. div24_81: rol Aux0 ;decalle le dividende dans 'Aux' (passage d'un bit par "c")
  817. rol Aux1
  818.  
  819. cp aux0,Diviseur
  820. brlo auxPetit
  821.  
  822. auxGrand: sub Aux0,Diviseur
  823. sec
  824. rjmp saut1
  825.  
  826. auxPetit: clc
  827.  
  828. saut1: rol Dividend0 ;decalle a gauche en incorporant 'c' comme bit 0
  829. rol Dividend1 ;decalle a gauche avec passage d'un bit par "c"
  830. rol Dividend2 ;decalle a gauche et envoie un bit par 'c' dans 'Aux' (apres le saut)
  831.  
  832. dec n1 ;important: ne touche pas a 'c'
  833. brne Div24_81
  834.  
  835. ret
  836.  
  837. ;----------------------------------------------------------------------
  838. ;TEMPO 1ms exactement avec un Qx=16.000MHz
  839. ;attention: sous reserve de retard par les interruptions...
  840.  
  841. .def i1=R20
  842. .def i2=R21
  843.  
  844. tp1ms: push R20
  845. push R21
  846.  
  847. ldi i1,16
  848. bcl2: ldi i2,248
  849. bcl3: dec i2
  850. ;cpi i2,0
  851. brne bcl3
  852.  
  853. nop ;pour ajuster exactement la duree
  854. nop
  855. nop
  856. dec i1
  857. ;cpi i1,0
  858. brne bcl2
  859.  
  860. nop
  861. pop R20
  862. pop R21
  863. ret
  864.  
  865. ;----------------------------------------------------------------------
  866. ;tempo 100ms
  867.  
  868. .def n=R20
  869.  
  870. tp100ms: push R17
  871. ldi n,100
  872.  
  873. bcl4: rcall tp1ms
  874. dec n
  875. ;cpi n,0
  876. brne bcl4
  877.  
  878. pop R17
  879. ret
  880.  
  881. ;----------------------------------------------------------------------
  882.  
  883.  
  884.  

4 -

Le bit5 du registre TIMSK (TICIE1) = Timer/Counter1, Input Capture Interrupt Enable est positionné à 1.

L'ATmega8 mesure la fréquence (plus exactement la période).

La mesure se fait par la routine d'interruption TIM1_CAPT (Timer1 Capture, voir le datasheet de l'ATmega8)
L'interruption est mise en service par la routine "mesure"

5 Documents techniques

6 -



23389