Я только что получил панель запуска MSP430F5529 и сделал одно руководство, в котором заставляю мигать светодиод, расположенный на P1.0. Я использую студию композитора кода в качестве своей IDE
Теперь я пытаюсь заставить светодиод на P1.0 (красный) и светодиод на P4.7 (зеленый) чередоваться в зависимости от того, нажата ли кнопка, расположенная на P2.1.
Что бы я ни делал, кнопка ничего не меняет. Что еще более странно, так это то, что нажатие кнопки изменяет несколько битов в P2IN, а не только в P2.1.
Я попытался использовать кнопку на P1.1 (на самом деле я попробовал это первым), и у меня было похожее поведение, когда кнопка меняет несколько битов, а иногда вообще ничего не меняет. Но хуже всего то, что даже если биты меняются и он сравнивает бит ввода с тем, что он должен быть для нажатия, он никогда не регистрируется как нажатый.
Кроме того, я не вижу свои переменные, поэтому я добавил переменную «бла» и попытался установить ее в 0x00, чтобы заставить себя войти в цикл, но это ничего не делает !!!! Это похоже на то, что он просто удаляет переменную blah.
Вот код, который я пытаюсь заставить работать:
#include <msp430f5529.h>
//defines
#define red_LED BIT0 //red LED @ P1.0
#define grn_LED BIT7 //green LED @ P4.7
#define BTN BIT1 //button is located a P2.1
#define BTN_PRESSED 0x00
//prototypes
void delay(int n);
//main
void main(void) {
WDTCTL = WDTPW + WDTHOLD; //disable watchdog timer
unsigned int flash; //variable to store LED flash flag
P1OUT = 0; //set output as low
P1DIR |= red_LED; // set LED pins to outputs
P4OUT = 0; //set output low
P4DIR |= grn_LED; //set green LED as output
/* Setting up Switch */
P2OUT = 0; //set output as low
P2DIR &= ~BTN; // Set the switch pin to input
P2REN |= BTN; // Use an internal resistor
P2OUT |= BTN; // The internal resistor is pullup
for (;;) {//inf loop
for (flash=0; flash<7; flash++) {
P1OUT |= red_LED; // red LED on
delay(60000); // call delay function
P1OUT &= ~red_LED; // red LED off
delay(60000); // delay again
}
while ((P2IN & BTN) == BTN); // wait for button press, loop forever while P1IN is high (button unpressed)
for (flash=0; flash<7; flash++) {
P4OUT |= grn_LED; // green LED on
delay(60000); // call delay function
P4OUT &= ~grn_LED; // green LED off
delay(60000); // delay again
}
while ((P1IN & BTN) == BTN); // wait for button press, loop forever while P1IN is high (button unpressed)
}//end inf loop
} // main
//functions
void delay(int n) {
//delays for a count of 60000 ticks
unsigned int count;
for (count=0; count<n; count++);
} // delay
и вот тестовый код, который я пытаюсь отлаживать безрезультатно (кнопка работает, если я попадаю в цикл delay(), но я никогда не могу попасть в него!
#include <msp430f5529.h>
//defines
#define red_LED BIT0
#define grn_LED BIT7
#define BTN BIT1
#define BTN_PRESSED 0x00
//prototypes
void delay(int n);
//main
void main(void) {
WDTCTL = WDTPW + WDTHOLD; //disable watchdog timer
unsigned int flash; //variable to store LED flash flag
P1OUT = 0; //set output as low
P1DIR |= red_LED; // set LED pins to outputs
P4OUT = 0; //set output low
P4DIR |= grn_LED; //set green LED as output
/* Setting up Switch */
P2OUT = 0; //set output as low
P2DIR &= ~BTN; // Set the switch pin to input
P2REN |= BTN; // Use an internal resistor
P2OUT |= BTN; // The internal resistor is pullup
int blah = 0;
for(;;){
if((blah) == BTN_PRESSED){
delay(5); // call delay function
}
}
//functions
void delay(int n) {
//delays for a count of 60000 ticks
unsigned int count;
for (count=0; count<n; count++);
} // delay
Должно быть, я делаю что-то принципиально неправильное, потому что бла никогда не появляется в моем списке переменных отладчика, а задержка (5) никогда не запускается!
Компилятор видит, что delay()
цикл пуст, поэтому он умно делает вывод, что функция может вычислить тот же результат намного быстрее, если полностью исключить цикл.
У переменной blah
та же проблема: компилятор видит, что ее значение никогда не изменяется внутри программы, поэтому она фактически является константой, и ее не нужно где-либо хранить. (И это никогда неif((blah) == BTN_PRESSED)
может произойти, поэтому его можно опустить.)
Чтобы сообщить компилятору, что он действительно должен получить доступ к некоторой переменной, вы должны объявить эту переменную как volatile
:
volatile int blah = 0; // allows changes with the debugger
...
volatile unsigned int count; // force the compiler to actually count up, even
// if the compiler does not see any effect
Обратите внимание, что все регистры типа P2IN
объявлены как as volatile
, потому что они могут изменяться без присваивания, видимого компилятором.
Также обратите внимание, что компилятор не знает, что обработчики прерываний могут прерывать другие функции, поэтому он может не утруждать себя повторным чтением некоторых переменных, которые могли быть изменены прерыванием. Таким образом, переменные, которые являются общими для некоторого обработчика прерываний и основной программы, также должны быть объявлены volatile
.
По умолчанию все контакты GPIO настроены как входы. Эти входы реализованы с помощью полевых МОП-транзисторов, а их затвор настолько мал, что может принимать случайный заряд от любых ближайших сигналов или даже по воздуху, если вы не активируете вход на высоком или низком уровне. Это называется "плавающий ввод".
Хуже того, вход, который оказался наполовину заряженным, наполовину включает и соединения «1», и «0», и ток от источника питания будет течь к земле.
Руководство пользователя говорит в разделе 12.2.8:
Настройка неиспользуемых контактов порта
Неиспользуемые контакты ввода-вывода должны быть настроены как функция ввода-вывода, направление вывода и оставлены неподключенными на печатной плате, чтобы предотвратить плавающий ввод и снизить энергопотребление. Значение бита PxOUT не имеет значения, потому что вывод не подключен. В качестве альтернативы встроенный подтягивающий/подтягивающий резистор можно включить, установив бит PxREN на неиспользуемом выводе для предотвращения плавающего входа.
DigitalNinja
пользователь 2237160
DigitalNinja
while ((P2IN & BTN) == BTN);
работает? То есть вы видите вспышку красного светодиода?ккрамбо
DigitalNinja
пользователь 2237160
пользователь 2237160
Прохожий
Прохожий