
- •Реферат
- •Перечень условных обозначений, единиц и терминов
- •Введение
- •Структурная организация
- •Алгоритмы обработки и управления
- •Выбор элементной базы
- •Выбор омк
- •Принципиальная электрическая схема
- •Программное обеспечение
- •Алгоритм тестирования
- •Инструкция по эксплуатации контроллера
- •Заключение
- •Список использованных источников
- •Приложение а
- •Приложение б
- •Приложение в
Приложение а
Электрическая схема МПУ, выполненная в Proteus
Приложение б
Таблица 1 – Спецификация элементов
Позиционное обозначение |
Наименование |
Количество |
Описание |
|
Микросхемы |
|
|
U1 |
ATtiny88 |
1 |
Однокристальный микроконтроллер |
U2 |
AT25F512A |
1 |
Внешняя Flash-память с интерфейсом SPI |
|
Дисплеи |
|
|
LCD1 |
LM016L |
1 |
ЖКИ с контроллером HD 44780 |
|
Резисторы |
|
|
R1 |
10 кОм |
1 |
|
R2 |
220 Ом |
1 |
|
|
Диоды |
|
|
D1 |
LED-GREEN |
1 |
Светодиоды |
|
Конденсаторы |
|
|
C1 |
0,1u |
1 |
|
C2, C3 |
22 пФ |
2 |
|
|
Кнопки |
|
|
BUTTON |
BUTTON |
1 |
|
|
Генераторы |
|
|
– |
DPULSE |
3 |
Генераторы цифровых сигналов заданной формы |
|
Кварцевые резонаторы |
|
|
X1 |
CRYSTAL |
1 |
|
Приложение в
Листинг программы
// Подключаем необходимые функции
#include <tiny88.h> // Функции для работы с ОМК
#include <alcd.h> // Функции алфавитно-цифрового ЖКИ
#include <spi.h> // Функции SPI
#include <stdio.h> // Функции форматирования
// Объявляем глобальные переменные
unsigned long mileage=0;
unsigned int periods=0, frequency=0, address=0x0;
float fuel = 0;
// Подпрограмма очистки памяти
void clear_memory(void)
{
PORTB.2=0; // Переключаемся на ведомую память
spi((unsigned char)0x62); // Стираем её
PORTB.2=1; // Делаем ведомую память не активной
}
// Подпрограмма обработки внешнего прерывания 0
interrupt [EXT_INT0] void ext_int0_isr(void) // Измерение пробега
{
unsigned char *byte;
unsigned int i;
mileage++;
if(mileage%10==0) // Вывод во внешнюю память
{
PORTB.2=0; // Переключаемся на ведомую память
spi((unsigned char)0x6);
PORTB.2=1; // Делаем ведомую память не активной
PORTB.2=0; // Переключаемся на ведомую память
spi((unsigned char)0x2); // Команда "запись"
spi((unsigned char)0x0);
byte=(unsigned char*)&address;
spi((unsigned char)byte[1]);
spi((unsigned char)byte[0]);
byte=(unsigned char*)&mileage;
for(i=0;i<sizeof(long);i++)
{
spi(byte[i]); // Пишем пробег в память
}
byte=(unsigned char*)&fuel;
for(i=0;i<sizeof(float);i++)
{
spi(byte[i]); // Пишем расход топлива в память
}
PORTB.2=1; // Делаем ведомую память не активной
address+=0x8; // Переходим на следующий адрес
}
if(mileage==1000000) // Если пробег достиг 1000 км
{
mileage=0; // Обнуляем его
address=0x0;
clear_memory(); // Очищаем память
}
}
// Подпрограмма обработки внешнего прерывания 1
interrupt [EXT_INT1] void ext_int1_isr(void) // Измерение частоты
{
periods++;
}
// Прерывание от таймера 1 по истечении секунды
interrupt [TIM1_COMPA] void timer1_compa_isr(void) // Подсчёт частоты и вывод на ЖКИ
{
char lcd_buf[33]; // Подготавливаем вывод
frequency=periods;
periods=0;
TCNT1H=0x00; // Обнуляем счётчик
TCNT1L=0x00;
fuel+=(frequency) / 3600.0;
//sprintf(lcd_buf,"Count=%dM\nFreq=%dHz",mileage,frequency); //
sprintf(lcd_buf,"Mileage=%dM\nFuel=%.2fL",mileage,fuel); // Форматируем выходную строку
lcd_gotoxy(0,0);
lcd_puts(lcd_buf); // Выводим на ЖКИ
}
void main(void)
{
// Делитель частоты кварца: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Инициализация входных/выходных портов
// Инициализация порта А
// Бит3=Вход Бит2=Вход Бит1=Вход Бит0=Вход
PORTA=0x00;
DDRA=0x00;
// Инициализация порта В
// Бит7=Вход Бит6=Вход Бит5=Выход Бит4=Вход Бит3=Выход Бит2=Выход Бит1=Вход Бит0=Вход
// Бит5=0 Бит3=0 Бит2=1
PORTB=0x04;
DDRB=0x2C;
// Инициализация порта С
// Бит7=Вход Бит6=Вход Бит5=Вход Бит4=Вход Бит3=Вход Бит2=Вход Бит1=Вход Бит0=Вход
PORTC=0x00;
DDRC=0x00;
// Инициализация порта D
// Бит7=Вход Бит6=Вход Бит5=Вход Бит4=Вход Бит3=Вход Бит2=Вход Бит1=Вход Бит0=Вход
PORTD=0x00;
DDRD=0x00;
// Инициализация Таймера/Счётчика 0
// Источник синхронизации: Системный генератор
// Синхронизируемое значение: Таймер 0 остановлен
// Режим: 8-битная верхушка=0xFF
TCCR0A=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Инициализация Таймера/Счётчика 1
// Источник синхронизации: Системный генератор
// Синхронизируемое значение: 7,813 kHz
// Режим: Нормальная верхушка=0xFFFF
// OC1A выход: Откл.
// OC1B выход: Откл.
// Подавление шума: Откл.
// Входной захват по спаду
// Прерывание при переполнении Таймера 1: Откл.
// Прерывание при захвате на входе: Откл.
// Прерывание при совпадении с регистром сравнения A: Вкл.
// Прерывание при совпадении с регистром сравнения В: Вкл.
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1E;
OCR1AL=0x85;
OCR1BH=0x00;
OCR1BL=0x00;
// Инициализация внешних прерываний
// INT0: Вкл.
// INT0 Режим: по фронту
// INT1: Вкл
// INT1 Режим: по Фронту
// Прерывание при любом изменении на ножках PCINT0-7: Выкл.
// Прерывание при любом изменении на ножках PCINT8-15: Выкл.
// Прерывание при любом изменении на ножках PCINT16-23: Выкл.
// Прерывание при любом изменении на ножках PCINT24-27: Выкл.
EICRA=0x0F;
EIMSK=0x03;
EIFR=0x03;
PCICR=0x00;
// Инициализация прерываний от Таймера/Счётчика 0
TIMSK0=0x00;
// Инициализация прерываний от Таймера/Счётчика 1
TIMSK1=0x02;
// Инициализация аналогового компаратора
// Аналоговый компаратор: Выкл.
// Захват входного значения компаратора Таймером 1: Выкл.
ACSR=0x80;
ADCSRB=0x00;
DIDR1=0x00;
// Инициализация АЦП
// АЦП отключен
ADCSRA=0x00;
// Инициализация SPI
// Тип SPI: Master
// Частота синхронизации SPI: 2000,000 kГц
// Фаза синхронизации SPI: Начало цикла
// Полярность SPI синхроимпульса: Низкая
// Порядок данных SPI: младший байт первый
SPCR=0x50;
SPSR=0x00;
// Инициализация TWI
// TWI отключен
TWCR=0x00;
// Инициализация алфавитно-цифрового ЖКИ
// RS - PORTC Бит 0
// RD - PORTC Бит 1
// EN - PORTC Бит 2
// D4 - PORTC Бит 3
// D5 - PORTC Бит 4
// D6 - PORTC Бит 5
// D7 - PORTC Бит 7
// Символов на строку: 16
lcd_init(16);
// Очищаем внешнюю память
clear_memory();
while (1) // Основной цикл программы
{
if(PIND.0==0) // Если пришёл сигнал "Старт"
{
#asm("sei") // Разрешаем прерывания
}
else // Иначе
{
#asm("cli") // Запрещаем прерывания
lcd_clear(); // Очищаем ЖКИ
mileage=0; // Обнуляем переменные
periods=0;
frequency=0;
//address=0x0;
fuel = 0;
}
}
}