Миландр

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

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




Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Странное поведение АЦП
СообщениеДобавлено: 2016-ноя-27 14:33 
Не в сети

Зарегистрирован: 2016-ноя-27 13:56
Сообщения: 10
Здравствуйте, проблема в следующем, при повышение измеряемого напряжения, погрешность АЦП постоянно растет. При 0.7 В погрешности почти не заметна, в то время как напряжение возрастает до 3, погрешность измерения составляет 0,6в. Подскажите, в чем может быть проблема, я все мозги сломал.
Инициализации АЦП.

ADC.c
Код:
// Настройка регистров тактирования
    MDR_RST_CLK->PER_CLOCK |= RSTCLK_PERCLOCK_ADC;              // Подаем тактироваие на АЦП
    MDR_RST_CLK->PER_CLOCK |= RSTCLK_PERCLOCK_PORTD;            // Подаем тактирование на порт D

    MDR_RST_CLK->ADC_MCO_CLOCK |= ADC_C1_SEL_1;                 // Источником тактового сигнала
    MDR_RST_CLK->ADC_MCO_CLOCK &= ~(ADC_C1_SEL_1);              // для ADC_C1_SEL выбираем CPU_C2

    MDR_RST_CLK->ADC_MCO_CLOCK |= ADC_C2_SEL_1;                 // Источником тактового сигнала
    MDR_RST_CLK->ADC_MCO_CLOCK &= ~(ADC_C2_SEL_1);              // для ADC_C2_SEL выбираем ADC_C1

    MDR_RST_CLK->ADC_MCO_CLOCK |= ADC_C3_SEL_DIV_1;             // Предделитель на 1

    MDR_ADC->ADC1_CFG |= ADC_CLK_EN;                            // Разрешить подачу тактовых сигналов на АЦП

    // Настраиваем выход PD8, как аналаговый вход
    MDR_PORTD->OE &= ~(PORT_OE_8);                              // Как вход
    MDR_PORTD->OE &= ~(MODE8_0 | MODE8_1);                      // Как порт
    MDR_PORTD->OE &= ~(ANALOG_EN_8);                            // Как аналоговый
    MDR_PORTD->OE &= ~(PORT_SHM_8);                             // Триггер Шмитта выключен

    // Настройка регистров управления АЦП
    MDR_ADC->ADC1_CFG |= Cfg_REG_CHS_CH_8;                      // Выбираем 8 канал
    MDR_ADC->ADC1_CFG |= Cfg_REG_ADON;                          // Включаем АЦП


ADC.h
Код:
#ifndef _ADC_H
#define _ADC_H

// Инклюды
#include "MDR32Fx.h"
#include "RCC.h"
#include "GPIO.h"

// Дефайны

/************************  ADC_MCO_CLOCK  ***********************/

#define  ADC_C1_SEL_0                     ((uint32_t)0x00000001)        /*!< Bit 0 */
#define  ADC_C1_SEL_1                     ((uint32_t)0x00000002)        /*!< Bit 1 */

#define  ADC_C2_SEL_0                     ((uint32_t)0x00000010)        /*!< Bit 0 */
#define  ADC_C2_SEL_1                     ((uint32_t)0x00000020)        /*!< Bit 1 */

#define  ADC_C3_SEL_DIV_1                 ((uint32_t)0x00000000)
#define  ADC_C3_SEL_DIV_2                 ((uint32_t)0x00000800)
#define  ADC_C3_SEL_DIV_4                 ((uint32_t)0x00000900)
#define  ADC_C3_SEL_DIV_8                 ((uint32_t)0x00000B00)
#define  ADC_C3_SEL_DIV_16                ((uint32_t)0x00000C00)
#define  ADC_C3_SEL_DIV_32                ((uint32_t)0x00000D00)
#define  ADC_C3_SEL_DIV_64                ((uint32_t)0x00000E00)
#define  ADC_C3_SEL_DIV_128               ((uint32_t)0x00000E00)
#define  ADC_C3_SEL_DIV_256               ((uint32_t)0x00000F00)

#define  ADC_CLK_EN                       ((uint32_t)0x00002000)

/**************************  ADC1_CFG  *************************/

#define  Cfg_REG_ADON                     ((uint32_t)0x00000001)              /* ADC ON */
#define  Cfg_REG_GO                       ((uint32_t)0x00000002)              /* Start Conversion */

#define  Cfg_REG_ADON                     ((uint32_t)0x00000001)
#define  Cfg_REG_CHS_CH_0                 ((uint32_t)0x00000000)               /* 0 канал */
#define  Cfg_REG_CHS_CH_1                 ((uint32_t)0x00000010)               /* 1 канал */
#define  Cfg_REG_CHS_CH_2                 ((uint32_t)0x00000020)               /* 2 канал */
#define  Cfg_REG_CHS_CH_3                 ((uint32_t)0x00000030)               /* 3 канал */
#define  Cfg_REG_CHS_CH_4                 ((uint32_t)0x00000040)               /* 4 канал */
#define  Cfg_REG_CHS_CH_5                 ((uint32_t)0x00000050)               /* 5 канал */
#define  Cfg_REG_CHS_CH_6                 ((uint32_t)0x00000060)               /* 6 канал */
#define  Cfg_REG_CHS_CH_7                 ((uint32_t)0x00000070)               /* 7 канал */
#define  Cfg_REG_CHS_CH_8                 ((uint32_t)0x00000080)               /* 8 канал */
#define  Cfg_REG_CHS_CH_9                 ((uint32_t)0x00000090)               /* 9 канал */
#define  Cfg_REG_CHS_CH_10                ((uint32_t)0x000000A0)               /* 10 канал */
#define  Cfg_REG_CHS_CH_11                ((uint32_t)0x000000B0)               /* 11 канал */
#define  Cfg_REG_CHS_CH_12                ((uint32_t)0x000000C0)               /* 12 канал */
#define  Cfg_REG_CHS_CH_13                ((uint32_t)0x000000D0)               /* 13 канал */
#define  Cfg_REG_CHS_CH_14                ((uint32_t)0x000000E0)               /* 14 канал */
#define  Cfg_REG_CHS_CH_15                ((uint32_t)0x000000F0)               /* 15 канал */
#define  Cfg_REG_CHS_CH_16                ((uint32_t)0x00000100)               /* 16 канал */
#define  Cfg_REG_CHS_CH_17                ((uint32_t)0x00000110)               /* 17 канал */
#define  Cfg_REG_CHS_CH_18                ((uint32_t)0x00000120)               /* 18 канал */
#define  Cfg_REG_CHS_CH_19                ((uint32_t)0x00000130)               /* 19 канал */
#define  Cfg_REG_CHS_CH_20                ((uint32_t)0x00000140)               /* 20 канал */
#define  Cfg_REG_CHS_CH_21                ((uint32_t)0x00000150)               /* 21 канал */
#define  Cfg_REG_CHS_CH_22                ((uint32_t)0x00000160)               /* 22 канал */
#define  Cfg_REG_CHS_CH_23                ((uint32_t)0x00000170)               /* 23 канал */
#define  Cfg_REG_CHS_CH_24                ((uint32_t)0x00000180)               /* 24 канал */
#define  Cfg_REG_CHS_CH_25                ((uint32_t)0x00000190)               /* 25 канал */
#define  Cfg_REG_CHS_CH_26                ((uint32_t)0x000001A0)               /* 26 канал */
#define  Cfg_REG_CHS_CH_27                ((uint32_t)0x000001B0)               /* 27 канал */
#define  Cfg_REG_CHS_CH_28                ((uint32_t)0x000001C0)               /* 28 канал */
#define  Cfg_REG_CHS_CH_29                ((uint32_t)0x000001D0)               /* 29 канал */
#define  Cfg_REG_CHS_CH_30                ((uint32_t)0x000001E0)               /* 30 канал */
#define  Cfg_REG_CHS_CH_31                ((uint32_t)0x000001F0)               /* 31 канал */

#define  Cfg_REG_TR_1                     ((uint32_t)0x00200000)               /*!< TRIM 1 */
#define  Cfg_REG_TR_2                     ((uint32_t)0x00400000)               /*!< TRIM 2 */
#define  Cfg_REG_TR_3                     ((uint32_t)0x00600000)               /*!< TRIM 3 */
#define  Cfg_REG_TR_4                     ((uint32_t)0x00800000)               /*!< TRIM 4 */
#define  Cfg_REG_TR_5                     ((uint32_t)0x00A00000)               /*!< TRIM 5 */
#define  Cfg_REG_TR_6                     ((uint32_t)0x00C00000)               /*!< TRIM 6 */
#define  Cfg_REG_TR_7                     ((uint32_t)0x00E00000)               /*!< TRIM 7 */
#define  Cfg_REG_TR_8                     ((uint32_t)0x01000000)               /*!< TRIM 8 */




// Прототипы
void ADC_Init(void);

#endif



Запуск АЦП происходит в главном цикле программы

Код:
while(1)
    {
        while(f <= 150)
        {
            /* АЦП */
            MDR_ADC->ADC1_CFG |= 0x02; // ADC Start
            for(i = 0; i <= 1000; i++){}
            while(!(MDR_ADC->ADC1_STATUS & 0x04)) __NOP();
            for(i = 0; i <= 1000; i++){}
            adc_result = MDR_ADC->ADC1_RESULT&0x0FFF;
            for(i = 0; i <= 1000; i++){}
            adc_result_volt = 3.3*adc_result/0x0FFF;
            for(i = 0; i <= 1000000; i++){}
            display(adc_result_volt);
            for(i = 0; i <= 1000000; i++){}
        }
    }


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-ноя-28 08:13 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1175
Откуда: Тула
Какова частота CPU_C2?
Результатом MDR_PORTD->OE &= ~(ANALOG_EN_8); должен быть ноль в соотв. бите.
Разумеется это adc_result_volt = 3.3*adc_result/0x0FFF; вещественный тип.

Что интересно, на результат может влиять не только настройка МК, но и его "обвеска" -- "не правильная" цепь ФНЧ (1 кОм + 1000 пф) вполне может давать такой результат.
Какое у Вас аппаратное обеспечение? Можно ли снять осциллограмму напряжения на измеряемом выводе?

P.S. использование операции |= подразумевает уверенность в модифицируемом значении. В случаях где применение этой операции можно избежать, лучше задавать значение регистров явно.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-ноя-28 08:49 
Не в сети

Зарегистрирован: 2010-авг-30 19:12
Сообщения: 401
Цитата:
в то время как напряжение возрастает до 3, погрешность измерения составляет 0,6в

1 - Величина опорного напряжения? внутреннее (питание) или внешнее?
2 - При превышении входным сигналом опорного напряжения происходит "засветка" сигналов на других каналах через внутренние защитные диоды.
3 -
Цитата:
"обвеска" -- "не правильная" цепь ФНЧ

_________________
О сколько нам открытий чудных
Готовит просвященья дух,
И опыт - сын ошибок трудных ... (Пушкин)

Пергаменты не утоляют жажду ("Фауст",Гете)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-ноя-29 22:04 
Не в сети

Зарегистрирован: 2016-ноя-27 13:56
Сообщения: 10
Во всём оказалось виновато внутренне опорное напряжение, После того как поставили, внешнее всё стало работать. Работаю на отладочной плате 1986ВЕ94Т, среда разработки - CodemasterArm.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-ноя-30 08:00 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1175
Откуда: Тула
Novosib писал(а):
Во всём оказалось виновато внутренне опорное напряжение, После того как поставили, внешнее всё стало работать. Работаю на отладочной плате 1986ВЕ94Т, среда разработки - CodemasterArm.

Можете дать технически более развернутый ответ?

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-дек-04 16:01 
Не в сети

Зарегистрирован: 2016-ноя-27 13:56
Сообщения: 10
prostoRoman писал(а):
Novosib писал(а):
Во всём оказалось виновато внутренне опорное напряжение, После того как поставили, внешнее всё стало работать. Работаю на отладочной плате 1986ВЕ94Т, среда разработки - CodemasterArm.

Можете дать технически более развернутый ответ?


Да, извиняюсь на работе завал, после того, как мы поставили прецизионный стабилизатор напряжения на 3.3 В, и подключили его в выходам ADC0_REF+ и ADC1_REF-, соответсвенно, показания стали точными.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-дек-06 19:18 
Не в сети

Зарегистрирован: 2016-ноя-27 13:56
Сообщения: 10
Всех категорически приветствую, возникла новая проблема, как только подключаешь к выводам ADC0_REF+ 3.3В, а к ADC0_REF- 0В, перестают работать порты, в своем проекте, я вывожу напряжение измеренное АЦП на 3 семисегментных индикатора. Причем, интересная вещь происходит, в режиме отладчика всё работает нормально, когда идешь по шагам, но как только из него выходишь и нажимаешь сброс, железо перестает работать.

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


Вложения:
RCC80Mhz.rar [132.15 КБ]
Скачиваний: 80
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-дек-07 08:15 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1175
Откуда: Тула
А что значит "перестаёт работать"?

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-дек-07 10:38 
Не в сети

Зарегистрирован: 2009-май-22 09:01
Сообщения: 1285
Откуда: АО "ПКК Миландр"
Novosib писал(а):
Всех категорически приветствую, возникла новая проблема, как только подключаешь к выводам ADC0_REF+ 3.3В, а к ADC0_REF- 0В, перестают работать порты, в своем проекте, я вывожу напряжение измеренное АЦП на 3 семисегментных индикатора. Причем, интересная вещь происходит, в режиме отладчика всё работает нормально, когда идешь по шагам, но как только из него выходишь и нажимаешь сброс, железо перестает работать.

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



Скорее всего дело в схеме включения, возможно не подключено батарейное питание, обычно в этом случае такое поведение с отладчиком работает, без не работает.
Приведите схему, посмотрим.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-дек-07 22:35 
Не в сети

Зарегистрирован: 2016-ноя-27 13:56
Сообщения: 10
-=Sergei=- писал(а):
Novosib писал(а):
Всех категорически приветствую, возникла новая проблема, как только подключаешь к выводам ADC0_REF+ 3.3В, а к ADC0_REF- 0В, перестают работать порты, в своем проекте, я вывожу напряжение измеренное АЦП на 3 семисегментных индикатора. Причем, интересная вещь происходит, в режиме отладчика всё работает нормально, когда идешь по шагам, но как только из него выходишь и нажимаешь сброс, железо перестает работать.

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



Скорее всего дело в схеме включения, возможно не подключено батарейное питание, обычно в этом случае такое поведение с отладчиком работает, без не работает.
Приведите схему, посмотрим.


Работаю на отладочной плате 1986ВЕ94Т - http://milandr.ru/index.php?mact=Produc ... eturnid=68. Схему на сайте не нашел. Схема есть только на работе, на диске, который, пришел с новым комплектом.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-дек-08 14:38 
Не в сети

Зарегистрирован: 2009-май-22 09:01
Сообщения: 1285
Откуда: АО "ПКК Миландр"
Novosib писал(а):
-=Sergei=- писал(а):
Novosib писал(а):
Всех категорически приветствую, возникла новая проблема, как только подключаешь к выводам ADC0_REF+ 3.3В, а к ADC0_REF- 0В, перестают работать порты, в своем проекте, я вывожу напряжение измеренное АЦП на 3 семисегментных индикатора. Причем, интересная вещь происходит, в режиме отладчика всё работает нормально, когда идешь по шагам, но как только из него выходишь и нажимаешь сброс, железо перестает работать.

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



Скорее всего дело в схеме включения, возможно не подключено батарейное питание, обычно в этом случае такое поведение с отладчиком работает, без не работает.
Приведите схему, посмотрим.


Работаю на отладочной плате 1986ВЕ94Т - http://milandr.ru/index.php?mact=Produc ... eturnid=68. Схему на сайте не нашел. Схема есть только на работе, на диске, который, пришел с новым комплектом.


Возможно не хватает таймоута для запуска HSE. И после этого вы выходите на HSI, но при этом АЦП не затактирован и не работает и вист в ожидании.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-дек-11 20:59 
Не в сети

Зарегистрирован: 2016-ноя-27 13:56
Сообщения: 10
Проверил систему тактирования, закомментировал свою функцию RCC_80MHz_Init, и с помощью цикла for() выставил задержку 1 сек, светодиод замигал с частотой 1 Гц, потом раскоментировал и светодиод замигал гораздо быстрее. Поэтому с системой тактирования всё впорядке.

Решил вернуться в начало, и понял, что упустил очень важный симптом. Если не подключать к выводам ADC0_REF+ 3.3В, а к ADC0_REF- 0В, то пошаговая отладка проходит нормально. Но как только подключаешь внешнюю опору, и когда заходишь внутрь функции, и начинаешь пошаговую отладку, то он может прыгнуть, в то место, куда бы он просто по всем законам языка СИ не попал бы.

Например, в моей функции void display(float x), есть такой кусок:

switch(y_sotni)
{
case 0: SET_PA7;
SET_PA1;
SET_PA0;
SET_PA6;
SET_PA4;
SET_PA3;
temp_reg1 = (MDR_PORTA->RXTX &= 0xffff);
break;
case 1: SET_PA4;
SET_PA6;
temp_reg1 = (MDR_PORTA->RXTX &= 0xffff);
break;
case 2: SET_PA3;
SET_PA4;
SET_PA2;
SET_PA1;
SET_PA0;
temp_reg1 = (MDR_PORTA->RXTX &= 0xffff);
break;
case 3: SET_PA3;
SET_PA4;
SET_PA2;
SET_PA6;
SET_PA0;
temp_reg1 = (MDR_PORTA->RXTX &= 0xffff);
break;
case 4: SET_PA7;
SET_PA2;
SET_PA4;
SET_PA6;
temp_reg1 = (MDR_PORTA->RXTX &= 0xffff);
break;
case 5: SET_PA3;
SET_PA7;
SET_PA2;
SET_PA6;
SET_PA0;
temp_reg1 = (MDR_PORTA->RXTX &= 0xffff);
break;
case 6: SET_PA3;
SET_PA7;
SET_PA1;
SET_PA0;
SET_PA6;
SET_PA2;
temp_reg1 = (MDR_PORTA->RXTX &= 0xffff);
break;
case 7: SET_PA3;
SET_PA4;
SET_PA6;
temp_reg1 = (MDR_PORTA->RXTX &= 0xffff);
break;
case 8: SET_PA2;
SET_PA4;
SET_PA3;
SET_PA7;
SET_PA6;
SET_PA0;
SET_PA1;
temp_reg1 = (MDR_PORTA->RXTX &= 0xffff);
break;
case 9: SET_PA0;
SET_PA6;
SET_PA4;
SET_PA3;
SET_PA7;
SET_PA2;
temp_reg1 = (MDR_PORTA->RXTX &= 0xffff);
break;
}

И если y_sotni = 2, то он заходит в case 2 и выполняет 3 строчки:

SET_PA3;
SET_PA4;
SET_PA2;

Не выполнив до конца, case 2, он может прыгнуть в case 7, выполнить там одну строку и прыгуть за оператор switch. Ни как не могу понять в чём же дело. Что-то не то твориться с PC ? Или с SP ? Или я неправильно подключаю опору? Опора у меня берется с прецизионного стабилизатора напряжения на 3.3 В. На ADC0_REF- я завожу землю, на ADC0_REF+ я завожу 3.3В с этого стабилизатора. Скажите, может быть опора должна иметь отдельную землю ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-дек-12 09:29 
Не в сети

Зарегистрирован: 2009-май-22 09:01
Сообщения: 1285
Откуда: АО "ПКК Миландр"
Novosib писал(а):
Проверил систему тактирования, закомментировал свою функцию RCC_80MHz_Init, и с помощью цикла for() выставил задержку 1 сек, светодиод замигал с частотой 1 Гц, потом раскоментировал и светодиод замигал гораздо быстрее. Поэтому с системой тактирования всё впорядке.

Решил вернуться в начало, и понял, что упустил очень важный симптом. Если не подключать к выводам ADC0_REF+ 3.3В, а к ADC0_REF- 0В, то пошаговая отладка проходит нормально. Но как только подключаешь внешнюю опору, и когда заходишь внутрь функции, и начинаешь пошаговую отладку, то он может прыгнуть, в то место, куда бы он просто по всем законам языка СИ не попал бы.



Проверьте поведение на другом образце микросхемы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-дек-12 10:35 
Не в сети

Зарегистрирован: 2010-авг-30 19:12
Сообщения: 401
Цитата:
Не выполнив до конца, case 2, он может прыгнуть в case 7, выполнить там одну строку и прыгуть за оператор switch. Ни как не могу понять в чём же дело. Что-то не то твориться с PC ? Или с SP ?

Возможно это оптимизация кода. Попробуйте изменить уровень оптимизации на O3(минимальная).

_________________
О сколько нам открытий чудных
Готовит просвященья дух,
И опыт - сын ошибок трудных ... (Пушкин)

Пергаменты не утоляют жажду ("Фауст",Гете)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Странное поведение АЦП
СообщениеДобавлено: 2016-дек-12 15:05 
Не в сети

Зарегистрирован: 2009-сен-21 12:39
Сообщения: 481
Цитата:
Попробуйте изменить уровень оптимизации на O3(минимальная)

Таки O0 минимальная, или нет?


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу 1, 2  След.

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


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

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


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

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