
- •1. Высокоскоростная передача через порты общего назначения.
- •2. Использование таймеров для генерации временных интервалов и тональных сигналов
- •3. Характеристики аналого-цифрового преобразователя
- •4. Генерация сигнала методом прямого цифрового синтеза. Быстрое преобразование Фурье (бпф)
- •4.1. Проверка работы генератора гармонического сигнала и аналого-цифрового преобразования.
- •4.2. Исследование особенностей бпф.
- •4.3. Использование оконной функции.
3. Характеристики аналого-цифрового преобразователя
Число "шумовых" разрядов без усреднения |
4 |
Число "шумовых" разрядов с усреднением |
2 |
Напряжение без знака |
Напряжение со знаком |
Смещенный код |
Дополнительный код |
||
10-чный |
двоичный |
10-чный |
двоичный |
||
3.3 |
1.65 |
4095 |
111111111111 |
2047 |
011111111111 |
2.417 |
0.767 |
3000 |
101110111000 |
952 |
001110111000 |
1.658 |
0.009 |
2058 |
100000001010 |
10 |
000000001010 |
1.651 |
0.001 |
2048 |
100000000000 |
0 |
000000000000 |
1.641 |
-0.008 |
2038 |
011111110110 |
-10 |
111111110110 |
0.806 |
-0.844 |
1001 |
001111101001 |
-1047 |
101111101001 |
0.017 |
-1.634 |
20 |
000000010100 |
-2028 |
100000010101 |
0 |
0 |
0 |
000000000000 |
-2048 |
100000000000 |
Текст программы
//---------------------------------------------------------------------------
//
// УЧЕБНЫЙ ПРОЕКТ
// Программирование аналого-цифрового преобразователя
// Copyright (C) 2013 МГТУ МИРЭА
//
// Для тестирования работы АЦП используется установленный на плате потенциометр
// (триммер), посредством которого на разряде порта PC0 можно изменять напряжение
// в пределах 0...3.3 В. Разряд PC0 имеет альтернативные функции: аналоговые входы
// ADC1_IN10, ADC2_IN10, ADC3_IN10.
// Реализованы режимы работы со смещенным и дополнительным кодами, режим усреднения.
//
//---------------------------------------------------------------------------
#include "stm32_p407.h" //Файл конфигурации отладочной платы STM32-P407
#include "lcd.h" //Функции для работы с дисплеем
#define AVERAGE 300 //Число усреднений данных с АЦП
//---------------------------------------------------------------------------
// ИНИЦИАЛИЗАЦИЯ АЦП
void ADCInitialize(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //Структура конфигурации портов общего назначения
ADC_CommonInitTypeDef ADC_CommonInitStruct; //Структура общей конфигурации АЦП
ADC_InitTypeDef ADC_InitStructure; //Структура конфигурации АЦП
//Конфигурирование разряда порта как аналогового входа
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //Разрешение тактирования порта
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //Номер разряда (маска)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //Альтернативная функция: аналоговый вход
GPIO_Init(TRIMER_PORT, &GPIO_InitStructure); //Функция конфигурирования
//Разрешение тактирования АЦП
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
//Задание общей конфигурации АЦП по умолчанию:
// - режим одиночного АЦП;
// - предварительный делитель тактовой частоты на 2;
// - запрет режима прямого доступа к памяти при совместной работе АЦП;
// - сдвиг между преобразованиями при совместной работе - 5 тактов.
ADC_CommonStructInit(&ADC_CommonInitStruct);
ADC_CommonInit(&ADC_CommonInitStruct);
//Конфигурирование АЦП (ADC2)
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //Разрядность преобразования: 12
// (возможно 10, 8, 6)
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //Многокан. сканирование: не разрешено
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //Непрерывное преобразование: разрешено
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
//Фронт сигнала запуска: нет
ADC_InitStructure.ADC_ExternalTrigConv = 0; //Источник запуска: не задан
// (используется программный)
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left; //Выравнивание кода в 16-разр.поле: влево
ADC_InitStructure.ADC_NbrOfConversion = 1; //Число каналов для преобразования: 1
ADC_Init(ADC2, &ADC_InitStructure); //Функция конфигурирования
//Дополнительные параметры для ADC2:
// - входной канал с номером 10 (возможные номера каналов: 1...15);
// - число групп преобразования - 1 (возможно до 16 групп),
// - время преобразования - 56 тактов (возможные значения: 3, 15, 28, 56, 84, 112, 144, 480)
ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_56Cycles);
//Разрешение работы АЦП
ADC_Cmd(ADC2, ENABLE);
}
//---------------------------------------------------------------------------
// ПРЕОБРАЗОВАНИЕ 12-РАЗРЯДНОГО КОДА В СТРОКУ ДВОИЧНЫХ СИМВОЛОВ
// Входной параметр: преобразуемый код
// Возвращается указатель на строку (с завершаюшим нулем)
char str12[13];
char* Bin12ToStr(unsigned short data)
{
int i;
for (i = 0; i < 12; i++) *(str12+i) = (char)(((data >> (11-i)) & 1) + '0');
*(str12+i) = '\0';
return str12;
}
//---------------------------------------------------------------------------
// ПОДПРОГРАММА ВРЕМЕННОЙ ЗАДЕРЖКИ
// Входной аргумент: значение задержки в микросекундах.
void Delay_us(int us)
{
volatile int i;
while (--us) { i = 27; while (--i); }
}
//---------------------------------------------------------------------------
// ГЛАВНАЯ ФУНКЦИЯ
int main()
{
long AdcData; //Исходные данные с АЦП
unsigned short UData16; //Приведенный смещенный (беззнаковый) код
short Data16; //Приведенный дополнительный (знаковый) код
bool OffsetCode = true; //Тип кода: смещенный - дополнительный
int Average = 1; //Текущее число усреднений
int i; //Текущая переменная цикла
//Инициализация кнопок
STM_PBInit(BUTTON_WAKEUP, BUTTON_MODE_GPIO); //Кнопка WAKEUP выхода из программы
STM_PBInit(BUTTON_LEFT, BUTTON_MODE_GPIO); //Позиции джойстика для переключения типа кода
STM_PBInit(BUTTON_RIGHT, BUTTON_MODE_GPIO);
STM_PBInit(BUTTON_UP, BUTTON_MODE_GPIO); //Позиции джойстика для переключения режима
STM_PBInit(BUTTON_DOWN, BUTTON_MODE_GPIO); // усреднения
//Инициализация дисплея
LCD_Init(); LCD_Clear(0);
LCD_FontSize(11);
LCD_TextPos(1,1); LCD_print("Смещенный код:");
LCD_TextPos(1,5); LCD_print("Напряжение, В:");
//Инициализация и первичный запуск АЦП
ADCInitialize();
ADC_SoftwareStartConv(ADC2);
//Цикл в основной программе
while (1)
{
//Изменение типа кода в зависимости от позиции джойстика
if (STM_PBGetState(BUTTON_LEFT))
{ OffsetCode = true;
LCD_TextPos(1,1); LCD_print("Смещенный код:");
}
if (STM_PBGetState(BUTTON_RIGHT))
{ OffsetCode = false;
LCD_TextPos(1,1); LCD_print("Дополнит.код: ");
}
//Изменение числа усреднений в зависимости от позиции джойстика
if (STM_PBGetState(BUTTON_UP))
{ Average = AVERAGE;
LCD_TextPos(1,0); LCD_print("- Усреднение -");
}
if (STM_PBGetState(BUTTON_DOWN))
{ Average = 1;
LCD_TextPos(1,0); LCD_print(" ");
}
//Цикл по измерениям
for (i = Average, AdcData = 0; i > 0; i--)
{
AdcData += ADC_GetConversionValue(ADC2); //Ввод и суммирование показаний
ADC_SoftwareStartConv(ADC2); //Новый запуск преобразования
}
//Преобразование кода с АЦП
UData16 = AdcData / Average; //Вычисление среднего
Data16 = UData16 ^ 0x8000; //Преобразование смещ. кода в дополнительный
Data16 >>= 4; UData16 >>= 4; //Приведение кода к 12-разрядному
//Вывод результатов на дисплей
LCD_TextPos(1,2);
LCD_print("%d ", OffsetCode ? UData16 : Data16); //В 10-й системе
LCD_TextPos(1,3);
LCD_print("%s", Bin12ToStr(OffsetCode ? UData16 : Data16)); //В 2-й системе
LCD_TextPos(1,6);
LCD_print("%.3f (%.3f) ", UData16*3.3f/4096.f, Data16*3.3f/4096.f); //Значения напряжений
Delay_us(100000); //Период обновления
// индикации
//Проверка нажатия кнопки WAKEUP завершения программы
if (STM_PBGetState(BUTTON_WAKEUP)) NVIC_SystemReset();
}
}
//---------------------------------------------------------------------------