- •Уточнение технического задания
- •Разработка структурной схемы
- •Выбор и обоснование элементной базы
- •Выбор расходомера
- •Выбор беспроводного интерфейса передачи данных
- •Выбор оптрона
- •Выбор микроконтроллера
- •Выбор преобразователей напряжения
- •Разработка функциональной схемы
- •Схема питания
- •Схема включения микроконтроллера
- •Схема сопряжения с интерфейсом передачи данных
- •Схема сопряжения с датчиками
- •Разработка алгоритма
- •Разработка программы
- •Спецификация протокола передачи
- •Получение значения счетчика поданного топлива
- •Получение значения счетчика возвращенного топлива
- •Получение значения разности счетчиков топлива
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
7СПЕЦИФИКАЦИЯ ПРОТОКОЛА ПЕРЕДАЧИ
Микроконтроллер обменивается с ПК пакетами размером 6 байт. Вид пакета представлен в таблице 5.
Таблица 5 – Общий вид пакета
Номер байта |
0 |
1 |
2 |
3 |
4 |
5 |
|
|
|
|
|
|
|
Имя байта |
HANDLE |
CMD |
DATAL |
DATAH |
CRCL |
CRCH |
Значение |
Заголовок |
Номер |
Данные |
|
Контрольная |
|
|
пакета |
команды |
|
|
сумма |
|
|
|
|
|
|
|
|
Заголовок пакета имеет значение 0x66. Номера и имена команд представлены в таблице 6. Контрольная сумма высчитывается функцией, приведенной в исходном тексте 1.
Таблица 6 – Команды
Номер команды |
Имя команды |
|
|
0x1 |
Получить значение счетчика поданного топлива |
|
|
0x2 |
Получить значение счетчика возвращенного топлива |
|
|
0x3 |
Получить значение разности счетчика топлива |
|
|
Исходный текст 1 – CRC16
ungigned short crc16(const char * msg, unsigned short msgSize)
{
unsigned char bcnt; unsigned char crcHi, crcLo; crcLo = crcHi = 0xFF; while(msgSize--)
{
crcLo ^= *msg++;
for(bcnt = 0; bcnt < 8; bcnt++)
{
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
if(crcLo & 1)
{
crcLo >>= 1; if(crcHi & 0x1)
crcLo |= 0x80; crcHi >>= 1;
crcLo ^= 0x01; crcHi ^= 0xA0;
}
else
{
crcLo >>= 1; if(crcHi & 0x1)
crcLo |= 0x80; crcHi >>= 1;
}
}
}
return (crcHi << 8) + crcLo;
}
7.1Получение значения счетчика поданного топлива
Пример запроса:
HANDLE CMD DAT A CRC
z}|{ |
z}|{ z |
2 |
}| |
|
{ z |
|
}| |
|
{ |
66 |
01 01 |
|
00 4E FC |
||||||
|{z} |
|{z} |{z} |{z} |{z} |{z} |
||||||||
0 |
1 |
|
|
3 |
|
4 |
|
5 |
|
Если DATA имеет значение 0x0001, то счетчик обнуляется. Пример от-
вета:
HANDLE CMD DAT A CRC
z}|{ |
z}|{ z |
2 |
}| |
|
{ z |
|
}| |
|
{ |
66 |
01 0A 00 49 CC |
||||||||
|{z} |
|{z} |{z} |{z} |{z} |{z} |
||||||||
0 |
1 |
|
|
3 |
|
4 |
|
5 |
|
Поле DATA имеет значение счетчика.
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
7.2Получение значения счетчика возвращенного топлива
Пример запроса:
HANDLE CMD DAT A CRC
z}|{ |
z}|{ z |
2 |
}| |
3 |
{ z |
|
}| |
5 |
{ |
66 |
02 01 |
|
00 BE FC |
||||||
|{z} |
|{z} |{z} |{z} |{z} |{z} |
||||||||
0 |
1 |
|
|
4 |
|
|
|
Если DATA имеет значение 0x0001, то счетчик обнуляется. Пример от-
вета:
HANDLE CMD DAT A CRC
z}|{ |
z}|{ z |
2 |
}| |
3 |
{ z |
|
}| |
5 |
{ |
66 |
02 03 |
|
00 BF 9C |
||||||
|{z} |
|{z} |{z} |{z} |{z} |{z} |
||||||||
0 |
1 |
|
|
4 |
|
|
|
Поле DATA имеет значение счетчика.
7.3Получение значения разности счетчиков топлива
Пример запроса:
HANDLE CMD DAT A CRC
z}|{ |
z}|{ z |
2 |
}| |
3 |
{ z |
|
}| |
5 |
{ |
66 |
03 01 |
|
00 EF 3C |
||||||
|{z} |
|{z} |{z} |{z} |{z} |{z} |
||||||||
0 |
1 |
|
|
4 |
|
|
|
Если DATA имеет значение 0x0001, то счетчики обнуляется. Пример
ответа:
HANDLE CMD DAT A CRC
z}|{ |
z}|{ z |
2 |
}| |
3 |
{ z |
|
}| |
5 |
{ |
66 |
03 07 |
|
00 EC 9C |
||||||
|{z} |
|{z} |{z} |{z} |{z} |{z} |
||||||||
0 |
1 |
|
|
4 |
|
|
|
Поле DATA имеет значение разности счетчиков.
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
ЗАКЛЮЧЕНИЕ
В данной работе была осуществлена разработка устройства измерения расхода топлива, предназначенного для установки на автомобиль. В ходе выполнения работы был проведён анализ задачи, на основе которого были сформулированы требования к конечному устройству. На основе требований была построена структурная схема. На основании структурной схемы были подобраны соответствующие устройства для реализации функций, возложенных на элементы системы. Далее, с использованием выбранных устройств была построена функциональная схема. Разработка завершилась составлением блоксхемы алгоритма и написанием исходного кода программы для микроконтроллера.
Устройство, описанное в этой работе, можно использовать в системах мониторинга транспорта. Его можно сопрягать с различными видами бортовых компьютеров: планшеты, смартфоны и другими МК и ПК, имеющими интерфейсы RS-232 или Bluetooth SPP. Также все элементы устройства имеют диапозон рабочих температур, позволяющий работать устройству в условиях умеренного и тропического климата (-40 C – 85 C).
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
СПИСОК ИСПОЛЬЗОВАННЫХ
ИСТОЧНИКОВ
1.Динамика розничных цен на бензин // АЗС Партнер. URL: http://azspartner.ru/gasolineprice (Дата обращения: 09.06.2013).
2. Системы |
контроля расхода |
топлива от |
Omnicomm // Спец- |
техника |
и нефтегазовое |
оборудование. |
URL: http://www.spec- |
technika.ru/?page=issue&pid=101035&sub=100024&item=101036 (Дата
обращения: 09.06.2013).
3.Счетчик расхода топлива DFM // DFM. URL: http://www.dfm5.ru/ (Дата обращения: 09.06.2013).
4.8-bit AVR Microcontroller with 8K Bytes In-System Programmable Flash. ATmega8, ATmega8L // Atmel. URL: http://www.atmel.com/Images/Atmel- 2486-8-bit-AVR-microcontroller-ATmega8_L_datasheet.pdf (Дата обращения: 09.06.2013).
5. Low Power, 3.3V, |
RS-232 |
Line Drivers/Receivers ADM3222 // |
|
Analog |
Devices. |
URL: |
http://www.analog.com/static/imported- |
files/data_sheets/ADM3202_3222_1385.pdf (Дата обращения: 09.06.2013).
6.Parani-SD1000 // Sena. URL: http://www.sena.com/products/ industrial_bluetooth/sd1000.php (Дата обращения: 09.06.2013).
7.Single-Channel: 6N137, HCPL2601, HCPL2611 // Fairchild Semiconductor. URL: http://www.fairchildsemi.com/ds/6N/6N137.pdf (Дата обращения: 09.06.2013).
8.LM1117-N/LM1117I 800mA Low-Dropout Linear Regulator // Texas Instruments. URL: http://www.ti.com/lit/ds/symlink/lm1117-n.pdf (Дата обращения: 09.06.2013).
9.LM3940 1A Low Dropout Regulator for 5V to 3.3V Conversion // Texas Instruments. URL: http://www.ti.com/lit/ds/symlink/lm3940.pdf (Дата обращения: 09.06.2013).
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
10.Кувшинов Н. С., Хейфец А. Л. Схемы электрические принципиальные в инженерной графике — Челябинск: ЮУрГУ, 2010. — 74 с.
11.Бродин В. Б., Шагурин И. И. Микроконтроллеры. Архитектура, программирование, интерфейс [Справочник] — М,: ЭКОМ, 1999. — 401 с.
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
Приложение А
(обязательное)
Исходный текст программы
#include <mega8.h>
#include <delay.h>
#define TXB8 0
#define RXB8 1
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define HNDL 0;
#define CMD 1;
#define DATAL 2;
#define DATAH 3;
#define CRCL 4;
#define CRCH 5;
#define HANDLE 0x66 /*Значение поля HNDL по умолчанию*/
#define PACKET_CRC(x) x[CRCL] | (x[CRCH] << 8) /*Макрос к полю CRC
пакета*/
#define PACKET_DATA(x) x[DATAL] | (x[DATAH] << 8) /*Макрос к полю DATA
пакета*/
#define PACKET_COMMAND(x) x[CMD] /*Макрос к полю CMD пакета*/
#define PACKET_HANDLE(x) x[HNDL] /*Макрос к полю HNDL пакета*/
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
volatile unsigned short count_0; /*Переменная счетчика поданного
топлива*/
volatile unsigned short count_1; /*Переменная счетчика возвращенного
топлива*/
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
char packet[6] = "packet"; /*Массивпакет-*/
char getchar(void) /*Получение байта от UART*/
{
char status, data; while(1)
{
while(((status = USCRA) & RX_COMPLETE) == 0)
{
data = UDR1;
if((status & (FRAMING_ERROR | PARITY_ERROR |
DATA_OVERRUN)) == 0)
return data;
}
}
}
void putchar(char c) /*Отправление байта через UART*/
{
while((UCSRA & DATA_REGISTER_EMPTY) == 0)
{
UDR = c;
}
}
void initUART(void) /*Инициализация UART*/
{
UCSRA = 0x00;
UCSRB |= 0x18; /*Активация приемника и передатчика*/
UBRRH = 0x00;
UBRRL = 0x33; /*Настройка скорости передачи битс9600/*/
}
void initInterrupt(void)
{
GICR |= 0xC0; /*Разрешенире прерываний от INT0 и INT1*/
MCUCR = 0x0A; /*Установка прерывания по спаду*/
}
#pragma vector=INT0_vect
__interrupt void int0(void) /*Обработка прерывания от INT0*/
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
{
count_0++;
}
#pragma vector=INT1_vect
__interrupt void int1(void) /*Обработка прерывания от INT1*/
{
count_1++;
}
unsigned short crc16(const char * msg, unsigned short msgSize) /*
Подсчет контрольной суммы сообщения*/
{
unsigned char bcnt; unsigned char crcHi, crcLo; crcLo = crcHi = 0xFF; while(msgSize--)
{
crcLo ^= *msg++;
for(bcnt = 0; bcnt < 8; bcnt++)
{
if(crcLo & 1)
{
crcLo >>= 1; if(crcHi & 0x1)
crcLo |= 0x80; crcHi >>= 1;
crcLo ^= 0x01; crcHi ^= 0xA0;
}
else
{
crcLo >>= 1; if(crcHi & 0x1)
crcLo |= 0x80; crcHi >>= 1;
}
}
}
return (crcHi << 8) + crcLo;
}
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
unsigned char checkCRC(const char * msg) /*Проверка пакета на правильность контрольной суммы*/
{
if(PACKET_CRC(msg) == crc16(msg, 4)) return 1;
return 0;
}
void createPacket1() /*Создание пакета со значением счетчика поданного топлива */
{
packet[DATA_L] = count_0 & 0xFF; packet[DATA_H] = (count_0 >> 8) & 0xFF; unsigned short crc = crc16(packet, 4); packet[CRC_L] = crc & 0xFF; packet[CRC_H] = (crc >> 8) & 0xFF;
}
void createPacket2() /*Создание пакета со значением счетчика возвращенного топлива */
{
packet[DATA_L] = count_1 & 0xFF; packet[DATA_H] = (count_1 >> 8) & 0xFF; unsigned short crc = crc16(packet, 4); packet[CRC_L] = crc & 0xFF; packet[CRC_H] = (crc >> 8) & 0xFF;
}
void createPacket3() /*Создание пакета с разностью счетчиков*/
{
packet[DATA_L] = (count_0 - count_1) & 0xFF; packet[DATA_H] = ((count_0 - count_1) >> 8) & 0xFF; unsigned short crc = crc16(packet, 4); packet[CRC_L] = crc & 0xFF;
packet[CRC_H] = (crc >> 8) & 0xFF;
}
void analyzePacket() /*Анализ пакета*/
{
unsigned data = 0;
if(checkCRC == 1 && PACKET_HANDLE(packet) == HANDLE) /*
Проверка контрольной суммы и заголовка пакета*/
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
{
switch(PACKET_COMMAND(packet)) /*Проверка команды*/
{
case 1: /*Команда получения счетчика поданного
топлива*/
data = PACKET_DATA(packet); createPacket1(); /*Создание пакета*/ if(data == 1) count_0 = 0; /*Если DATA == 1
сбросить счетчик*/
sendPacket(); /*Отправка пакета*/ break;
case 2: /*Команда получения счетчика возвращенного
топлива*/
data = PACKET_DATA(packet); createPacket2(); /*Создание пакета*/ if(data == 1) count_1 = 0; /*Если DATA == 1
сбросить счетчик*/
sendPacket(); /*Отправка пакета*/ break;
case 3: /*Команда получения разности счетчиков*/ data = PACKET_DATA(packet); createPacket3(); /*Создание пакета*/ if(data == 1) /*Если DATA == 1 сбросить
счетчики*/
{
count_1 = 0; count_0 = 0;
}
sendPacket(); /*Отправка пакета*/
break;
}
}
}
void sendPacket() /*Отправка пакета*/
{
for(int i = 0; i < 6; i++)
putchar(packet[i]); /*Побайтное отправление пакета*/
}
void receivePacket() /*Прием пакета*/
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
{
char c = getchar(); /*Получение байта*/ for(int i = 1; i < 6; i++)
packet[i - 1] = packet[i]; /*Сдвиг байтов пакета
влево*/
packet[5] = c; /*Последний байт пакета полученный байт*/
}
void main(void) /*main*/
{
initUART(); /*Инициализация UART*/ initInterrupt(); /*Инициализация прерываний*/ count_0 = 0;
count_1 = 0
while(1)
{
receivePacket(); /*Прием пакета*/ analyzePacket(); /*Анализ пакета*/
}
}
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А4 |
Инв. № подл. Подп. и дата Взам. инв. № Инв. № дубл. Подп. и дата
Приложение Б
(обязательное)
Функциональная схема
|
|
|
|
|
Устройство измерения расхода |
Лист |
|
|
|
|
|
||
Изм. |
Лист |
№ докум. |
Подп. |
Дата |
топлива |
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Копировал |
Формат А3 |