Toon posts:

[c] seriele communicatie

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Voor en project op school moeten we een robot maken die bestuurbaar is via het pc keyboard (letters z,q,s,d) dit doorgestuurd via RS232 naar de microcontroller (AT89S52). Nu had ik voorheen nog nooit geprogrammeerd ( alleen beetje in visual basic) en is C compleet nieuw voor mij. Heb ondertussen wat samen geflanst (code trekt waarschijnlijk op niks), maar nu zit ik vast bij de seriele communicatie. Alles werkt tot wanneer ik aan de regel met " invoer = getCharacter (); " ben. Dan krijg ik 2 warnings. Dit is de foutcode op de site van mijn compiler... Hoe krijg ik dit werkend ?

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <AT89X51.H>
#include <stdio.h>        

#define L1 P2_0                                 /* pin 1 van motor links */
#define L2 P2_1                                 /* pin 2 van motor links */ 
#define R1 P2_2                                 /* pin 1 van motor rechts */
#define R2 P2_3                                 /* pin 2 van motor rechts */
#define zoemer P2_4                             /* Pin van de zoemer */

#define interrupt1 P3_2                         /* externe intterupt    (int0) */ 
 
/* Functies */

char getCharacter (void);                       /* lees een letter van de seriele poort */
void sendCharacter (char);                      /* schrijf een letter van de seriele poort */


void serial_int (void) interrupt 4
{
       static char        chr = '\0';           /* buffer van de letters */


       if (RI == 1)                             /* ontvang interrupt (receive interrupt) */
       {
               chr = SBUF;                      /* steek de letter in het buffer */
               RI = 0;                          /* reset de receive interrupt om terug te kunnen ontvangen */
               TI = 1;                          /* transmit itterrupt hoog om te zenden */
       }
       else if (TI == 1)                        /* anders een transmit interrupt */
       {
               TI = 0;                          /* reset de transmit interrupt */
               if (chr != '\0')                 /* als er iets in het buffer is dan enters toevoegen en nieuwe lijn */
               {
                       if (chr == '\r') chr = '\n';        
                       SBUF = chr;              /* zet de letters in het transmit buffer */
                       chr = '\0';
               }
       }
}

/* Einde functies */
  

main()
{
       char invoer;

       SCON = 0x50;                             /* mode 1, 8-bit uart, enable receiver */
       TMOD = 0x20;                             /* timer 1, mode 2, 8-bit reload */
       TH1  = 0xFE;                             /* reload value for 2400 baud */
       ET0  = 0;                                /* geen interrupts via deze timer */
       TR1  = 1;                                /* start de timer */
       TI   = 1;                                /* maak het buffer leeg */
       ES   = 1;                                /* zet seriele interrupts aan */
       EA   = 1;                                /* zet alle interrupts aan */

       while(1){                                /* while lus die constant doorlopen wordt */

            invoer = getCharacter (); 
        
            if (interrupt1 == 0){               /* als de externe intterupt 1 is, dan zoemer aanzetten, alle motor ingangen op 1 zodat de dc   */
                zoemer = 0;                     /* blokkeren   */
                L1 = 0;
                L2 = 0;
                R1 = 0;
                R2 = 0;
            } else {                            /* anders onderstaande uitvoeren om motors aan te sturen */
                zoemer = 1;             
    
                if (invoer == 0x7A){                    /*vooruit door op de letter "z" op het keyboard te duwen */
                    L1 = 1;
                    R1 = 1;
                    L2 = 0;
                    R2 = 0;
                    }
                else if(invoer == 0x73){                /*achteruit  door letter "s"*/      
                    L2 = 1;
                    R2 = 1;
                    L1 = 0;
                    R1 = 0;
                    }
                else if(invoer == 0x71){                /*links  door letter "q"  */
                    L2 = 1;
                    R1 = 1;
                    L1 = 0;
                    R2 = 0;
                    }
                else if(invoer == 0x64){                /*rechts door letter "d"    */
                    L1 = 1;
                    R2 = 1;
                    L2 = 0;
                    R1 = 0;
                    }
                else{                           /*stoppen  */
                    L1 = 0;                 
                    L2 = 0;
                    R1 = 0;
                    R2 = 0;
                    }
                }
            }


  
      
}

Acties:
  • 0 Henk 'm!

  • Alain
  • Registratie: Oktober 2002
  • Niet online
Je roept de functie getCharacter() aan, waar alleen een prototype voor bestaat. Dan krijg je een probleem tijdens het linken. ;)

Je moet de code voor getCharacter dus nog schrijven of de juiste libraries includen.

[ Voor 25% gewijzigd door Alain op 07-04-2009 23:10 ]

You don't have to be crazy to do this job, but it helps ....


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Heb de code voor het seriele deel van deze site gehaald. In de code staat geen librarie geinclude :s

[ Voor 93% gewijzigd door Verwijderd op 07-04-2009 23:16 ]


Acties:
  • 0 Henk 'm!

  • Alain
  • Registratie: Oktober 2002
  • Niet online
C:
1
char getCharacter (void);                        /* lees een letter van de seriele poort */ 


Deze regel is een prototype van de functie getCharacter. Nu is alleen bekend dat de functie er is en hoe de functie eruit ziet. De functie doet alleen nog niks.

You don't have to be crazy to do this job, but it helps ....


Acties:
  • 0 Henk 'm!

  • Alain
  • Registratie: Oktober 2002
  • Niet online
Verwijderd schreef op dinsdag 07 april 2009 @ 23:11:
Heb de code voor het seriele deel van deze site gehaald. In de code staat geen librarie geinclude :s
Kijk eens hier op dezelfde site:

http://www.8051projects.info/expC3.asp

You don't have to be crazy to do this job, but it helps ....


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dus als ik dit bij mijn program schrijf zou het moeten werken...

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 /*************************************************************************
* getCharacter - Waits for a new character to arrive in the serial port,
*  then reads it.
*
* INPUT: N/A
* RETURNS: newly received character
*/

char getCharacter (void)
{
       char chr;        /* variable to hold the new character */

       /*
        * Wait until the serial port signals a new character has arrived.
        * It does so by setting the Received interrupt flag, RI, which
        * this routine loops on until it is set to 1.  This is known
        * as polling.
     */

       while (RI != 1) {;}

       /* now read the value in the serial buffer into the local variable */

       chr = SBUF;

       /*
        * Once the character is read, the serial port must be told that it is
        * free to receive a new character.  This is done by clearing the
        * Received Interrupt flag.
        */

       RI = 0;

       /* the character is then returned to the calling function. */

       return(chr);
}

/*************************************************************************
* sendCharacter - Waits until the serial port is ready to send a new
*  character, then sends it.
*
* INPUT:
*        chr - The character to send
*
* RETURNS: N/A
*/

void sendCharacter
(
    char        chr        /* character to send */
)
{
       /*
        * Because of the way terminal programs for serial ports work, we want
        * to replace carriage returns with line feeds.
        */

       if (chr == '\r') chr = '\n';

       /*
        * Wait until the serial port signals the previous character has
        * been sent. It does so by setting the Transmit interrupt flag, TI,
        * which this routine loops on until it is set to 1. 
     */

       while (TI != 1) {;}

       /*
        * Clear the Transmit Interrupt flag to prepare the serial port
        * to send a new character.
        */

       TI = 0;

       /* Write the character into the serial port buffer register, SBUF */

       SBUF = chr;

       /*
        * The serial port hardware takes over from here, and the program
        * may continue with other operations.
        */

       return;
}

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Inderdaad dom van me |:( Thanks !!

[ Voor 16% gewijzigd door Verwijderd op 07-04-2009 23:30 ]


Acties:
  • 0 Henk 'm!

  • Alain
  • Registratie: Oktober 2002
  • Niet online
Knippen en plakken van code zonder na te denken is nooit goed. Je moet natuurlijk wel snappen wat er gebeurd, dus ga dat eerst eens na zou ik zeggen. ;)

You don't have to be crazy to do this job, but it helps ....


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:17
Die getcharacter is een blocking functie, terwijl je al code had staan in je serial interrupt routine, zonde. ( De rest van je main zal dus alleen werken als je serieel characters blijft ontvangen, wat normaal gesproken niet echt gewenst is )

[ Voor 37% gewijzigd door farlane op 07-04-2009 23:36 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ja had toch de code doorlopen en bijgeschreven wat elke regel doet, verschillende tutorials gevolgt , op forums zitten surfen alles aandachtig gelezen.

Ben traag van begrip zeker ?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
farlane schreef op dinsdag 07 april 2009 @ 23:33:
Die getcharacter is een blocking functie, terwijl je al code had staan in je serial interrupt routine, zonde. ( De rest van je main zal dus alleen werken als je serieel characters blijft ontvangen, wat normaal gesproken niet echt gewenst is )
Nee dat ziet er niet goed uit :/ Kom er wel uit...

[ Voor 26% gewijzigd door Verwijderd op 08-04-2009 00:22 ]


Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 19-09 10:19
Ik vind ook dat hier geen sprake is van effe c/p. het commentaar is heel duidelijk, en je hebt zo te zien prima onderzocht wat alles doet, dat je dan niet weet wat een prototype is/ wanneer iets dat is kan je iemand die alleen is wat vb heeft gedaan niet kwalijk nemen. Maar het gebeurt hier te vaak dat dat wel zo is, vandaar de misschien wat allergische reactie Alains na je reply waar "gekopieerd van.." in staat :)

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:17
Verwijderd schreef op dinsdag 07 april 2009 @ 23:39:
Nee dat ziet er niet goed uit :/ Kom er wel uit...
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#define RX_BUFFER_LEN   16
#define TX_BUFFER_LEN   16
volatile static uint8_t RxBuffer[ RX_BUFFER_LEN ] = { 0 };
volatile static uint8_t RxLen = 0;
volatile static uint8_t TxBuffer[ TX_BUFFER_LEN ] = { 0 };
volatile static uint8_t TxLen = 0;
void serial_int (void) interrupt 4
{
    if( RI == 1 )
    {
        volatile uint8_t RxChar = SBUF;
        if( RxLen < RX_BUFFER_LEN )
            RxBuffer[ RxLen++ ] = RxChar;
    }
       
    if( TI == 1 )
    {
        if( TxLen )
        {
            --TxLen;
            SBUF = TxBuffer[ TxLen ];
        }
        else
            TI = 0;
    }
}

uint8_t SerialTx( const uint8_t* Buffer, uint8_t Len )
{
    uint8_t R = min( Len, TX_BUFFER_LEN );

    memcpy( TxBuffer, Buffer, R );
    TxLen = R;
    TI = 1;
    return R;
}

uint8_t SerialRx( uint8_t* Buffer, uint8_t Len )
{
    uint8_t R = min( Len, RxLen );
    memcpy( Buffer, RxBuffer, R );
    RxLen = 0;
    return R;
}


Een dergelijk iets zou moeten werken, zonder dat je aanroepen van SerialRx/SerialTx blocken. Natuurlijk kan het altijd mooier wb bufferhandling en er zitten ook een aantal problemen in mbt interlocking van de volatile variabelen maar daar mag je zelf mee aan de gang :)

Overigens, iha is seriele communicatie asynchroon, dus er kan een TI en een RI vlag tegelijk aanwezig zijn.

disclaimer: ongetest

[ Voor 3% gewijzigd door farlane op 08-04-2009 14:21 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1