Доброго времени суток. Имеется АЦП, реализованный на MSP430G2553, работают 4-е канала. СпойлерADC10CTL0 &= ~ENC;//отключили преобразование (бит должен быть "0" чтобы не возникало проблем с конфигом АЦП,в данном случае смена канала) ADC10CTL1 = INCH_0;//канал А0 ADC10CTL0 |= ENC + ADC10SC;// аля "конфиг принять" и Start Convertion LPM0; a = ADC10MEM; ADC10CTL0 &= ~ENC;//отключили преобразование (бит должен быть "0" чтобы не возникало проблем с конфигом АЦП,в данном случае смена канала) ADC10CTL1 = INCH_1;//канал А0 ADC10CTL0 |= ENC + ADC10SC;// аля "конфиг принять" и Start Convertion LPM0; b = ADC10MEM; DC10CTL0 &= ~ENC;//отключили преобразование (бит должен быть "0" чтобы не возникало проблем с конфигом АЦП,в данном случае смена канала) ADC10CTL1 = INCH_2;//канал А0 ADC10CTL0 |= ENC + ADC10SC;// аля "конфиг принять" и Start Convertion LPM0; c = ADC10MEM; ADC10CTL0 &= ~ENC;//отключили преобразование (бит должен быть "0" чтобы не возникало проблем с конфигом АЦП,в данном случае смена канала) ADC10CTL1 = INCH_3;//канал А0 ADC10CTL0 |= ENC + ADC10SC;// аля "конфиг принять" и Start Convertion LPM0; d = ADC10MEM; Необходимо для каждой переменной, реализовать усреднение. По железной части вылизано все - фильтры НЧ на входе, соединение с датчиками витой парой и т.д. Наблюдается дребезг входного сигнала - на последнем разряде (принимаемое число 4-х разрядное). Помогите с реализацией алгоритма на С.
Поставьте весь код в цикл, выполняемый, например, 4 раза и суммируйте показания. Например, a += ADC10MEM; Перед входом в цикл значение а следует обнулить. По выходу из цикла разделите а на 4. Еще лучше сделать скользящее среднее, см. в Википедии.
А последний разряд всегда будет плавать даже с идеальным АЦП, т.к. в каждом сигнале есть шум.
Здравствуйте! Купил на днях лаунчпад с целью научиться работать с микроконтроллерами, ну и в целом хотябы паять До этого кодил на asm'e по мелочи. Сделал, чтобы лампочка мигала, всё ок. Решил потом по нажатию на кнопу включать и выключать лампочку(без мигания). И тут что-то пошло не так! Сначала долго искал, как вообще обрабатывать прерывания(на С много примеров, на ASM'e, да еще и IAR'овском, примеров с этим маловато). Потом вроде сел обрабатывать, но не тут то было! По нажатию на кнопу не происходит ровным счетом ничего, зато когда трогаю ногу P1.3, срабатывает и обрабатывается прерывание. Внимание - вопрос: почему на кнопку то не реагирует? И вдогонку еще один - когда трогаю контакт, прерывание срабатывает n раз, пока не отпущу, т.е. лампочка хаотично включается-выключается. Как бы заставить её независимо от длины нажатия срабатывать только один раз?
Vyvod knopki nado podtyanut' k pitaniyu I obrabatyvat' drebezg. Po ostal"nym voprosam sm. knigu J. Davies "MSP430 basics...". Ona est' v seti dlya skachivaniya.
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
"подтянуть" = см. pull up resistor mov #0x08, &P1OUT mov #0x08, &P1OUT "дребезг" = см. debouncing v wikipedia.com http://processors.wiki.ti.com/index.php ... PushButton А вообще, читайте книгу, что я рекомендовал выше. Там есть ответы на все заданные Вами выше вопросы.
Подскажите, а приведённый мною код не работает потому что среди всевозможных тактовых сигналов для всего и вся можно поставить только один? P.S. Не могу точно найти подтверждающую мою инфу (плохо ищу). P.S.2 код [пока не] выводит сообщение в com-порт на PC, когда меняет состояние светодиодов.
Спойлер#include "io430g2553.h"
#include "string."
unsigned int sch=0, zaderzhka = 1; //счётчик, и "какждый какое по счёту" срабатываний прерывания таймера будут вкл/выкл светодиоды string str = "ok";
char c='l';
void UARTWriteString(string str);
int main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD;
//готовим порт1 с диодам P1DIR = BIT0 + BIT6; //инициализируем выходы 0 и 6 (на 0 выведен красный светодиод, на 6 - зелёный) P1OUT = BIT6; //ставим выход 6 в 1
//готовим таймер CCTL0 = CCIE; //Capture/Compare разрешаем прерывание по переполнению счётчика-таймера TACTL = TASSEL_2 + MC_2 + ID_3; //Timer_A Control, источник тактов на SMCLK (SubMainCLocK), и режим таймера - continuous, и (медленнее в 8 раз) делитель 8 __bis_SR_register(CPUOFF + GIE); //флаги в Status Register: экономичный режим CPUOFF и разрешаем глобально прерывания GIE
Кстати, снизу этой страницы в документации есть важные замечания, которые не вошли в скриншот.
Видим, что на выходе модуля тактирования имеется три сигнала. И каждый из них может быть подключен только к одному генератору в один момент времени. Впрочем, ничто не мешает переключать их в рантайме.
Мораль: каждая из трех линий тактирования может быть подключена только к одному генератору из доступных и каждый модуль может быть подключен только к одной (произвольной) линии тактирования из этих трех. Что, в общем, естесственно.
Тактировать все модули от одной линии (если Вы об этом) необязательно.
_________________ Разница между теорией и практикой на практике гораздо больше, чем в теории.
Только надо иметь в виду, что, если модули подключены к физически разным генераторам, могут возникнуть проблемы с синхронизацией. Подробнее см. в мануале.
_________________ Разница между теорией и практикой на практике гораздо больше, чем в теории.
Приветствую всех ещё раз. Теперь я написал программу, по нажатию кнопки меняющая скорость мигания светодиодам. Работает так: - нажал на кнопку - и мигание происходит в 2 раза быстрее. - и так далее, пока мигание не станет максимально быстрым. Если мигание самое быстрое, то при очередном нажатии кнопки мигание светодиодами становится самым медленным. При "нормальной" работе требуется 6 нажатий, для прохода от самого медленного мигания до самого медленного же, по кругу.
Работает. Проблема в том, что для прохода от самого медленного мигания до самого медленного же по кругу, проходит разное количество нажатий - то 6, то 5, а то и 4. Никак не могу понять, в чём дело. Пробовал сбрасывать таймер, останавливать вручную прерывания (при обработке прерываний) - нивкакую.
Подскажите, в чём проблема. P.S.Код привёл. В нём то, что я добавил для отладки, я отметил пустым //. Спойлер#include "io430g2553.h"
unsigned int maxPause=0x1F;//FFF; unsigned int maxDelitel = 16; unsigned int i_time = 0, i_delitel = 1;
void timer_run();
int main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD;
//готовим порт с диодам P1DIR = (BIT0 + BIT6); //инициализируем выходы 0 и 6 P1OUT = BIT6; //ставим выход 6 в 1
//готовим таймер CCTL0 = CCIE; //разрешаем прерывание по переполнению счётчика-таймера timer_run(); __enable_interrupt(); //глобально разрешаем прерывания в status register
//готовим кнопку P1REN |= BIT3; //разрешаем подтяжку P1OUT |= BIT3; //подтяжка вывода P1.3 вверх, иначе будет всегда срабатывать if ((P1IN & BIT3) == 0)
P1IFG &= ~BIT3; // Очистка флага прерываний для P1.3 // P1IES |= BIT3; // Прерывание происходит по 1/0 (отпусканию/нажатию) P1IE |= BIT3; //разрешаем прерывание для P1.3
//используются три системных тактовых сигнала: ACLK, MCLK и SMCLK и INCLK (INCLK is device-specific) TACTL = (TASSEL_2 + MC_2 + ID_0); //ставим источник тактов на SMCLK, и режим таймера - continuous, и делитль =1 (1 2 4 }
//прерывание по таймеру используем для вкл/выкл с/диодов #pragma vector = TIMER0_A0_VECTOR //приоритет 0xFFF0 __interrupt void TIMER0_A0_PRE (void) { // __disable_interrupt(); //глобально запрещаем прерывания в status register
// __enable_interrupt(); //глобально разрешаем прерывания в status register }
//прерывание по кнопке используем для игр с паузой #pragma vector = PORT1_VECTOR //приоритет 0xFFE4 __interrupt void PORT1_VECTOR_PRE (void) { // __disable_interrupt(); //глобально запрещаем прерывания в status register
P1IE &= ~BIT3; // Запрет прерываний на P1.3 if (i_delitel<=maxDelitel) i_delitel *= 2; else i_delitel = 1; P1IFG &= ~BIT3; // Очистка флага прерываний для P1.3, т.к. это прерывание имеет несколько флагов P1IE |= BIT3; // Разрешение прерываний на P1.3 timer_run();
// __enable_interrupt(); //глобально разрешаем прерывания в status register }
И ещё вопрос. Как я понял, самый цивилизованный метод решения - это делать паузу используя второй таймер (предварительно запретив прерывания от кнопки), в срабатывании которого разрешается прерывания от кнопки. Так?
2.2.3.1 Interrupt Acceptance The interrupt latency is 5 cycles (CPUx) or 6 cycles (CPU), starting with the acceptance of an interrupt request and lasting until the start of execution of the first instruction of the interrupt-service routine, as shown in Figure 2-6. The interrupt logic executes the following: 1. Any currently executing instruction is completed. 2. The PC, which points to the next instruction, is pushed onto the stack. 3. The SR is pushed onto the stack. 4. The interrupt with the highest priority is selected if multiple interrupts occurred during the last instruction and are pending for service. 5. The interrupt request flag resets automatically on single-source flags. Multiple source flags remain set for servicing by software. 6. The SR is cleared. This terminates any low-power mode. Because the GIE bit is cleared, further interrupts are disabled. 7. The content of the interrupt vector is loaded into the PC: the program continues with the interrupt service routine at that address.
_________________ Разница между теорией и практикой на практике гораздо больше, чем в теории.
Последний раз редактировалось YS Чт июл 25, 2013 14:10:19, всего редактировалось 1 раз.
Строка в С - массив ASCII-кодов, заканчивающийся нулем (именно нулем, не ASCII-кодом нуля). Все функции из string.h работают именно с такими строками.
Все "присвоения" строк (кроме как при инициализации) - это уже ООП с неявными вызовами методов и сопутствующим выжиранием ресурсов. Для ПК это удобно и гламурно, для МК - ненужная красотулька.
Вот такая запись
Код:
uint8_t str[] = {"Hello"};
Определяет строку в стандарте С. Компилятор здесь сам положит завершающий ноль. А можно сделать так:
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения