Здравствуйте, по долгу службы хорошо было бы овладеть работой с АЦП, увидеть как что работает, что выдает и т.д. На работе имеется отладочная плата LDM-K1986BE92QI, на мк написано MDR32F9Q2I ARM 1523 (возможно это важно). Нашёл в различных пособиях и лабниках по программированию Миландра и этого типа мк примеры программ. Первая - ввод бита информации в com-port и получение его обратно (я сделал увеличенный на единицу для наглядности)
работает на ура. Вторая - работа с АЦП, а именно снятие напряжения с определённого вывода. Хотел разобраться как и что - создал проект в Keil, объединил эти две программы, ожидая, что через com-port увижу символы, по котором можно расшифровать напряжение на выводе (в проге PD7).
В результате получаю, что есть оцифровка сигнала, но...частично. от 0,03 до 0,1 В, 0,24 - 0,31, 0,44 - 0,52, 0,65 - 0,72, 0,85 - 0,93, 1,06 - 1,13, 1,27 - 1,33, 1,47 - 1,53, 1,67 - 1,73, 1,88 - 1,96, 2,09 - 2,16, 2,29 - 2,37, 2,51 - 2,57, 2,73 - 2,79, 2,92 - 3,00, 3,12 - 3,20.
При этом, в каждом из этих промежутков действительно меняются символы с % через цифры, заглавные и строчные буквы до }. Если перебирать по 10 мВ, то перед каждой такой областью, в 2-3-х значениях программа не выдаёт результат оцифровки. (длинные пробелы, перескок строки или просто ничего), также иногда сбивается выполнение программы и стирается весь терминал com-port (использую PuTTy). Ну а теперь основное - в остальных значениях программа выдаёт символ, напоминающий закрашенный прямоугольник.
Если у кого-нибудь было что-нибудь похожее или есть идеи в чём проблема (всё таки хочется оцифровывать диапазон от 0 до 3,3В), прошу помочь

. Не судите строго программу,которую прикрепляю, её стиль и т.д., не профессиональный программист

. Буду благодарен за помощь.
#include "MDR32F9Qx_port.h"
#include "MDR32F9Qx_rst_clk.h"
#include "MDR32F9Qx_adc.h"
#include "stdbool.h"
#include "MDR32F9Qx_uart.h"
#include "MDR32Fx.h"
#define delay(T) for(i = T; i > 0; i--)
#define SCALE 1
//#define SCALE 1252.5
int i; //Счетчик для задержки циклом
ADC_InitTypeDef ADC; //Общая инициализацинная структура подсистемы АЦП
ADCx_InitTypeDef ADC1; //Инициализацинная структура для АЦП1
PORT_InitTypeDef PortInit; // определение переменной для инициализации портов ввода вывода
UART_InitTypeDef UART_InitStructure; // определение переменной для инициализации UART
uint32_t uart2_IT_TX_flag = RESET; // Флаг устанавливается после передачи одного байта
uint32_t uart2_IT_RX_flag = RESET; // Флаг устанавливается после приема одного байта
void ADCInit() {
//Подача тактования на процессор и АЦП
RST_CLK_PCLKcmd(RST_CLK_PCLK_RST_CLK | RST_CLK_PCLK_ADC, ENABLE);
ADC_StructInit(&ADC); //Заполнение структуры умолч. значениями
ADC_Init(&ADC); //Инициализация
ADCx_StructInit(&ADC1);
ADC1.ADC_ChannelNumber = ADC_CH_ADC7; //Switch to TRIM!!! //Выбор седьмого канала
ADC1.ADC_LevelControl = ADC_LEVEL_CONTROL_Disable;
/* ADC1.ADC_LevelControl = ADC_LEVEL_CONTROL_Enable;
ADC1.ADC_LowLevel = 3;
ADC1.ADC_HighLevel = 0;*/
ADC1.ADC_LowLevel = 0;
ADC1.ADC_HighLevel = 0;
ADC1.ADC_DelayGo = 7;
ADC1.ADC_Prescaler = ADC_CLK_div_512;
ADC1_Init(&ADC1);
//Int
//Инициализация прерываний АЦП
NVIC_EnableIRQ(ADC_IRQn);
NVIC_SetPriority(ADC_IRQn, 0);
//Включение прерываний по окончанию преобразования
ADC1_ITConfig(ADCx_IT_END_OF_CONVERSION, ENABLE);
ADC1_Cmd(ENABLE); //Включение АЦП1
}
void UART2_IRQHandler(void)
{
if (UART_GetITStatusMasked(MDR_UART2, UART_IT_RX) == SET)
//проверка установки флага прерывания по окончании приема данных
{
UART_ClearITPendingBit(MDR_UART2, UART_IT_RX);//очистка флага прерывания
uart2_IT_RX_flag = SET; //установка флага передача данных завершена
}
if (UART_GetITStatusMasked(MDR_UART2, UART_IT_TX) == SET)
//проверка установки флага прерывания по окончании передачи данных
{
UART_ClearITPendingBit(MDR_UART2, UART_IT_TX); //очистка флага прерывания
uart2_IT_TX_flag = SET; //установка флага передача данных завершена
}
}
bool conInProgress; //Флаг «в процессе преобразования»
unsigned int rawResult; //Необработанный результат
unsigned char channel; //Номер канала
float result; //Результат в вольтах
void ADC_IRQHandler() { //Обработчик прерываний АЦП
//Проверка что причина прерывания соответствует концу преобразования
if(ADC_GetITStatus(ADC1_IT_END_OF_CONVERSION)) {
rawResult = ADC1_GetResult(); //Получение результата
channel = (rawResult & 0x1F0000) >> 16; //Сохранение номера канала
rawResult &= 0x00FFF; //Удаление номера канала из результата
//Преобразование результата в вольты
result = (float)rawResult / (float)SCALE;
conInProgress = false; //Очистка флага «в процессе преобр-я»
NVIC_ClearPendingIRQ(ADC_IRQn); //Очистка флага прерывания
}
}
int main(void) {
static uint8_t ReciveByte=0x00; //данные для приема
ADCInit();
RST_CLK_HSEconfig(RST_CLK_HSE_ON);
// static uint8_t ReciveByte=0x00; //данные для приема
// Включение HSE осциллятора (внешнего кварцевого резонатора) для обеспечения стабильной
// частоты UART
if (RST_CLK_HSEstatus() == SUCCESS){
// Если HSE осциллятор включился и прошел текст
// Выбор HSE осциллятора в качестве источника тактовых импульсов для CPU_PLL
// и установка умножителя тактовой частоты CPU_PLL равного 8 = 7+1
RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSEdiv1, 7);
// Включение схемы PLL
RST_CLK_CPU_PLLcmd(ENABLE);
if (RST_CLK_HSEstatus() == SUCCESS){ //Если включение CPU_PLL прошло успешно
RST_CLK_CPUclkPrescaler(RST_CLK_CPUclkDIV2); // Установка CPU_C3_prescaler = 2
RST_CLK_CPU_PLLuse(ENABLE);
// Установка CPU_C2_SEL от CPU_PLL выхода вместо CPU_C1 такта
/* Выбор CPU_C3 такта на мультиплексоре тактовых импульсов микропроцессора (CPU
clock MUX) */
RST_CLK_CPUclkSelection(RST_CLK_CPUclkCPU_C3);
}
else while(1);// блок CPU_PLL не включился
}
else while(1); // кварцевый резонатор HSE не включился
RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTF, ENABLE); //Разрешение тактирования порта F
// заполнение полей переменной PortInit для обеспечения работы UART
PortInit.PORT_PULL_UP = PORT_PULL_UP_OFF;
PortInit.PORT_PULL_DOWN = PORT_PULL_DOWN_OFF;
PortInit.PORT_PD_SHM = PORT_PD_SHM_OFF;
PortInit.PORT_PD = PORT_PD_DRIVER;
PortInit.PORT_GFEN = PORT_GFEN_OFF;
PortInit.PORT_FUNC = PORT_FUNC_OVERRID;
PortInit.PORT_SPEED = PORT_SPEED_MAXFAST;
PortInit.PORT_MODE = PORT_MODE_DIGITAL;
// Конфигурация 1 ножки порта PORTD как выхода (UART2_TX)
PortInit.PORT_OE = PORT_OE_OUT;
PortInit.PORT_Pin = PORT_Pin_1;
PORT_Init(MDR_PORTD, &PortInit);
// Конфигурация 2 ножки порта PORTD как входа (UART2_RX)
PortInit.PORT_OE = PORT_OE_IN;
PortInit.PORT_Pin = PORT_Pin_2;
PORT_Init(MDR_PORTD, &PortInit);
//Разрешение тактирования UART2
RST_CLK_PCLKcmd(RST_CLK_PCLK_UART2, ENABLE);
// Инициализация делителя тактовой частоты для UART2
UART_BRGInit(MDR_UART2, UART_HCLKdiv1);
// Разрешение прерывания для UART2
NVIC_EnableIRQ(UART2_IRQn);
// Заполнение полей для переменной UART_InitStructure
UART_InitStructure.UART_BaudRate = 9600; //тактовая частота передачи данных
UART_InitStructure.UART_WordLength = UART_WordLength8b; //длина символов 8 бит
UART_InitStructure.UART_StopBits = UART_StopBits1; //1 стоп бит
UART_InitStructure.UART_Parity = UART_Parity_No; // нет контроля четности
UART_InitStructure.UART_FIFOMode = UART_FIFO_OFF; // выключение FIFO буфера
/* Аппаратный контроль за передачей и приемом */
UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_RXE | UART_HardwareFlowControl_TXE;
UART_Init (MDR_UART2, &UART_InitStructure); //Инициализация UART2
UART_ITConfig (MDR_UART2, UART_IT_RX, ENABLE);//Разрешение прерывания по приему
UART_ITConfig (MDR_UART2, UART_IT_TX, ENABLE);//Разрешение прерывания по окончани передачи
UART_Cmd(MDR_UART2, ENABLE); //Разрешение работы UART2
while (1) {
while (uart2_IT_RX_flag != SET); //ждем пока не не установиться флаг по приему байта
uart2_IT_RX_flag = RESET; //очищаем флаг приема
ReciveByte = UART_ReceiveData (MDR_UART2); //считываем принятый байт
delay(0xFFFF);
if (!conInProgress) { //Не выполняется ли преобразование?
ADC1_Start(); //Начать преобразование!
conInProgress = true; //Преобразование выполняется
}
UART_SendData (MDR_UART2, ++ReciveByte);
UART_SendData (MDR_UART2, rawResult);
UART_SendData (MDR_UART2, result); //отправляем принятый байт, увеличенный на единицу обратно
while (uart2_IT_TX_flag != SET); //ждем пока байт уйдет
uart2_IT_TX_flag = RESET; //очищаем флаг передачи
}
}