|
Кнопки, таймеры, АЦП, взрыв мозга, Помогите новичку |
|
|
|
Aug 2 2013, 08:49
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 2-08-13
Пользователь №: 77 769

|
Здравствуйте! Есть у меня задачка, которую никак не могу решить. У меня есть 6 кнопок (картинка прилагается), подключены они по две штуки к одному пину. Необходимо сделать так, чтобы при нажатии на каждую кнопку, происходило какое-то своё действие: светодиод мигал с разной чистотой, или динамик гудел различными тонами. И, вот, если одну пару кнопок я уже научился контролировать, то другие никак не могу. Подробности в комментариях к коду. Сам я программировать и разбираться с МК начал меньше месяца назад. Прошу не судить строго за любые возможные глупые ляпы. Буду благодарен вам за любую помощь! Мозг уже разрывается на части Прогаю в IAR EW на MSP430f2112. Код #include "msp430f2112.h"
#define RED_LEDS (BIT0) //красненький светодиодик #define GREEN_LED (BIT2) //зелёненький
#define SPKR (BIT3) // Динамик (здесь я смотрю результат через осциллограф)
#define BUTTON1 (BIT0) // Две кнопки (SB1 и SB2), подсоединённые к P2.0 #define BUTTON2 (BIT3) // Две кнопки (SB3 и SB4), подсоединённые к P2.3 #define BUTTON3 (BIT4) // Две кнопки (SB5 и SB6), подсоединённые к P2.4
volatile char flash = 0; volatile char flash2 = 0;
void TA_init(void); void ADC_init(void);
//***********************Главная функция*************************
void main(void) { WDTCTL = WDTPW + WDTHOLD; // Останавливаем сторожевой таймер
BCSCTL3 = LFXT1S1; // Источником сигнала ACLK будет низкочастотный встроенный генератор со сверхнизким // энергопотреблением VLO. Частота ACLK = 12 кГц
P1DIR |= GREEN_LED; // Устанавливаем порт на выход P1OUT &= ~GREEN_LED; // Отключаем диод P1DIR |= RED_LEDS; P1OUT &= ~RED_LEDS; P1DIR |= SPKR; P1REN |= SPKR; // Устанавливаем резистор подтяжки, в нашем случае он уменьшает громкость динамика в ~4раза P1OUT &= ~SPKR;
TA_init(); ADC_init();
__bis_SR_register(GIE); // Разрешаем прерывания
while(1) { /*ADC10CTL0 &= ~ENC; ADC10CTL1 = INCH_4; ADC10CTL0 |= ENC + ADC10SC; // Если здесь снять комментарии, то мигать светодиод будет LPM3; // только при нажатии трёх! кнопок одновременно. ADC10CTL0 &= ~ENC; // Т.е., допустим, чтобы мигать по таймеру А0, нужно ADC10CTL1 = INCH_3; // нажать SB1, SB3 и SB5. По отдельности они вызывают ADC10CTL0 |= ENC + ADC10SC; // какие-то отдельные колебания, которые только складываясь LPM3;*/ // вместе, дают желаемый сигнал. ADC10CTL0 &= ~ENC; ADC10CTL1 = INCH_0; ADC10CTL0 |= ENC + ADC10SC; LPM3; } }
//***********************Инициализируем АЦП*************************
void ADC_init(void) { ADC10CTL0 = MSC + SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE; // настраиваем и включаем АЦП, разрешаем прерывания ADC10CTL1 = ADC10SSEL_1 + CONSEQ_0; // Буду благодарен, если кто-нибудь объянит мне, что меняет, // и на практике делает CONSEQ, т.к. в моём случае, его изменение ни к чему не приводит. // и я не понимаю чего люди пытаются им добиться. ADC10AE0 |= BUTTON1 + BUTTON2 + BUTTON3; // Пины с кнопками как входы АЦП }
//***********************Инициализируем Таймер*************************
void TA_init(void) { //Создаём таймер для удобного моргания через прерывания TA0CCR0 = 56; TA0CCR1 = 28; TA0CCTL0 = CCIE; // Разрешаем прерывание таймера по достижении CCR0 TA0CCTL1 = OUTMOD_3 + CCIE; TA0CTL = TASSEL_1 + MC_1 + TAIE; // ACLK, Прямой счёт }
//***********************Инициализируем Прерывания*************************
#pragma vector = TIMER0_A0_VECTOR __interrupt void T0_A0(void) { P1OUT ^= flash; // если flash == 0, светодиод не горит // если flash == GREEN_LED, мигаем светодиодом LPM3_EXIT;
}
#pragma vector = TIMER0_A1_VECTOR __interrupt void T0_A1(void) { P1OUT ^= flash2; // если flash2 == 0, светодиод не горит // если flash2 == GREEN_LED, мигаем светодиодом
TA0IV = 0x00; //чистим регистр вектора LPM3_EXIT; }
#pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR (void) { if (0x03FC < ADC10MEM && ADC10MEM < 0x0400) // Если нажата SB1 { P1OUT &= ~RED_LEDS; //flash = GREEN_LED; //мигает светодиод по таймеру A0 flash = SPKR; // или гудит динамик flash2 = 0; } else if (0x025A < ADC10MEM && ADC10MEM < 0x03FA) // Если кнопки не нажаты { P1OUT &= ~GREEN_LED; P1OUT &= ~RED_LEDS; flash = 0; flash2 = 0; } else if (0x0246 < ADC10MEM && ADC10MEM < 0x025A) // Если обе кнопки нажаты { P1OUT &= ~GREEN_LED; P1OUT |= RED_LEDS; flash = 0; flash2 = 0; } else if (0x017F < ADC10MEM && ADC10MEM < 0x0193) // Если нажата SB2 { P1OUT &= ~RED_LEDS; //flash2 = GREEN_LED; //мигает светодиод по таймеру A1 flash2 = SPKR; //или гудит динамик flash = 0; } LPM3_EXIT; }
|
|
|
|
|
 |
Ответов
|
Aug 14 2013, 09:19
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 2-08-13
Пользователь №: 77 769

|
Всё довольно грустно. Даже загадочно. Вот код: CODE void delay_ms(uint16_t ms); void InitSystem(void);
#pragma vector = TIMER0_A0_VECTOR __interrupt void T0_A0(void) { uiRealTime += 1; if (uiRealTime < uiTimer1) { P1OUT ^= SPKR; } } // Задержка в мииллисекундах void delay_ms(uint16_t ms) { static uint16_t delay_timer;
delay_timer = uiRealTime + ms;
while(uiRealTime < delay_timer);
} // Инициализация системы void InitSystem(void) { WDTCTL = WDTPW + WDTHOLD; // Останавливаем собаку // Инициализируем ACLK BCSCTL3 = LFXT1S_2; // Устанавливаем источник частоты для таймера Timer_A TACCR0 = 11; // (12 kHz / TACCR + 1) = 1 kHz, T = 1 мc TA0CCTL0 = CCIE; // Разрешаем прерывание таймера по достижении CCR0 TA0CTL |= TASSEL_1 + MC_1 + TACLR; // (ACLK) = 12 kHz }
//***********************Главная функция*************************
void main(void) { InitSystem(); P1DIR &= ~BUTTON3; P1IES = BUTTON3; P1IE = BUTTON3; P1DIR |= SPKR; P1REN |= SPKR; P1OUT &= ~SPKR; __bis_SR_register(GIE); while (1) {
} }
#pragma vector = PORT1_VECTOR __interrupt void P1_isr(void) { P1IFG &= ~BUTTON3; uiTimer1 = uiRealTime + 1000; //delay_ms(1000); // от дребезга } Под SPKR понимается выход на динамик, с которого я осциллографом снимаю импульсы. Я исправил код, но результат очень странный: если проверяю на подключённой по JTAG плате, то при нажатии кнопки как надо инициируется секундный писк. ОДНАКО, после некоторого времени тишины, писк неожиданно самопроизвольно включается вновь, но уже на БОЛЕЕ длительное время, и так же внезапно отключается. Если плата отключена, то писк срабатывает только при первом нажатии, а затем уходит в глухую оборону... Думаю факт подключения здесь особую роль не играет, а просто я опять где-то накосячил и чего-то не понял. А функция delay_ms, вроде как уходит в бесконечный цикл, после строчки while(uiRealTime < delay_timer); И если я её (функцию delay_ms) добавляю в конце своего кода, то, соответственно, ничего не происходит.  Прошу прощения, ступил. Никто за меня переменную uiTimer1 не обнулил, вот полтергейст и возникал. CODE #pragma vector = TIMER0_A0_VECTOR __interrupt void T0_A0(void) { uiRealTime += 1; if (uiRealTime < uiTimer1) { P1OUT ^= SPKR; } else uiTimer1 = 0; // Вот, обнулил её здесь, теперь ничего без моего нажатия не гудит } Хотя не совсем понимаю, как она могла влезать в неравенство if (uiRealTime < uiTimer1) А вот вопрос с delay_ms остаётся открытым. Там наверняка тоже всё на поверхности лежит, только я не догнал ещё. Раньше я делал так: Был у меня таймер CODE TA1CCR0 = 6; // Частота писка = (12000/TA1CCR0+1) TA1CTL = TASSEL_1 + MC_1 + TACLR; // ACLK, Прямой счёт, обнуление таймера И, был следующий код: CODE if (m >= 0) //Если выполняется условие { TA1CCTL0 = CCIE; // Разрешаем прерывание таймера __delay_cycles(50000); flash3 = SPKR; } Возникало прерывание: CODE #pragma vector = TIMER1_A0_VECTOR // Прерывания таймера на динамик __interrupt void T1_A0(void) { if (l == 200) // Если моргнули 200 раз { TA1CCTL0 &= ~CCIE; // Запрещаем прерывания (писк) flash3 = 0; // Говорим, что flash3 уже не спикер P1OUT &= ~SPKR; // Спикер отключаем l = 0; // Обнуляем кол-во морганий сигналами } if (flash3 == SPKR) // если flash3 == SPKR, { P1OUT ^= flash3; // мигаем сигналом l++; // Говорим, что моргнули сигналом очередной раз } LPM3_EXIT; } Сейчас разбираюсь с системными тиками, и мне всё больше кажется, что они так не смогут, ведь тогда мне нужны часы - 1 таймер, определённая частота гудения - второй таймер, а ведь у меня в проге ещё и светодиоды разной частотой мигают. Если только при помощи этих системных таймеров возможно будет этими светодиодами управлять (менять их частоту мигания). Я уже как-то совсем запутался  Может у меня всё хорошо было для моего случая
|
|
|
|
Сообщений в этой теме
Turbo_enot Кнопки, таймеры, АЦП, взрыв мозга Aug 2 2013, 08:49 Turbo_enot Прошу прощения, в комментариях немного ошибся: Что... Aug 2 2013, 12:08 d7d1cd Я может чего то не понимаю, но как микроконтроллер... Aug 2 2013, 13:41 Turbo_enot Цитата(d7d1cd @ Aug 2 2013, 16:41) Я може... Aug 5 2013, 05:49 MrYuran Вообще-то, на один вход АЦП можно повесить все ваш... Aug 5 2013, 07:33 Turbo_enot Цитата(MrYuran @ Aug 5 2013, 10:33) Вообщ... Aug 5 2013, 09:44  MrYuran Цитата(Turbo_enot @ Aug 5 2013, 12:44) Та... Aug 5 2013, 10:20   Turbo_enot Цитата(MrYuran @ Aug 5 2013, 13:20) Компа... Aug 5 2013, 10:32 Turbo_enot В принципе, проблему мне удалось решить. Все диоды... Aug 5 2013, 12:30 MrYuran КодADC10CTL1 = ADC10SSEL_1 + CONSEQ_0; // Буду бла... Aug 5 2013, 13:25 Turbo_enot Цитата(MrYuran @ Aug 5 2013, 16:25) КодAD... Aug 6 2013, 06:11  MrYuran Цитата(Turbo_enot @ Aug 6 2013, 09:11) А ... Aug 6 2013, 08:03   Turbo_enot Цитата(MrYuran @ Aug 6 2013, 11:03) Означ... Aug 6 2013, 11:56 Turbo_enot Ребят, ещё такой вопрос: Как сделать короткий ШИМ ... Aug 9 2013, 09:44 VasyaT Цитата(Turbo_enot @ Aug 9 2013, 13:44) Ре... Aug 9 2013, 20:43  Turbo_enot Цитата(VasyaT @ Aug 9 2013, 23:43) 1. Вкл... Aug 12 2013, 06:46   MrYuran Цитата(Turbo_enot @ Aug 12 2013, 09:46) Д... Aug 12 2013, 07:21    Turbo_enot Цитата(MrYuran @ Aug 12 2013, 10:21) К не... Aug 12 2013, 10:44     MrYuran Цитата(Turbo_enot @ Aug 12 2013, 13:44) Р... Aug 12 2013, 11:36      Turbo_enot Цитата(MrYuran @ Aug 12 2013, 14:36) Ну в... Aug 12 2013, 12:03       MrYuran Цитата(Turbo_enot @ Aug 12 2013, 15:03) Н... Aug 13 2013, 05:29        Turbo_enot Цитата(MrYuran @ Aug 13 2013, 08:29) Засе... Aug 13 2013, 08:04        Turbo_enot Да, кстати, вот ещё что. Создал я небольшой пример... Aug 13 2013, 11:43 MrYuran Все не так
Таймер (физический) настраивается о... Aug 13 2013, 13:09 Turbo_enot Цитата(MrYuran @ Aug 13 2013, 16:09) Все ... Aug 13 2013, 14:20 Turbo_enot Ещё такой вопрос: как долго счётчик uiRealTime буд... Aug 14 2013, 10:52 Turbo_enot Буду очень благодарен, если кто-нибудь объяснит, к... Aug 15 2013, 11:03 thodnev В общем посмотрите примеры на обучающем вики от те... Aug 16 2013, 08:02 Turbo_enot Спасибо за советы, подразобрался Aug 21 2013, 14:10
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|