www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ENQ empfang testen


Autor: Penie Lydos (peniely)
Datum:

Bewertung
0 lesenswert
nicht 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.
int main(void)
{
  char kommando; 
  
  // RS232 einschalten ... 
  setup_uart();
  DDRB = 0xFF;
  
  //sendet Anforderung (ENQ)
  uart_putchar('5');    
  kommando = uart_getchar(); 
   
  if (kommando='6')
  {   
     PORTB = 0x0F;
  }
  else
     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

Autor: Jens Krause (jjk) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Penie Lydos (peniely)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke,
jetzt habe ich
 
void uart_putchar(char c)
{
  // Warten bis Buffer bereit ...
  while (!(UCSRA & (1 << UDRE)));
  // Senden...
  UDR = c;
  _delay_ms(10);  
}

char uart_getchar()
{
  // Ist schon ein Zeichen im Buffer?
  while( !(UCSRA & (1<<RXC)) );
   return UDR;  
}

int main(void)
{
  char kommando; 
  
  // RS232 einschalten ... 
  setup_uart();
  DDRB = 0xFF;
  
  //sendet Anforderung (ENQ)
  uart_putchar('E');    
  kommando = uart_getchar(); 
   
  if (kommando='F')   
     PORTB = 0x0F;
  else
     PORTB = 0x55;
  return0;

aber ich kriege immer gar nichst an Portb

gruß

Autor: Jens Krause (jjk) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
//sendet Anforderung (ENQ)
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:
response = uart_getchar(); 
   
if (response == 0x06) {
   // irgendwas machen was eben gemacht werden soll wenn die cam ACK gesendet hat
}


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

Gruß
  Jens

Autor: Penie Lydos (peniely)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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ß
void uart_putchar(char c)
{
  // Warten bis Buffer bereit ...
  while (!(UCSRA & (1 << UDRE)));
  // Senden...
  UDR = c;
  _delay_ms(10);  
}

char uart_getchar()
{
  // Ist schon ein Zeichen im Buffer?
  while( !(UCSRA & (1<<RXC)) );
   return UDR;  
}

int main(void)
{
  char kommando; 
  
  // RS232 einschalten ... 
  setup_uart();
  DDRB = 0xFF;
  
  //sendet Anforderung (ENQ)
  uart_putchar(0x05);    
  kommando = uart_getchar(); 
   
  if (kommando=0x06)   
     PORTB = 0x0F;
  else
     PORTB = 0x55;
  return0;

Autor: Penie Lydos (peniely)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Jens Krause (jjk) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
if (kommando == 0x06)   
     PORTB = 0x0F;
  else
     PORTB = 0x55;

Autor: Penie Lydos (peniely)
Datum:

Bewertung
0 lesenswert
nicht 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
void initall()
{
  setup_uart(); 
  
  //interrupt
  TCNT0 = 5;        //Set Timer/counter
  TIMSK |= (1<<TOIE0);  //Enable Timer/counter0 overflow interrupt
  TCCR0 |= (1<<CS01);
  TCCR0 |= (1<<CS00);  //Select the clock source to be used by the timer/counter --> CPU Takt  --> 4MHz/64 
  TIFR |= (1<<TOV0);  //interrupt starts with each overflow   
}//End initall()


//Interrupt Service Routine 
ISR(TIMER0_OVF_vect) 
{
  ADIteiler++;    //clocks interrupt counter value on each ms 
  if(ADIteiler >= 60)  //Counter cycle for all ms 60
  {
    ADIteiler=0;    //counter 0 set
    DDRB = 0xFF;
    char kommando;
    kommando = uart_getchar(); 
       
    if (kommando == 0x06)
      PORTB = 0x0F;
   else
      PORTB = 0x55;  
 }
}//End ISR(TIMER0_OVF_vect) 

int main(void) 
{
    initall();
  
    //sendet Anforderung (ENQ)
    uart_putchar(0x05);
    sei();
    return 0;                     
} //end main()

gruß
peniely

Autor: Jens Krause (jjk) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Penie Lydos (peniely)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jens Krause (jjk) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?
PC  <---------------->  PC
PC  <--Pegelwandler-->  AVR
AVR <---------------->  Cam
PC  <--Pegelwandler-->  Cam

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

Jens

Autor: Penie Lydos (peniely)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke an alle

>AVR-UART ohne Pegelwandler zum PC geht?
ja ich habe PC <--------AVR----------->PC getestet und ich brauchte 
keine Pegelwandler.
#ifndef F_CPU
/* In the new version of the WinAVR/Mfile Makefile guideline One can defined F_CPU in the Makefile, a repeated 
   definition here would lead to a compiler warning . therefore "prevention" through    #ifndef/#endif

   This "Prevention" can lead to Debugger, if AVRStudio use a another, not the hardware fitting Clock rate: 
   Then the    following definition doesn't use, but instead the default value (1 MHz?) of AVRStudio - hence 
   the Output of a warning if F_CPU yet does not define:*/ 
#warning "F_CPU was not defined yet, now make up with 4000000"
#define F_CPU 4000000L                  // Systemtakt in Hz - define as  long>> Without errors in the computation 
#endif


#define BAUD 9600L
#define UBRR_VAL ((F_CPU+BAUD * 8)/(BAUD*16)-1)     //clever round
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))         //real baud rate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)     //Error per thousand


#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
#error Systematic error in the baud rate more than 1% and thus too high!
#endif


#include <avr/io.h>
#include <stdlib.h>
#include <inttypes.h>
#include <util/delay.h>



void USART_Init(void) 
{
  
  UBRRH = (unsigned char)(UBRR_VAL>>8);      // Set baud rate
  UBRRL = (unsigned char)UBRR_VAL;
  
  UCSRB |= (1<<RXEN)|(1<<TXEN);          // Enable receiver and transmitter
  
  UCSRC = (1<<URSEL) | (1<<UCSZ0)|(1<<UCSZ1);  // Set frame format: 8data, 1stop bit        
}//end USART_Init()


void USART_Putc(unsigned char c)
{
    while (!(UCSRA & (1<<UDRE))); // Do nothing until data have been transmited 
    
  UDR = c;                      // Put data into Buffer, sends the data
  _delay_ms(10);   
}//end USART_Putc()


void USART_Puts (char *string)
{
    while( *string != '\0' )  //as long as *string != '\0' so unlike the "stringer end-character"
    {  
        USART_Putc(*string);
        string++;
    }
}//end USART_Puts()


unsigned char USART_Receive()
{

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

Autor: Penie Lydos (peniely)
Datum:

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

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.