Автомобильный тахометр

Автор работы: Пользователь скрыл имя, 25 Декабря 2011 в 15:25, курсовая работа

Описание работы

Используя средства языка программирования необходимо создать цифровой тахометр на основе микроконтроллера ATtiny 2313 семейства AVR. Должны выполняться действия: измерение оборотов двигателя, вывод значений оборотов на светодиодный индикатор, возможность уменьшения яркости индикатора при включении габаритных огней.

Содержание работы

1 Теоретическая часть 3
1.1 Аннотация 3
1.2 Постановка задачи 3
1.3 Общие сведения о микроконтроллерах AVR 3
1.4 Описание ATtiny2313 3
1.5 Основные параметры ATtiny2313 4
1.6 Блок-схема ATtiny2313 6
1.7 Расположение выводов ATtiny2313 7
1.8 Программирование микроконтроллера с использованием программы на языке С 8
2 Конструкторская часть 9
2.1 Общие сведения.Функциональное назначение используемых программ 9
2.2 Реальзация 10
2.3 Схема принципиальная 10
2.4 Вызов и загрузка 11
3 Заключение 11
4 Быблиографический список 11

Файлы: 1 файл

Автомобильный тахометр.doc

— 272.50 Кб (Скачать файл)

         {

           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;

Информация о работе Автомобильный тахометр