Смекни!
smekni.com

Система вимірника струмів (стр. 2 из 2)

Рис. 2.6 – Схема стабілізатору напруги живлення

Розрахунок резистора R4:

R4 = UVcc/Id – R3 = 5/0.0006 – 1800 = 6333 Ом

Приймемо значення опору R4 рівним 6,2 кОм.


3. Проектування програмного забезпечення мікропроцесора

Розробку програми для мікроконтролеру варто почати з алгорітму його функціонування. Програма повинна послідовно виконувати наступні задачі:

- ініціалізувати необхідні у схемі вузли;

- знімати результати перетворення АЦП;

- перетворювати данні з АЦП;

- видавати оброблені данні на РКІ;


3.1 Проектування процедури ініціалізації апаратури мікропроцесора

У процедурі ініціалізації ми повинні налаштувати усі задіяні вузли мікроконтролеру та зовнішніх пристроїв за допомогою функцій, які встановлять усі необхідні режими роботи та початкові значення регістрів, потрібних для роботи програми. Ми повинні проініціалізувати наступні блоки:

- порти вводу/виводу;

- таймер-лічильник 0;

- АЦП;

- РКІ;

Функція налаштування портів, АЦП та таймеру:

void init_mega (void)

{

DDRC = 0xFF; // порт С на вивід

DDRB = 0xFF; // порт В на вивід

DDRD = 0xFF; // порт D на вивід

ACSR = 0x80; // вимкнення компаратору

ADMUX = ADC_VREF_TYPE; // зовнішнє джерело опорної напруги, вхід АЦП – порт А, вхід 0

ADCSRA = 0xEE; // АЦП – вкл, почати перетворення, режим переривання від Т/Л0, дозвіл переривання від АЦП

SFIOR = 0x80; // переривання по переповненню Т/Л0

#asm("cli") // заборона усіх переривань

TIMSK |= (1 << TOIE0); // дозвіл переривань від Т/Л0

TCNT0=Tmr0_Reload; // завантаження початкового значення

TCCR0=PrescalerTmr0; // обрання частоти тактового сигналу

}


Функція налаштування роботи РКІ

void lcd_init (void)

Ця функція використана із стандартного include – файлу LCD.h компілятору. Її повне описання можна переглянути у компіляторі. Вона налаштовує РКІ на режим роботи з 4 лініями даних, без включення курсору, відображення символів ввімкнено, режим роботи з двома строками. Керуюча послідовність:

_lcd_init_write(0x30);

_long_delay();

_lcd_init_write(0x30);

_long_delay();

_lcd_init_write(0x30);

_long_delay();

_lcd_init_write(0x20);

_long_delay();

_lcd_write_data(0x28);

_long_delay();

_lcd_write_data(0x04);

_long_delay();

_lcd_write_data(0x85);

_long_delay();

3.2 Проектування процедур обробки переривань

Обробка процедури переривань досить проста:

- переривання від Т/Л0

interrupt [TIM0_OVF] void TIMER0_OVF_interrupt(void)

{

TCNT0=Tmr0_Reload; // перезавантаження Т/Л0

TMR0Flag = 1; // встановлення флагу переривання Т/Л0

SETBIT(ADCSRA,6); // запуск АЦП

}

- переривання від АЦП

interrupt [ADC_INT] void adc_isr(void)

{

ADCFlag = 1; // встановлення флагу переривання АЦП

}

3.3 Проектування процедур вводу інформації

Процедура вводу інформації полягає у об’яві змінної та присвоєнні їй значення 16 бітного регістру доступу до АЦП ADCW.

int A;

A = ADCW;

3.4 Проектування процедур виводу інформації

Вивід інформації полягає у виводі даних після обробки на РКІ. Ця процедура виконується за допомогою функцій, які входять до бібліотеки LCD.lib та файлу LCD.h

lcd_gotoxy(2,0); //Встановлення адреси знакомісця на 2 позицію у першій строці

lcd_putsf("Current, A:"); //Вивід строки

lcd_gotoxy(5,1); // Встановлення адреси знакомісця на 5 позицію у другій строці

lcd_putchar(a1 + 0x30); // Вивід першої значущої цифри результату із зміщенням

lcd_gotoxy(6,1); // Встановлення адреси знакомісця на 6 позицію у другій строці

lcd_putchar(0x2C); // Вивід символу коми

lcd_gotoxy(7,1); // Встановлення адреси знакомісця на 7 позицію у другій строці

lcd_putchar(a2 + 0x30); // Вивід другої значущої цифри результату із зміщенням

lcd_gotoxy(8,1); // Встановлення адреси знакомісця на 8 позицію у другій строці

lcd_putchar(a3 + 0x30); // Вивід третьої значущої цифри результату із зміщенням

3.5 Проектування процедури перетворення інформації

Для виводу інформації на дисплей її необхідно обробити. АЦП має 10 розрядів, тобто він може перетворювати вимірювану величину з кроком 1/1023*Uref. Для простоти перетворень задамось, що максимальне значення нашої змінної яка буде зберігати значення після перетворення буде дорівнювати 2048. Таким чином ми отримуємо формулу для перетворення:

Current = 2 * ADC

Current = ((long)2 * (long)A;

Максимальне значення АЦП – 1023 буде відповідати значенню 2048 нашої змінної.

Тепер нам необхідно перекодувати значення змінної Current до BCD формату. Це можна реалізувати за допомогою функцій:


a1 = a/1000;

a2 = (a - (a1 * 1000))/100;

a3 = (a - (a1 * 1000) - (a2 * 100))/10;

a4 = (a -(a1 * 1000) - (a2 * 100) - (a3 * 10));

де а – вхідна змінна типу int;

а1 – тисячі;

а2 – сотні;

а3 – десятки;

а4 – залишок;

3.6 Проектування процедури main()

Процедура main() повинна складатися з процедур ініціалізації, основного тіла програми та незкінченного циклу. Після ініціалізації всіх вузлів дозволяються усі переривання і ми очікуємо переривання від АЦП, при приході переривання ми аналізуємо флаг ADCFlag , і якщо він дорівнює 1, то ми переходимо до тіла основної програми. Зчитуємо значення АЦП, перетворюємо його, виводимо текстове повідомлення на РКІ. Далі ми аналізуємо чи змінилось значення АЦП, і якщо так, то забороняємо переривання, викликаємо процедури перетворення та відображення результату, відновлюємо дозвіл на переривання.

void main(void)

{

init_mega();

lcd_init(16);

#asm("sei")

while(1)

{


int A, Current;

A = ADCW;

if (ADCFlag)

{

ADCFlag = 0;

Current = 2 * A;

lcd_gotoxy(2,0);

lcd_putsf("Current, A:");

//lcd_gotoxy(0,1);

//lcd_putsf("PREVED AE-022!!!");

if (d != A)

{

#asm("cli")

bar (2000,0);

d = A;

convert_out (Current, 5, 1);

#asm("sei")

}

}

}

}


4. Лістінг програми

#include "interrupt.h"

#include "io.h"

#include "mega16.h"

#include "signal.h"

#include "delay.h"

#include "string.h"

#include <stdio.h>

#include <delay.h>

#include <lcd.h>

//############################################################################################

#define ADC_VREF_TYPE 0x40

#define Tmr0_Reload 0

#define PrescalerTmr0 5 // timer0 counts clk/256

#define TOIE0 0

#define ADSC 0

#define CLRBIT(x,y) ((x&=~(1<<y)))

#define SETBIT(x,y) ((x|=(1<<y)))

//############################################################################################

#asm

.equ __lcd_port=0x15 ;PORTC

#endasm

//############################################################################################

unsigned char ADCFlag = 0;

unsigned char TMR0Flag = 0;

int d;

//############################################################################################

interrupt [ADC_INT] void adc_isr(void)

{

ADCFlag = 1;

}

//############################################################################################

interrupt [TIM0_OVF] void TIMER0_OVF_interrupt(void)

{

TCNT0=Tmr0_Reload;

TMR0Flag = 1;

SETBIT(ADCSRA,6);

}

//############################################################################################

void init_mega (void)

{

DDRC = 0xFF;

DDRB = 0xFF;

DDRD = 0xFF;

ACSR = 0x80;

ADMUX = ADC_VREF_TYPE;

ADCSRA = 0xEE;

SFIOR = 0x80;

#asm("cli")

TIMSK |= (1 << TOIE0);

TCNT0=Tmr0_Reload;

TCCR0=PrescalerTmr0;

}

//############################################################################################

void convert_out (int a, char position_x, char position_y )

{

int a1, a2, a3, a4;

a1 = a/1000;

lcd_gotoxy(position_x,position_y);

lcd_putchar(a1 + 0x30);

a2 = (a - (a1 * 1000))/100;

lcd_gotoxy(position_x + 1,position_y);

lcd_putchar(0x2C);

lcd_gotoxy(position_x + 2,position_y);

lcd_putchar(a2 + 0x30);

a3 = (a - (a1 * 1000) - (a2 * 100))/10;

lcd_gotoxy(position_x + 3,position_y);

lcd_putchar(a3 + 0x30);

a4 = (a -(a1 * 1000) - (a2 * 100) - (a3 * 10));

lcd_gotoxy(position_x + 4,position_y);

lcd_putchar(a4 + 0x30);

}

//############################################################################################

void bar (char time, char posit)

{

lcd_clear();

lcd_gotoxy(posit,0);

lcd_putsf("Working.");

delay_ms(time);

lcd_clear();

lcd_putsf("Working..");

delay_ms(time);

lcd_clear();

lcd_putsf("Working...");

delay_ms(time);

lcd_clear();

lcd_putsf("Working....");

delay_ms(time);

lcd_clear();

}

//############################################################################################

void main(void)

{

init_mega();

lcd_init(16);

#asm("sei")

while(1)

{

int A, Current;

A = ADCW;

if (ADCFlag)

{

ADCFlag = 0;

Current = 2 * A;

lcd_gotoxy(2,0);

lcd_putsf("Current, A:");

//lcd_gotoxy(0,1);

//lcd_putsf("PREVED AE-022!!!");

if (d != A)

{

#asm("cli")

bar (2000,0);

d = A;

convert_out (Current, 5, 1);

#asm("sei")

}

}

}

}

//############################################################################################

Файл LCD.h

#ifndef _LCD_INCLUDED_

#define _LCD_INCLUDED_

#pragma used+

void _lcd_ready(void);

void _lcd_write_data(unsigned char data);

// write a byte to the LCD character generator or display RAM

void lcd_write_byte(unsigned char addr, unsigned char data);

// read a byte from the LCD character generator or display RAM

unsigned char lcd_read_byte(unsigned char addr);

// set the LCD display position x=0..39 y=0..3

void lcd_gotoxy(unsigned char x, unsigned char y);

// clear the LCD

void lcd_clear(void);

void lcd_putchar(char c);

// write the string str located in SRAM to the LCD

void lcd_puts(char *str);

// write the string str located in FLASH to the LCD

void lcd_putsf(char flash *str);

// initialize the LCD controller

unsigned char lcd_init(unsigned char lcd_columns);

#pragma used-

#pragma library lcd.lib

#endif


5. Рекомендаціі по розробці програмних та апаратних діагностичних засобів для перевірки працездатності пристрою

Для розробки програми варто використати достатньо легкий у освоєнні пакет CodeVisionAVR C Compiler . До його функцій входить така важлива риса, як наявність власного програматора. Для відпрацювання програми треба використовувати фірмовий пакет ATMEL AVR Studio.

Зібраний пристрій треба запрограмувати та відкалібрувати за допомогою точного зовнішнього амперметру, джерела живлення, навантаження. Калібрування треба проводити встановленням або зняттям перемичок на шунті (резистор R1 на схемі пристрою) виконаним друкованим способом. Встановити таким чином рівні показання приладу та амперметру при різних значеннях струму.


6. Проектування плати друкованої пристрою

На сьогоднішній день існує багато програмних пакетів спеціально розроблених для розведення та проектування друкованих плат, таких як PCad, OrCad, Eagle, але з метою закріплення знань з таких дисциплін як САПР, ТЕМЦ , метрології та т.п. вирішено розробити плату друковану ручним способом у пакеті Sprint-Layout4 з урахуванням усіх вимог та стандартів. Розмір ПД вирішено обрати таким самим як і розміри плати РКІ. Їх крепіжні отвори співпадають. У корпусі вони кріпляться друг за другом за допомогою гвинтів.


Висновок

У даному курсовому проекту ми детально розібрали устрій, алгорітм роботи та способи програмування мікроконтролерами фірми ATMEL. На прикладі МК ATmega16 розробили пристрій вимірювання струму до 2А. Відладили програму, розробили принципову схему та плату друковану. Зібрали пристрій на макетній платі та опробували його працездатність.


Література

1. Программирование на языке С для AVR и PIC микроконтроллеров. / Сост. Ю.А.Шпак – К.: «МК-Пресс» , 2006. – 400 с., ил

2. Микроконтроллеры AVR семейств Tiny и Mega фирмы ATMEL, 2-е изд., стер. – М.: Издательский дом «Додека-ХХІ», 2005. – 560с.


Вид со стороны А (деталей)

Вид со стороны В


Схема расположения элементов (вид сверху)