Думал, что с написанием проги не возникнут проблема, но...
Небось прерывания - штуки капризные.
Вот наваял такой код:
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
#include <util/delay.h>
#define iter 64000UL // переполнение = 8 мс
#define HI(x) ((x)>>8)
#define LO(x) ((x)&0xFF)
// a f b e d dp c g
// 0 1 2 3 4 5 6 7 8 9 .
volatile unsigned char codes[] = {0xFA,0x22,0xB9,0xAB,0x63,0xCB,0xDB,0xA2,0xFB,0xEB,0x04,0x00};
volatile unsigned char answer[] = {0x00, 0x00, 0x00};
volatile unsigned char flags = 0b0000000;
// ||
// | ----- прерывание ИНТ0
// ------ прерывание ИНТ1
volatile unsigned int ov_count = 0;
volatile unsigned int iteration = 0;
volatile float dist = 0;
volatile unsigned int ans = 0;
/* Функция перевода числа в коды, для отображения
на динамической индикации */
void FORMAT(unsigned int val)
{
unsigned char a, b, c, temp = 0;
a = val/100;
temp = val - 100*a;
b = temp/10;
c = temp - b*10;
answer[0] = codes[a];
answer[1] = codes[b];
answer[2] = codes[c];
}
/* Функция отображения данных на индикаторе */
void DISPLAY()
{
PORTB = answer[0];
PORTD |= 0b00010000;
_delay_ms(5);
PORTD &= 0b11101111;
PORTB = answer[1];
PORTD |= 0b00100000;
_delay_ms(5);
PORTD &= 0b11011111;
PORTB = answer[2];
PORTD |= 0b01000000;
_delay_ms(5);
PORTD &= 0b10111111;
}
/* Функция отправки пачки УЗ импульсов (10 шт) */
void SENDIMPULSE()
{
PORTD |= 0b00000001;
_delay_us(12.5);
PORTD &= 0b11111110;
_delay_us(12.5);
PORTD |= 0b00000001;
_delay_us(12.5);
PORTD &= 0b11111110;
_delay_us(12.5);
PORTD |= 0b00000001;
_delay_us(12.5);
PORTD &= 0b11111110;
_delay_us(12.5);
PORTD |= 0b00000001;
_delay_us(12.5);
PORTD &= 0b11111110;
_delay_us(12.5);
PORTD |= 0b00000001;
_delay_us(12.5);
PORTD &= 0b11111110;
_delay_us(12.5);
PORTD |= 0b00000001;
_delay_us(12.5);
PORTD &= 0b11111110;
_delay_us(12.5);
PORTD |= 0b00000001;
_delay_us(12.5);
PORTD &= 0b11111110;
_delay_us(12.5);
PORTD |= 0b00000001;
_delay_us(12.5);
PORTD &= 0b11111110;
_delay_us(12.5);
PORTD |= 0b00000001;
_delay_us(12.5);
PORTD &= 0b11111110;
_delay_us(12.5);
PORTD |= 0b00000001;
_delay_us(12.5);
PORTD &= 0b11111110;
_delay_us(12.5);
}
// Обработчие прерывания от таймера 1
ISR(TIMER1_COMPA_vect)
{
ov_count++;
}
// Обработчик внешнего прерывания INT1 (пришло эхо)
ISR(INT1_vect)
{
TCCR1B = 0b00001000; //останавливаем таймер
flags |= 0b00000010;
}
// Обработчик внешнего прерывания INT0 (нажата кнопка)
ISR(INT0_vect)
{
flags |= 0b00000001;
}
int main()
{
cli(); // запрещаем все прерывания
DDRB = 0b11111111; // все ноги порта В на вывод
DDRD = 0b11110011; // все кроме инт1 и инт0 на вывод, те на ввод
// даташит с 62 страницы
MCUCR &= 0b11111010; // прерывания инт1 и инт0 по falling edge
GIMSK = 0b11000000; // разрешаем прерывание инт1 и инт0
TCCR1A = 0b00000000; // выбираем режим СТС
TCCR1B = 0b00001000; // таймер пока остановлен
OCR1AH = HI(iter); // старший байт
OCR1AL = LO(iter); // младший байт
TIMSK = 0b01000000; // прерывание по сравнению
sei(); // разрешаем все прерывания
for(;;)
{
if((flags & 0b00000001) == 1) // если взведен флаг инт0
{
TCCR1B = 0b00001000; // останавливаем счетчик
ov_count = 0; // обнуляем переменную переполнения счетчика
TCNT1H = 0; // обнуляем значения счетчика
TCNT1L = 0;
flags &= 0b11111110; // очищаем флаг
TCCR1B = 0b00001001; //запускаем счетчик
SENDIMPULSE(); //начинаем посылать импульсы
}
if((flags & 0b00000010) == 2) // если взведен флаг инт1
{
cli(); // запрещаем все прерывания
flags &= 0b11111101; // очищаем флаг
iteration = 0; // обнуляем перменные
dist = 0;
ans = 0;
iteration |= TCNT1H;
iteration <<= 8;
iteration |= TCNT1L; // прочитали значение счетчика
dist = (iteration * 0.000125 + ov_count) * 16.5; // посчитали расстояние в см
ans = trunc(dist + 0.5); // округлили
FORMAT(ans); // софрмировали ответ для отображения
sei(); // разрешили все прерывания
}
DISPLAY(); // отображаем что насчитали
}
return(0);
}Хоть убейте, но не вижу причин, почему б ему не работать)))
Помогите кто чем сможет))
Принципиалка устройства в прикрепленке.