[ASM][PIC16F877] MIDI note ON/OFF
Répondre à la discussion
Affichage des résultats 1 à 26 sur 26

[ASM][PIC16F877] MIDI note ON/OFF



  1. #1
    genocyber

    [ASM][PIC16F877] MIDI note ON/OFF


    ------

    J'aimerai apprendre a faire un midi in avec un pic16f877 au dépard j'aimerai que la note LA3 déclenche un évènement ( note la3 d'un chip sonore ) .
    J'ai lu q'un message midi c'est 1 octet pour le channel , 1 octet pour les note et 1 octet pour la vélocité .

    Vu que RCREG fait 1 octet , je me demande comment faire pour disoscier les 3 octets et les sauvegarder dans des variables différentes .

    je comptais faire une interruption avec RCIE , Avec 3 compteur mis a 8 , dois-je compter 3*8 passages dans l 'interruption et stocker les 3 resultat dans des variables différentes ? Sa marcherai ?

    -----

  2. #2
    inoxxam

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Salut,
    Pour le MIDI c'est très très simple. Le protocole est organisé en trames, et dans chaque trame, le bit de poids fort du premier octet vaut 1, le bit de poids fort des autres octets vaut 0. Rien de plus simple donc de les différentier.

    A bientôt.

  3. #3
    paulfjujo

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    bonjour,

    je comptais faire une interruption avec RCIE , Avec 3 compteur mis a 8 ,
    dois-je compter 3*8 passages dans l 'interruption et stocker les 3 resultat dans des variables différentes ? Sa marcherai ?
    RCIE est le flag d'autorisation d'interruption.
    il suffit de tester si RCIF ==1 dans le traitement de l'interruption pour verifier
    que RCREG soit rempli ( 1 octet recu)
    pas besoin de compter les bits !
    de stocker celui ci (RCREG) dans buffer [Cpt]
    incrementer l'indice du buffer Cpt
    et attendre dans la boucle principale du programme,
    que Cpt=3 ( si Cpt initialisé au depart à 0)
    Buffer contiendra alors les 3 octets recus

    attention si les trames d'envoi de 3 octets sont contigus ..
    espace temporel entre les trames ?
    Dernière modification par paulfjujo ; 21/04/2014 à 15h06.

  4. #4
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    merci de vos réponses j'ai pu un peu avancer , mais bon je tatonne plus qu'autre chose .

    J'ai donc fait une routine pour distinguer l octet des notes , elle marche apparemment , enfin quelque chose ce passe .
    Quand j'appuie sur une touche du piano ( n'importe laquelle ) mon chipsound me joue une note que je lui ai assigné , mais il joue 4 ou 3 notes de suite puis ce bloque .

    Je pense que les octets sont effectivement contigus et je ne saurai vous dire si il y a un espace temporel entre les trames , a vrai dire j'ai vraiment difficile a trouvé un document ( en français ) qui expliquerai clairement la norme midi et je suis un peu perdu c'es la première fois que j'essaye de la communication entre midi et µc .

    j'ai choisi 31250 baud pour un pic 16f877 cadencer a 4MHZ esque c es bien judicieux ?

    Pourriez-vous m'éclairer un peu ?

  5. A voir en vidéo sur Futura
  6. #5
    paulfjujo

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    bonjour,


    la vitesse 31250 bauds me semble judicieuse,
    j'avais fait quelques test il y a fort longtemps avec un clavier GEM DSK6
    pour enregistrer les notes jouees dans un fichier
    voir programme Tbasic joint..

    il faudrait afficher sur un terminal , les notes recues sur l'UART
    en mode hexadecimal pour verifier le contenu d'une trame et si il y a des aracteres
    specifiques de terminaison comme un CR ou LF.
    J'utilise Vbray terminal tres utile pour debugger....

    je n'ai plus l'instrument Midi pour faire quelques tests...


    MIDI_003.BAS.txt

  7. #6
    freepicbasic

    A+, pat

  8. #7
    freepicbasic

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    J'ai mis un paquet de page web sur la norme midi dans un zip de 3 Mo , la plupart n'existe plus;

    http://www.speedyshare.com/qTnx2/Nou...ier-WinZip.zip
    A+, pat

  9. #8
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Merci a tous et un grand merci pour le zip de 3mo

    Je vais bosser tous ça .

  10. #9
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Salut

    Vu que je n'arrivais a rien , j ai donc décider de simplement recevoir un message midi de stocker les 3 bytes dans un buffer et d allumer l'etat du buffer sur trois led , mais y en a jamais que 2 qui s allume ( led1 et led2) je vois pas ce que je fais de mal mais vu que je suis pas habituer a utilisé un buffer surement je fais une erreur de débutant , je vous mets ici une partie de mon code .

    Mon interruption

    ;sauvegarder registres
    ;---------------------
    org 0x004 ; adresse d'interruption
    movwf w_temp ; sauver registre W
    swapf STATUS,w ; swap status avec résultat dans w
    movwf status_temp ; sauver status swappé
    ; passer en banque0

    BANK0
    ; Interruption réception USART
    ; ----------------------------

    call intrc ; oui, traiter interrupt
    ; LE FLAG NE DOIT PAS ETRE REMIS A 0
    ; C'EST LA LECTURE DE RCREG QUI LE PROVOQUE
    swapf status_temp,w ; swap ancien status, résultat dans w
    movwf STATUS ; restaurer status
    swapf w_temp,f ; Inversion L et H de l'ancien W
    ; sans modifier Z
    swapf w_temp,w ; Réinversion de L et H dans W
    ; W restauré sans modifier status
    retfie ; return from interrupt


    ;***************************** ****************************** ******************
    ; INTERRUPTION RECEPTION USART *
    ;***************************** ****************************** ******************
    intrc
    MOVF RCREG,W
    MOVWF INDF
    INCF FSR
    return ; fin d'interruption






    et mon code principale


    ; Set up USART

    bsf STATUS,RP0 ; goto page 1
    movlw 01h ; 31250 baud for MIDI
    movwf SPBRG
    movlw b'00100000' ; async tx 8 bit
    movwf TXSTA
    bcf STATUS,RP0 ; return to page 0
    movlw b'10010000' ; async rx 8 bit
    movwf RCSTA

    MOVLW LOW MIDI_MESS
    MOVWF FSR
    bsf INTCON,GIE ; valider interruptions
    goto start ; programme principal


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

    start
    TEST1
    MOVF MIDI_MESS+0,W
    MOVWF STAT
    MOVF STAT,F
    BTFSS STATUS,Z
    GOTO LEDON1
    GOTO LEDOFF1
    LEDON1
    BSF LED1
    GOTO TEST2
    LEDOFF1
    BCF LED1
    TEST2
    MOVF MIDI_MESS+1,W
    MOVWF BYTE1
    MOVF BYTE1,F
    BTFSS STATUS,Z
    GOTO LEDON2
    GOTO LEDOFF2
    LEDON2
    BSF LED2
    GOTO TEST3
    LEDOFF2
    BCF LED2
    TEST3
    MOVF MIDI_MESS+2,W
    MOVWF BYTE2
    MOVF BYTE2,F
    BTFSC STATUS,Z
    GOTO LEDOFF3
    GOTO LEDON3
    LEDOFF3
    BCF LED3
    GOTO start
    LEDON3
    BSF LED3
    SUITE
    BTFSS RCSTA,OERR
    GOTO SUITE_0
    bcf RCSTA,CREN
    bsf RCSTA,CREN
    SUITE_0
    MOVLW MIDI_MESS
    MOVWF FSR

    goto start ; boucler






    END ; directive fin de programme


    merci d'avance

  11. #10
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    désoler mais enfaite ça marche , ptet pas terrible mais ça marche ^^

  12. #11
    mgduc

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Je suis comme toi, je commente rarement mes code mais une autre personne aura de la difficulté à déchiffrer un code non commenter. Comme on n'a pas de schéma et qu'on ne sais pas trop ce que tu a voulu faire, le code devient incompréhensible, en plus d’être incomplet.

    Donc ça marche finalement? reste de petite ajustement et c'est ok?

    A+

  13. #12
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    a oui , j avais pas penser que ça allais etre incomprehensible ...
    Oui ça marchais juste avec des leds ... DOnc j 'essayais de tester si mes 3 buffers etait différent de 0 et la ça marchais .
    Maintenant j'essaye de déclencher un évenement avec un LA4 ( d'69') mais rien ne ce passe , je suppose donc qu'il y a un souci ^^

    Vu que c'est 3 octets qui se suivent ( 1 start bit - 8 bit data et 1 bit stop ) .

    Je dois faire perdre 1bit et demi au debut et 1 bit a la fin , pour que mes octet soit synchro ?

    Si oui , je me demande comment faire .

  14. #13
    freepicbasic

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    RCIF il est effacé où ?
    A+, pat

  15. #14
    freepicbasic

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    MOVLW LOW MIDI_MESS
    MOVWF FSR
    LOW sert a déterminé l'adresse basse programme !
    FSR pointe forcément sur de la RAM !

    ou est ce MIDI_MESS ?
    Pour mémoriser ce doit être de la RAM !
    A+, pat

  16. #15
    freepicbasic

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    MIDI_MESS est remis "au début" dans le main !
    c est dans l'int qu'il faut le remettre "au début"...
    Sinon on risque de le remettre "au début" en cours de réception.
    Ou alors on bloque la réception pour que le main analyse, de plus s'il n'y a pas de limite rien empêche d'écrire sur le reste de la mémoire.
    A+, pat

  17. #16
    paulfjujo

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Citation Envoyé par freepicbasic Voir le message
    RCIF il est effacé où ?
    ; LE FLAG NE NECESSITE PAS D' ETRE REMIS A 0
    ; SI ON FAIT UNE LECTURE DE RCREG
    c'est VRAI, mais c'est une bonne habitude de le remettre à 0 ..

    Concernant les leds, il est preferable de compter le Nb de car arriavnt dans le buffer
    et surtout d'initialiser celui ci au depart, et rajouter une tempo pour visualiser l'etat des leds
    des le buffer remplis de 3 cars.


    Code:
    initialiser au depart 
    Cpt
    BYTE1
    BYTE2
    BYTE3
    
    
    ... etc ......
    
    ;***************************** ****************************** ******************
    ; INTERRUPTION RECEPTION USART *
    ;***************************** ****************************** ******************
    intrc
    incf Cpt    ; compteur de car dans le buffer
    MOVF	RCREG,W
    MOVWF	INDF
    INCF	FSR
    return	 ; fin d'interruption
    
    
    ; Set up USART
    
    bsf STATUS,RP0 ; goto page 1
    movlw 01h ; 31250 baud for MIDI
    movwf SPBRG
    movlw b'00100000' ; async tx 8 bit
    movwf TXSTA
    bcf STATUS,RP0 ; return to page 0
    movlw b'10010000' ; async rx 8 bit
    movwf RCSTA
    
    movlw 0
    mowf LOW_MIDI_MESS
    mowf LOW_MIDI_MESS+1
    mowf LOW_MIDI_MESS+2
    mowf LOW_MIDI_MESS+3
    mowf Cpt		;  Compteur de bytesI
    
    MOVLW	LOW MIDI_MESS
    MOVWF	FSR
    bsf	INTCON,GIE	; valider interruptions
    
    start
    
    
    
    TEST1
    
    	MOVF Cpt,W
                sublw 1
    	BTFSS STATUS,Z
    	BRA	LEDOFF1
    LEDON1
    	MOVF	MIDI_MESS,W
    	MOVWF  BYTE1
    	BSF LED1
    	BRA TEST2
    LEDOFF1
    	BCF LED1
    
    TEST2
    
    	MOVF Cpt,W
                sublw 2
    	BTFSS STATUS,Z
    	BRA	LEDOFF2
    LEDON2
    	MOVF	MIDI_MESS+1,W
    	MOVWF  BYTE2
    	BSF LED2
    	BRA TEST3
    LEDOFF2
    	BCF LED2
    
    TEST3
    	MOVF Cpt,W
                sublw 3
    	BTFSS STATUS,Z
    	BRA	LEDOFF3
    LEDON3
    	MOVF	MIDI_MESS+2,W
    	MOVWF  BYTE3
    	BSF LED3
    	BRA SUITE
    LEDOFF3
    	BCF LED3
    	goto Start
    
    SUITE
    
    	bcf	INTCON,GIE	; invalider interruptions
    ;----------------------------------------
    rajouter ici un gros delai
    le temps de visulaiser les 3 leds dans un etat stable
             call tempo2sec
    ;----------------------------------
    	BTFSS	RCSTA,OERR
    	GOTO SUITE_0
    	bcf	RCSTA,CREN
    	bsf	RCSTA,CREN
    SUITE_0
    	movlw 0
    	mowf LOW_MIDI_MESS
    	mowf LOW_MIDI_MESS+1
    	mowf LOW_MIDI_MESS+2
    	mowf LOW_MIDI_MESS+3
    	mowf Cpt		;  Compteur de bytesI
    	MOVLW	LOW MIDI_MESS
    	MOVWF	FSR
    	bsf	INTCON,GIE	; valider interruptions
    	
    	goto start	 ; boucler


    Remarque avec LOW_MIDI_MESS :
    verifier auparavant que l'evoultion du pointeur ne puisse pas deborder de page..
    exemple si MIDI_MESS est à l'adresse 0xFE d'une page
    à MID_MESS+3 on est sur une autre page alors que LOW_MIDI_MESS se retrouve à 0x01 de la meme page
    Dernière modification par paulfjujo ; 25/04/2014 à 09h12.

  18. #17
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Donc enfaite MIDI_mess c es mon buffer que j ai mis dans les variables commune ( MIDI_MESS:3), donc dans le main je teste si buffer+2 est different de zero si oui je stock les 3 octets dans trois variables et j'envoi l adresse basse de mon buffer via fsr pour qu'il n ai pas plus loin et qu a la prochaine interruption il soit bien replacer sur buffer+0 .
    Rcif est éffacer par la lecture de rcreg dans mon interruption .

    Sinon pas d avis sur le stop bit ?

    merci pour l aide

  19. #18
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Ok j ai enfin trouvé pourquoi ça foirais

    un message midi c'est 3bytes qui se suivent et le bit rcif reste allumé pendant 2 byte , donc fallais dans l'interruption faire une tempo de 10bit ,320µs dans mon cas , donc j'ai fait .

    debut d'interruption( pseudo code)
    ****************
    Code:
    ;*****************************************************************************
    ;                     INTERRUPTION RECEPTION USART                        *
    ;*****************************************************************************
    intrc
    	BANKSEL	RCSTA		;selection bank
    	MOVF	RCREG,W		;lecture du premier byte 
    	MOVWF	STAT		; dans variables stat ( status )
    	call delay320		; on attend que les 10 bit suivant 
    	MOVF	RCREG,W		; lecture du deuxieme byte
    	MOVWF	BYTE1		;dans variable byte1
    	call delay320		; on attend que les 10 bit suivant
    	MOVF	RCREG,W		;lecture du dernier byte
    	MOVWF	BYTE2		; dans variables	byte2
    	BANK0
    	return
    Merci pour votre aide

  20. #19
    paulfjujo

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    bonjour,

    et le bit rcif reste allumé pendant 2 bytes !
    il faut que le buffer RCREG soit plein pour pour rearmer RCIF
    donc apres avoir lu RCREG et stocké la valeur dans le buffer
    il te reste 320µS - (duree de sauvegarde et restitution du contexte) avant de revenir dans l'interrupt.UART

    Bon avec Q=4MHz , cela ne laisse pas beacoup de temps de traitement dans le main(). moins de 320 cycles dispo....

    Avec Q=20Mhz cela laisserai plus de possibilité de traitement hors interruption.<16000 cycles ....dispo.



    Mettre une tempo de 320µS correspondant au temps d'attente d'arrivée d'un Byte
    dans une interruption n'est pas TOP ! et c'est une mauvaise habitude à prendre.
    meme si cela peut fonctionner.
    ( et dans ton cas,il n'ya pas d'autres sources d'interrupt tel que timer...)

    en general on utilise une interruption pour ne pas etre tributaire du temps...
    donc on evite toute tempo. Il est preferable d'utiliser les evenements (tel que RCIF).

    Au pis aller:

    Code:
    intrc
    	RCIE=0 		<- syntax à revoir !!!!	desarmer les interrupt UART
    //donc maintenent on travaille en mode pooling
    
    	BANKSEL	RCSTA		;selection bank
    	MOVF	RCREG,W		;lecture du premier byte 
    	MOVWF	STAT		; dans variables stat ( status )
    
         RCIF=0;	<- syntax à revoir !!!!	RAZ du flag recpetion UART
        while(RCIF==0); 	<- syntax à revoir !!!!   attentdre que le Flag repasse à 1
    
    	MOVF	RCREG,W		; lecture du deuxieme byte
    	MOVWF	BYTE1		;dans variable byte1
    
         RCIF=0;	        <- syntax à revoir !!!!	RAZ du flag reception UART
        while(RCIF==0); 	<- syntax à revoir !!!!   attentdre que le Flag repasse à 1
    
    	MOVF	RCREG,W		;lecture du dernier byte
    	MOVWF	BYTE2		; dans variables	byte2
    	BANK0
        
     RCIF=0;<- syntax à revoir !!!!
     RCIE=1;<- syntax à revoir !!!!      à moins de remettre à 1 RCIE dans la main apres avoir traité tes 3 bytes recus
    	return

    le principe du buffer de reception par IT sur chaque byte
    devrait tout de meme fonctionner
    sans aucune tempo ou boucle de test interne... Surtout si Q=20Mhz
    Dernière modification par paulfjujo ; 27/04/2014 à 15h01.

  21. #20
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Donc , le mieu serai dans l interruption de simplement stocker RCREG dans une variables et de tester la variables dans le main pour voir si c es un byte status ou un byte de données ?
    Ce que je n arrive pas a comprendre alors c'es comment faire la différence entre les byte 1 et byte 2 vu qu'il vont tous les deux de 0 a 127 ou reste encore la solution du compteur de passage .

    Aussi pour la tempo de 320µs donc apres sortie de mon interruption de reception , je pensais alors , desactiver les interruption periphérique a la fin de l 'interruption reception usart et relancer l interruption periphérique 320µs plus tard avec une interruption timer , ça serai mieux ?

    J'avais choisi le quartz 4MHZ par faciliter pour un test code pour tester mon chipsound qui tourne a 4MHZ , maintenant que ça avance un peu je pense repasser sur 20MHZ .


    merci pour l'aide

  22. #21
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Aussi , J'avais cru lire qu'avec la file FIFO le bit rcif n'était pas remis a zero apres lecture du premier octet mais seulement apres lecture du second , c'est vrai ? Ou c'est une fausse idée que je me fait ?

  23. #22
    paulfjujo

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Surtout ne pas compliquer davantage avec un timer en plus dans l'IT UART
    Si le 1er byte recu STATUS a toujours son bit de poids fort à 1
    on peut s'en servir pour synchroniser le remplissage d'un buffer de 3 bytes
    qui representera STATUS,BYTE1,BYTE2

    Code:
    // l'interrupt rempli le buffer 
    // en mettant toujour le STATUS avec bit d epoids fort=1 dans buffer[0]
    intrc
    
    	BANKSEL	RCSTA		;selection bank
    	MOVF	RCREG,W		;lecture du premier byte 
    	MOVWF     Car_Recu  . stockage  intermediaire
    
    // pseudo code 
    si  	Car_Recu & 0x80h ==0x80
    	Cpt=0;
    sinon   
             Cpt++
    finsi
    	cpt=cpt & 0x03  	 // limit excursion possible dans le buffer
            buffer[Cpt]=Car_Recu;//stockage dans buffer[Cpt]
           BANK0
           return
    si le caractere recu a son bit 7 egal à 1 , Cpt est initalisé à 0
    STATUS se retrouve donc dans Buffer[0]
    le cractere suivant n'ayant pas son bit 7 à un, on incremente Cp => Cpt=1
    et on le stocke dans Buffer[1]
    au 3em passage Cpt=2
    et on le stocke dans Buffer[2]

    dans le main, boucle principale
    on recupere et gere ces 3 bytes...
    STATUS=buffer [0];
    BYTE1=buffer[1];
    BYTE2=buffer[2];

    on pourrait aussi geler les interrupt des que Cpt=2
    pour travailler tranquille sur le contenu des 3 bytes
    et rearmer l'interrupt pour la suite..

  24. #23
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Aussi , J'avais cru lire qu'avec la file FIFO le bit rcif n'était pas remis a zero apres lecture du premier octet mais seulement apres lecture du second , c'est vrai ? Ou c'est une fausse idée que je me fait ?

  25. #24
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    Sinon , auriez - vous un liens vers des explication de l utilisation de buffers ? ( en français si possible ) , j'ai vraiment du mal a faire marcher mon code avec des buffer , je dois avoir zapper quelque chose d 'important .

  26. #25
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    ORIGINAL: RE
    ..
    when the PIC recieve a character string does it after every byte (characther)set the RCIF Falg then you must clear it after evry character received..

    No, you cannot clear RCIF directly. It will clear automatically after you read RCREG and there are no more characters in the hardware queue.
    Donc si je comprend , vu qu un message midi s'apparente a une suite continue de 3 byte +1 stop et un start ,je dois lire trois fois RCREG pour qu'il se remette a 0 car meme si je lis une fois RCREG il restera 2 Byte dans la file d attente FIFO, donc si je comprend bien c est impossible qu'il y ai trois interruption pour un message midi , il n'y en a qu 'une qui est lancer et tant que j'ai pas lu trois fois RCREG l interruption ne se relancera pas meme si je BCF le bit RCIF .
    Comment faire alors ?
    Dernière modification par genocyber ; 29/04/2014 à 12h23.

  27. #26
    genocyber

    Re : [ASM][PIC16F877] MIDI note ON/OFF

    OK , j 'ai enfin compris et reussi , sans delay de 320µs dans mon interruption .

    merci a tous de votre patience

Découvrez nos comparatifs produits sur l'informatique et les technologies.