Таблица 5.4 - Состояния Source Code Control.
SCC состояние | Описание |
Проверенный. Файл доступен для редактирования | |
Проверенный. Файл доступен для редактирования и был изменен. | |
(серый замок) | Зарегистрированный. Во многих системах SCC это означает, что файл защищен от записи. |
(серый замок) | Зарегистрированный. Есть новая версия, доступная в архиве. |
(красный замок) | Во многих системах SCC это означает, что нельзя проверить файл. |
(красный замок) | Есть новая версия, доступная в архиве. Во многих системах SCC это означает, что нельзя проверить файл. |
ВЫВОДЫ
цифровой тахометр микроконтроллер
Данный курсовой проект позволил более детально ознакомится с микроконтроллерами типа AVR Attiny 2313. В процессе разработки проекта были получены навыки проектирования, реализации и внедрение проекта в реальную модель.
В результате выполнения комплексного курсового проекта был описан процесс создания и программно реализованы устройства электронных часов на основе микроконтроллера Attiny 2313.
|
|
Полученные результаты показывают, что программа работоспособна и готова к использованию.
Конечным результатом проведенной работы, явилась структурная и принципиальная схема цифрового тахометра, а также сборка самого устройства и проверка его на работоспосбность.
ПЕРЕЧЕНЬ ССЫЛОК
1. Методические указания к лабораторным работам по курсу “Микроконтроллеры во встроенных системах управления для студентов всех специальностей / Составители Аврунин О.Г., Крук О.Я., Семенец В.В. – ХНУРЭ, 2005. – 105 с.
2. В. А. Гулиус, В. Г. Лобода, В. П. Степанов, В. Ю. Цуканов. “Средства автоматизированного проектирования специализированных микропроцессорных устройств”: Учебное пособие – Харьков: ХНУРЭ, 2001. – 228 с.
3. Белова Н. В., Коряк С. Ф., Лобода В. Г.. “Основы построения ориентированных ЭВМ и систем”. Под общ. ред. В. Г. Лободы. – Харьков: ООО «Компания СМИТ», 2007. – 148 с.
4. Проектирование встроенных устройств на микропроцессорах: Учеб. пособие /В. Г. Лобода, В. В. Логвин, В. Б. Таранов. – К.: УМК ВО, 1988. – 128 с.
5. Методические указания к комплексному курсовому проекту / Составители: В.Г. Лобода, А.С. Шкиль, Л.К. Штец.- Харков, ХНУРЭ,2001. – 8с.
6. Arduino programming notebook /Brian W.Adams
7. Wikipedia.org
ПРИЛОЖЕНИЕ А. Программа реализации устройств
#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
#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();
}
/************************************************************************\
Преобразование скорости мотора в данные экранного буфера
\************************************************************************/
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();
}
}
Размещено на Allbest.ru