Witam
Piszę w C, WinAVR, pony prog, STK 200
Zwracam się do was z prośbą o pomoc w rozwiązaniu problemu, wziąłem się za programowanie i w ramach nauki, zapoznania się z AVR obmyśliłem popełnienie takiego czegoś:
Docelowo:
- pomiar temperatury - 3 czujniki lm 35
- wysterowanie 3 wentylatorów PWM
- sterowanie automatyczne i ręczne(przyciski)
- wyświetlanie LED albo LCD
Schemat ideowy: SCHEMAT
Od strony fizycznej raczej jest ok, chociaż podłączenie nie do końca mi wyszło, dałem pod pint które zostały wolne, jak inaczej można to rozwiązać?
W czym problem
Po zabawie diodami, multipleksowaniem LED, udało mi się uruchomić ADC.Na chwilę obecną nie posiadam LCD więc wyświetlam na dwóch segmentach. Na początek zrobiłem termometr.
LM35 >> 10mV/°C
Robię konwersję w odniesieniu do VREF = 2560 mV
Np. Dla 23 stopni dosteje 230 mV, po konwersji mamy wartość 92
Przeliczam ją spowrotem na mV czyli 92*2.5= 230
Teraz to wartość rozbijam na stopnie czyli, 230/100=2 , oraz 230%100=3
jednak po kompilacji wyświetla nie to co powinno.. poprawnie jest gdy dziele przez 10 i nie mam pojęcia dlaczego, będę wdzięczny za wyjaśnienie tego zjawiska..
Mile widziane wszelkie uwagi do kodu, dopiero się uczę, więc krytyka mile widziana.
KOD:
Piszę w C, WinAVR, pony prog, STK 200
Zwracam się do was z prośbą o pomoc w rozwiązaniu problemu, wziąłem się za programowanie i w ramach nauki, zapoznania się z AVR obmyśliłem popełnienie takiego czegoś:
Docelowo:
- pomiar temperatury - 3 czujniki lm 35
- wysterowanie 3 wentylatorów PWM
- sterowanie automatyczne i ręczne(przyciski)
- wyświetlanie LED albo LCD
Schemat ideowy: SCHEMAT
Od strony fizycznej raczej jest ok, chociaż podłączenie nie do końca mi wyszło, dałem pod pint które zostały wolne, jak inaczej można to rozwiązać?
W czym problem
Po zabawie diodami, multipleksowaniem LED, udało mi się uruchomić ADC.Na chwilę obecną nie posiadam LCD więc wyświetlam na dwóch segmentach. Na początek zrobiłem termometr.
LM35 >> 10mV/°C
Robię konwersję w odniesieniu do VREF = 2560 mV
Np. Dla 23 stopni dosteje 230 mV, po konwersji mamy wartość 92
Przeliczam ją spowrotem na mV czyli 92*2.5= 230
Teraz to wartość rozbijam na stopnie czyli, 230/100=2 , oraz 230%100=3
jednak po kompilacji wyświetla nie to co powinno.. poprawnie jest gdy dziele przez 10 i nie mam pojęcia dlaczego, będę wdzięczny za wyjaśnienie tego zjawiska..
Mile widziane wszelkie uwagi do kodu, dopiero się uczę, więc krytyka mile widziana.
KOD:
/* układ ATmega 1MHz */
#define F_CPU 1000000L // taktowenie wewnetrznym MHz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/sfr_defs.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <stdlib.h>
#include <math.h>
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) // makra clear bit i set bit
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define VREF 2560
int x,y,j; // zmienne potrzebne do wyswietlenia x segment 1(jednosci)
// y segment 2 (dziesiatki)
double temp1,tempw; // do zapisu temperatury z ADC
float k;
void Inicjalizacja(void) //funkcja inicjalizacji przetwornika ADC
{
// Wybranie wewnętrznego żródła napięcia odniesienia
sbi(ADMUX,REFS0); //wew 2,56 z C do GND //ADMUX |= _BV(REFS0);
sbi(ADMUX,REFS1); //ADMUX |= _BV(REFS1);
// Zezwolenie na konwersję
sbi(ADCSRA,ADEN); // wlaczenie ADC //ADCSRA |= _BV(ADEN);
// Wybranie częstotliwości dla taktowania przetwornika (1/8 częstotliwosci zegara kontrolera)
sbi(ADCSRA,ADPS0); //ADCSRA |= _BV(ADPS0);
sbi(ADCSRA,ADPS1); // 1Mhz / 8 = 125 Khz //ADCSRA |= _BV(ADPS1);
}
double pomiar(void) //funkcja dokonująca pomiaru
{
//wybor pinu //ADC3
sbi(ADMUX,MUX0);
sbi(ADMUX,MUX1);
//sbi(ADMUX,MUX2);
//sbi(ADMUX,MUX2);
//
int i;
temp1=0;
for(i=0;i<10;i++) //petla pomiarowa
{
sbi(ADCSRA,ADSC); // Rozpoczęcie przetwarzania // ADCSRA |= _BV(ADSC);
while(bit_is_set(ADCSRA,ADSC)) // Oczekiwanie na zakończenie przetwarzania
{};
temp1=(double)ADCW; // Zapisanie wyniku konwersji do zmiennej
// _delay_ms(1);
}
temp1=temp1/10; //wyliczenie sredniej wartosci
return temp1;
}
/*
---A----
| |
| |
F B
| |
| |
|---G----|
| |
| |
E C
| |
| |
---D----
*/
void led7(int i) // funkcja do zapalania kolejnych segmentow w zaleznosci od cyfry
{ // dla kazdej cyfry kolejno ustawione odpowiednie bity na porcie D
#define A 0 // A odpowiada 0 itd...
#define B 1
#define C 2
#define D 3
#define E 4
#define F 5
#define G 6
if(i==0)
{PORTD &= ~_BV(A) &~_BV(B) &~_BV(C) &~_BV(D) &~_BV(E) &~_BV(F); //0
}
if(i==1)
{PORTD &= ~_BV(B) &~_BV(C); //1
}
if(i==2)
{PORTD &= ~_BV(A) &~_BV(B) &~_BV(D) &~_BV(E) &~_BV(G); //2
}
if(i==3)
{PORTD &= ~_BV(A) &~_BV(B) &~_BV(C) &~_BV(D) &~_BV(G); //3
}
if(i==4)
{PORTD &= ~_BV(B) &~_BV(C) &~_BV(F) &~_BV(G); //4
}
if(i==5)
{PORTD &= ~_BV(A) &~_BV(C) &~_BV(D) &~_BV(F) &~_BV(G); //5
}
if(i==6)
{PORTD &= ~_BV(A) &~_BV(C) &~_BV(D) &~_BV(E) &~_BV(F) &~_BV(G); //6
}
if(i==7)
{PORTD &= ~_BV(A) &~_BV(B) &~_BV(C); //7
}
if(i==8)
{PORTD &= ~_BV(A) &~_BV(B) &~_BV(C) &~_BV(D) &~_BV(E) &~_BV(F) &~_BV(G); //8
}
if(i==9)
{PORTD &= ~_BV(A) &~_BV(B) &~_BV(C) &~_BV(D) &~_BV(F) &~_BV(G); //9
}
} // koniec led7
int main(void) // główna funkcja
{
// DDRx // 1 wyjscie --- 0 wejscie
// DDRB |= _BV(0)|_BV(1);
// DDRC =0x00; // port c jako wejscie
// PORTB =3;
// PORTC =0xFF; // likwidacja smieci na porcie
DDRC =0b00010000; // wejscie na przycisk PC5 // uPC --> switch --> GND
//PORTC =0xFF;
DDRD =0xFF; // wyjscia dla segmentu porty PD0 - PD6 // PD7 tranzystor zalaczajacy caly segment 1
PORTD =0xFF; // ustawienie 1
k=2.5;
Inicjalizacja();
while (1) /**********************************/
{
//if(bit_is_clear(PINC,5))a=1;
//if(bit_is_set(PINC,5))a=0;
tempw=pomiar();
//tempw=tempw*VREF;
//tempw=tempw/1024;
tempw=tempw*k;
y=tempw/10;
x=(int)tempw%10;
/*WYSWIETLANIE POCZATEK*/
for(j=0;j<500;j++)
{
// taki sposob zapisu jak ponizej po testach wykazal ze nie ma efektu
// poswiaty poprzedniej wartosci
_delay_ms(2);
PORTD =0xFF; // wyzerowanie portu D - zgaszenie wszystkich lini
sbi(PORTC,4); //zgaszenie segmentu 2
led7(x);
cbi(PORTD,7); // zapalenie segment 1
_delay_ms(2);
PORTD =0xFF;
sbi(PORTD,7); ///zgaszenie segmentu 1
led7(y);
cbi(PORTC,4); // zapalenie segment 2
}
/*WYSWIETLANIE KONIEC*/
}/*****************************************/
} // koniec main