(STK300 / ATmega103)
nun ist es endlich soweit. ich beschäftige mich mit meinem A/D-Wandler,
und bin schon auf eine Menge Fragen gestoßen, von denen ich jetzt ein
paar loslassen will.
ich habe meinen luftsensor an die AREF-spannung des A/D-Ports
angeschlossen, und gemessen. 4,33V.
der ausgang meines sensors gibt mir 3,87V. Diesen Ausgang habe ich an
einen der A/D Wandler geschlossen.
Die Masse vom Sensor habe ich an die Masse des STK300 geschlossen.
Im Programm lese ich mein ADCH und ADCL aus.
multipliziere diesen wert mit 4,33.
und dividiere das ganze durch 1024.
und raus bekomme ich 3,57V.
da 3,87 nicht gleich 3,57 ist, hab ich mir gedacht, da läuft irgend
etwas falsch.
hier mein programmcode. ich hoffe jemand kann mir weiterhelfen.
--------------------------------------------------------
#include <mega103.h>
#include <stdio.h>
#include <delay.h>
#include <delay.h>
#include <stdlib.h>
unsigned int adc_data;
unsigned int a;
float b;
char s[6];
// ADC interrupt service routine
#pragma savereg-
interrupt [ADC_INT] void adc_isr(void)
{
printf("interrupt\n\r");
#asm
push r30
push r31
#endasm
// Read the AD conversion result
adc_data=ADCW;
#asm
pop r31
pop r30
#endasm
ADCSR|=0x40;
delay_ms(10);
a=ADCH;
a=a<<8;
delay_ms(10);
a=a | ADCL;
a*=4,33;
b= a/1024.0;
printf("%f\n\r",b);
ftoa(b,3,s);
puts(s);
putchar('\n');
putchar('\r');
getchar();
}
#pragma savereg+
// Read the AD conversion result
// with noise canceling
unsigned int read_adc(unsigned char adc_input)
{
printf("read_adc\n\r");
ADMUX=adc_input;
ADCSR&=0x7f;
ADCSR|=0xc0;
#asm
in r30,mcucr
cbr r30,__sm_mask
sbr r30,__se_bit
out mcucr,r30
sleep
cbr r30,__se_bit
out mcucr,r30
#endasm
return adc_data;
}
unsigned char k;
void main(void)
{
// UART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// UART Receiver: On
// UART Transmitter: On
// UART Baud rate: 9600
UCR=0x18;
UBRR=0x19;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
// ADC initialization
// ADC Clock frequency: 125,000 kHz
ADCSR=0x8D;
#asm("sei")
while (1)
{
read_adc(0);
}
}
--------------------------------------------------------
Hallo! Was ist dann denn für ein C-Compiler? Ich überlege gerade, ob "a = a | ADCL" ein ODER sein soll (kenne nur || für ODER). Aber wenn der Compiler es schon möglich macht, 10 Bit-Werte zu dividieren (1024), dann könntest du den gesamten 16Bit-Wert (bzw. 10 Bit) aus ADCH und ADCL deiner Variable a zuordnen und weiterrechnen. Wäre das nicht einfacher?
"ich habe meinen luftsensor an die AREF-spannung des A/D-Ports angeschlossen, und gemessen. 4,33V" Kannst du deinen Schaltplan mal näher erläutern?
@infiniter: | ist bitweises OR, d.h. die Bits werden einzeln verknüpft, während bei || nur 0 oder 1 rauskommen kann. http://web.cs.mun.ca/~michael/c/op.html
CodeVisionAVR verwende ich. übrigens danke für den Link Andreas. mir ist gerade noch eine andere möglichkeit meiner schaltung eingefallen, ich werde die heute erstmal ausprobieren, und mich dann nochmal melden.
es funktioniert.
ich erklärs mal, falls ein anderer mal nen luftdrucksensor an ein STK300
anschliesen möchte.
Versorgungspannung von 5V hab ich vom LCD-displayanschluss genommen. ich
wollts erst von einen Portausgang nehmen, aber da brach die spannung
immer zusammen. ich weiss aber nicht warum. vielleicht kann mir da ja
jemand weiterhelfen.
den ausgang des sensors hab ich an Pin1 vom analogport angeschlossen.
die spannung vom LCDdisplayausgang muss man zusätzlich noch an AREF
anlegen, da das maximale AREF vom STK ansonsten über einen drehknopf
einstellbar ist, der aber bei maximum nicht auf 5V kommt, zumindest be
mir nicht. die Referenzspannung muss aber gleich der eingangsspannung am
Sensor sein.
dann folgendes programm, und fertig.
----------------------------------------------------------
#include <mega103.h>
#include <stdio.h>
#include <delay.h>
#include <stdlib.h>
unsigned int adc_data;
int Vmess;
float b;
char s[6];
// ADC interrupt service routine
#pragma savereg-
interrupt [ADC_INT] void adc_isr(void)
{
printf("interrupt\n\r");
#asm
push r30
push r31
#endasm
// Read the AD conversion result
adc_data=ADCW;
#asm
pop r31
pop r30
#endasm
}
#pragma savereg+
// Read the AD conversion result
// with noise canceling
unsigned int read_adc(unsigned char adc_input)
{
printf("read_adc\n\r");
ADMUX=adc_input;
ADCSR&=0x7f;
ADCSR|=0xc0;
#asm
in r30,mcucr
cbr r30,__sm_mask
sbr r30,__se_bit
out mcucr,r30
sleep
cbr r30,__se_bit
out mcucr,r30
#endasm
return adc_data;
}
void main(void)
{
// UART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// UART Receiver: On
// UART Transmitter: On
// UART Baud rate: 9600
UCR=0x18;
UBRR=0x19;
#asm("sei")
while (1)
{
if (PIND.0==0)
{
ADCSR|=0x40; //Bei High im 6. Bit wird Conversation
gestartet
Vmess=read_adc(0b00000001); //wert aus ADCL und ADCH an Pin1
auslesen
delay_ms(10);
printf ("%7d",Vmess);
delay_ms(10);
Vmess*=5;
b= Vmess/1023.0;
printf("%f\n\r",b);
ftoa(b,3,s);
puts(s);
putchar('\n');
putchar('\r');
delay_ms(400);
}
}
}
----------------------------------------------------------
ich muss trotzdem nocheinmal nachfragen.
warum kann ich den sensor nicht mit 5V von irgendeinem PortPin
betreiben?
warum fällt die spannung da zusammen?
ich wollte nun weiter arbeiten. hab das programm nicht verändert, aber es geht nicht mehr. es hat auch nichts mit dem problem zu tun, was ich hier auch gerade gepostet habe, da ich der chip manchmal doch richtig programieren lässt. ich hab herrausgefunden, dß es an folgender stelle klemmt. und zwar bleibt er in der praxis irgendwo in diesem codestück hängen. im AVR-studio geht er zwar durch, setzt aber das ADIF-Bit im ADCSR-register nicht, welches ja den interrupt auslösen soll, der ADCH und ADCL beschreibt. ------------------------------ #asm in r30,mcucr cbr r30,__sm_mask sbr r30,__se_bit out mcucr,r30 sleep cbr r30,__se_bit out mcucr,r30 #endasm ------------------------------ mein assembler ist leider zu schlecht, als ob ich hier einen fehler bemerken könnte. dazu sei noch gesagt, daß dieser programmteil vom codewizard geschrieben wurde. und wie gesagt vorher funktionierte. ich kapiers einfach nicht.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.