PIC 16F84A Programmierung



  • Hallo an Alle ich bin Neu hier,
    und ich habe ein Problem bei einem Projekt dass ich für die Schule machen muss.
    Es geht um folgendes:
    Ich will ein kleines Quiz programmieren, in dem die Fragen im LCD Display angezeigt werden, und man mit Wahr oder Falsch antworten muss, das jeweils mit einem Schalter für Wahr und Falsch.
    Ich benutze einen LCD Display in der Grösse 16X4, zwei Schalter und einen Buzzer, das macht insgesamt 13 pics was für den PIC 16F84A ausreichend ist. Ich werde dabei aber das hier benutzen http://digitalelectrosoft.com/pic-simulator und keinen echten PIC programmieren.

    Ich habe zwar Kenntnisse in Java aber mir scheint C schwieriger zu sein. Und es ist das erste Mal dass ich C mache.

    hier des bisherige Code:

    #define LCD_data PORTB
    #define LCD_D7 PORTB
    #define LCD_rs PORTA.0
    #define LCD_rw PORTA.1
    #define LCD_en PORTA.2
    
    //
    // ######## Initialisation des ports du programme ########
    //
    
    void initPorts()
    {
    	TRISB = 0b00000000;
    	TRISA = 0b00011000;
    	OPTION = 0b11000111;
    	TMR0 = 0;
    }
    
    //
    // ######### Initialisation de l'afficheur LCD #########
    //
    
    void LCD_init()
    {
    	LCD_data = 0x38;
    	LCD_rs = 0;
    	LCD_rw = 0;
    	LCD_en = 1;
    	LCD_en = 0;
    	LCD_busy();
    	LCD_data = 0x0F;
    	LCD_rs = 0;
    	LCD_rw = 0;
    	LCD_en = 1;
    	LCD_en = 0;
    	LCD_busy();
    	LCD_data = 0x01;
    	LCD_rs = 0;
    	LCD_rw = 0;
    	LCD_en = 1;
    	LCD_en = 0;
    	LCD_busy();
    	LCD_data = 0x06;
    	LCD_rs = 0;
    	LCD_rw = 0;
    	LCD_en = 1;
    	LCD_busy();
    }
    
    void LCD_command(unsigned char var)
    {
    	LCD_data = var; 
    	LCD_rs = 0; 
    	LCD_rw = 0;
    	LCD_en = 1; 
    	LCD_en = 0;
    	LCD_busy(); 
    }
    
    void LCD_senddata(unsigned char var)
    {
    	LCD_data = var; 
    	LCD_rs = 1; 
    	LCD_rw = 0; 
    	LCD_en = 1; 
    	LCD_en = 0;
    	LCD_busy(); 
    }
    
    //
    // ######### Attente entre les caractères #########
    //
    
    void LCD_busy()
    {
    	unsigned char i,j;
    	for(i=0;i<50;i++) 
    		for(j=0;j<255;j++);
    }
    
    // program Main;
    #include <stdio.h>
    
    int main(void)
    {
    
    	questionCourante == 0;
    	jeuFini == FALSE;
    
    	string tab[10];
    tab [0] = Fumer tue?;
    tab [1] = Mont-Vully une montagne?;
    tab [2] = Xavi un skieur?;
    tab [3] = Amour un fleuve?;
    tab [4] = Russy un village ?;
    tab [5] = Mer Caspienne une mer?;
    tab [6] = Nil le plus long fleuve?;
    tab [7] = ;
    tab [8] = ;
    tab [9] = ;
    
    	while (!jeuFini)
    	{
    		# afficher QUESTION[questionCourante];
    		temps == 187;
    		while (temps > 0)) 
    		{
    			if ( TMR0 == 255 )
    			{
    				TMR0 == 0;
    				temps--;
    				if (temps == 0)
    				{
    					jeuFini == TRUE;
    				}
    			}
    			if (boutonOUI==1)
    			{
    				rep == 1;
    				repondu == TRUE;
    			}
    			if (boutonNON==1)
    			{
    				rep == 0;
    				repondu == TRUE;
    			}
    			while (boutonNON==1 || boutonOUI==1) 
    			{
    			}
    			if ( repondu )
    			{
    				temps == 0;
    				if ( rep == REPONSE[questionCourante] )
    				{
    					if (questionCourante < MAXQUESTIONS)
    					{
    						questionCourante++;
    					}
    					else
    					{
    						jeuFini == TRUE;
    					}
    				}
    				else
    				{
    					jeuFini == TRUE;
    				}
    			}
    		}
    	}
    
    	Affiche questionCourante;				// Le score quoi...
    	return 0;
    }
    

    Es lässt sich noch nicht compilieren ich denke es hat Fehler drin. Die Comments sind in französisch geschrieben aber ich denke ihr versteht bestimmt was ich meine.

    Ich danke für jede Hilfe 🙂



  • Es ist nahezu alles falsch 😃

    1. Variablen müssen deklariert werden!
    2. Variablen müssen mit = initialisiert werden.
    3. == ist ein Vergleich keine Zuweisung welches ein = ist.
    4. Du definierst irgendwas was nirgends irgendwie erklärt ist.
    5. Du kannst defines nicht als globale Variablen verwenden, defines sind Wortersetzungen.
    6. Und noch viel mehr falsch...

    Die Fehler kann man nicht mal mit gutem Willen beheben, so das es funktioniert. Das mit Java glaubt dir niemand, denn bei dem Code müsste es nahezu identisch in C sein. Ich glaube nicht mal dass du je ein Programm in Java geschrieben hast... Dafür sind einfach die simpelsten Sachen falsch.

    168 Fehler in 157 Zeilen... Habe ich "nahezu" gesagt?



  • Für Frankreich tue ich doch alles 🙂
    Über die Sinnhaftigkeit des Codeinhaltes äußere ich mich aber nicht.

    // program Main;
    #include <stdio.h>
    
    #define  PORTB   0x0c
    #define  PORTA0  0x0d
    #define  PORTA1  0x0e
    #define  PORTA2  0x0f
    #define MAXQUESTIONS 10
    
    int LCD_data =PORTB;
    int LCD_D7 =PORTB;
    int LCD_rs =PORTA0;
    int LCD_rw =PORTA1;
    int LCD_en =PORTA2;
    
    enum{FALSE,TRUE};
    
    int    TRISB;
    int    TRISA;
    int    OPTION;
    int    TMR0;
    
    //
    // ######### Attente entre les caractères #########
    //
    
    void LCD_busy()
    {
        unsigned char i,j;
        for(i=0;i<50;i++)
            for(j=0;j<255;j++);
    }
    
    //
    // ######## Initialisation des ports du programme ########
    //
    
    int fromBin(char *b)
    {
      int r=0;
      while(*b)
        r<<=1,r|=*b++=='1';
      return r;
    }
    
    void initPorts()
    {
        TRISB = fromBin("00000000");
        TRISA = fromBin("00011000");
        OPTION = fromBin("11000111");
        TMR0 = 0;
    }
    
    //
    // ######### Initialisation de l'afficheur LCD #########
    //
    
    void LCD_init()
    {
        LCD_data = 0x38;
        LCD_rs = 0;
        LCD_rw = 0;
        LCD_en = 1;
        LCD_en = 0;
        LCD_busy();
        LCD_data = 0x0F;
        LCD_rs = 0;
        LCD_rw = 0;
        LCD_en = 1;
        LCD_en = 0;
        LCD_busy();
        LCD_data = 0x01;
        LCD_rs = 0;
        LCD_rw = 0;
        LCD_en = 1;
        LCD_en = 0;
        LCD_busy();
        LCD_data = 0x06;
        LCD_rs = 0;
        LCD_rw = 0;
        LCD_en = 1;
        LCD_busy();
    }
    
    void LCD_command(unsigned char var)
    {
        LCD_data = var;
        LCD_rs = 0;
        LCD_rw = 0;
        LCD_en = 1;
        LCD_en = 0;
        LCD_busy();
    }
    
    void LCD_senddata(unsigned char var)
    {
        LCD_data = var;
        LCD_rs = 1;
        LCD_rw = 0;
        LCD_en = 1;
        LCD_en = 0;
        LCD_busy();
    }
    
    int main(void)
    {
        static int questionCourante,temps,jeuFini,boutonOUI,boutonNON,rep,repondu,REPONSE[MAXQUESTIONS];
    
        char *tab[10];
    tab [0] = "Fumer tue?";
    tab [1] = "Mont-Vully une montagne?";
    tab [2] = "Xavi un skieur?";
    tab [3] = "Amour un fleuve?";
    tab [4] = "Russy un village ?";
    tab [5] = "Mer Caspienne une mer?";
    tab [6] = "Nil le plus long fleuve?";
    tab [7] = "";
    tab [8] = "";
    tab [9] = "";
    
        while (!jeuFini)
        {
            //# afficher QUESTION[questionCourante];
            temps = 187;
            while (temps > 0)
            {
                if ( TMR0 == 255 )
                {
                    TMR0 = 0;
                    temps--;
                    if (temps == 0)
                    {
                        jeuFini = TRUE;
                    }
                }
                if (boutonOUI==1)
                {
                    rep = 1;
                    repondu = TRUE;
                }
                if (boutonNON==1)
                {
                    rep = 0;
                    repondu = TRUE;
                }
                while (boutonNON==1 || boutonOUI==1)
                {
                }
                if ( repondu )
                {
                    temps = 0;
                    if ( rep == REPONSE[questionCourante] )
                    {
                        if (questionCourante < MAXQUESTIONS)
                        {
                            questionCourante++;
                        }
                        else
                        {
                            jeuFini = TRUE;
                        }
                    }
                    else
                    {
                        jeuFini = TRUE;
                    }
                }
            }
        }
    
        //Affiche questionCourante;                // Le score quoi...
        return 0;
    }
    


  • Es wäre sicher noch ganz hilfreich die Zählvariablen vor der Optimierung zu bewahren. Und char als Datentyp ist schon sehr optimistisch. Dem nächsten ist die Pause zu kurz oder hat einen Denkfehler und schreibt eine 256.

    void LCD_busy()
    {
        volatile unsigned int i;
        for(i=0;i<(50*255);i++)
           ;
    }
    


  • Ich habe den Code jetzt ein wenig korrigiert.
    Was jedoch noch nicht klappt sind die Schalter. Ich kann auf keine Frage antworten.

    /* ***********************************************************
    	Notre projet novembre 2010 module 242 classe 2i1
    
    	Nom1 et Prenom1:Loïc Dufresne
    	Nom2 et Prenom2:Mensur Izairi
    
    	Fichier:	index.c
    	Date:	    du x octobre 2010 au 25 novembre 2010
    	Version:	1.0
    
    	Langage:	C pour Pic 16F84A et 16F690 
    	Langue:	    Français
    	Fichiers:	
                - 16F690.h pour les références de codage aux ports disponibles 
    	    - messousprogrammes.c contient nos sous-programmes génériques
    
    	************************************************************
       	************************************************************/
    
    #define LCD_BUSY_WAIT_TICKS	100
    #define CATCH_BUTTON_PRESS_REPEATS 25
    
    #define LCD_CMD_CLEAR_DISPLAY		0x01		
    #define LCD_CMD_NOCURSOR_NOBLINK	0x0C		
    #define LCD_CMD_CURSOR_BLINK		0x0F		
    #define LCD_CMD_GO_FIRST_LINE		0x80		
    #define LCD_CMD_GO_SECOND_LINE		0xC0		
    
    #define TRUE					1
    #define FALSE					0
    
    #define MAXQUESTIONS			7
    
    #define LCD_data PORTB
    #define LCD_rs PORTA.0
    #define LCD_rw PORTA.1
    #define LCD_en PORTA.2
    
    //
    //######## PORTA.3 = boutonOUI ############
    //######## PORTA.4 = boutonNON ############
    //
    
    static unsigned char prevBtnStateLeft;		
    static unsigned char prevBtnStateRight;
    
    static unsigned char questionCourante;
    static const char *questions[ MAXQUESTIONS ];
    static unsigned char reponses[ MAXQUESTIONS ];
    static unsigned char rep;
    
    //
    // ######### Initialisation des ports du programme #########
    //
    
    void initPorts()
    {
    
    	TRISA = 0b00011000;
    	TRISB = 0b00000000;
    	PORTA = 0b00000000;
    	PORTB = 0b00000000;
    	OPTION = 0b11000111;
    	TMR0 = 0;
    }
    
    //
    // ######### Attente entre les caractères #########
    //
    
    void LCD_busy()
    {
    	TMR0 = 0;
    	while ( TMR0 < LCD_BUSY_WAIT_TICKS ) { nop(); }
    }
    
    void LCD_command(unsigned char var)
    {
    	LCD_data = var; 
    	LCD_rs = 0; 
    	LCD_rw = 0;
    	LCD_en = 1; 
    	LCD_en = 0;
    	LCD_busy(); 
    }
    
    void LCD_senddata(unsigned char var)
    {
    	LCD_data = var; 
    	LCD_rs = 1; 
    	LCD_rw = 0; 
    	LCD_en = 1; 
    	LCD_en = 0;
    	LCD_busy(); 
    }
    
    //
    // ######### Initialisation de l'afficheur LCD #########
    //
    
    void LCD_init( unsigned char shift )
    {
    
    	// We should wait at least 30ms after DCC stable at 4.5v
    	LCD_command( 0b00111000 );			// Set 2 lines mode and 5x7 dots per line
    
    	// We should wait at least 39us here
    	if ( shift )
    		LCD_command( LCD_CMD_NOCURSOR_NOBLINK );
    	else
    		LCD_command( LCD_CMD_CURSOR_BLINK );
    
    	// We should wait at least 39us here
    	LCD_command( LCD_CMD_CLEAR_DISPLAY );
    
    	// We should wait at least 39us here
    	if ( shift )
    		LCD_command( 0b00000111 );		// Incremement mode ON / entire shift ON
    	else
    		LCD_command( 0b00000110 );		// Incremement mode ON / entire shift OFF
    }
    
    void LCD_senddatastring( const unsigned char *pvar )
    {
    	while ( *pvar )
    		LCD_senddata( *pvar++ );
    }
    
    //
    // ########## Méthode qui indique si le bouton gauche est pressé ##########
    //
    
    unsigned char boutonOUI()
    {
    
    unsigned char boutonEstPresse;
    	unsigned int newTMR0;
    	prevBtnStateLeft = 0;
    
    	if ( ( prevBtnStateLeft == 0 ) && ( PORTA.3 == 0 ) )	// le bouton est pressé, mais le restera-t-il durant tout un laps de temps ??
    	{
    		prevBtnStateLeft = 1;	// En principe, le bouton a été correctement pressé 1x
    
    		newTMR0 = TMR0 + CATCH_BUTTON_PRESS_REPEATS;
    
    		while ( TMR0 < newTMR0 )
    		{
    			if (PORTA.3 != 0)	// si le bouton n'est plus pressé, alors c'est fini
    			{
    				prevBtnStateLeft = 0;	// erreur, il y a eu un changement d'état entretemps...
    				break;
    			}
    		}
    
    		boutonEstPresse= 0;
    	}
    
    	if ( ( prevBtnStateLeft == 1 ) && ( PORTA.3 != 0 ) )	// le bouton est maintenant relâché mais il avait été pressé
    	{
    		prevBtnStateLeft = 0;
    		boutonEstPresse=1;
    	}
    
    	return boutonEstPresse;
    }
    
    //
    // ########## Méthode qui indique si le bouton droite est pressé ##########
    //
    
    unsigned char boutonNON()
    {
    
    	unsigned char boutonEstPresse;
    	unsigned int newTMR0;
    	prevBtnStateRight = 0;
    
    	if ( ( prevBtnStateRight == 0 ) && ( PORTA.4 == 0 ) )	// le bouton est pressé, mais le restera-t-il durant tout un laps de temps ??
    	{
    		prevBtnStateRight = 1;	// En principe, le bouton a été correctement pressé 1x
    
    		newTMR0 = TMR0 + CATCH_BUTTON_PRESS_REPEATS;
    
    		while ( TMR0 < newTMR0 )
    		{
    			if (PORTA.4 != 0)	// si le bouton n'est plus pressé, alors c'est fini
    			{
    				prevBtnStateRight = 0;	// erreur, il y a eu un changement d'état entretemps...
    				break;
    			}
    		}
    
    		boutonEstPresse = 0;
    	}
    
    	if ( ( prevBtnStateRight == 1 ) && ( PORTA.4 != 0 ) )	// le bouton est maintenant relâché mais il avait été pressé
    	{
    		prevBtnStateRight = 0;
    		boutonEstPresse= 1;
    	}
    
    	return boutonEstPresse;
    }
    
    //
    // To send a whole string at once
    //
    
    void afficheEntree()
    {									
    	LCD_command( LCD_CMD_CLEAR_DISPLAY );    	//Efface l'ecran.
    	LCD_command( LCD_CMD_GO_FIRST_LINE );      	// Va à la première ligne du LCD
    	LCD_senddatastring("Quiz cree par");		
    	LCD_command( LCD_CMD_GO_SECOND_LINE );		// Va à la deuxième ligne du LCD
    	LCD_senddatastring("Mensur et Loic");
    
    }
    
    void afficheQuestion( unsigned char iQuestion )
    {
    	//
    	// ####### Pareil au afficheEntree #######
    	//
    
    	LCD_command( LCD_CMD_CLEAR_DISPLAY );
    	LCD_command( LCD_CMD_GO_FIRST_LINE );
    	LCD_senddatastring(questions[iQuestion]);
    	LCD_command( LCD_CMD_GO_SECOND_LINE );
    	LCD_senddatastring("Vrai ou Faux ?");
    }
    
    void wait1sec()
    {
    	unsigned char nbre = 0;
    
    	TMR0 = 0;
    
    	//
    	// Un overflow du registre TMR0 (passage de 0, 1, 2, ... 255, puis à 0) prend exactement 65ms.
    	// Il faut donc (255*1000)/65 = 3923 unités d'attente pour 1sec.
    	// Il faut donc le laisser aller 15x jusqu'à 255 et 1x jusqu'à 98 (15 * 255 + 98 = 3923)
    	//
    	while (1)
    	{
    		if (TMR0 == 255)
    		{
    			nbre++;
    			TMR0 = 0;
    		}
    		else if (TMR0 == 98 && nbre == 15)
    			break;
    	}
    }
    
    //
    //######### program Main #########
    //################################
    //
    
    void main(void)
    {	
    	unsigned char shift = 0;
    	initPorts();
    	LCD_init(shift);	
    
    	afficheEntree();    // méthode définie plus en haut, premiere chose affichée
    	wait1sec();wait1sec();wait1sec();
    
    	questionCourante = 0;			// Variable du type unsigned char
    	bit jeuFini = 0;				// Variable booleenne qui signifi la fin du jeu
    
    	// 
    	//######### Tableau de questions ##########
    	//
    
    	questions[0] = "Hitler allemand?";
    	questions[1] = "Fumer tue ?";
    	questions[2] = "Xavi un skieur?";
    	questions[3] = "Amour un fleuve?";
    	questions[4] = "Russy une village?";
    	questions[5] = "Massalia Marseille?";
    	questions[6] = "Nil long fleuve?";
    
    	// 
    	//########## Tableau avec les reponses, les questions sont liés avec les réponses ##############
    	//
    
    	reponses[0] = 0;
    	reponses[1] = 1;
    	reponses[2] = 0;
    	reponses[3] = 1;
    	reponses[4] = 0;
    	reponses[5] = 1;
    	reponses[6] = 1;
    
    	//
    	// ####### boucle while, tant que jeuFini est à 1 le jeu continue...
    	//
    
    	while (!jeuFini)
    	{
    		// 
    		//####### affiche les questions depuis le tableau questions[] #######
    		//
    
    		afficheQuestion( questionCourante );
    
    		//
    		// ###### 15 secondes que l'on a à disposition pour répondre à la question$
    		//
    
    		unsigned short temps = 187;
    
    		//
    		//####### Tant que temps est plus grand que 0 la boucle s'effectue.
    		//
    		while (temps > 0)
    		{
    
    			//
    			//######## Test si il reste encore du temps à disposition pour répondre, si le temps est écoulé la variable jeuFini passe à vrai.
    			//
    			if ( TMR0 == 255 )
    			{
    				TMR0 = 0;
    				temps--;
    				if (temps == 0)
    				{
    					jeuFini = TRUE;
    				}
    			}
    
    			//
    			//######### si le boutonOui est pressé alors la variable réponse passe à 1
    			//
    
    			if (boutonOUI()==1)
    			{
    				rep = 1;
    
    			}
    
    			//
    			//######## si le bouton est pressé alors la variable réponse passe à 1
    			//
    			if (boutonNON()==1)
    			{
    				rep = 0; 
    
    			}
    			while (boutonNON()==1 || boutonOUI()==1) 
    			{
    			}
    			if ( rep )
    			{
    				temps = 0;
    
    				if ( rep == reponses[questionCourante] )
    				{
    					if (questionCourante < MAXQUESTIONS)
    					{
    						questionCourante++;
    					}
    					else
    					{
    						jeuFini = TRUE;
    					}
    				}
    				else
    				{
    					jeuFini = TRUE;
    				}
    			}
    		}
    	}
    
    		// 
    		//afficher QUESTION[questionCourante]
    		//
    		afficheQuestion( questionCourante );
    
    }
    


  • HighLigerBiMBam schrieb:

    Es ist nahezu alles falsch 😃

    1. Variablen müssen deklariert werden!
    2. Variablen müssen mit = initialisiert werden.
    3. == ist ein Vergleich keine Zuweisung welches ein = ist.
    4. Du definierst irgendwas was nirgends irgendwie erklärt ist.
    5. Du kannst defines nicht als globale Variablen verwenden, defines sind Wortersetzungen.
    6. Und noch viel mehr falsch...

    Die Fehler kann man nicht mal mit gutem Willen beheben, so das es funktioniert. Das mit Java glaubt dir niemand, denn bei dem Code müsste es nahezu identisch in C sein. Ich glaube nicht mal dass du je ein Programm in Java geschrieben hast... Dafür sind einfach die simpelsten Sachen falsch.

    168 Fehler in 157 Zeilen... Habe ich "nahezu" gesagt?

    Ehm ja viele Fehler ich weiss, aber es muss nicht heissen dass ich nichts kann 😞
    Bei diesem Projekt bekamen wir verschiedene Quellcodes und wir mussten uns daraus ein Programm bauen deswegen meine Schwierigkeiten, aber ansonsten hasst du eben recht ich bin nicht der Hellste wenn es um Programmierung geht...

    Was meinst du zum neuen Code?

    So nun zu einem anderen Problem.
    Die Methoden unsigned char boutonOUI() und unsigned char boutonNON() machen nicht das was ich will. Wenn ich das Programm starte dann wird die Methode afficheEntree() auch angezeigt und nach 3 Sekunden kommt dann auch die erste Frage, wenn ich dann aber auf einen Schalter drücke passiert nichts, ich möchte aber dass es mir einen Wert gibt den ich dann mit denen der Tabelle reponses[] vergleiche um zu bestimmen ob die antwort richtig ist oder eben nicht...


Anmelden zum Antworten