Witam,
jestem początkujący jeżeli chodzi o programowanie mikrokontrolerów, więc poniższy kod nie jest przepiękny. Proszę o poprawę...
Główny problem:
układzik jest to dalmierz ultradźwiękowy uzyskujący spory zasięg. Jednak by mógł też mierzyć odległość przedmiotów blisko umieszczonych muszę przełączać próg komparatora atmegi. Robię to za pomocą portu B5 i dodatkowego układu podłączonego do niego. Dodatkowo zmniejszam czas strefy martwej(opóźnienie).
Każdy pomiar jest wykonywany po przyciśnięciu przycisku i wyświetlany na wyświetlaczu. Pobierana też jest temperatura, ale jeszcze nie wpływa na dokładność odległości.
Układ działa dobrze, dopóki nie przełączę portu B5. Gdy to zrobię, układ zamiast zrobić 2 pomiary(1 dalekosiężny i drugi już bliski) robi ich duuużo, aż atmega się zawiesza(sprawdzałem na oscyloskopie). Podejrzewam, że to jakiś problem z komparatorem, ale na moim stopniu zaawansowania to mogą to być też inne problemy.
Bardzo proszę o pomoc i poprawę kodu.
jestem początkujący jeżeli chodzi o programowanie mikrokontrolerów, więc poniższy kod nie jest przepiękny. Proszę o poprawę...
Główny problem:
układzik jest to dalmierz ultradźwiękowy uzyskujący spory zasięg. Jednak by mógł też mierzyć odległość przedmiotów blisko umieszczonych muszę przełączać próg komparatora atmegi. Robię to za pomocą portu B5 i dodatkowego układu podłączonego do niego. Dodatkowo zmniejszam czas strefy martwej(opóźnienie).
Każdy pomiar jest wykonywany po przyciśnięciu przycisku i wyświetlany na wyświetlaczu. Pobierana też jest temperatura, ale jeszcze nie wpływa na dokładność odległości.
Układ działa dobrze, dopóki nie przełączę portu B5. Gdy to zrobię, układ zamiast zrobić 2 pomiary(1 dalekosiężny i drugi już bliski) robi ich duuużo, aż atmega się zawiesza(sprawdzałem na oscyloskopie). Podejrzewam, że to jakiś problem z komparatorem, ale na moim stopniu zaawansowania to mogą to być też inne problemy.
Bardzo proszę o pomoc i poprawę kodu.
#include <avr/io.h> // dostęp do rejestrów
#include <avr/interrupt.h> // funkcje sei(), cli()
#include <avr/signal.h> // definicje SIGNAL, INTERRUPT
#include <util/delay.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include "lcd.h"
#define DDR_GEN DDRB
#define PORT_GEN PORTB
#define PORT_GEN_PIN 3
#define KOMPARATOR_ON ACSR |= _BV(ACIS1) | _BV(ACIS0) | _BV(ACIE);
#define KOMPARATOR_OFF ACSR |= _BV(ACD);
#define ZASIEG_MAX 16000
#define ZASIEG_MIN 900
volatile int opoznienie;
volatile int czas=0;
volatile int value;
volatile long pomiar;
int flag=3;
void za_daleko(void){
cli();
KOMPARATOR_OFF;
TCCR2=0;
lcd_init(LCD_DISP_ON);
lcd_clrscr();
lcd_puts("Obiekt jest poza\nzasiegiem");
}
void wynik_pomiaru(void){
float odl;
char buffer[7];
lcd_init(LCD_DISP_ON);
lcd_clrscr();
odl=0.017*(opoznienie+12.5*czas);
if(odl<(0.017*opoznienie)+1){
if(flag==2){
lcd_puts("Obiekt jest za\nblisko czujnika");
}else{ flag=1;
flag=2;
opoznienie=10;
PORTB &= !_BV(5);
Pomiar();
}
}else{
lcd_puts("Temp: ");
dtostrf( pomiar ,3,1, buffer);
lcd_puts(buffer);
lcd_putc(0xDF);
lcd_puts("C");
lcd_puts("\nOdl: ");
dtostrf( odl ,3,1, buffer);
lcd_puts(buffer);
lcd_puts(" cm");
}
}
SIGNAL(SIG_COMPARATOR)
{
cli();
KOMPARATOR_OFF;
TCCR2=0;
wynik_pomiaru();
}
ISR(TIMER2_COMP_vect){
czas++;
if(czas>ZASIEG_MAX) za_daleko();
}
void gen40kHz(void){
PORT_GEN |= _BV(PORT_GEN_PIN);
_delay_us(12.5);
PORT_GEN ^= _BV(PORT_GEN_PIN);
_delay_us(12.5);
}
void ping(void){
DDR_GEN |= _BV(PORT_GEN_PIN);
for(int i=0;i<10;i++){
gen40kHz();
}
DDR_GEN &= !_BV(PORT_GEN_PIN);
}
void Timer_init(void){
OCR2=99;
TCCR2 = _BV(WGM21) | _BV(CS20);
TIMSK |= (1 << OCIE2);
}
void Pomiar(void){
cli();
czas=0;
lcd_init(LCD_DISP_OFF);
DDRD |=_BV(PD6);
PORTD&=!_BV(PD6);
DDRD&=!_BV(PD6) ;
ping();
_delay_us(opoznienie);
Timer_init();
ACSR &= !_BV(ACD);
KOMPARATOR_ON;
sei();
}
int main(void)
{
DDRD &= !_BV(6);
PORTD &= !_BV(6);
DDRB &= !_BV(0);
PORTB |= _BV(0);
DDRB |= _BV(4);
PORTB |=_BV(4);
DDRB |=_BV(5);
DDR_GEN |= _BV(PORT_GEN_PIN);
lcd_init(LCD_DISP_ON);
lcd_clrscr();
lcd_puts("Dalmierz BETA\n");
ADMUX |= _BV(REFS0)|_BV(ADLAR)|_BV(MUX1)|_BV(MUX0);
ADCSRA |= _BV(ADEN)| _BV(ADPS0)| _BV(ADPS1);
for(;;){
if(!(PINB & _BV(0))){
flag=0;
ADCSRA |= _BV(ADSC);
while( ADCSRA & _BV(ADSC)) {};
pomiar=ADCH;
pomiar=pomiar*500/256-273.15;
opoznienie=ZASIEG_MIN;
PORTB |= _BV(5);
Pomiar();
while(!(PINB & _BV(0))) {}
_delay_ms(80);
}
}
}