Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

ASM à l'aide de MikroC
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#1 Message par paulfjujo » dim. 26 nov. 2017 14:55

Un lien tres interessant sur les PICs et l'ASM
(déja cité par ailleurs sur ce forum..)
qui peut aussi être utilisé pour le C .. sachant qu'on peut inclure de l'ASM dans MikroC

//Binary to Decimal converter for 10 Bit A2D
// 10 bits 5 volts
// version originale:
/*
; Program to convert a 10 bit a/d reading
; to ascii decimal. A/d reference is 5volts.
; CVD00 to CVD05 contains ascii decimal characters
; wuth the decimal point being between CVD02 and CVD03
; Put a/d reading in ADHIGH and ADLOW, call CVDEC
; and get value from CVD00 through CVD05
; Bill Cornutt Jan 1, 2006

Apres adaptation en MikroC , cela donne
une fonction permettant d'afficher directement soit sur UART soit sur LCD
une chaine de caractere representant la valeur en Volt, avec 3 decimales, d'une mesure ADC 10 bits..
Le lien ci-dessus permet de definir l'echelle ..ici 5 (Volts) et la resolution ici 10 bits
Nota: On peut donc aussi traiter du 12 ou 16 bits ADC ..
L'avantage est que la conversion n'utilise pas la librairie MikroC ADC
et surtout, pas de flottant , ni la lib MATH.

Les registres utilises dans la partie ASM seront declaré en absolute => adresse figee et imuable, non utilisée par le compilo..
Les registre interne du compilo R0 ..à R15 pourrait etre utilisé aussi..mais à mon avis, trop Risky ..interferences possibles.
La partie acquisition ADC, necessite une initialisation dans le main program .. depend beaucoup du PIC utilisé
ici , pour le (vieux) 18F252 TRISA=0xFF et les 2 registres ADCON0 et ADCCON1 ( il n'a pas d' ANSEL !)
La fonction inclue l'acquisition ADC, en lui passant comme parametre , le numero de channel ADC.
Ce PIC est configuré pour 3 channel .. 0,1,3 .. il n'a pas de channel 2 !

Dans la foulée , j'ai reecris la fonction CRLF() en asm .. qui est plus concise que CRLF1() en MikroC, meme si elle prend
plus de place 28 bytes au lieu de 18

Cette fonction utilise 6 digits .. les 2 premiers sont inutiles, remplacé par des blancs (espace)
La fonction pourrait donc etre allégée dans le cas du 5V 10 bits..
avis aux specialistes ASM..

Code : Tout sélectionner



#include "Int_To_floatStr.h"

char * ADC_To_Float_Str( unsigned char Channel)
 {

 // la partie ADC doit etre prealablement initialisée
 // voir ADCON0 et ADCON1 ..ou ANSEL
 // n'utilise pas MikroC ADC_Read library  taille=62 bytes
      ADCON0=0;
      ADCON0=0xC0 + (Channel<<3);
      ADCON0.ADON=1;
      Delay_us(22);
      ADCON0.GO=1; // lance conversion
      _asm Nop
      while
( ADCON0.GO_DONE==1);  // finie
      ADHIGH=ADRESH;
      ADLOW =ADRESL;

  //http://www.piclist.com/techref/A2DCodeGenerator.asp
  //Binary to Decimal converter for 10 Bit A2D
  // 10 bits  5 volts
  // version originale:
/*
 ;  Program to convert a  10  bit a/d reading
;  to ascii decimal.  A/d reference is  5volts.
;  CVD00 to CVD05 contains ascii decimal characters
;  wuth the decimal point being between CVD02 and CVD03
;  Put a/d reading in ADHIGH and ADLOW, call CVDEC
;  and get value from CVD00 through CVD05
;  Bill Cornutt   Jan 1, 2006
 rev 25/11/2017  paulfjujo
*/
 _asm{
  ;ATTENTION  Variables assignées en Fixe en debut de programme!
  ;unsigned char CVD00 absolute at 0x20;
  ;unsigned char CVD01 absolute at 0x21;
  ;unsigned char CVD02 absolute at 0x22;
  ;unsigned char komma absolute at 0x23; // virgule ou point decimal
  ;unsigned char CVD03 absolute at 0x24;
  ;unsigned char CVD04 absolute at 0x25;
  ;unsigned char CVD05 absolute at 0x26;
  ;unsigned char CVD06 absolute at 0x27;   // zero terminator de string
  ;unsigned char ADHIGH absolute at 0x28;
  ;unsigned char ADLOW absolute at 0x29;

;
    clear receiving bytes
        CLRF        _CVD00
        CLRF        _CVD01
        CLRF        _CVD02
        CLRF        _CVD03
        CLRF        _CVD04
        CLRF        _CVD05
        CLRF        _CVD06
        movlw 46      
; or 44 !
        movwf _Komma
;  for bit 0     2.5
CVDEC00
:
        BTFSS        _ADHIGH,01
        GOTO        CVDEC01
        MOVLW        2         
;D'02'
        ADDWF        _CVD02,F
        MOVLW        5   
; D'05'
        ADDWF        _CVD03,F
;  for bit 1     1.25
CVDEC01
:
        BTFSS        _ADHIGH,0
        GOTO        CVDEC02
        MOVLW        1          
; D'01'
        ADDWF        _CVD02,F
        MOVLW        2        
;   D'02'
        ADDWF        _CVD03,F
        MOVLW        5      
;D'05'
        ADDWF        _CVD04,F
;  for bit 2     0.625
CVDEC02
:
        BTFSS        _ADLOW,07
        GOTO        CVDEC03
        MOVLW        6   
;D'06'
        ADDWF        _CVD03,F
        MOVLW        2      
;D'02'
        ADDWF        _CVD04,F
        MOVLW        5    
;D'05'
        ADDWF        _CVD05,F
;  for bit 3     0.3125
CVDEC03
:
        BTFSS        _ADLOW,6
        GOTO        CVDEC04
        MOVLW        3   
; D'03'
        ADDWF        _CVD03,F
        MOVLW        1    
;D'01'
        ADDWF        _CVD04,F
        MOVLW        3    
;D'03'
        ADDWF        _CVD05,F
;  for bit 4     0.15625
CVDEC04
:
        BTFSS        _ADLOW,5
        GOTO        CVDEC05
        MOVLW        1     
;D'01'
        ADDWF        _CVD03,F
        MOVLW        5    
;D'05'
        ADDWF        _CVD04,F
        MOVLW        6    
;D'06'
        ADDWF        _CVD05,F
;  for bit 5     0.078125
CVDEC05
:
        BTFSS        _ADLOW,4
        GOTO        CVDEC06
        MOVLW        7   
;D'07'
        ADDWF        _CVD04,F
        MOVLW        8    
;D'08'
        ADDWF        _CVD05,F
;  for bit 6     0.0390625
CVDEC06
:
        BTFSS        _ADLOW,3
        GOTO        CVDEC07
        MOVLW        3   
;D'03'
        ADDWF        _CVD04,F
        MOVLW        9    
;D'09'
        ADDWF        _CVD05,F
;  for bit 7     0.01953125
CVDEC07
:
        BTFSS        _ADLOW,2
        GOTO        CVDEC08
        MOVLW        2   
;D'02'
        ADDWF        _CVD04,F
;  for bit 8     0.009765625
CVDEC08
:
        BTFSS        _ADLOW,1
        GOTO        CVDEC09
        MOVLW        1     
;D'01'
        ADDWF        _CVD04,F
;  for bit 9     0.0048828125
CVDEC09
:
        BTFSS        _ADLOW,0
        GOTO        CVDEC10
        MOVLW        5   
;D'05'
        ADDWF        _CVD05,F
CVDEC10
:
        MOVLW        10   ;D'10'
;   adjust digit  5
CVDEC10a
:
        INCF        _CVD04,F
        SUBWF        _CVD05
,F
        BTFSC        STATUS
,C
        GOTO        CVDEC10a    
;$-3
        
;  went past zero
        DECF        _CVD04
,F
        ADDWF        _CVD05
,F
;   adjust digit  4
CVDEC10b
:
        INCF        _CVD03,F
        SUBWF        _CVD04
,F
        BTFSC        STATUS
,C
        GOTO        CVDEC10b  
; $-3
        
;  went past zero
        DECF        _CVD03
,F
        ADDWF        _CVD04
,F
;   adjust digit  3
CVDEC10c
:
        INCF        _CVD02,F
        SUBWF        _CVD03
,F
        BTFSC        STATUS
,C
        GOTO        CVDEC10c 
; $-3
        
;  went past zero
        DECF        _CVD02
,F
        ADDWF        _CVD03
,F
;   adjust digit  2
 CVDEC10d
:
        INCF        _CVD01,F
        SUBWF        _CVD02
,F
        BTFSC        STATUS
,C
        GOTO         CVDEC10d 
;GOTO        $-3
        
;  went past zero
        DECF        _CVD01
,F
        ADDWF        _CVD02
,F
;   adjust digit  1
 CVDEC10e
:
        INCF        _CVD00,F
        SUBWF        _CVD01
,F
        BTFSC        STATUS
,C
        GOTO        CVDEC10e 
; $-3
        
;  went past zero
        DECF        _CVD00
,F
        ADDWF        _CVD01
,F
        
;  no need to adjust high order byte
;   convert to ascii
        MOVLW        48           
;D'48'
        ADDWF        _CVD00,F   //centaine
        ADDWF        _CVD01,F   // dizaines
        ADDWF        _CVD02,F   //unites
        ADDWF        _CVD03,F   // 1/10e
        ADDWF        _CVD04,F   // 1/100e
        ADDWF        _CVD05,F   // 1/1000e
//        variante avec un blanc devant les unites
        MOVLW 32
        MOVWF _CVD00
,F
        MOVWF _CVD01
,F
 
;        max value a/d is 4.996
 
;        RETURN
 
} //asm
 return &CVD00 ;
 // return &CVD02;     // saute par dessus les 2 zeros ou blancs inutiles
}
 


resultat du test , avec sortie sur UART :

18F252 Test affichage format fixe simili flottant
Test version CRLF en ASM

Test valeurs fixes avec Val_To_Str en asm
4.981
3.750
2.500
1.250
0.625
0.313
0.156
0.078
0.039

18F252 Test affichage format simili float
Test fonction lecture ADC via ADC_To_Float_Str en asm
Numero de channel (0,1,3 possible) passé en parametre
0.210
0.210
0.210
0.591
1.036
1.519
2.090
2.617
3.189
3.726
4.278
4.825
4.996
4.771
3.945
3.174
2.452
1.671
0.977
0.273


le projet complet zipé

18F252_test_ADC_To_FloatStr_2017.zip
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

ASM à l'aide de MikroC
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#2 Message par Temps-x » dim. 26 nov. 2017 15:36

Bonjour paulfjujo


Ta routine ASM, me fait pensée à celle là : viewtopic.php?p=3687#p3687


A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 33 invités