Forum: Mikrocontroller und Digitale Elektronik ENQ empfang testen


von Penie L. (peniely)


Lesenswert?

Hallo,
ich versuche seit einige Tag die kommunikartion zwischen mein Avr 
(atmega 8) und meine Kamera einzubauen, Um zuerst zu überprüfen on es 
überhaupt eine Kommunication zwischen die beiden gibt, habe ich mir 
gedacht so ein programm zu schreiben, wo der kontrollersendet ein (enq) 
sende und bekommt eine (ack), die auf dem Portb angezeigt muss, leider 
kriege ich es nicht hin.
1
int main(void)
2
{
3
  char kommando; 
4
  
5
  // RS232 einschalten ... 
6
  setup_uart();
7
  DDRB = 0xFF;
8
  
9
  //sendet Anforderung (ENQ)
10
  uart_putchar('5');    
11
  kommando = uart_getchar(); 
12
   
13
  if (kommando='6')
14
  {   
15
     PORTB = 0x0F;
16
  }
17
  else
18
     PORTB = 0x55;

Ich bin Neuilling in Microcontroller und wäre auch dankbar von einem 
Stuck code.

Die Kommunikation sequence sieht si aus:

controller                                   camera
                 ENQ(05h)
    ------------------------------------------->
                  ACK(06h)
    <-----------------------------------------
                COMMAND
    ------------------------------------------->
                  ACK(06h)
    <-----------------------------------------
                  RESPONSE
    <-----------------------------------------
                  ACK(06h)
    ------------------------------------------>

viele grüße

von Jens K. (jjk) Benutzerseite


Lesenswert?

Penie Lydos schrieb:

> controller                                   camera
>                  ENQ(05h)

Ohne Deine uart_putchar() zu kennen, wenn Du das obige senden willst, 
darfst Du nicht

>   uart_putchar('5');

machen. Damit schickst Du (normalerweise) 35h, nicht 05h ...

Gruß
  Jens

von Penie L. (peniely)


Lesenswert?

danke,
jetzt habe ich
1
 
2
void uart_putchar(char c)
3
{
4
  // Warten bis Buffer bereit ...
5
  while (!(UCSRA & (1 << UDRE)));
6
  // Senden...
7
  UDR = c;
8
  _delay_ms(10);  
9
}
10
11
char uart_getchar()
12
{
13
  // Ist schon ein Zeichen im Buffer?
14
  while( !(UCSRA & (1<<RXC)) );
15
   return UDR;  
16
}
17
18
int main(void)
19
{
20
  char kommando; 
21
  
22
  // RS232 einschalten ... 
23
  setup_uart();
24
  DDRB = 0xFF;
25
  
26
  //sendet Anforderung (ENQ)
27
  uart_putchar('E');    
28
  kommando = uart_getchar(); 
29
   
30
  if (kommando='F')   
31
     PORTB = 0x0F;
32
  else
33
     PORTB = 0x55;
34
  return0;

aber ich kriege immer gar nichst an Portb

gruß

von Jens K. (jjk) Benutzerseite


Lesenswert?

Du solltest Dich erstmal mit grundlegenden Sachen beschäftigen, z.B. dem 
Unterschied zwischen dem Zeichen 'E' und dessen hexadezimaler 
wertigkeit. Die ist nämlich nicht 05h sondern 45h

schau dir mal diese Tabelle an:
http://www.torsten-horn.de/techdocs/ascii.htm

Wenn Du das Zeichen 05h senden willst, dann mußt Du sowas machen:
1
//sendet Anforderung (ENQ)
2
uart_putchar(0x05);

Und beim Empfang ebenso, das ACK was die Cam liefert ist nicht das 
Zeichen '6' sondern der hexadezimale Wert 06h ... Also müßte das in etwa 
so aussehen:
1
response = uart_getchar(); 
2
   
3
if (response == 0x06) {
4
   // irgendwas machen was eben gemacht werden soll wenn die cam ACK gesendet hat
5
}


Leute mit mehr C Wissen mögen mich bitte berichtigen falls das jetzt 
Schwachsinn ist ...

Gruß
  Jens

von Penie L. (peniely)


Angehängte Dateien:

Lesenswert?

danke,
so geht auch nicht,
wenn ich eine test mit eine andere PC als terminal, lauft alles gut ich 
kann senden und empfangen ohne pb.

Leider kann ich nichst mit meine KAmera anfangen.
Als Anhang noch die interface spécifications.
Falls jemand mir helfen kann, danke im voraus.
gruß
1
void uart_putchar(char c)
2
{
3
  // Warten bis Buffer bereit ...
4
  while (!(UCSRA & (1 << UDRE)));
5
  // Senden...
6
  UDR = c;
7
  _delay_ms(10);  
8
}
9
10
char uart_getchar()
11
{
12
  // Ist schon ein Zeichen im Buffer?
13
  while( !(UCSRA & (1<<RXC)) );
14
   return UDR;  
15
}
16
17
int main(void)
18
{
19
  char kommando; 
20
  
21
  // RS232 einschalten ... 
22
  setup_uart();
23
  DDRB = 0xFF;
24
  
25
  //sendet Anforderung (ENQ)
26
  uart_putchar(0x05);    
27
  kommando = uart_getchar(); 
28
   
29
  if (kommando=0x06)   
30
     PORTB = 0x0F;
31
  else
32
     PORTB = 0x55;
33
  return0;

von Penie L. (peniely)


Lesenswert?

Hallo,
ich habe jetzt schritt für schritt fehler gesucht und es scheint das der 
Programm hier kommando = uart_getchar();
hängt.
Bitte kan jemand mir sagen warum!?

gruß

von Jens K. (jjk) Benutzerseite


Lesenswert?

Penie Lydos schrieb:
> Hallo,
> ich habe jetzt schritt für schritt fehler gesucht und es scheint das der
> Programm hier kommando = uart_getchar();
> hängt.

Wahrscheinlich weil er auf was zum Empfangen wartet. Ich hab in c auch 
noch nix mit dem UART gemacht, aber ich würde vllt. eher zum 
Interruptbetrieb wechseln.

Ausserdem solkltest Du in der if Anweisung auch wirklich einen Vergleich 
machen, und keine Zuweisung:
1
if (kommando == 0x06)   
2
     PORTB = 0x0F;
3
  else
4
     PORTB = 0x55;

von Penie L. (peniely)


Lesenswert?

danke
>if (kommando == 0x06)

tipp fehler habe geändert.

>Wahrscheinlich weil er auf was zum Empfangen wartet

habe ich auch wie du gedacht und eine interrupt service routine gemacht, 
bekomme ich trotzdem 0 an PORTB
1
void initall()
2
{
3
  setup_uart(); 
4
  
5
  //interrupt
6
  TCNT0 = 5;        //Set Timer/counter
7
  TIMSK |= (1<<TOIE0);  //Enable Timer/counter0 overflow interrupt
8
  TCCR0 |= (1<<CS01);
9
  TCCR0 |= (1<<CS00);  //Select the clock source to be used by the timer/counter --> CPU Takt  --> 4MHz/64 
10
  TIFR |= (1<<TOV0);  //interrupt starts with each overflow   
11
}//End initall()
12
13
14
//Interrupt Service Routine 
15
ISR(TIMER0_OVF_vect) 
16
{
17
  ADIteiler++;    //clocks interrupt counter value on each ms 
18
  if(ADIteiler >= 60)  //Counter cycle for all ms 60
19
  {
20
    ADIteiler=0;    //counter 0 set
21
    DDRB = 0xFF;
22
    char kommando;
23
    kommando = uart_getchar(); 
24
       
25
    if (kommando == 0x06)
26
      PORTB = 0x0F;
27
   else
28
      PORTB = 0x55;  
29
 }
30
}//End ISR(TIMER0_OVF_vect) 
31
32
int main(void) 
33
{
34
    initall();
35
  
36
    //sendet Anforderung (ENQ)
37
    uart_putchar(0x05);
38
    sei();
39
    return 0;                     
40
} //end main()

gruß
peniely

von Jens K. (jjk) Benutzerseite


Lesenswert?

Penie Lydos schrieb:
> habe ich auch wie du gedacht und eine interrupt service routine gemacht,
> bekomme ich trotzdem 0 an PORTB

So meinte ich das nicht, lies Dir mal hier im Forum das AVR-GCC Tutorial 
durch. Da steht wie man UART mit Interrupt macht:

Allgemein das Tutorial: AVR-GCC-Tutorial

Interrupt bei UART: AVR-GCC-Tutorial: Interruptbetrieb

Gruß
  Jens

von Michael U. (amiga)


Lesenswert?

Hallo,

laß den Quatsch an dieser Stelle auch noch mit Interrupts zu spielen.

UART-Init stimmt?
Verbindung AVR mit PC-Terminalprogramm als Test geht?

An den Routinen kann man genaugenommen nichts falsch machen...

Was hast Du als Pegelwandler am AVR? MAX232`? Spannungen dort stimmen?

Gruß aus Berlin
Michael

von Penie L. (peniely)


Lesenswert?

Hallo,
danke erst mal an alle

>Michael
>Was hast Du als Pegelwandler am AVR? MAX232`? Spannungen dort stimmen?

Alles stimmt, nur das ich keine pegelwandler habe, ich dachte es wäre 
nicht nötig!!!!

alle die USART funktionen habe ich schon getestet, dieses mal war mein 
Terminal nicht die camera sonders eine andere PC. Und es ging alles 
wunderbar.

gruß

von Michael U. (amiga)


Lesenswert?

Hallo,

AVR-UART ohne Pegelwandler zum PC geht?
Bezweifle ich jetzt mal, +/-12V RS232 sind keine 0V/5V vom AVR und die 
Signalpolarität wäre auch falsch rum...

Gruß aus Berlin
Michael

von Jens K. (jjk) Benutzerseite


Lesenswert?

Penie Lydos schrieb:
> alle die USART funktionen habe ich schon getestet, dieses mal war mein
> Terminal nicht die camera sonders eine andere PC. Und es ging alles
> wunderbar.

Also, welche Kombination hast Du jetzt wie getestet?
1
PC  <---------------->  PC
2
PC  <--Pegelwandler-->  AVR
3
AVR <---------------->  Cam
4
PC  <--Pegelwandler-->  Cam

Wenn die Cam TTL Pegel liefert, und nur dann, kann AVR <---> Cam 
funktionieren ohne Pegelwandler.

Jens

von Penie L. (peniely)


Lesenswert?

Danke an alle

>AVR-UART ohne Pegelwandler zum PC geht?
ja ich habe PC <--------AVR----------->PC getestet und ich brauchte 
keine Pegelwandler.
1
#ifndef F_CPU
2
/* In the new version of the WinAVR/Mfile Makefile guideline One can defined F_CPU in the Makefile, a repeated 
3
   definition here would lead to a compiler warning . therefore "prevention" through    #ifndef/#endif
4
5
   This "Prevention" can lead to Debugger, if AVRStudio use a another, not the hardware fitting Clock rate: 
6
   Then the    following definition doesn't use, but instead the default value (1 MHz?) of AVRStudio - hence 
7
   the Output of a warning if F_CPU yet does not define:*/ 
8
#warning "F_CPU was not defined yet, now make up with 4000000"
9
#define F_CPU 4000000L                  // Systemtakt in Hz - define as  long>> Without errors in the computation 
10
#endif
11
12
13
#define BAUD 9600L
14
#define UBRR_VAL ((F_CPU+BAUD * 8)/(BAUD*16)-1)     //clever round
15
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))         //real baud rate
16
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)     //Error per thousand
17
18
19
#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
20
#error Systematic error in the baud rate more than 1% and thus too high!
21
#endif
22
23
24
#include <avr/io.h>
25
#include <stdlib.h>
26
#include <inttypes.h>
27
#include <util/delay.h>
28
29
30
31
void USART_Init(void) 
32
{
33
  
34
  UBRRH = (unsigned char)(UBRR_VAL>>8);      // Set baud rate
35
  UBRRL = (unsigned char)UBRR_VAL;
36
  
37
  UCSRB |= (1<<RXEN)|(1<<TXEN);          // Enable receiver and transmitter
38
  
39
  UCSRC = (1<<URSEL) | (1<<UCSZ0)|(1<<UCSZ1);  // Set frame format: 8data, 1stop bit        
40
}//end USART_Init()
41
42
43
void USART_Putc(unsigned char c)
44
{
45
    while (!(UCSRA & (1<<UDRE))); // Do nothing until data have been transmited 
46
    
47
  UDR = c;                      // Put data into Buffer, sends the data
48
  _delay_ms(10);   
49
}//end USART_Putc()
50
51
52
void USART_Puts (char *string)
53
{
54
    while( *string != '\0' )  //as long as *string != '\0' so unlike the "stringer end-character"
55
    {  
56
        USART_Putc(*string);
57
        string++;
58
    }
59
}//end USART_Puts()
60
61
62
unsigned char USART_Receive()
63
{

aber PC  <-------AVR--------->  Kam geht nicht,
brauche ich dann ein pegelwandler?!

von Penie L. (peniely)


Lesenswert?

>Bezweifle ich jetzt mal,  0V/5V RS232 sind keine  +/-12V vom AVR und die
oder bin ich falsch
gruß

von ... .. (docean) Benutzerseite


Lesenswert?

ich würde mal AVR --- Pegelwnadler --- Cam testen...

Oder hab ich den Fall übersehen?

Weil die CAM kann ja einfach so an den PC und der macht +/-12V...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.