Перейти к содержанию
    

Помогите с ATtiny2313+HC-SR04

Помогите с ATtiny2313+HC-SR04, никак не могу заставить работать.

Я еще новичок, средствами отладки не владею. Писал в CodeVision.

 

Исходные данные:

1. ATtiny2313, внутренние 8 МГц без делителя.

2. HC-SR04 - Trig на PD1, Echo на PD2(INT0).

3. 7-сегментный индикатор (PB0..6 для сегментов, PD3..6 для выбора цифры)

 

При работе кода получаю хаотичные цифры, причем только на два знака, первые два всегда нули.

Ветку с индикатором и таймером0 можно не смотреть - в ней все работает.

 

/*******************************************************
This program was created by the
CodeWizardAVR V3.12 Advanced


Chip type               : ATtiny2313
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Tiny
External RAM size       : 0
Data Stack size         : 32
*******************************************************/
#define F_CPU 8000000UL
#include <tiny2313.h>
#include <delay.h>
#include <interrupt.h>

//---------------------- 0 --- 1 --- 2 --- 3 --- 4---- 5 ---- 6 --- 7 -- 8 --- 9 ---//
unsigned char segm[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
unsigned char segcounter = 3;
volatile unsigned int dist = 0;
volatile unsigned int res = 0;


// Timer0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
  PORTB = 0xFF;             // погасить все разряды  
  PORTD = (1<<segcounter);  // выбор разряда индикатора
  switch(segcounter) {
    case 3:
      PORTB = ~(segm[dist % 10000 / 1000]); 
      break;
    case 4:
      PORTB = ~(segm[dist % 1000 / 100]); 
      break;
    case 5:
      PORTB = ~(segm[dist % 100 / 10]); 
      break;
    case 6:
      PORTB = ~(segm[dist % 10]); 
      break;
  }
  if (segcounter++ > 6) segcounter = 3;
}

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
  if (PIND&(1<<2)) {          // если передний фронт
    TCNT1H=0;                   // обнуляем
    TCNT1L=0;  
    TCCR1B|=(1<<CS11);   // запуск таймера с предделителем 8   
    }
  else {
    TCCR1B|=(0<<CS11);   // останавливаем таймер  
    res=TCNT1H;                 // считываем старший и младший байты
    res<<=8;          
    res|=TCNT1L;  
  }
}

void main(void)
{
// Crystal Oscillator division factor: 1      Для DIV8: (1<<CLKPS1) | (1<<CLKPS0)
#pragma optsize-
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port A initialization
// Function: Bit2=In Bit1=In Bit0=In 
DDRA=(0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit2=T Bit1=T Bit0=T 
PORTA=(0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=Out Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out 
DDRB=(1<<DDB7) | (1<<DDB6) | (1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=0 Bit6=0 Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port D initialization
// Function: Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=In Bit1=Out Bit0=Out 
DDRD=(1<<DDD6) | (1<<DDD5) | (1<<DDD4) | (1<<DDD3) | (0<<DDD2) | (1<<DDD1) | (0<<DDD0);
// State: Bit6=0 Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0 
PORTD=(0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: CTC top=OCR0A
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
TCCR0B=(1<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A=0xFF;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: CTC top=ICR1
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 0,032 ms
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<TOIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<ICIE1) | (0<<OCIE0B) | (0<<TOIE0) | (1<<OCIE0A);

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=(0<<INT1) | (1<<INT0) | (0<<PCIE);
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (1<<ISC00);
EIFR=(0<<INTF1) | (0<<INTF0) | (0<<PCIF);

// USI initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=(0<<USISIE) | (0<<USIOIE) | (0<<USIWM1) | (0<<USIWM0) | (0<<USICS1) | (0<<USICS0) | (0<<USICLK) | (0<<USITC);

// USART initialization
// USART disabled
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (0<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR=(0<<AIN0D) | (0<<AIN1D);


// Global enable interrupts
#asm("sei");

delay_ms(1000);
while (1)
      {
      //dist++;
      //delay_ms(100);    
      PORTD|=(1<<1);    // устанавливаем 1
      delay_us(12);         // длительность импульса
      PORTD|=(0<<1);    // устанавливаем 0   
      delay_ms(100);
      dist=res*8;            // определяем время импульса
      dist/=58;               // дистанция
      delay_ms(500);
      }
}

 

Изменено пользователем Swyters

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поменяйте порядок чтения

 

res=TCNT1L; // считываем младший байт и старший заносим в регистр-буфер.

res|=(TCNT1H<<8); // считываем из регистра-буфера значение старшего байта

Изменено пользователем aiwa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я был небольшим спецом по битовой математике.

Учился в основном по примерам, и несколько не так представлял себе считывание двухбайтных чисел.

Ну и ничего не изменилось, все так же цифры прыгают без всякой логики.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я был небольшим спецом по битовой математике.

Учился в основном по примерам, и несколько не так представлял себе считывание двухбайтных чисел.

Дело не в математике.

Это аппаратные особенности процессора.

Команда чтения из старшего регистра в действительности является командой чтения из буферного регистра,

который является общим для узлов с 16-битными регистрами: таймер, АЦП и прочего.

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...