Lab_4 / MPU_lab_4
.docxСанкт – Петербургский государственный электротехнический университет им. В. И. Ульянова (Ленина)
Лабораторная работа №4
«Применение аналого-цифрового преобразователя»
Цель работы: освоение принципов работы с аналого-цифровым преобразователем
микроконтроллера AT91SAM7S и получения результатов измерений.
Задание:
На вход нормирующего преобразователя, подключённого к каналу 4 АЦП
поступает случайный сигнал, имеющий математическое ожидание, равное 15 В.
Диапазон возможных значений сигнала: 0 … 35 В. Коэффициент усиления
нормирующего преобразователя 0,08. По нажатию на кнопку на отладочной плате
необходимо выполнить серию из 20000 измерений, по результатам которой зажечь
светодиод на отладочной плате, если СКО сигнала превышает 2 В. По окончании
серии повторное нажатие на кнопку должно запускать новую серию измерений.
Частота тактирования АЦП — 3 МГц. Время выборки — 1 мкс.
Структурная схема измерительного канала:
Ux
K Ux
Nx
НП
АЦП
АЦП – Аналого-цифровой преобразователь.
НП – Нормирующий преобразователь.
– код преобразования.
– измеряемый сигнал.
- коэффициент усиления нормирующего преобразователя.
Функция обратного преобразования измерительного канала:
Обоснование выбора разрядности преобразования:
Для выполнения данной задачи можно использовать, как и 8-и разрядное преобразование, так и 10-разрядное, 8-разрядные преобразования обычно используют, если требуется повысить быстродействие АЦП за счет меньшего времени преобразования. В данном случае нам не требуется быстродействие системы. Поэтому используем 10-ти разрядное преобразование с целью повышения точности измерений.
Оценка погрешности измерительного канала:
Погрешность вносимая АЦП микроконтроллера:
Аддитивная погрешность ед. младшего разряда.
Мультипликативная погрешность ед. младшего разряда.
Погрешность нелинейности ед. младшего разряда.
Складывая погрешности находим полная погрешность равна:
Вывод формулы для вычисления СКО:
Формула дисперсии для n измерений имеет вид:
Запишем формулу для n+1измерений
Настройка параметров работы АЦП:
Для настройки АЦП необходимо в регистр ADC_MR необходимые параметры.
AT91C_ADC_LOWRES_10_BIT – Устанавливаем бит, отвечающий за разрядность преобразования.
AT91C_ADC_SLEEP_NORMAL_MODE- Устанавливаем бит нормального режима работы АЦП.
Найдем параметр PRESCAL который необходимо записать в 8-13 биты в регистра для установки частоты тактирования равной 3 МГц:
Делитель частоты, формирующий частоту тактирования АЦП.
Частота тактирования определяется по формуле:
где – частота главного тактового генератора.
0x0E<<8 - установка параметра делителя PRESCAL
Найдем параметр SHTIM который необходимо записать после 24-27 бита в регистр для установки времени выборки равной 1 мкс:
Величина, определяющая время выборки.
Время выборки определяется по формуле:
0x02<< 24 - Установка времени выборки равное 1мкс.
Алгоритм решения задачи:
Исходный текст программы:
#include "Board.h"
#include "math.h"
// Массив масок для ножек микроконтроллера,
// к которым подключены светодиоды.
static const int ledMask[2]= {LED1, LED2};
// Указатель на структуру, предназначенную для
// управления контроллером параллельного ввода-вывода (PIO)
static AT91PS_PIO pioa = AT91C_BASE_PIOA;
// Указатель на структуру, управляющую контроллером питания (PMC).
// Через него включается тактирование PIO, необходимое для
// считывания состояния кнопок, находящихся на отладочной плате.
static AT91PS_PMC pmc = AT91C_BASE_PMC;
// Создать переменную типа 'указатель на структуру данных AT91S_ADC'
// и присвоить ей начальное значение AT91C_BASE_ADC
static AT91PS_ADC adc = AT91C_BASE_ADC;
// Подготовка к работе со светодиодами
void setUpLeds (void)
{
// Указываем, что ножками, к которым подключены светодиоды
// управляет PIO, а не встроенная периферия.
pioa->PIO_PER = LED_MASK;
// Ножки будем использовать как выходы
// (для подачи напряжения).
pioa->PIO_OER = LED_MASK;
// Гасимсветодиоды
pioa->PIO_SODR = LED_MASK;
}
//Подготовка к работе с АЦП
void setupADC (void)
{
//Установка режима работы АЦП
//AT91C_ADC_LOWRES_10_BIT - 10 разрядное преобразование
// AT91C_ADC_SLEEP_NORMAL_MODE – Нормальный режим работы.
//(0x07<<8)Установка частоты тактирования АЦП равной 3Мгц
//(установка параметра делителя (PRESCAL)
//(0x02<< 24) Установка времени выборки равное 1мкс
adc->ADC_MR = AT91C_ADC_LOWRES_10_BIT | AT91C_ADC_SLEEP_NORMAL_MODE | (0x07<<8) | (0x02<< 24);
// Включить 4й канал (разрешить преобразование по 4му каналу)
adc->ADC_CHER = AT91C_ADC_CH4;
}
// Подготовка к работе с кнопками
void setUpButtons (void)
{
// За кнопки отвечает PIO. По умолчанию соответствующие
//ножки сконфигурированы как входы.
pioa->PIO_PER = SW_MASK;
// Включаем тактирование PIO.
// Без этого не удастся прочитать состояния кнопок.
pmc->PMC_PCER = 1 << AT91C_ID_PIOA;
}
//Получение значения одного преобразования АЦП.
unsigned int getADCvalue (void)
{
//ЗапускАЦП
adc->ADC_CR = AT91C_ADC_START;
//Ожидания конца преобразования
// В цикле постоянно проверяем флаг готовности результата по 4му
// каналу (ждём пока не завершится преобразование)
while (! (adc->ADC_SR & AT91C_ADC_EOC4)) {};
//Считываниезначения
const unsigned in tadcCode = adc->ADC_CDR4;
return adcCode;
}
// Зажечь светодиод с указанным номером (нумерация от нуля)
// и погасить все остальные
void indicate (intindex)
{
// Зажечь светодиод
pioa->PIO_CODR = ledMask[index];
// Погасить все остальные.
pioa->PIO_SODR = (~ledMask[index]) & LED_MASK;
}
// Определить нажатие кнопки.
// Функция возвращает 1 если нажата одна из кнопок или 0, если никакая
// кнопка нен ажата.
int pressedButton (void)
{
// Прочитать состояния ножек
unsigned int pinsStatus = pioa->PIO_PDSR;
//Сравнение состояния ножек с маской вывода светодиода
//Если да, то ставим флаг нажатия кнопки
if (((~pinsStatus) & SW1)||((~pinsStatus) & SW2))
return 1;
return 0;
}
//Функция подготовки к работе устройств.
void int(void)
{
setUpLeds();
setUpButtons();
setupADC();
}
//ФункциявычисленияДисперсии.
double newdisp(double oldDisp, double newValue, int n)
{
double disp;
disp=oldDisp*(n-1)/n+(newValue-15)*(newValue-15)/n;
return (sqrt(disp));
}
// Начало программы.
int main(void)
{
//Инициализирование констант.
static const double K=3.3/1024/0.08;
static const int X=15;
init();// Подготовка к работе устройств. Начальные установки.
// Вечный цикл
while (1)
{
// Определяет, нажата ли кнопка.
int buttonIndex = pressedButton();
// Если нажата то выполняем расчеты.
if (buttonIndex ==1)
{
//Сброс переменных.
static double D=0;
static double Ux=0;
static int Value=0;
pioa->PIO_SODR = LED_MASK;// Гасимсветодиоды
for(intn=1;n<=20000;n++)//Цикл измерений.
{
Value=getADCvalue();//Получение кода преобразования.
Ux=Value*K;//Вычисление значения преобразования.
D=newdisp(D, Ux, n); //Вычисления дисперсии
}
if (D>=2)//Проверка условия превышения СКО.
indicate(1);//Зажигаем светодиод.
}
}
}
Выводы: .Применение АЦП в микроконтроллерных системах позволяют автоматически производить большой ряд измерений состояний нескольких объектов, по нескольким каналам связи, с последующей обработкой результатов и выводом информации об объекте измерения оператору. Регистровая организация позволяет настроить АЦП для корректной работы,управлять им, а также считывать результаты методом записи или чтения из определенных регистров.