TI MSP430 Launch Pad

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 3795
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Хорошая подборка идей! От себя добавлю, что основной цикл в приведенных реализациях молотит все время и сводит на нет все преимущества обработки нажатий и обработки дребезга через прерывания. Лучше отправлять МК в сон. Кроме того, определенным недостатком программ является частая обработка прерываний от таймера - каждые 4 мс даже если кнопки не нажаты.

Улучшить ситуацию можно несколько модифицировав алгоритм. Именно, разрешать прерывания по совпадению в самом начале обработки дребезга (получения первого прерывания от кнопки) и запрещать их по окончании обработки (в момент когда опять разрешаются прерывания от кнопки). Моменты совпадения нужно будет каждый раз пересчитывать в прерывании по совпадению (добалять одну и ту-же константу к счетчику), что не проблема. Так сделано, например, в моей конструкции
http://radiokot.ru/circuit/digital/measure/71/
В этой реализации, правда, каждый канал совпадения таймера обслуживает только одну кнопку. Но это не сильное ограничение, поскольку в современных моделях семейства MSP430 имеется несколько таймеров и у каждого 3-7 каналов сравнения.
Реклама
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 23
Зарегистрирован: Пт июн 05, 2009 12:06:56

Сообщение Bujhm666 »

Согласен. Если нужен экономичный режим, то вы предлагаете хороший вариант. Передо мной такая задача не стояла. Эти примеры просто заточены под мой проект лабораторного БП, поэтому и 16МГц и 4мс (там не только кнопки), это я думаю каждый настроит под себя. Перепробовав много способов борьбы с дребезгом, я остановился на самом первом варианте (с задержкой на таймере WDT), из тех примеров, что я привел на мой взгляд он менее всего загружает контроллер.
Вот еще один рабочий код обработки кнопок с защитой от дребезга (это мне на easyelectronics.ru ShadS предложил):
Спойлер

Код: Выделить всё

//******************************************************************************
//
// Пример работы с кнопками
//
// Определение короткого и длинного нажатия. Антидребезг реализован с помощью
// задержек на нажатие/отпускание кнопок.
// Организовать вызов из прерывания с частотой 100Гц - функцию BtnExe();
// Чтение значения состояния флагов кнопок производится с помощью
// глобальной переменной BtnFlags например так (в главном цикле): 
// if (BtnFlags) {
//      if (BtnMask & BTN_SHRT_S1) {....ветка короткого нажатия кнопки S1}
//      if (BtnMask & BTN_SHRT_S2) {....ветка короткого нажатия кнопки S1}
//      if (BtnMask & BTN_LONG_S1) {....ветка длинного нажатия кнопки S1}
//      и т.д.
//      BtnFlags = 0    //Обнулить байт флагов нажатия кнопок
//  }
//
//******************************************************************************

#include "msp430g2553.h"
#include <stdint.h>         // Standard integer types

#define     LED_1   BIT6                // Зеленый светодиод
#define     LED_2   BIT0                // Красный светодиод
#define     S1      BIT3                // Кнопка 1
#define     S2      BIT4                // Кнопка 2

//настройка параметров работы функций
#define BTN_LOCK_TIME   30              //время обработки дребезга в милисекундах (10-100)
#define BTN_LONG_TIME   1000            //время фиксации длинного нажатия в милисекундах (1000 - 2500)

//глобальные переменные
volatile uint8_t BtnFlags;              //байт флагов нажатия кнопки
#define BTN_SHRT_S1         (1<<0)      //бит короткого нажатия кнопки S1 
#define BTN_SHRT_S2         (1<<1)      //бит короткого нажатия кнопки S2 
#define BTN_LONG_S1         (1<<2)      //бит длинного нажатия кнопки S1 
#define BTN_LONG_S2         (1<<3)      //бит длинного нажатия кнопки S2

void BtnExe (void);


// Обработчик прерываний от Timer A1
#pragma vector = TIMER1_A0_VECTOR
__interrupt void TimerA1_ISR(void) {

    BtnExe();
}

void main(void) {

    WDTCTL = WDTPW + WDTHOLD;           // WatchDog off
    BCSCTL1 = CALBC1_1MHZ;              // 1MHz clock
    DCOCTL = CALDCO_1MHZ;

    // *** led ***
    P1DIR |= LED_1 + LED_2;
    P1OUT &= ~(LED_1 + LED_2);

    // *** button ***
    P1DIR &= ~(S1 + S2);                // Установка вывода кнопки как входного
    P1OUT |= S1 + S2;                   // Подтяжка к питанию
    P1REN |= S1 + S2;                   // Включение подтягивающего резистора

        // *** Timer1 ***
    TA1CTL = TASSEL_2 + ID_3 + MC_1 + TACLR;    // SMCLK/8, upmode
    TA1CCR0 = 2000;                             // sample every 10ms
    TA1CCTL0 = CCIE;                            // CCR0 interrupt enabled

    __bis_SR_register(GIE);                     // Разрешаем прерывания

    while(1)
    {
        if (BtnFlags) {                         // Если была нажата кнопка
            if (BtnFlags & BTN_SHRT_S1) {       // Ветка короткого нажатия кнопки S1
                P1OUT ^= LED_1;                 // Переключаем состояние выхода на противоположное
            }
            if (BtnFlags & BTN_SHRT_S2) {       // Ветка короткого нажатия кнопки S2

            }
            if (BtnFlags & BTN_LONG_S1) {       // Ветка длинного нажатия кнопки S1
                P1OUT ^= LED_2;                 // Переключаем состояние выхода на противоположное
            }
            if (BtnFlags & BTN_LONG_S2) {       // Ветка длинного нажатия кнопки S2

            }
            BtnFlags = 0;
        }
    }
}

//-----------------------------------------------------------------------------------------------------------------------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании с частотой 100 Гц)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
void BtnExe (void)
{    
    static uint8_t BtnLockBit;            //защелка (защита от дребезга)
    static uint8_t BtnLockCoun;           //счетчик защелки (защита от дребезга)
    static uint8_t BtnLongCoun;           //счетчик длинного нажатия
    static uint8_t BtnLastState;          //последнее состояние кнопок перед отпусканием

    uint8_t mask = 0;
    if (!(P1IN & S1)) mask = BTN_SHRT_S1;
    if (!(P1IN & S2)) mask = BTN_SHRT_S2;
    
    if (mask){                                      //опрос состояния кнопки
        if (BtnLockCoun < (BTN_LOCK_TIME/10)){      //клавиша нажата
            BtnLockCoun++;
            return;                                 //защелка еще не дощитала - возврат
        }
        BtnLastState = mask;
        BtnLockBit =1;                              //нажатие зафиксировано                
        if (BtnLongCoun >= (BTN_LONG_TIME/10))                                
            return;                                 //возврат, т.к. счетчик длинн нажат досчитал до максимума еще раньше        
        if (++BtnLongCoun >= (BTN_LONG_TIME/10))
            BtnFlags |= (BtnLastState<<2);          //счетчик досчитал до максимума - устанавливаем биты длинного нажатия 
    }            
    else{                                           //клавиша отжата            
        if (BtnLockCoun){
            BtnLockCoun --;
            return;                                 //защелка еще не обнулилась - возврат
        }
        if (! BtnLockBit)                           //СТАТИЧЕСКИЙ ВОЗВРАТ
            return;                                
        BtnLockBit =0;                              //отжатие зафиксировано
        if (BtnLongCoun < (BTN_LONG_TIME/10))
            BtnFlags |= BtnLastState;               //установка бита короткого нажатия
        BtnLongCoun = 0;                            //сброс счетчика длительности нажатия
    }
}
You cannot arrest an idea.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3795
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Опять-таки, прерывание происходит каждые 10 мс независимо от того нажата кнопка или нет. Если это прерывание еще для чего-то нужно (как у Вас в проекте) то сойдет. В противном случае процессор будет слишком часто и понапрасну отвлекаться на обработку прерывания.

Я всегда делаю обработку нажатий кнопок на основе прерываний порта, регистра сдвига, и отключаемых прерываний каналов сравнения таймера. Сейчас заканчиваю проект с участием кнопок, где вышеупомянутый алгоритм адаптирован с FR57xx для MSP430G2332. Выложу его сюда на форум с исходником скорее всего после конкурса. Кстати, Bujhm666, может напишите сюда статью про Ваш блок питания или дадите ссылку если она уже опубликована?
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 23
Зарегистрирован: Пт июн 05, 2009 12:06:56

Сообщение Bujhm666 »

Ser60 писал(а):Сейчас заканчиваю проект с участием кнопок, где вышеупомянутый алгоритм адаптирован с FR57xx для MSP430G2332
Ну можно было бы только код обработки кнопок выложить. Желательно на Си, если можно конечно.
Насчет моего блока питания, статью не напишу (не силен я в этом), а код и схему покажу, как доведу до ума (он хоть уже в корпусе и работает, но пока в стадии доводки). В схемотехнике там ничего нового, просто вместо обычных здесь пиков или меги управление от MSP430. Вот фотографии я выкладывал на схем.нет http://forum.cxem.net/index.php?showtop ... try1622650
You cannot arrest an idea.
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 3795
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Bujhm666 писал(а):просто вместо обычных здесь пиков или меги управление от MSP430
Вот это и похвально. Не понимаю, чего остальные ждут. Вообще, конструкция выглядит добротной. Насчет моего кода, он на АСМе. Вместо того, чтобы вырезать куски кода, вот ссылка на весь код:
http://mcs.uwsuper.edu/sb/Electronics/BigLCD/clock.s43
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 677
Зарегистрирован: Чт янв 20, 2011 09:07:08
Откуда: Пермь

Сообщение prinv »

Читаю здесь о ЦАП
Приложения, нуждающиеся в генерации периодических колебаний, могут получить преимущества от использования контроллера DMA с ЦАП12. К примеру, приложение, вырабатывающее синусоидальное колебание может сохранит значения синуса в таблице. Контроллер DMA может непрерывно автоматически переносить эти значения в ЦАП12 через заданные интервалы, создавая синусоиду без участия ЦПУ
Не подскажете, где бы поглядеть рабочий пример по работе ЦАП и DMA?
Никакая контра не уйдёт от нас
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3795
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Все правильно там написано. Рабочего примера с ЦАП12 у меня нет, но работа с ним и DMA не отличается от других DMA получателей. В целом будет аналогично использованию DМА с I2C или SPI. Пример работы с последними через DMA можно посмотреть, например, в моем проекте
http://radiokot.ru/circuit/digital/measure/71/
Вымогатель припоя
Аватара пользователя
Сообщения: 677
Зарегистрирован: Чт янв 20, 2011 09:07:08
Откуда: Пермь

Сообщение prinv »

Спасибо за инфу, смотрю.

В догонку - как в CSS 5.4 отключить warnings о неинициализированных обработчиках прерываний?
Никакая контра не уйдёт от нас
Контактная информация:
Родился
Сообщения: 14
Зарегистрирован: Чт дек 06, 2012 20:20:29
Откуда: Питер

Сообщение evgenich »

prinv писал(а):В догонку - как в CSS 5.4 отключить warnings о неинициализированных обработчиках прерываний?
А вот они сами отключились в следующей версии :)
Контактная информация:
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

Коллеги, я 430-ми раньше не занимался, а тут возникла потребность склепать частотомер, так вот, беглый просмотр даташитов не дал ответа на вопрос: какую максимальную частоту можно подать на внешний вход таймера? У АВР, допустим, подсчитываемые импульсы привязываются к тактовой, так, что строго меньше половины тактовой. У каких-то ПИКов, говорят, при включенном внутреннем прескалере можно давать чуть ли не 100-200 МГц. А как у 430-х? Конкретно - у F149 и F169. В общем, подскажите, плз, в каком документе и на какой странице это написано.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
akl
Друг Кота
Сообщения: 4475
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Наверно, здесь. Раздел 11.
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

afz писал(а):я 430-ми раньше не занимался, а тут возникла потребность склепать частотомер
а почему именно на 430? На пиках делали раньше частотомеры, но до 60 МГц: http://cxem.net/izmer/izmer89.php
сейчас можно взять микроконтроллер посовременнее - цитата из темы:
Плата STM32VLDISCOVERY STM32F100RBT6B@24MHz ...
Метод Reciprocal Counter...
По входу TIM2_CH1_ETR - 90MHz с точностью +-10Hz влёгкую!!!
Без внешних навесов и соединений!!!

http://radiokot.ru/forum/viewtopic.php?f=59&t=75552
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

oleg110592
а почему именно на 430?
Для начала прикидываю на тех МК, что есть под рукой (430, АВР) или легкодоступны (по дороге завернул в лавочку и купил за недорого - ПИК какой-нибудь). Не сойдется - буду заказывать...
Последний раз редактировалось afz Сб дек 07, 2013 14:56:19, всего редактировалось 1 раз.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

akl писал(а):Наверно, здесь. Раздел 11.

Точнее можно? А то что-то я просмотрел этот 11-й раздел более внимательно, результат тот же. Поиск в этом документе по "MHz" и "frequ" тоже ничего не дал.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
akl
Друг Кота
Сообщения: 4475
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

afz писал(а):а тут возникла потребность склепать частотомер, так вот, беглый просмотр даташитов не дал ответа на вопрос: какую максимальную частоту можно подать на внешний вход таймера?
Плохо искали, видимо потому что бегло. :)
СпойлерИзображение
FREQ_MAX_14x.GIF
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

akl писал(а):Плохо искали, видимо потому что бегло. :)
Угу, да еще и не в том документе. Я укачал несколько даташитов, часть из них просмотрел, а в этот заглянуть не удосужился. А может и заглянул, но сильно бегло. Потом, с Вашей подачи, стал внимательно изучать slau049f.pdf, оказалось, надо было читать slas272f.pdf. Кто же, кроме TI, виноват в том, что у них "лирические" названия файлов документов?
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Встал на лапы
Аватара пользователя
Сообщения: 131
Зарегистрирован: Пт апр 01, 2011 20:59:47
Откуда: Саратов

Сообщение Кефир »

Народ. Привет!
может кто использует Code Blocks как компилятор для msp430? Неудается скомпилить проект для msp430g2744. Хотя с 2553 все хорошо. Спасибо!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3795
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Ответил в личку.
Прорезались зубы
Аватара пользователя
Сообщения: 202
Зарегистрирован: Пн сен 26, 2011 13:48:25
Откуда: Харьков

Сообщение slavokhire5 »

Доброго времени суток, товарищи коты. Недавно начал разбираться с msp430g2553. После АВР идет туго и со скрипом :) Понадобилось мне прикрутить I2C на DMA. Нашел какую-то библиотеку, правда на 430f2619. Но вся беда в том, что в файле msp430g2553.h нет ни слова про DMA. дописывать хеадер как-то не хочется, уж очень там всего много... может кто сталкивался с DMA и знает, как его прикрутить?
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Сообщение Psych »

slavokhire5 писал(а):Но вся беда в том, что в файле msp430g2553.h нет ни слова про DMA.
Тык вроде бы DMA в вашем проце и нету :roll:
Ответить

Вернуться в «Разные вопросы по МК»