Исходный код

// Включение заголовочных файлов

#include <avr/io.h>

#include <avr/interrupt.h>

// Задание частоты процессора 10 МГц

#define F_CPU 10000000UL

// Если частота не задана, то 16 МГц

#ifndef F_CPU

#define F_CPU 16000000UL

#endif

#include <util/delay.h>

#include <math.h>

#include "lcd.h"

/*Глобальные переменные

i - переменная-счетчик

a - номер действия

lim_i - целочисленное значение предела счета

f - частота для вывода на ЖКИ */

int i = 0, a = 0, lim_i = 0, f = 0;

// Прерывание по переполнению счетчика 1

ISR(TIMER1_OVF_vect) {

/* new_d - значение коэффициента заполнения ШИМ

lim - предел счета i

s - коэффицент для пересчета i в градусы */

int new_d;

double lim, s;

// Запуск преобразования АЦП

ADCSRA |= (1 << ADSC);

while ((ADCSRA & (1 << ADIF)) == 0);

// Если результат преобразования больше 20 (Напряжение на ножке больше 0.1 В)

if(ADCW >= 20) {

// Расчет предела счета i

lim = 10230 / ADCW;

// Защита от выхода за предел счета

if(i >= lim_i)

i = lim_i;

// Расчет коэффициента s

s = 90 / lim;

// Сохранение целочисленного предела счета

lim_i = ceil(lim);

// Расчет коэффиицента заполнения

new_d = sin(i * s * M_PI / 180) * 10000;

// Обновление коэффициента заполнения

ICR1 = 10000;

OCR1A = new_d;

// Расчет частоты для вывода на дисплей

f = ceil(500 / lim);

}

// Если меньше

else {

// Частота равна 0

f = 0;

// Коэффициент заполнения равен 0

OCR1A = 0;

}

// Выбор действия над i

switch(a) {

case 0:

i++;

if(i >= lim_i)

a++;

break;

case 1:

i--;

if(i == 0)

a--;

break;

}

}

int main(void) {

// str - буфер строки для вывода на ЖКИ

// f_b - буфер частоты для вывода на ЖКИ

char str[32], f_b;

// Инициализация портов

DDRA = 0x70;

DDRB = 0x20;

PORTA = 0x00;

PORTB = 0x00;

// Инициализация дисплея

lcd_init();

// Инициализация таймера-счетчика в режиме Fast PWM

ICR1 = 10000;

OCR1A = 5000;

TCCR1A |= (1 << COM1A1) | (1 << WGM11);

TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10);

TCCR1C = 0x00;

TIMSK |= (1 << TOIE1);

ETIMSK = 0x00;

// Инициализация АЦП

ADCSRA |= (1 << ADEN) | (1 << ADPS0);

ADMUX |= (1 << REFS0) | (1 << MUX0);

SFIOR = 0x00;

// Разрешение прерываний

sei();

// Рабочий цикл

while(1) {

if(f_b!= f) {

// Создание строки

sprintf(str, "freq = %d Hz", f);

// Очистка дисплея

lcd_clear();

// Вывод строки на дисплей

lcd_put_str(str);

f_b = f;

}

}

}

Проверка работы программы

Проверка работы программы осуществлялась на симуляторе. Результаты проверки показали, что работа программы соответствует условию задания.

Вывод

В результате выполнения лабораторной работы:

1. Изучены устройство и порядок работы с аналого-цифрового преобразователем (АЦП) МК ATmega128

2. Разработана программа, использующая АЦП. Алгоритм работы программы выполнен в виде блок-схем и представлен в отчете вместе с исходным кодом, содержащим необходимые комментарии. Произведена проверка, в результате которой программа показала корректную работу. Задача решена.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: