Čau,
snažím se přes ADC měřit teplotu pořád se mi nedaří, program je v C. Potřeboval by jsem poradit jestli má někdo zkušenost nejlépe krátký příklad, díky.
Fórum › Mikrokontroléry
LM35 Atmega88
A co se nedari?
zprovoznit ADC?
int zmerit_adc(char kanal)
{
ADMUX=kanal | (1<<REFS0); //ad prevodnik vref=avcc a kondikem na aref pinu
char adcpomocna=50; //cekani na prepnuti MUXu, hodnota muze byt i mensi, treba otestovat
while(adcpomocna--);
sbi(ADCSRA,ADSC); //start mereni
while (!(ADCSRA & 16)); //cekani na konec mereni
return ADC;
}
void ADC_init()
{
ADCSRA=128; //zapnuti ad prevodniku
}//init adc
rozsah prevodniku je 0-1023, je treba si to potom prepocitat na pozadnovane hodnoty
A o jaky prekladac se jedna?
Avr studio + winavr tohle urcite zna
nechybi nahodou jako prvni vec ve zdrojaku napsat
#include <avr/io.h>
to co jsem napsal je jenom rutina pro nastaveni a obsluhu AD prevodniku
vic nic
zbytek programu chybi
jeste dodam ze fyzicky rozsah AD je 0-5V
Čau, zkoušel jsem podle návodu tento program, vždy se napíše na LCD jedno číslo a pak to zatuhne. Rád by jsem poprosil pokud budete mít někdo čas se na to podívat. Mám mezi AREF a GND kondenzátor 100nF. AVCC na VCC 5V. LM335 na ADC0.
Nerozumím řádce "return ADCW; "
par dotazu
1) proc nastavujes port C jako vystupni, kdyz potrebujes aby minimalne pin na kterem je LM35 byl vstupni
2) proc nastavujes ze mas referencni napeti na Aref, kdyz na nem mas jenom kondik, tedy 0V
3) return ADCW = vratit hodnotu obsahu registru ADCW
4) proc kdyz pouzivas float, pouzivas pro odeslani na lcd funkci ITOA
5) na avr neni dobre pouzivat float, je to pomale - osobni zkusenost, lepsi je pouzivat treba 32bit int a desetinne mista mit treba jako jednotky a desitky, priklad 3,14 zapsat jako 314, ale pri zobrazovani pamatovat na to ze pred poslednimi 2 misty je treba udelat desetinny znak
6) init portu D je zrejme zbytecny, predpokladam ze se to provadi v modulu LCD.h
Zdravím,
opravil jsem zapojení i program a pořád to nešlape. Mám momentálně AREF=AVCC=5V. LM335 stále na PC0. opravil jsem program,rád bych poprosil o projití programu.
#include <mega88.h>
#include <io.h>
#include <delay.h>
#include <lcd.h>
#include <stdlib.h>
#include <stdio.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x0B ;PORTD
#endasm
unsigned char pom[12];
unsigned int read_adc(unsigned char kanal)
{
ADMUX = kanal;
ADCSRA |= 0x40; // Nastavením ADSC v registru ADCSRA spouštění převodu
while ((ADCSRA & 0x10)==0); //ADIF – konec převodu.
ADCSRA |= 0x10;
return ADCW;
}
int main(void)
{
unsigned int vysledek;
unsigned char kanal = 0;
unsigned int realne;
PORTC = 0x00;
DDRC = 0x00;
ADMUX = 0x40;
ADCSRA = 0x80;
lcd_init(16);
while (1)
{
vysledek = read_adc(kanal);
realne = 5.03 / 1023;
realne = realne * vysledek;
vysledek = realne * 100;
lcd_gotoxy(3,0);
itoa(vysledek,pom);
lcd_puts(pom);
if (kanal) kanal = 0; else kanal = 1;
}
}
Ahoj,
Zkus toto:
Pin AVCC je na +5V.
Na pinu AREF je jen kond proti zemi !!
#include <mega88.h>
#include <stdlib.h>
#include <lcd.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x0B ;PORTD
#endasm
//definice I/O bitů
#define REFS0 6
#define ADSC 6
#define ADEN 7
#define ADPS2 2
#define ADPS1 1
#define ADPS0 0
#define REF (1<<REFS0) // REFS1=0 REFS0=1 => Reference = AVCC
#define Uref 5000 // referenční napětí 5000 mV (přesnou hodnotu změřit na pinu AREF)
//-----------------------------------------------------------------------------
unsigned int read_adc(unsigned char kanal)
{
ADMUX = REF | kanal;
ADCSRA |= (1<<ADSC); // start převodu
while (ADCSRA & (1<<ADSC)); // čekej na konec převodu.
return ADCW;
}
//-----------------------------------------------------------------------------
main(void)
{
unsigned long adc_value, napeti0, napeti1;
static char tempstr[10];
//Init Ports
PORTC = 0x00;
DDRC = 0x00;
//Init ADC
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // zapni ADC ; předdělič 128
//Init LCD
lcd_init(16);
while (1)
{
adc_value = read_adc(0);
napeti0 = (adc_value * Uref) / 1024; // napětí v mV
adc_value = read_adc(1);
napeti1 = (adc_value * Uref) / 1024; // napětí v mV
itoa(napeti0,tempstr);
lcd_gotoxy(3,0);
lcd_puts(tempstr);
delay_ms(500);
}
}
jak napsal AB
to ze si nekde priradim do ADMUX ze mam zapnout referencni napeti na AVCC jeste neznamena ze tam ta hodnota bude porad.
Proto je chybou napsat
ADMUX=kanal
, protoze kanal obsahuje cislo od 1 do 8 (vynechavam specialni pripady), coz jsou prvni 3 bity
Datasheet nam rika ze v dalsich 5 bitech jsou ulozeny informace zrovna o zdroji referencniho napeti
tedy musim napsat
ADMUX = kanal or nastaveni referencniho napeti, tedy ADMUX = 64 + kanal
napsano "normalni" logikou, jinak je samozrejme vyhodnejsi pouzit logicky soucet OR
ale tohle bude fungovat taky
jeste k prikladu AB
viz muj http://programujte.com/?akce=diskuze&kam=vlakno&tema=16631-m8-a-2-kanaly-z-adc-ovlivnujou-se kde jsem psal, ze mezi zapsanim hodnoty do ADMUX a spustenim mereni je potreba pockat na to, nez se mux prepne. V mem pripade se stavalo ze se hodnota z ADC dostavala jakoby do druheho kanalu
Děkuji za radu, zkusím podle návodu. Včera jsem ještě zkoušel různé nastavení ve starém programu při AREF=AVCC=5V. chvilku to pracovalo něco jsem měřil potom ADC přestal pracovat. Napájení je stéle 5V používám z USB počítače a napětí jsem měřil na LM335 (vždy menší než 5V) tak snad jsem nezničil ADC na procesoru.
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Časovač Atmega88 — založil ZdeněkAVR
Atmega88 regulace otáček střídavého motoru — založil ZdeněkAVR
Moderátoři diskuze