Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Zapiska.docx
Скачиваний:
6
Добавлен:
04.09.2019
Размер:
2.12 Mб
Скачать
  1. Програмна реалізація системи

4.1. Програмне забезпечення мікроконтролеру

Як раніше було сказано, для розробки програми для мікроконтролера, вибрано потужне середовище розробки IAR Embedded Workbench використовуючи мову С [8].

При подачі напруги живлення на мікроконтролер він запускається та відбувається ініціалізація всієї периферії, що використовується для роботи телеметрії, з головної функції програми int main(void) виконується функція void InitAll(void), в якій послідовно виконуються функції void InitGPIO( void), void InitUSART( void), void InitADC( void), відповідно, ці функції ініціалізують цифрові порти введення-виведення загального призначення, універсальний синхронно-асинхронний прийомо-передавач (УСАПП) та аналого-цифрового перетворювача. Розглянемо основні моменти в ініціалізації периферії мікроконтролера.

Функція void InitGPIO( void) використовується для конфігурації цифрових портів введення-виведення загального призначення. Кожна цифрова лінія введення-виведення може бути сконфігурована як лінія на введення чи на виведення загального призначення або альтернативну функцію. Порти мікроконтролера позначаються буквами A … E і сумісні з напругою 5В. Передбачені відповідні регістри, що дозволяє конфігурувати ніжки порта. Після завершення конфігурації, доступ до зміни можна заблокувати. У кожного порта є два 32-бітових конфігураційних регістра. Спільно вони утворюють 64-бітний конфігураційний регістр. Ці 64 біта розділені на 4-бітні поля, що дозволяють налаштувати відповідну їм лінію введення-виведення. У свою чергу, 4-бітове поле конфігурації складається з 2-бітного поля режиму і 2-бітного поля конфігурації. Поле режиму дозволяє вказати, в якому напрямку працює лінія: на введення або на виведення, а поле конфігурації дозволяє налаштувати характеристики управління:

  • якщо лінія налаштована як вхід, на неї можна подавати логічний нуль чи логічну одиницю, використовувати як АЦП вхід;

  • лінія, налаштована на вивід, може бути або двотактною, або з відкритим стоком. Для ліній виводу можна також вказати її максимальну швидкодію: 2, 10 або 50 МГц.

Для того щоб налаштувати цифрові порти введення-виведення загального призначення, в нашому випадку, спочатку вмикається тактування порта «С» викликаючи функцію RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE). Після цього створюється та ініціалізується структура GPIO_InitStructure типу GPIO_InitTypeDef. В цій структурі вказується, що порти PC9 та PC8 працюють на вихід. До цих портів під’єднанні два вбудованих у відлагоджувальну плату світлодіоди. Використання цих двох ідбувається буде сигналізувати користувача про робочу дію системи, тобто, якщо світлодіоди блимають система працює. Структура GPIO_InitTypeDef має наступні властивості:

  • GPIO_Pin – встановлює які саме ніжки порта будуть конфігуруватися. Цій властивості можна присвоїти як і конкретну ніжку, наприклад GPIO_Pin_6, так і перелік всіх ніжок GPIO_Pin_All;

  • GPIO_Speed – максимальна швидкодія порта. Може набувати GPIO_Speed_2MHz, GPIO_Speed_10MHz, GPIO_Speed_50MHz, відповідно може працювати з максимальною частотою 2МГц, 10МГц, 50МГц;

  • GPIO_Mode – встановлює режим роботи порта введення/виведення.

В нашому випадку GPIO_InitStructure структура налаштована наступним чином:

  • GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

  • GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

  • GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP.

Для того щоб налаштування вступили в дію потрібно виконати функцію GPIO_Init( GPIOC, &GPIO_InitStructure), яка отримує два параметри, назву порту, що ініціалізується і структуру з налаштуваннями.

Також потрібно конфігурувати виводи мікроконтролера для роботи USART та ADC периферії, для цього створюються, ще структури типу GPIO_InitTypeDef.

Налаштування п’ятого вивода порта «С» як цифровий вхід, що використовується для аналого-цифрового перетворювача 15 каналу:

  • GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

  • GPIO_InitStructure.GPIO_Speed = (GPIOSpeed_TypeDef)0;

  • GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  • GPIO_Init (GPIOC, &GPIO_InitStructure).

Конфігурація виводів Tx, Rx для USART1 інтерфейсу проводиться наступним чином. Для налаштування Tx виводу:

  • GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; - конфігурується 9 ніжка порта «А». Це Transmitted Data (Tx), передавальний вивід, що буде використовуватися для передачі даних робочій станції.

  • GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  • GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  • GPIO_Init(GPIOA, &GPIO_InitStructure).

Для налаштування Rx виводу, використовується та сама структура, що і для Tx вивода, змінюються наступні властивості:

  • GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  • GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  • GPIO_Init(GPIOA, &GPIO_InitStructure).

Після цих дій конфігурація цифрових портів введення-виведення загального призначення завершена. Тепер можна приступити до налаштовувати USART та ADC периферію.

Функція InitUSART(void) використовується для конфігурації USART1 інтерфейсу до якого підключений USB-USART перетворювач. Після того як налаштовані порти, до яких буде під’єднаний USART кабель, можна налаштувати асинхронну роботу інтерфейсу, тобто налаштувати переривання яке буде викликатися при обміні даними між робочою станцією та мікроконтролером. Для цього потрібно налаштувати контролер вкладених векторних переривань (NVIC) – це стандартний модуль ядра Cortex. Спочатку створюється структура NVIC_InitStructure типу NVIC_InitTypeDef, яка згодом буде ініціалізувати переривання для USART1 інтерфейсу. Властивості цієї структури налаштовуються наступним чином:

  • NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

  • NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  • NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  • NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

Викликом функції NVIC_Init(&NVIC_InitStructure) ідбувається ініціалізація переривань. Після цього налаштовується система тактування, після якої відбувається конфігурація USART1 інтерфейсу:

  • USART_BaudRate = 115200; - встановлюється швидкість роботи інтерфейсу 256000 бод;

  • USART_WordLength = USART_WordLength_8b; - довжина даних однієї посилки 8 біт;

  • USART_StopBits = USART_StopBits_1; - кількість стопових бітів дорівнює одному;

  • USART_Parity = USART_Parity_No; - облік парності при передачі даних не ведеться;

  • USART_HardwareFlowControl = USART_HardwareFlowControl_None; - апаратне керування потоком вимкнуте;

  • USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - налаштування режиму роботи USART інтерфейсу. В даному випадку, він працює як на прийом, так і на передачу даних.

Викликом функції USART_Init(USART1, &USART_InitStructure), структура USART_InitStructure ініціалізує інтерфейс USART1.

Після цього, при обміні даних між робочою станцією та мікроконтролером буде виконуватися переривання void USART1_IRQHandler (void) (рисунок 4.1), в якому перевіряється, якщо функція USART_GetITStatus(USART1, USART_IT_RXNE) повертає значення SET в цьому випадку йде прийом даних від робочої станції, відповідно, якщо USART_GetITStatus(USART1, USART_IT_TXE) повертає SET, йде передача даних робочій станції.

Рисунок 4.1 – Обробник УСАПП переривання

функція InitADC(void) використовується для ініціалізації та конфігурації вбудованого 12 бітного аналого-цифрового перетворювача. Спочатку конфігуруються виводи PC5 та PB0 мікроконтролера як аналогові входи. До цих виводів під’єднаний потенціометр та термоопір. Після того як ніжки контролера сконфігуровані, створюється та ініціалізується структура ADC_InitStructure яка і буде конфігурувати АЦП. Також виконується функція ADC_TempSensorVrefintCmd(ENABLE) яка вмикає 17 канал АЦП мікроконтролера, до якого під’єднаний вбудований термо датчик. Приведемо ініціалізацію властивостей структури ADC_InitStructure:

  • ADC_Mode = ADC_Mode_Independent;

  • ADC_ScanConvMode = DISABLE;

  • ADC_ContinuousConvMode = DISABLE;

  • ADC_ExternalTrigConv=DC_ExternalTrigConv_None;

  • DataAlign = ADC_DataAlign_Right;

  • ADC_NbrOfChannel = 1;

Потім викликається функція ADC_Init(ADC1, &ADC_InitStructure) яка ініціалізує аналого-цифровий перетворювач. Для вмикання АЦП викликається ADC_Cmd(ADC1, ENABLE).

Після того, коли вся периферія контролера сконфігурована, програма переходить на виконання нескінченого циклу while(1){}, в якому по черзі змінюється потенціал з високого рівня на низький, і навпаки, на виводах PC9 та PC8 до яких підключені світлодіоди, що заставляє їх блимати. Високий рівень на виводі встановлюється за допомогою функції GPIO_SetBits( GPIOC, GPIO_Pin_9), де GPIOC вказує на регістр порту С, а GPIO_Pin_9 вказує на 9 ніжку порта, відповідно низький потенціал встановлюється за допомого функції GPIO_ResetBits( GPIOC, GPIO_Pin_9). Щоб було помітно, що світлодіод блимає, потрібно виконати затримку між встановленням низького та високого потенціалу, тому між цими функціями виконується delay_ms(20), затримка в 20 мілісекунд.

Наступним йде перетворення аналогового сигналу, викликом функції GetADC1Channel(ADC_Channel_15) з 15 каналу АЦП, отримані цифрові данні ділимо на 4095 (максимальне значення 12 біт АЦП) і множимо на 3.3 (максимальне значення напруги, яке можна подати на вхідний канал АЦП) в результаті отримуємо величину напруги яка приходить на 15 вивід контролеру.

Таким самим чином виконуються два інших переретворення температур, викликом двох функцій GetADC1Channel(ADC_Channel_8) з 8 каналу АЦП та GetADC1Channel17( ADC_Channel_16 ) з 16, вбудованого в мікроконтролер термо датчика (рисунок 4.2).

Рисунок 4.2 – Виконання алгоритму роботи мікроконтролера

Коли від робочої станції надходять дані, виникає USART1 переривання void USART1_IRQHandler(void), в якому виконується прийом одного байту за допомогою USART_ReceiveData(USART1) функції. Контролер реагує і дає відповідь робочій станції, якщо він отримав «1», «2», «3» відповідно він відправляє по USART перетворенні дані з АЦП, в іншому випадку всі прийняті дані контролером ігноруються.

4.2. Програмне забезпечення робочої станції

Написання програми для робочої станції проводилося в середовищі розробки MS Visual Studio 2008 .NET на мові Visual C# [9].

Для організації зв’язку з мікроконтролером в програмі використовується клас SerialPort. Цей клас використовується для управління файловим ресурсом послідовного порту. Даний клас надає можливості керування введенням-виведенням в синхронному режимі або на основі подій, доступу до стану лінії і станом розриву, а також доступу до властивостей послідовного драйвера. Крім того, функції цього класу можна упакувати у внутрішній об’єкт Stream, доступний через властивість BaseStream, і передавати в класи, використовують потоки. В таблиці 4.1 наведені основні властивості класу. В таблиці 4.2 наведені основні методи класу [7].

Клас SerialPort підтримує наступні кодування: ASCIIEncoding, UTF8Encoding, UnicodeEncoding, UTF32Encoding, а також будь-яке кодування, яке підтримується бібліотекою mscorlib.dll.

Таблиця 4.1 – Властивості класу System.IO.Ports.SerialPort

Назва

Опис

BaudRate

Отримує або задає швидкість передачі для послідовного порту (у бодах).

BytesToRead

Отримує число байтів даних, що знаходяться в буфері.

Таблиця 4.1 (продовження)

BytesToWrite

Отримує число байтів даних, що знаходяться в буфері відправки.

DataBits

Отримує або задає стандартне число бітів даних у байті.

Encoding

Отримує або задає кодування байтів для перетворення тексту до і після передачі.

IsOpen

Отримує значення, що вказує стан об’єкта SerialPort – відкритий або закритий.

Parity

Отримує або задає протокол контролю парності.

PortName

Отримує або задає послідовний порт, зокрема, будь-який з доступних портів COM.

ReadBufferSize

Отримує або задає розмір вхідного буфера SerialPort.

ReadTimeout

Отримує або задає термін очікування в мілісекундах для завершення операції читання.

StopBits

Отримує або задає стандартне число стопових бітів у байті.

WriteTimeout

Отримує або задає термін очікування в мілісекундах для завершення операції запису.

Таблиця 4.2 – Методи класу System.IO.Ports.SerialPort

Назва

Опис

Close

Закриває з’єднання порту, привласнює властивості IsOpen значення false і знищує внутрішній об’єкт Stream.

Open

Відкриває нове з’єднання послідовного порту.

GetPortNames

Отримує масив імен послідовних портів для поточного комп’ютера.

Read(Byte[], Int32, Int32)

Зчитує з вхідного буфера SerialPort певне число байтів і записує їх у айтів масив, починаючи із зазначеної позиції.

Таблиця 4.2 (продовження)

ReadByte

Зчитує з вхідного буфера SerialPort один байт у синхронному режимі.

Write(String)

Записує вказаний рядок в послідовний порт.

Write(Byte[], Int32, Int32)

Записує вказане число байтів в послідовний порт, використовуючи дані з буфера.

Після створення об’єкту «sp» цього класу, виконується його ініціалізація наступних властивостей:

  • властивість BaudRate – задає швидкість передачі для послідовного порту (в бодах), в нашому випадку 115200;

  • властивість StopBits – задає кількість стопових бітів (в байтах), в нашому випадку 1 стоп біт;

  • властивість PortName – задає назву порта, до якого підключений мікроконтролер;

  • властивість DataBits – кількість біт даних 8;

  • властивість Parity – контроль парності вимкнено.

Після ініціалізації об’єкту можна відкрити порт за допомогою методу Open(), відповідно закрити порт можна за допомогою методу Close().

В програмі створено об’єкт «trd» класу Thread. Цей потік починає виконуватися, коли користувач з’єднається з контролером натиснувши кнопку «Підключитися». В цьому потоці виконується надсилання команд мікроконтролеру, за допомогою методу sp.WriteLine(«Command»), в нашому випадку «Command» може набувати: «1», «2», «3» (рисунок 4.3).

При надсиланні контролеру команду «1», він перетворює аналоговий сигнал з каналу АЦП ADC1_IN15 в цифрову інформацію, обчислює напругу і повертає робочій станції результат.

При надсиланні команди «2», контролер перетворює аналоговий сигнал з каналу АЦП ADC1_IN8 в цифрову інформацію, обчислює температуру і повертає робочій станції результат.

Рисунок 4.3 – Опитування мікроконтролера робочою станцією

При надсиланні команди «3», контролер перетворює аналоговий сигнал з каналу АЦП ADC1_IN16 в цифрову інформацію, обчислює температуру вбудованого термометра та повертає робочій станції результат.

Всі перераховані вище команди надсилаються послідовно.

Після надсилання команди контролеру, виконується затримка за допомогою функції Thread.Sleep(TimerInterval) де «TimerInterval» час затримки в мілісекундах, який може задавати користувач. Це потрібно виконувати через відсутність прикладного рівня протоколу обміну даними. Затримка дає час мікроконтролеру на перетворення аналогового сигналу в цифрові данні та на перетворення їх в потрібний результат.

Після затримки відбувається зчитування інформації з порту за допомогою методу sp.ReadExisting(). Всі прийняті данні присвоюються глобальним змінним «strgetV», «strgetT1», «strgetT2» відповідно. В подальшому всі ці змінні використовуються для виведення графіків.

Було написано клас «DrawGraphics» за допомогою якого будуються графіки. В цьму класі використовується системний класс «Graphics». Клас Graphics – це основний клас, необхідний для малювання. Перед тим як малювати лінії і фігури, відображати текст, виводити зображення і керувати ними, необхідно створити об’єкт Graphics. Об’єкт Graphics представляє поверхню малювання і використовується для створення графічних зображень.

Нижче представлені два етапи роботи з графікою.

  1. Створення об’єкта Graphics.

  2. Використання об’єкта Graphics для малювання ліній і фігур, відображення тексту або зображення і керування ними.

Після створення об’єкту Graphics його можна використовувати для малювання ліній і фігур, відображення тексту або зображення і керування ними. Нижче представлені основні об’єкти, що використовуються з об’єктом Graphics.

  • Клас Pen – служить для малювання ліній, контурів і відтворення інших геометричних об’єктів.

  • Клас Brush – служить для заливки областей, наприклад фігур, зображень або тексту.

  • Клас Font – містить опис фігур, які повинні використовуватися при відображенні тексту.

  • Структура Color – містить різні кольори [10].

Так як будується три графіки створено три об’єкта: «obj1», «obj2», «obj3» класу «DrawGraphics». В конструктор об’єктів передається об’єкт класу PictureBox на якому буде малюватися графік.

Для малювання графіків створений окремий таймер «TimerDraw» в якому послідовно викликається метод Draw(float new_y) обєктів «obj1», «obj2», «obj3» де new_y відповідна величина аналогового сигналу в конкретний момент часу (рисунок 4.4).

Рисунок 4.4 – Побудова графіків

Для збереження отриманих даних в базу даних формату Access 2002 – 2003, написаний клас BDAddapter. Було також створено, ще один таймер «TimerWriteToBD», який використовується для додавання нових записів в базу даних. Цей таймер виконується з інтервалом який встановлює користувач через графічне середовище програми. В таймері виконується метод AddToLog(string sensor_id, DateTime date, string value) класу BDAddapter, який і додає в базу даних новий запис, через кожний інтервал роботи таймеру.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]