Курсовой проект "Тахометр на Attiny 2313"

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
SabitofF
Нашел транзистор. Понюхал.
Сообщения: 191
Зарегистрирован: Сб июн 26, 2010 12:08:42

Курсовой проект "Тахометр на Attiny 2313"

Сообщение SabitofF »

Помогите доработать курсовой. Задание прикрепил. Хочу собрать _http://hardlock.org.ua/mc/tiny/tahometr/index.html вот это данное устройство только не знаю как и где в прошивке сделать так чтобы отщет начинался от 100 до 7000 об/мин.-1
Код исходника:

Код: Выделить всё

#define    TRUE    (!FALSE)
#define    FALSE   0
#define    BYTE    unsigned char
#define    WORD    unsigned short int
#define    BOOLEAN char

#define TIMER_OVF_ENOUGHT   49
#define NO_PULSES_INTERVAL  200 

#define LED_delay 250    
#define Light_delay 2500
//#define Anode
#define Cathode        

#define     CNT_100_MS  6250

#define byBladeCnt 2 //1- две катушки, 2 - одна катушка, 4 - мотоцикл...
#define Prescaler 0x01 //0x00 - для кварца 4MHz, 0x01 - для кварца 8MHz...
#define UpCount 4  // +1 = количество пропусков (0,1S) до обновления

#include    <tiny2313.h>
#include    <delay.h>                               


BOOLEAN btTimeUpdate;   // = 1, когда нужно обновить время на дисплее
WORD wTime;             // Время, которое показывает секундомер (в десятых секунды)

BOOLEAN btTimerOn;      // TRUE - таймер запущен, FALSE - остановлен

BYTE    byTcnt;         // счетчик десятых секунд

BYTE    byDisplayRefreshCnt;    // 

void ShowDisplayData(void);     // Вывод экранного буфера
void PrepareRpmData(WORD wRpm);

BOOLEAN btDisplayUpdate;        // = TRUE, если пришло время обновить дисплей


BYTE byDisplay[4];        // буфер данных, для вывода на экран       
WORD    wLockedRpm;

// Массив знакогенератора
BYTE byCharacter[12] = {0xFA,     //0
                0x82,   //1
 	        0xB9,   //2
	        0xAB,	//3 
	        0xC3,     //4 
	        0x6B,     //5 
	        0x7B,     //6
                0xA2,    //7 
                0xFB,      //8
                0xEB,      //9 
                0x00,      //blank   
                0x01     //-
                }; 

WORD    wRpm;           // Скорость вращения ротора (об/мин)

//BOOLEAN btRpmUpdate;    // = 1, когда измеряно новое значение оборотов

WORD    wTimerOvfCnt;   // Счетчик переполнений таймера (нужен для
                        // увеличения разрядности

WORD    wFlashCnt;      // Счетчик срабатываний датчика прохождения допасти

BOOLEAN btFirstLowRateFlash;    // FALSE - если отсчет периода еще не начался
                                // (датчик ни разу не сработал)    
                                                                    

/************************************************************************\
  Обновление дисплея.
      Вход:  -
      Выход: -
\************************************************************************/
void RefreshDisplay(void)
{                                
    #asm("cli");
    if (btDisplayUpdate)
    {
      wLockedRpm = wRpm;
      btDisplayUpdate = FALSE;
    }
    #asm("sei");
    
    PrepareRpmData(wLockedRpm);
    ShowDisplayData();
}

/************************************************************************\
  Преобразование скорости мотора и количества лопастей
  в данные экранного буфера
      Вход:  wRpm - обороты ротора, byBladeCnt - количество лопастей
      Выход: -
\************************************************************************/
void PrepareRpmData(WORD wRpm)
{
    BYTE i;
    WORD R;
    
    R = wRpm;       
    
    byDisplay[3] = wRpm % 10;
    wRpm /= 10;
              
    if (byDisplay[3] > 4)  //округляем
    {
      wRpm++;
      R += 10;
    }        
    
    byDisplay[3] = 0;
    
    
    // Первые 4 цифр - обороты двигателя
    for(i=0; i<3; i++)
    {
       byDisplay[2-i] = wRpm % 10;
       wRpm /= 10;
    }
    
    if (R < 10)
    {
      byDisplay[0] = 10;
      byDisplay[1] = 10;
      byDisplay[2] = 10;            
      goto exit;
    }   
    if ((R >= 10) & (R <100))
    {
      byDisplay[0] = 10;
      byDisplay[1] = 10;
      goto exit;
    }
    if ((R >= 100) & (R <1000))
    {
      byDisplay[0] = 10;
      goto exit;
    }            
    
    
                    
exit:
}


/************************************************************************\
  Вывод экранного буфера на дисплей.
      Вход:  -
      Выход: -
\************************************************************************/
void ShowDisplayData(void)
{
#ifdef Cathode
  PORTB = byCharacter[byDisplay[0]];
  PORTD.5 = 0;
  delay_us(LED_delay);
  PORTD.5 = 1;    
     
  PORTB = byCharacter[byDisplay[1]];
  PORTD.1 = 0;
  delay_us(LED_delay);
  PORTD.1 = 1;
      
  PORTB = byCharacter[byDisplay[2]];
  PORTD.0 = 0;
  delay_us(LED_delay);
  PORTD.0 = 1;
      
  PORTB = byCharacter[byDisplay[3]];
  PORTD.4 = 0;
  delay_us(LED_delay);
  PORTD.4 = 1;
#endif

#ifdef Anode
  PORTB = ~byCharacter[byDisplay[0]];
  PORTD.5 = 1;
  delay_us(LED_delay);
  PORTD.5 = 0;    
     
  PORTB = ~byCharacter[byDisplay[1]];
  PORTD.1 = 1;
  delay_us(LED_delay);
  PORTD.1 = 0;
      
  PORTB = ~byCharacter[byDisplay[2]];
  PORTD.0 = 1;
  delay_us(LED_delay);
  PORTD.0 = 0;
      
  PORTB = ~byCharacter[byDisplay[3]];
  PORTD.4 = 1;
  delay_us(LED_delay);
  PORTD.4 = 0;
#endif
  
  if (! PIND.6)
  {     
    delay_us(Light_delay); 
  }
}                                
                                
/**************************************************************************\
   Обработка прерываний от OC1 (для отсчета импульсов 0.1 сек)
      Вход:  -
      Выход: -
\**************************************************************************/
interrupt [TIM1_COMPA] void SYSTEM_TICK_interrupt(void)
{
    // Вычисляем оммент следующего срабатывания таймера
    OCR1A += CNT_100_MS;

    // 3 раза в секунду перерисовываем дисплей,
    // независимо от обстоятельств.
    if( ++byDisplayRefreshCnt == UpCount )
    {
        byDisplayRefreshCnt = 0;
        btDisplayUpdate = TRUE;

    }
    // Если секундомер запущен - инкрементируем его показания
    if( btTimerOn )    
    {
        if (++byTcnt == 10)
        {
            byTcnt = 0;
            if( ++wTime == 60000)
                wTime = 0;
        }
    }


}
                                
/**************************************************************************\
    Обработка прерываний от управляющих импульсов
      Вход:  -
      Выход: -
\**************************************************************************/
interrupt [EXT_INT0] void RPM_PULSE_interrupt(void)
{
    long lTmp;

    GIMSK &= ~0x40;

    if(btFirstLowRateFlash)
    {
        // Первый импульс, сбрасываем счетчик периода и
        // счетчик импульсов
        wTimerOvfCnt = 0;
        wFlashCnt = 0;
        TCNT0 = 0;
        TIFR = 0x02;
        TCCR0B = 0x03;   // FCK / 64 ( 62.5 KHz )
        TCNT0 = 0;
        TIMSK |= 0x02;  // Разрешаем прерывания от TMR0

        btFirstLowRateFlash = FALSE;
    }
    else
    {
        wFlashCnt++;
        // Проверяем, не пора ли закончить измерения
        if( wTimerOvfCnt > TIMER_OVF_ENOUGHT )
        {
            TCCR0B = 0;      // Останавливаем TMR0
            GIMSK &= 0x40;  // Запрещаем прерывания от INT0
            TIMSK &= ~0x02; // Запрещаем прерывания от TMR0
            if(TIFR & 0x02)
                wTimerOvfCnt++;    // Учитываем возможность переполнения

            lTmp = (62500L * 60L * (long)wFlashCnt);
            lTmp /= ((wTimerOvfCnt << 8) + TCNT0);
            lTmp /= byBladeCnt;
            wRpm = lTmp;

            // Перезапускаем измерения
            btFirstLowRateFlash = TRUE;

            wTimerOvfCnt = 0;
            TCNT0 = 0;
            TCCR0B = 0x03;   // FCK / 64 ( 62.5 KHz )
            TCNT0 = 0;
            TIFR = 0x02;
            TIMSK |= 0x02;  // Разрешаем прерывания от TMR0

//            GIFR = 0x40;

        }
    }
    EIFR = 0x40;
    GIMSK |= 0x40;
}

/**************************************************************************\
    Обработка переполнений TMR0 (добавляем к счетчику еще 8 разрядов)
      Вход:  -
      Выход: -
\**************************************************************************/
interrupt [TIM0_OVF] void TIMER0_interrupt(void)
{
    wTimerOvfCnt++;

    // Если импульсов не было слишком долго, то показываем
    // 0 оборотов и запускаем измерение заново
    if( wTimerOvfCnt > NO_PULSES_INTERVAL )
    {
        wRpm = 0;
        btFirstLowRateFlash = TRUE;
        wTimerOvfCnt = 0;
    }
}                                
                                
/**************************************************************************\
    Головная функция. Инициализация всех модулей. Цикл вызова рабочих
    подпрограмм.
      Вход:  -
      Выход: -
\**************************************************************************/
void main(void)
{    
// Crystal Oscillator division factor:
#pragma optsize-
CLKPR=0x80;
CLKPR=Prescaler;        //0x00 - для кварца 4MHz, 0x01 - для кварца 8MHz...
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

    #asm("cli");
    
    MCUCR = 0x00;   // Запрещаем SLEEP, режимы прерывания пока не важны.
                    // В принципе, этого можно и не делать.
    
    GIMSK = 0x00;   // Запрещаем внешние прерывания
    EIFR = 0xFF;    // Очищаем флаги прерываний
    
    TIMSK = 0x00;   // Запрещаем прерывания от таймеров
    TIFR = 0xFF;    // Очищаем флаги прерываний

        //Разряд DDRx - определяет направление передачи данных (0 - вход, 1 - выход).
        //Разряд PORTx - если вывод определен выходом (DDRx = 1), то:
        //         если установлена 1 - то на выводе устанавливается лог. 1
        //         если установлена 0 - то на выводе устанавливается лог. 0
        //    если вывод определен входом (DDRx = 0), то PORTx - определяет состояние подтягивающего резистора (при PORTx = 1 резистор подключен)
        //Разряд PINx - доступен только для чтения и содержит физическое значение вывода порта
        
        PORTA=0b00000011;
        DDRA= 0b00000011;           
        
        PORTB=0b00000000;
        DDRB= 0b11111111;
                 
      #ifdef Cathode  
        PORTD=0b01111111;
        DDRD= 0b00110011;
      #endif
      
      #ifdef Anode  
        PORTD=0b01001100;
        DDRD= 0b00110011;
      #endif
      
    // Инициализируем модули
    //time------------------------------------
    btTimerOn = FALSE;
    wTime = 0;
    byTcnt = 0;
    byDisplayRefreshCnt = 0;
    
    btTimeUpdate = FALSE;
    
    TCNT1 = 0;
    
    TCCR1A = 0x00;      // Отключаем управление выводом OC1 и PWM

    TCCR1B = 0x03;      // На таймер подается FCK через делитель на 64,
                        // шумодав отключен, никакого сброса нет

    OCR1A = TCNT1 + CNT_100_MS;

    TIFR  |= 0x40;      // Сбрасываем флаг прерываний от Output-Compare
    TIMSK |= 0x40;      // Разрешаем прерывание от Output-Compare
    //time------------------------------------
    
    //rmp-------------------------------------
    btFirstLowRateFlash = TRUE;
    wRpm = 0;

    // Разрешаем прервание INT1
    EIFR = 0x40;
    GIMSK |= 0x40;
    MCUCR = 0x02;   // Настраиваем INT0 на спад, остальные биты не важны.
    
    // Таймер запускаем сразу, чтобы проверять
    // отсутствие сигнала
    wTimerOvfCnt = 0;
    TCNT0 = 0;
    TCCR0B = 0x03;   // FCK / 64 ( 62.5 KHz )
    TCNT0 = 0;
    TIMSK |= 0x02;  // Разрешаем прерывания от TMR0
    //rmp-------------------------------------
    
    
    
    #asm("sei");

//    StartLowRateRpm();
    while(TRUE)
    {
       
            RefreshDisplay();

 
    }
}

Вложения
1.jpg
(68.78 КБ) 548 скачиваний
Реклама
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Курсовой проект "Тахометр на Attiny 2313"

Сообщение BCluster »

Код мутный, как вы в нем разбираться будете?
Могу сделать код и схему, если интересно в личку
Реклама
Аватара пользователя
zhu4er
Вымогатель припоя
Сообщения: 544
Зарегистрирован: Пт июн 04, 2010 17:40:13
Откуда: Непокорный город-герой Севастополь

Re: Курсовой проект "Тахометр на Attiny 2313"

Сообщение zhu4er »

Мне кажется надо искать/разбираться более конкретно вот в этой процедуре "Преобразование скорости мотора и количества лопастей в данные экранного буфера"
Даже у стен есть уши...
DimmONN
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Вт окт 06, 2009 17:18:09
Откуда: Minsk

Re: Курсовой проект "Тахометр на Attiny 2313"

Сообщение DimmONN »

Реклама
Эиком - электронные компоненты и радиодетали
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»