www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik StartUp atmega8 und AVR-Studio


Autor: Martin K. (seesharp1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich bein leider ein ziemlicher Neuling in der 
Mirkocontroller-Programmierung. Ich habe einen atmega8 via 
USB-Schnittstelle zur Verfügung und als Entwicklungsumgebung das 
AVR-Studio.

Ich möchte über den Mikrocontroller mit den ADC 2 Spannungen auslesen 
und die Daten an MATLAB senden bzw. auch über den Mirkocontroller 
Ausgangssignale senden.
Für das auslesen habe ich schon im Tutorial hier im Forum etwas gefunden 
:)
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Leider sind die Punkte senden an MATLAB und senden über den 
Mikrocontroller noch hoffen :(. Kann mir da jemand weiterhelfen?

MFG
Martin

Autor: Kevin K. (nemon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klar können wir dir helfen:

1) lies dich in die Materie ein, dann verstehst du sie auch!

2) schick die Daten erstmal über einen UART mit einem FT232 dran. Der 
erscheint als virtuelle serielle Schnittstelle auf dem PC und die kann 
Matlab sehr einfach ansprechen.

Autor: Martin K. (seesharp1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Info, ich werde mich einlesen. Leider ist mir ein Detail 
bezüglich den ADC noch nicht klar und zwar wie erkennt man die Zuordnung 
der einzelnen Kanäle? Sprich wie stelle ich die Beziehung zur Hexzahl 
"0x1F" da?

Autor: Harald M. (mare_crisium)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin,

wenn Dein PC eine RS232-Schnittstelle hat, dann kannst Du die Daten 
direkt (ohne FT232) über die zweite RS232 ("RS232 spare") am STK500 
übertragen, die Sache ist im Begleitheft zum STK500 auf Seite 3-5 
beschrieben. Muster für die Programme, die Du dazu brauchst, gibt's hier 
im Mikrocontroller.net aber auch im Netz. Ich glaube, es wäre gut, wenn 
Du erstmal diese Verbindung ans Laufen kriegst. Damit kannst Du Dir 
nämlich die Registerinhalte des ATmega am Bildschirm angucken; das hilft 
ungemein beim Fehlersuchen und beim Verstehen des Chips ;-).

Bei der Beschäftigung mit so einem MC ist das Datenblatt Deine "Bibel". 
Die Datenblätter von Atmel sind ziemlich gut. Ich habe bisher noch alle 
meine Fragen darin beantwortet gefunden.

mare_crisium

Autor: Thomas Forster (igel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Leider ist mir ein Detail bezüglich den ADC noch nicht klar und zwar wie
> erkennt man die Zuordnung der einzelnen Kanäle?

Du sagst dem ADC vorher , welchen Kanal er als nächstes wandeln soll. 
Dazu dient das Register ADMUX.

Autor: Martin K. (seesharp1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen dank für die Hilfestellungen. Mittlerweile ist es so, dass ich 
ADC auslesen kann und die Kommunikation mit MATLAB (in beide Richtungen) 
steht :-).
Leider bin ich jetzt auf das nächste Problem gestoßen. Denn ich möchte 
mir einen Timer machen, der mir z.B. jede Sekunde (wird dann später 
natürlich kleiner gewählt) meine Spannung ausliest.
Für den Anfang hätte ich einfach mal versucht einen Conuter zu basteln 
der jede Sekunde erhöht wird und dann in meiner MATLAB-Gui ausgegeben 
wird. Leider bekomme ich immer eine Zeitverzögerung rein :(.

Ich hätte hier anschliessend noch meinen Code gepostet, mir ist klar, 
dass es nicht so lustig ist fremden Code durch zu schauen. Aber 
vielleicht ist ja jemand so nett. Ich sitze schon seit Anfang Nachmittag 
an diesem Problem und es geht nicht wirklich was weiter.
#include <avr/io.h>

#ifndef F_CPU
#warning "F_CPU was not defined"
#define F_CPU 18432000UL
#endif


#include <util/delay.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#define BAUD 115200
#define UART_BUFFER_SIZE 3

#define IRQS_PER_SECOND   0.2

#include <util/setbaud.h>

/*=============================================================================
        GLOBAL VARIABLES
=============================================================================*/

volatile char uart_buffer[UART_BUFFER_SIZE]={'v', 'v', 'v'};
volatile int8_t  uart_count  = 0;
//Variablen für die Zeit
volatile unsigned int  millisekunden;
volatile unsigned int sekunde;
volatile unsigned int minute;
volatile unsigned int stunde;



/*=============================================================================
        SUBROUTINES
=============================================================================*/

void uart_putc(char c)
//send single character
{
    while (!(UCSRA & (1<<UDRE)));
    UDR = c;
}

void uart_puti8(uint8_t c)
//send 8 bit unsigned integer
{
    while (!(UCSRA & (1<<UDRE)));
    UDR = c;
}

void uart_puti16(int16_t c)
// send 16bit signed integer
{
    while (!(UCSRA & (1<<UDRE)));
    UDR = c;                //lowbyte
    while (!(UCSRA & (1<<UDRE)));
    UDR = (c >> 8);              //highbyte
}

void uart_puts(char *data)
//send stiring via usart
{
    while(*data)
    {
        uart_putc(*data);
        data++;
    }
}

void uart_puti(int16_t value)
//send integer as sting
{
    char s[5];

    sprintf(s,"%u",value);
    uart_puts(s);
}

inline void uart_init(void)
//initailize uart communication
{
    //set baudrate
  

  UBRRH    = UBRRH_VALUE;
    UBRRL    = UBRRL_VALUE;

  #if USE_2X
    UCSRA |= (1<<U2X);
  #else
    UCSRA &= ~(1<<U2X);
  #endif

    UCSRB |= (1<<RXCIE) | (1<<TXEN) | (1<<RXEN);    //enable transmit, receive, interrupt
    UCSRC |= (1<< URSEL) | (1<<UCSZ1) | (1<<UCSZ0);    //8N1

    sei();                        //global interrupt enable

    //send welcomestring 36 chars
    _delay_ms(10);
    uart_puts("currentbox - initialisation complete");
}



/* ADC initialisieren */
void ADC_Init_saxi(void) {
 
  uint16_t result;
 
//  ADMUX = (0<<REFS1) | (1<<REFS0);      // AVcc als Referenz benutzen
  ADMUX = (0<<REFS1) | (0<<REFS0);      // externe Referenzspannung nutzen
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
  ADCSRA |= (1<<ADEN);                  // ADC aktivieren
 
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
 
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
  while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
     Wandlung nicht übernommen. */
  result = ADCW;
}
 
/* ADC Einzelmessung */
uint16_t ADC_Read_saxi( uint8_t channel )
{
  // Kanal waehlen, ohne andere Bits zu beeinflußen
  if (channel == 1) {
    ADMUX = (ADMUX & ~(0x1F)) | 0x00; // alle Kanäle rücksetzen und gewünschten Kanal dazu odern;
  } else if (channel == 2) {
    ADMUX = (ADMUX & ~(0x1F)) | 0x01;
  }
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
  while (ADCSRA & (1<<ADSC) ) {}  // auf Abschluss der Konvertierung warten
  return ADCW;                    // ADC auslesen und zurückgeben
}
 
 
/* Beispielaufrufe: */
 
int main()
{
  uint16_t adcvals, adcvalc;
  //float uref = 5.2; // Spannungsversorgung usb Schnittstelle
  //float us = 0; 
  //float uc = 0; 
  uint8_t state = 0;





  ADC_Init_saxi();
  uart_init();   // Kommunikation mit Matlab

  DDRB=0xFF;

  // Timer 1 konfigurieren
  TCCR1A = 0; // CTC Modus

  #if defined (CTC1) && !defined (WGM12)
   TCCR1B = (1 << CTC1)  | (1 << CS10) | (1 << CS12);
  #elif !defined (CTC1) && defined (WGM12)
   TCCR1B = (1 << WGM12) | (1 << CS10) | (1 << CS12);
  #else
  #error Keine Ahnung, wie Timer1 fuer diesen AVR zu initialisieren ist!
  #endif


  OCR1A = (unsigned short) ((unsigned long) F_CPU / (1024*IRQS_PER_SECOND)-1);

  #if defined (TIMSK1)
    TIMSK1 |= (1 << OCIE1A);
  #elif defined (TIMSK)
    TIMSK  |= (1 << OCIE1A);
  #else   
  #error Keine Ahnung, wie IRQs fuer diesen AVR zu initialisieren sind!
  #endif

 



  // Compare Interrupt erlauben
  //TIMSK |= (1<<OCIE1A);
 
  // Global Interrupts aktivieren
  sei();

 
  while( 1 ) {
    switch(state)
  {
  case 0:
    if(uart_count!=0)
    {
      if(uart_buffer[0]=='t')
      {
        state = 1;
      }
      else if(uart_buffer[0]=='u')
      {
        state = 2;
      }
      if(uart_buffer[0] =='s')
        state = 3;
    }
    break;
  case 1:
    adcvals = ADC_Read_saxi(1);  // Kanal 0
    uart_puti16(adcvals);
    uart_buffer[0]=uart_buffer[1];
    uart_buffer[1]=uart_buffer[2];
    uart_count--;
    state = 0;
    break;
  case 2:
    adcvalc = ADC_Read_saxi(2);  // Kanal 1
    uart_puti16(adcvalc);
    uart_buffer[0]=uart_buffer[1];
    uart_buffer[1]=uart_buffer[2];
    uart_count--;
    state = 0;
    break;
  case 3:
    uart_puti16(sekunde);
    uart_buffer[0]=uart_buffer[1];
    uart_buffer[1]=uart_buffer[2];
    uart_count--;
    state = 0;
    break;
  default:
    state = 0;
    uart_count = 0;
    break;
  }//switch
    

  }//while 
} 

/*=============================================================================
        INTERRUPT SERVICE ROUTINES
=============================================================================*/

ISR(USART_RXC_vect)            // isr for usart receive
{
    if (uart_count < UART_BUFFER_SIZE) uart_buffer[uart_count] = UDR;  //protect overwriting/overflow
    uart_count++;
}


ISR (TIMER1_COMPA_vect)
{
  millisekunden= millisekunden+1000;
  if(millisekunden == 1000)
  {
    sekunde++;
    millisekunden = 0;
    if(sekunde == 60)
    {
      minute++;
      sekunde = 0;
    }
    if(minute == 60)
    {
      stunde++;
      minute = 0;
    }
    if(stunde == 24)
    {
      stunde = 0;
    }
  }
} 


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.