Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: C8051F320
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры
evsx1
Есть отладочный набор C8051F32X DEVELOPMENT KIT ,у сего девайся на порт 2 подключены на пин0 и пин1 две кнопочки и на пины 2,3 светодиоды.имею простую задачку зажигать диод при нажатии(компилятор IAR)
Код
/-----------------------------------------------------------------------------
#include <ioC8051f320.h>                    // SFR declarations
#include <intrinsics.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F32x
//-----------------------------------------------------------------------------

__sfr __no_init volatile unsigned short TMR2RL   @ 0xCA;                    // Timer2 reload value
__sfr __no_init volatile unsigned short TMR2     @ 0xCC;                    // Timer2 counter

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

#define SYSCLK       24500000 / 8         // SYSCLK frequency in Hz

#define LED P2_bit.P22                          // LED='1' means ON
#define SW2 P2_bit.P0                          // SW2='0' means switch pressed

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void PORT_Init (void);
void Timer2_Init (int counts);
__interrupt void Timer2_ISR (void);

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void) {

   // disable watchdog timer
   PCA0MD &= ~0x40;                       // WDTE = 0 (clear watchdog timer
                                          // enable)

   SYSCLK_Init ();                        // Initialize system clock to
                                          // 24.5MHz
   PORT_Init ();                          // Initialize crossbar and GPIO
  

   while (1) {
  
    
     if (!P2_bit.P20)  {P2_bit.P22&=0x01;} else {P2_bit.P22==0x00;};
     if (!P2_bit.P21)  {P2_bit.P23&=0x01;} else {P2_bit.P23==0x00;};// код мигания
   }
}

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use the internal 24.5MHz / 8
// oscillator as its clock source.  Also enables missing clock detector reset.
//
void SYSCLK_Init (void)
{
   OSCICN = 0x80;                         // configure internal oscillator for
                                          // its lowest frequency
   RSTSRC = 0x08;                         // enable missing clock detector
}


void PORT_Init (void)
{
   XBR0     = 0x00;                      
   XBR1     = 0x40;                      
   P2      &= 0x03;                               // настраиваем пины 0 и 1 на вход
   P2MDOUT |= 0x0C;                       // обозначаем выход для пинов на которых диоды
    P2_bit.P22&=0x00;                       //гасим загорающиеся диоды
       P2_bit.P23&=0x00;                    //гасим загорающиеся диоды
}

Однако условия не выполняются,независимо от того нажата кнопка или нет,такое ощущения что эти пины не настроились на ввод.Ошибка в коде?
barabek
Цитата(evsx1 @ Nov 26 2010, 21:24) *
Однако условия не выполняются,независимо от того нажата кнопка или нет,такое ощущения что эти пины не настроились на ввод.Ошибка в коде?

В IAR не работал. Какие-то конструкции совершенно для Keil не знакомые. Не важно. Что конкретно не работает? Что отладчик дает?




evsx1
Цитата(barabek @ Nov 26 2010, 15:08) *
В IAR не работал. Какие-то конструкции совершенно для Keil не знакомые. Не важно. Что конкретно не работает? Что отладчик дает?

После настройки порта,диоды загораются,далее их гашу,по конструкции в цикле while(1) должно быть если уровень на пине 0 и 1 низкий то загораются соответственно диоды на пинах 2.2 2.3,но после перехода на тело основного цикла независимо от состояния на пине 0или1,те по условию else вообще не переходит,но и после проверки состояния пина,прыгает на выполнение
Код
P2_bit.P22&=0x01
но диод не загорается
kosyak©
Цитата(evsx1 @ Nov 26 2010, 14:24) *
...
while (1) {


if (!P2_bit.P20) {P2_bit.P22&=0x01;} else {P2_bit.P22==0x00;};
if (!P2_bit.P21) {P2_bit.P23&=0x01;} else {P2_bit.P23==0x00;};// код мигания
}
}
...

Почему в Else используется == ?
evsx1
Цитата(kosyak© @ Nov 26 2010, 19:35) *
Почему в Else используется == ?

равняем бит с единичкой,что нам это мешает сделать,здесь не принципиально присваивание или приравнивание
kosyak©
У Вас случаем компилятор этот кусок кода не выкинул при оптимизации???
Хм...сейчас всмотрелся - конструкции действительно очень странные...нифига не понял..
P2_bit.P22 - это что порт 2 бит 22 ? ... странная штука IAR
Палыч
Цитата(evsx1 @ Nov 26 2010, 18:51) *
Код
P2_bit.P22&=0x01
но диод не загорается
Наверное, нужно приравнять единице (т.е. убрать &).


Цитата(evsx1 @ Nov 26 2010, 19:42) *
равняем бит с единичкой,что нам это мешает сделать,здесь не принципиально присваивание или приравнивание
О-па! Что это - вдруг: "не принципиально"? Еще как - принципиально!
evsx1
Цитата(Палыч @ Nov 26 2010, 19:57) *
Наверное, нужно приравнять единице (т.е. убрать &).


О-па! Что это - вдруг: "не принципиально"? Еще как - принципиально!

в данном случае,преобразования типов то нет.так что в конкретном этом случае не вижу принципиальной разницы,объясните если я не прав
P22 просто не ставится точка,те идет указание порта 2,и снова P22(порт 2 и пин 2)(почему так не знаю)
kosyak©
Код вообще не понятный. сам для х51 на ИАр никогда не писал.
у 320 все порты 8 пиновые.."пин 20 порта 2" эт что-то странное... хотя мож иаровцы как нибудь извернулись...

P2_bit.P22&=0x01 - зачем тут вообще & - мы обращаемся к конкретному пину.. т.е. никаких масок вообще не надо

P2_bit.P22 = 0x01
P2_bit.P22 = 0x00


ага... теперь понял P2_bit.P22 порт 2 пин 2 ... ну а маски все арвно уберите - они тут не нужны
evsx1
в данном случае меня интересуют настройки порта,по дефауту в даташите пишут что порт настраивается на выход,если хотите отдельные пины на вход,то надо ставить в регистр защелку порта 1ки

Действительно инициализация правильная,использование &= в основном цикле программы не работает,вопрос почему,маска для одного бита не приемлема7,но в функции инициализации порта есть строки присваивания 00 порту,те я вижу что порт настроился на выход(оба диода загорелись),затем глушу по одному- это работает, а в теле основного цикла не работает..почему?есть мнения?

Модераторы,простите за косяк могли бы перенести в специализированную тему c51,не заметил ее вначале создания темы
kosyak©
В 51 есть возможность оперировать битами. т.е. Чтобы сбросить или установить бит вы так и пишите
BitX = 0 или 1..

А маска нужна если минимальной единицей для работы был бы байт (2 байта 4 .. )
т.е. ЧТобы сбросить в переменной Byte скажем первый бит и не затронуть остальные - Byte = Byte & (~0x01)

чет объяснение какоето сумбурное получилось..но ночь на дворе smile.gif

Попробуйте написать так

if (!P2_bit.P20) {P2_bit.P22 = 0x01;} else {P2_bit.P22 = 0x00;};


Палыч
Цитата(evsx1 @ Nov 26 2010, 20:57) *
...использование &= в основном цикле программы не работает ... затем глушу по одному- это работает, а в теле основного цикла не работает..почему?есть мнения?
Нужно вспомнить (кто не знал - узнать), что выражение вида X &= Y эквивалентно следующему: X= X & Y
Если Y равно нулю, то и X & 0 всегда равно нулю. Таким образом X &= 0 вырождается в Х=0
Если же Y равно единице (и вспомним, что X - это бит), то X &= 1 преобразуется в Х = Х & 1, что вырождается в X=X (т.е. никакого изменения величины X не производится).
barabek
Цитата(Палыч @ Nov 27 2010, 06:22) *
Нужно вспомнить (кто не знал - узнать), что выражение вида X &= Y эквивалентно следующему: X= X & Y

слегка дополню. Не знаю как в ИАР, а в кейл имеется один важный момент. В конструкциях X &= Y если X - порт, компилятор подставляет команды "чтение-модификация-запись", т.е. минуя аккумулятор. Иногда это удобно, т.к. только в этом случае считывается выходной регистр, а не состояние на пинах. Например P1^=(P1^CHANGE)&OUTMASK; позволяет изменять одновременно несколько выходных пинов (определяется маской CHANGE), при этом входные пины (вернее их регистры) в этом же порту остаются нетронутыми (в маске OUTMASK -  еденицами обозначены выходные пины). 

esvx1 обратите внимание чем отличается сравнение "==" (при этом никакогоприсваивания не происходит) и оператором "="
evsx1
Цитата(Палыч @ Nov 26 2010, 23:22) *
Нужно вспомнить (кто не знал - узнать), что выражение вида X &= Y эквивалентно следующему: X= X & Y
Если Y равно нулю, то и X & 0 всегда равно нулю. Таким образом X &= 0 вырождается в Х=0
Если же Y равно единице (и вспомним, что X - это бит), то X &= 1 преобразуется в Х = Х & 1, что вырождается в X=X (т.е. никакого изменения величины X не производится).

Вот,в логике программы следующее:если лог ноль,то делаем x=X&1,ставлю &= не выполняет,ставлю =1,выполняет.тогда где вырождение?компилятор такое вырождение не принимает.Просто в данном конкретном примере я пока не понял разницы между &= и =,по идее нам надо установить только уровни,ну вот выполнил я побитовы и с одним битом,должн....
а вот теперь понял(пока писал,состояние X может быть ноль и тогда я получу 0,а в данном примере так и есть)
Палыч
Цитата(evsx1 @ Nov 27 2010, 14:26) *
не понял разницы между &= и =
Срочно - читать Kernighan & Ritchie!
Хотя бы из разного написания, мне кажется, должно быть ясно, что это - разные операции (так же разные = и ==). Поэтому не стоит заменять в Вашей программе = на == или на &= (им нет там места). Выше kosyak© абсолютно правильно подсказал, как должен выглядеть участок Вашей программы. В других местах &= нужно так же заменить на =
Sujan
Цитата(evsx1 @ Nov 27 2010, 13:26) *
Вот,в логике программы следующее:если лог ноль,то делаем x=X&1,ставлю &= не выполняет,ставлю =1,выполняет.тогда где вырождение?компилятор такое вырождение не принимает.Просто в данном конкретном примере я пока не понял разницы между &= и =,по идее нам надо установить только уровни,ну вот выполнил я побитовы и с одним битом,должн....
а вот теперь понял(пока писал,состояние X может быть ноль и тогда я получу 0,а в данном примере так и есть)


Вы судя по всему не правильно понимаете значение оператора &.
Если кратко, то для масок &(логическое И) используют для сброса конкретного бита в 0, не затрагивая остальные, например P2&=0xFE - сбросит бит 0 а остальные биты оставит неизменными (0xFE = 1111 1110b).
Для установки конкретного бита в 1 используется оператор | (логическое или), например P2|=0x01 - установит бит 0 в 1, а осталные останутся неизменными.

Однако в вашем случае можно написать всё ещё проще: P2_bit.P22 = P2_bit.P20; // без всяких IF smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.