реклама на сайте
подробности

 
 
> глюк АЦП в C8051F412, переключение каналов
Leen
сообщение May 29 2007, 23:50
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 172
Регистрация: 5-08-06
Из: Владивосток
Пользователь №: 19 343



Мерял 2 канала по очереди - внешний вход (к ноге через фильтр подключен нормирующий усилитель) и внутренний датчик температуры. АЦП сконфигурено так:
Код
REF0CN = 0x17;// Vref = 2.2 B, темп. сенсор вкл., генератор тока вкл.
// внутренний буфер вкл.
ADC0MX = 0x0B;// замеры с выв. Р1.3
ADC0CF = 0xF8;// SAR = Fclk/32, 1 замер за раз
ADC0TK = 0x07;// posttracking - режим замера. Он дает наибольшую точность
// время накопления напряжения макс. - 16 SAR
ADC0CN = 0x80;// АЦП вкл.
// 16/04/07 - замер по переполнению таймера 2
ADC0CN = 0x83;
IDA0CN = 0xF4;// ЦАП вкл., 0,25 мА, выравнивание вправо.

Данные с АЦП читались в прерывании:
Код
void ADC0_ISR(void) interrupt INTERRUPT_ADC0_EOC
{
register unsigned short int t;
AD0INT = 0;
if (ADC0MX == PRESS_EXT)
    {
    ADC0MX = TEMP_INT;
    t = ADC0;
    if (t>0x140)// игнорируем значения меньше 170 мВ
        PressData.upress = t;
    ADC0 = 0;
    }
else
    {
    ADC0MX = PRESS_EXT;
    PressData.temp = ADC0;
    ADC0 = 0;
    }
}

Это первозданный вид прерывания.
В диапазоне входных напряжений 0,73 - 0,88 В заметил такой глюк:
один раз upress = 0x580 и temp = 0x715, один раз наоборот... Т.е. какая-то ерунда. Почему это возникало, да еще и в таком узком диапазоне (150 мВ из полной шкалы 2,2 В), я не выяснял. Помогла перестановка строк - изменение ADC0MX поставил в конец блоков. Глюк исчез.
Код
{
    t = ADC0;
    if (t>0x140)// игнорируем значения меньше 170 мВ
        PressData.upress = t;
    ADC0 = 0;
    ADC0MX = TEMP_INT;
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 2)
TBI
сообщение May 30 2007, 06:47
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 170
Регистрация: 11-05-07
Пользователь №: 27 656



Возможно в прерывании, когда контроллер доходит до строчки с кодом: "t = ADC0;" уже случилось переполнение таймера 2 и началось измерение новой выбоки АЦП. Поэтому этот код сохраняет непонятное значение. Мне кажется необходимо при входе в процедуру обработки прерывания первым делом обнулить флаг прерывания (AD0INT = 0), а затем сразу же сохранить значение выборки АЦП (t = ADC0). Только после этого делать необходимые сравниния и вычисления. Мне непонятна строчка ADC0 = 0. Зачем она нужна?
Go to the top of the page
 
+Quote Post
Leen
сообщение May 30 2007, 07:26
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 172
Регистрация: 5-08-06
Из: Владивосток
Пользователь №: 19 343



Нет, таймер переполняться не успевает, проверял. Тем более, что чем выше напряжение, тем меньше его период - он генерит частоту линейно зависящую от кода АЦП.
ADC = 0 осталась от тестовых версий, когда пытался делать аппаратно усреднения. Просто не убрал. Не мешает, да и ляд с ней. Кстати, насчет усреднений - если задавал больше одного, флаг AD0INT переставал взводиться. Делал в эмуляторе - ставишь усреднение 1, пускаешь по шагам - видно, что через заданное время флаг поднимается, и ядро переходит на прерывание. Меняем число, шагаем - нифига, хоть тресни. Короче, плюсов у камня есть, но и минусов - тоже. Ну его, пусть причесывают, там посмотрим.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 09:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.01416 секунд с 7
ELECTRONIX ©2004-2016