Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2018-дек-12 05:33

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 4 ] 
Автор Сообщение
 Заголовок сообщения: Помощь начинающему =)
СообщениеДобавлено: 2018-окт-19 19:24 
Не в сети

Зарегистрирован: 2018-окт-18 22:29
Сообщения: 4
Здравствуйте, по долгу службы хорошо было бы овладеть работой с АЦП, увидеть как что работает, что выдает и т.д. На работе имеется отладочная плата 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В), прошу помочь :roll: . Не судите строго программу,которую прикрепляю, её стиль и т.д., не профессиональный программист :D . Буду благодарен за помощь. :)

Код:
#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;                            //очищаем флаг передачи 
    }
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь начинающему =)
СообщениеДобавлено: 2018-окт-22 09:05 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1183
Откуда: Тула
Покажите что у Вас выводится в PuTTY.
Расскажите что Вы ожидаете там увидеть? (при разных напряжениях)
Как Вы видите работу этого кода?
Цитата:
UART_SendData (MDR_UART2, rawResult);
UART_SendData (MDR_UART2, result);

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь начинающему =)
СообщениеДобавлено: 2018-окт-22 09:13 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 195
Откуда: ПКК "Миландр"
Я бы поменял логику основного цикла, сейчас происходит:
- Прием слова ReciveByte по UART
- Запуск АЦП
- Передача ++ReciveByte
- Передача rawResult и result - Что в этих переменных, предыдущие значения или АЦП успел их обновить?

АЦП для измерения необходимо 28 тактов, но и делитель частоты выставлен в 512.

АЦП и UART работают правильно, значения не пропадают. Вы убедитесь в этом если отладчиком проверите значения выдаваемые АЦП. Полагаю, что проблема в логике работы программы.

_________________
Отдел технической поддержки support@milandr.ru


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь начинающему =)
СообщениеДобавлено: 2018-ноя-27 16:48 
Не в сети

Зарегистрирован: 2018-окт-18 22:29
Сообщения: 4
Действительно проблема в логике программы.
Поставил инициализацию АЦП в другую прогу и все заработало :)
Спасибо за направление мысли :)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB