0 / 0 / 0
Регистрация: 18.11.2015
Сообщений: 5
|
|
1 | |
Данные с двух каналов АЦП по очередно.[Решено]09.01.2017, 23:48. Показов 10214. Ответов 16
Метки нет (Все метки)
Всем привет.
Столкнулся с непоняткой, чип stm8s003f на время теста подцепил два переменных резистора на 100к и 68к на пины PD3 и PD2 код чтения ацп для канала 3 для канал 4 такой же Код
int ADC_ch_3(void){ int data=0, t=0; ADC_CSR_CH3; //Выбераем канал ADC_CR1_SPSEL8; //Делитель на 18 ADC_TDRL_DIS(0); //Отключаем тригер Шмидта ADC_CR2_ALIGN_LEFT; //Выравнивание по левому краю ADC_CR1_ADON_ON; //Запуск ADC for(t=0;t<64;t++){ //Пауза __asm__("nop\n"); } data=ADC_DRH; //Считываем показания return data; } МК виснет. Если опрашивать только один канал не важно 3 или 4 все работает. НО на stm8s003k3 этот код работает как задумано. Вопрос: я что то упустил/не правильно сделал в программе или я не учел каких то особенностей 003f3 ?
0
|
09.01.2017, 23:48 | |
Ответы с готовыми решениями:
16
АЦП несколько каналов Использование нескольких каналов АЦП Переключение каналов АЦП atmega88 Stm8l и несколько каналов АЦП Большое количество АЦП каналов |
0 / 0 / 0
Регистрация: 07.08.2016
Сообщений: 432
|
|
10.01.2017, 13:00 | 2 |
А если на stm8s003k3 опрашивать существующие каналы, например 2 и 3, то работает?
0
|
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
|
|
10.01.2017, 13:31 | 3 |
А если еще и вот так сделать после считывания:
Код
ADC_CSR &= 0x3f; // clear EOC & AWD flags Кстати, а что делает функция ADC_TDRL_DIS(0); ? Скажем, у меня конфигурация третьего канала такова: Код
// select PD2[AIN3] & enable interrupt for EOC ADC_CSR = 0x23; ADC_TDRL = 0x08; // disable Schmitt triger for AIN3 // right otygnment ADC_CR2 = 0x08; // dont forget: first read ADC_DRL! // f_{ADC} = f/18 & continuous non-buffered conversion & wake it up ADC_CR1 = 0x73; ADC_CR1 = 0x73; // turn on ADC (this needs second write operation)
0
|
0 / 0 / 0
Регистрация: 18.11.2015
Сообщений: 5
|
|
10.01.2017, 23:09 | 4 |
Сообщение от Kitvym
Сообщение от Iddy_Im
Сообщение от Iddy_Im
Сообщение от Iddy_Im
или считывание ADC_DRL обязательно?
0
|
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
|
|
12.01.2017, 00:30 | 5 |
Обязательно!
0
|
0 / 0 / 0
Регистрация: 04.11.2012
Сообщений: 81
|
|
12.01.2017, 18:25 | 6 |
Причем в строго определенном порядке, в зависимости от выравнивания.
0
|
0 / 0 / 0
Регистрация: 18.11.2015
Сообщений: 5
|
|
12.01.2017, 23:23 | 7 |
Проблема решена.
Причина: невнимательность(в принципе как всегда) #define ADC_CSR_CH3 ADC_CSR|=(1<<1)|(1<<0) тут устанавливается 1 в нулевой бит #define ADC_CSR_CH2 ADC_CSR|=(1<<1) а тут этот бит не сбрасывается и получается всегда выбран 3 канал Спасибо ребята, ваши советы учтены, код подправлен.
0
|
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
|
|
13.01.2017, 00:35 | 8 |
Скинь пожалуйста последний вариант, сохраню себе чтобы потом долго не разбираться...
С одним каналом я давно разобрался, а вот с несколькими - вдруг там нюансы какие...
0
|
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
|
|
13.01.2017, 00:44 | 9 |
Не нужно magick numbers использовать. Лучше все в заголовочном файле определить!!
0
|
0 / 0 / 0
Регистрация: 18.11.2015
Сообщений: 5
|
|
13.01.2017, 22:58 | 10 |
Вот код, ни чего специфического если внимательно)
Код
void main(void) { unsykned int i=1, s=0; //переменные для хранения данных Init_HSE(); //инициализируем переферию gpio_init(); ADC_CR1|=(1<<6); //Делитель на 18 ADC_TDRH|=(1<<5); //Отключаем тригер Шмидта для канала 5 ADC_TDRH|=(1<<6); //Отключаем тригер Шмидта для канала 6 ADC_CR2&=~(1<<3); //Выравнивание по левому краю ADC_CR1|=(1<<0); //Первый запуск ADC while(1) { /***********************читаем 5 канал************************************/ ADC_CSR&=~((1<<3)|(1<<2)|(1<<1)|(1<<0)); //сбрасываем выбранный до этого канал ADC_CSR|=(1<<2)|(1<<0); //Выбераем канал 5 ADC_CR1|=(1<<0); //запуск преобразования while(!(ADC_CSR&(1<<7))) //ждем окончания преобразования { __asm__("nop\n"); } s=ADC_DRH; //первым читается значемый регистр в данном случае ADC_DRH i=ADC_DRL; ADC_CSR&=~(1<<7); //очищаем флаг окончания преобразования PC_ODR=s; //выводим данные в порт С delay(100); s=i=0; /***********************читаем 6 канал*************************************/ ADC_CSR&=~((1<<3)|(1<<2)|(1<<1)|(1<<0)); ADC_CSR|=(1<<2)|(1<<1); ADC_CR1|=(1<<0); while(!(ADC_CSR&(1<<7))) { __asm__("nop\n"); } s=ADC_DRH; i=ADC_DRL; ADC_CSR&=~(1<<7); PC_ODR=s; delay(100); s=i=0; /**************************************************************/ } }
0
|
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
|
|
14.01.2017, 04:15 | 12 |
Код
ADC_CR1|=(1<<6); //Делитель на 18 ADC_TDRH|=(1<<5); //Отключаем тригер Шмидта для канала 5 ADC_TDRH|=(1<<6); //Отключаем тригер Шмидта для канала 6 ADC_CR2&=~(1<<3); //Выравнивание по левому краю ADC_CR1|=(1<<0); //Первый запуск ADC у меня сделано так: Код
//настройка ADC ADC_CR1_bit.ADON = 1; //включить ADC ADC_CSR_bit.CH = 0x03; //номер канала ADC_CR1_bit.SPSEL = 0x07; //делитель скорости ADC_CR2_bit.ALIGN = 0; //выровнять влево ADC_CR1_bit.ADON = 1; //включить ADC
0
|
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
|
|
14.01.2017, 04:20 | 13 |
Сообщение от Iddy_Im
Код
if (ADC_DRH < ADC_MARK_VOT) PWR_ODR_bit = 1; //шунтируется балласт и питание увеличивается else PWR_ODR_bit = 0; //добавляется балласт и питание уменьшается ADC_CR1_bit.ADON = 1; //старт ADC
0
|
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
|
|
14.01.2017, 11:05 | 14 |
Сообщение от ShodS
У меня инит АЦП сделан так: Код
#define ADC1_TDRH_MASK ((u8)((1 << (ADC1_CSR_CH8 - 8)) * 0 \ | (1 << (ADC1_CSR_CH9 - 8)) * 0 \ | (1 << (ADC1_CSR_CH10 - 8)) * 0 \ | (1 << (ADC1_CSR_CH11 - 8)) * 0 \ | (1 << (ADC1_CSR_CH12 - 8)) * 0 \ | (1 << (ADC1_CSR_CH13 - 8)) * 0 \ | (1 << (ADC1_CSR_CH14 - 8)) * 0 \ | (1 << (ADC1_CSR_CH15 - 8)) * 0)) // маска триггеров шмитта каналов 8-12 #define ADC1_TDRL_MASK ((u8)((1 << ADC1_CSR_CH0) * 1 \ | (1 << ADC1_CSR_CH1) * 1 \ | (1 << ADC1_CSR_CH2) * 1 \ | (1 << ADC1_CSR_CH3) * 1 \ | (1 << ADC1_CSR_CH4) * 1 \ | (1 << ADC1_CSR_CH5) * 1 \ | (1 << ADC1_CSR_CH6) * 1 \ | (1 << ADC1_CSR_CH7) * 0)) // маска триггеров шмитта каналов 0-7 /***************************************************************************** * Настройка АЦП *****************************************************************************/ void init_adc (void) { // Инициализация АЦП ADC1->CR1 &= ~ADC1_CR1_ADON; // выключить АЦП для изменения настроек ADC1->TDRH = ADC1_TDRH_MASK; // маска используемых входов ADC1->TDRL = ADC1_TDRL_MASK; // маска используемых входов ADC1->CSR = ADC_IN // измерять до входа 6 | ADC1_CSR_AWDIE * 0 // запретить прерывания аналогового вочдога | ADC1_CSR_EOCIE * 1; // Разрешить прерывание по окончании измерения ADC1->CR1 = ADC1_CR1_SPSEL4 // частота преобразования 16МГц / 4 = 4 МГц | ADC1_CR1_CONT * 0 // режим однократного измерения | ADC1_CR1_ADON * 0; ADC1->CR2 = ADC1_CR2_EXTTRIG * 0 // внутренний триггер | ADC1_CR2_EXTSEL * 0 // внешний триггер не используется | ADC1_CR2_ALIGN * 0 // выравнивание влево | ADC1_CR2_SCAN * 1; // Режим сканирования ADC1->CR3 = ADC1_CR3_DBUF * 1; // с использованием буфера ADC1->CR1 |= ADC1_CR1_ADON; // включить АЦП } Запускаю из прерывания таймера: Код
/****************************************************************************** * Системное прерывание 1 мс ******************************************************************************/ INTERRUPT_HANDLER (SysTick_Timer_ISR, 23) { static u16 ADC_timer = 0; TIM4->SR1 = 0; // Сбросим флаг прерывания // счётчики работают с интервалом в 1 мс system_time++; // системный счётчик времени if ((system_time - ADC_timer) >= ADC_TIMER) { ADC_timer = system_time; ADC1->CR1 |= ADC1_CR1_ADON; // запустить АЦП } } Код
static u8 buf [7]; // массив отсчётов ацп /***************************************************************************** * прерывание по окончании измерения * здесь считывается напряжение сети *****************************************************************************/ INTERRUPT_HANDLER (ADC1_End_of_conversion_ISR, 22) { u8 flags = ADC1->CSR; flags &= ~ADC1_CSR_EOC; // снять флаг прерывания ADC1->CSR = flags; buf [0] = ADC1->DB0RH; // сохраняем значения buf [1] = ADC1->DB1RH; buf [2] = ADC1->DB2RH; buf [3] = ADC1->DB3RH; buf [4] = ADC1->DB4RH; buf [5] = ADC1->DB5RH; buf [6] = ADC1->DB6RH; control_func (); }
0
|
0 / 0 / 0
Регистрация: 18.11.2015
Сообщений: 5
|
|
14.01.2017, 16:09 | 15 |
Сообщение от ShodS
ADC_TDRH|=(1<<5); //Отключаем тригер Шмидта для канала 5 ADC_TDRH|=(1<<6); //Отключаем тригер Шмидта для канала 6 ADC_CR2&=~(1<<3); //Выравнивание по левому краю ADC_CR1|=(1<<0); //Первый запуск ADC Почему так сделал? у меня сделано так: Код
//настройка ADC ADC_CR1_bit.ADON = 1; //включить ADC ADC_CSR_bit.CH = 0x03; //номер канала ADC_CR1_bit.SPSEL = 0x07; //делитель скорости ADC_CR2_bit.ALIGN = 0; //выровнять влево ADC_CR1_bit.ADON = 1; //включить ADC нет, я пользуюсь SDCC, там нет библиотек, а свою пока не написал.
Сообщение от ShodS
0
|
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
|
|
14.01.2017, 16:15 | 16 |
У меня тоже как раз под sdcc писано: https://sourceforge.net/projects/stm8samples/
Правда, сейчас больше в сторону STM32F0 смотрю. Интересней они. Хотя, конечно, можно и с STM8 что-нибудь интересное сделать. Заказал "про запас" на работе десяток STM8S003 — их можно хоть даже как "умные регистры/триггеры" использовать.
0
|
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
|
|
15.01.2017, 02:06 | 17 |
Сообщение от Iddy_Im
Сообщение от SOVO
Сообщение от somyk
Почитал DS, и вроде - правильное чтение двух регистров важно только в случае использования 10 бит значения... иначе, при чтении 8 бит - нет необходимости в чтении второго регистра... так что в нашем случае - чтение только ADC_DRH - это нормально... Еще у меня не выключались триггеры шмидта на задействованных ADC входах, я смотрю все их выключают, я сначала подумал что это как то влияет на результаты замеров ADC, но опять же из DS следует что это нужно только для уменьшения энергопотребления, и как я понял - никак не влияет на результаты замеров, так что тоже не критично...
0
|
15.01.2017, 02:06 | |
15.01.2017, 02:06 | |
Помогаю со студенческими работами здесь
17
Защита каналов АЦП от импульсных помех AVR АЦП использование нескольких каналов Опрос нескольких регулярных каналов АЦП STM32F100 Atmega16, АЦП и Протеус [решено] [РЕШЕНО] Не отвечает АЦП AD7124-4 Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Блоги программистов | |||||
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален
В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
|
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
|
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели
В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
|
Полезные поделки на Arduino, которые можно сделать самому
raxper 06.01.2025
Arduino как платформа для творчества
Arduino представляет собой удивительную платформу для технического творчества, которая открывает безграничные возможности для создания уникальных проектов. Эта. . .
|
Подборка решений задач на Python
IT_Exp 06.01.2025
Целью данной подборки является предоставление возможности ознакомиться с различными задачами и их решениями на Python, что может быть полезно как для начинающих, так и для опытных программистов.
. . .
|
С чего начать программировать микроконтроллеры
raxper 06.01.2025
Введение в мир микроконтроллеров
Микроконтроллеры стали неотъемлемой частью современного мира, окружая нас повсюду: от простых бытовых приборов до сложных промышленных систем. Эти маленькие. . .
|
Из чего собрать игровой компьютер
inter-admin 06.01.2025
Сборка игрового компьютера требует особого внимания к выбору комплектующих и их совместимости. Правильно собранный игровой ПК не только обеспечивает комфортный геймплей в современных играх, но и. . .
|
Обновление сайта www.historian.by
Reglage 05.01.2025
Обещал подвести итоги 2024 года для сайта. Однако начну с того, что изменилось за неделю. Добавил краткий урок по последовательности действий при анализе вредоносных файлов и значительно улучшил урок. . .
|
Как использовать GraphQL в C# с HotChocolate
Programming 05.01.2025
GraphQL — это современный подход к разработке API, который позволяет клиентам запрашивать только те данные, которые им необходимы. Это делает взаимодействие с API более гибким и эффективным по. . .
|
Модель полного двоичного сумматора с помощью логических операций (python)
AlexSky-coder 04.01.2025
def binSum(x:list, y:list):
s=^y]
p=x and y
for i in range(1,len(x)):
s. append((x^y)^p)
p=(x and y)or(p and (x or y))
return s
x=list()
y=list()
|
Это мы не проходили, это нам не задавали...(асихронный счётчик с управляющим сигналом задержки).
Hrethgir 04.01.2025
Асинхронный счётчик на сумматорах (шестиразрядный по числу диодов на плате, но наверное разрядов будет больше - восемь или шестнадцать, а диоды на старшие), так как триггеры прошли тестирование и. . .
|
Руководство по созданию бота для Телеграм на Python
IT_Exp 04.01.2025
Боты для Телеграм представляют собой автоматизированные программы, которые выполняют различные задачи, взаимодействуя с пользователями через интерфейс мессенджера. В данной статье мы рассмотрим,. . .
|