Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
16.03.2011, 20:14
|
|
Временная регистрация
Регистрация: 25.09.2008
Сообщений: 95
Сказал спасибо: 39
Сказали Спасибо 7 раз(а) в 7 сообщении(ях)
|
Работа с отдельными битами в CVAVR
Доброго времени суток всем! Подскажите пожалуйста, каким образом в CVAVR я могу передать отдельный бит из переменной в отдельный бит порта?
например: из переменной perem передать значение ее старшего бита (7) в PORTB второй (2) разряд.
|
|
|
|
16.03.2011, 21:20
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
|
Re: Работа с отдельными битами в CVAVR
if(perem &(1‹‹7)) PORTB |= (1‹‹2); else PORTB &= ~(1‹‹2);
Вариант 2
PORTB.2 = ((perem &(1‹‹7)) != 0);
Второй вариант будет работать не везде.
Последний раз редактировалось kison; 16.03.2011 в 21:22.
|
|
|
|
16.03.2011, 21:55
|
|
Супер-модератор
Регистрация: 13.03.2004
Адрес: Minsk
Сообщений: 2,378
Сказал спасибо: 1,949
Сказали Спасибо 1,327 раз(а) в 578 сообщении(ях)
|
Re: Работа с отдельными битами в CVAVR
Сообщение от kison
|
if(perem &(1‹‹7)) PORTB |= (1‹‹2); else PORTB &= ~(1‹‹2);
Вариант 2
PORTB.2 = ((perem &(1‹‹7)) != 0);
Второй вариант будет работать не везде.
|
На IAR компиляторе второй вариант сработает, но - построенный код будет какой-то кривоватый. Так что я всегда использую вариант с IF - хоть и менее читабельно.
Так что у меня бы было так:
Код:
|
if (perem & 0x80) PORTB_Bit2=1; else PORTB_Bit2=0; |
__________________
[ жизнь приятна и красива, если выпить литр пива ]
|
|
|
|
16.03.2011, 22:11
|
|
Вид на жительство
Регистрация: 14.10.2009
Сообщений: 338
Сказал спасибо: 35
Сказали Спасибо 92 раз(а) в 73 сообщении(ях)
|
Re: Работа с отдельными битами в CVAVR
С IFами делать думаю не вариант (((
Проще некуда:
PORTx.y=(peremennaya››y)&1;
А если брать весь порт то както так
PORTx=PORTB
PORTx=(PORTx&(0xFF^(1‹‹y))|(peremennaya&(1‹‹y));
PORTB=PORTx
Подробнее это выглядит как
Допустим у=4
Мы должны будем вначале снулить бит y в порту. Воспользуемся обнулением по маске.
0xFF это инициализационное значение для маски порта
^ используется чтобы в маске сбросить один из битов
1‹‹y это мы смещаем бит который хотим снулить в нужное положение маски
Под конец первой части у нас будет чтото типа
PORTx&0b11101111
Далее мы данные из переменной peremennaya "обнуляем" всю кроме нужного бита через &
Тоесть получим PORTx без бита 4 плюс только 4й бит из переменной peremennaya.
Но еслибиты переменной и порта не совпадают тогда так:
PORTx=(PORTx&(0‹‹y))|(((peremennaya&(1‹‹z))››z)‹‹y )
__________________
Найди путь или проложи сам!
Последний раз редактировалось MasterMushi; 16.03.2011 в 22:26.
|
|
|
Сказали "Спасибо" MasterMushi
|
|
|
17.03.2011, 10:20
|
|
Временная регистрация
Регистрация: 25.09.2008
Сообщений: 95
Сказал спасибо: 39
Сказали Спасибо 7 раз(а) в 7 сообщении(ях)
|
Re: Работа с отдельными битами в CVAVR
спасибо всем за советы, буду пробовать
|
|
|
|
17.03.2011, 11:11
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: Работа с отдельными битами в CVAVR
Видел вот такую конструкцию:
Код:
|
#define SETBIT(x,i) x[i››3]|=(1‹‹(i&7));
#define CLEARBIT(x,i) x[i››3]&=(1‹‹(i&7))^0xFF; |
|
|
|
|
17.03.2011, 14:34
|
|
Гражданин KAZUS.RU
Регистрация: 02.06.2003
Адрес: Челябинск
Сообщений: 545
Сказал спасибо: 10
Сказали Спасибо 341 раз(а) в 202 сообщении(ях)
|
Re: Работа с отдельными битами в CVAVR
Сообщение от MasterMushi
|
С IFами делать думаю не вариант (((
Проще некуда:
PORTx.y=(peremennaya››y)&1;
А если брать весь порт то както так
PORTx=PORTB
PORTx=(PORTx&(0xFF^(1‹‹y))|(peremennaya&(1‹‹y));
PORTB=PORTx
Подробнее это выглядит как
Допустим у=4
Мы должны будем вначале снулить бит y в порту. Воспользуемся обнулением по маске.
0xFF это инициализационное значение для маски порта
^ используется чтобы в маске сбросить один из битов
1‹‹y это мы смещаем бит который хотим снулить в нужное положение маски
Под конец первой части у нас будет чтото типа
PORTx&0b11101111
Далее мы данные из переменной peremennaya "обнуляем" всю кроме нужного бита через &
Тоесть получим PORTx без бита 4 плюс только 4й бит из переменной peremennaya.
Но еслибиты переменной и порта не совпадают тогда так:
PORTx=(PORTx&(0‹‹y))|(((peremennaya&(1‹‹z))››z)‹‹y )
|
Ну, ну...
|
|
|
|
17.03.2011, 18:00
|
|
Прописка
Регистрация: 17.10.2010
Сообщений: 113
Сказал спасибо: 2
Сказали Спасибо 20 раз(а) в 12 сообщении(ях)
|
Re: Работа с отдельными битами в CVAVR
Сообщение от wellcom
|
каким образом в CVAVR я могу передать отдельный бит из переменной в отдельный бит порта
|
для начала открыть справку CVAVR и прочитать:
Код:
|
Bit Level Access to the I/O Registers
--------------------------------------------------------------------------------
Bit level access to the I/O registers can be performed by using the special macros that are defined in the iobits.h header file, located in the .\INC subdirectory.
The following macros are available:
SETBIT(port,b)
sets bit b of port to logic 1 state.
Example:
/* set bit 5 of I/O Port A output to logic 1 for non-ATxmega chips */
SETBIT(PORTA,5);
/* set bit 5 of I/O Port A output to logic 1 for ATxmega chips */
SETBIT(PORTA.OUT,5);
CLRBIT(port,b)
sets bit b of port to logic 0 state.
Example:
/* set bit 5 of I/O Port A output to logic 0 for non-ATxmega chips */
CLRBIT(PORTA,5);
/* set bit 5 of I/O Port A output to logic 0 for ATxmega chips */
CLRBIT(PORTA.OUT,5);
TGLBIT(port,b)
toggles (inverts) the logic state of bit b of port.
Example:
/* toggles bit 5 of I/O Port A output for non-ATxmega chips */
TGLBIT(PORTA,5);
/* toggles bit 5 of I/O Port A output for ATxmega chips */
TGLBIT(PORTA.OUT,5);
EQUBIT(port,b,value)
assigns a value to bit b of port.
If the assigned value is different from 0, then the bit is set to logic 1 state.
If the assigned value is 0, then the bit is set to logic 0 state.
Example:
/* sets bit 5 of I/O Port A output to the logic state of variable i
for non-ATxmega chips */
EQUBIT(PORTA,5,i);
/* sets bit 5 of I/O Port A output to the logic state of variable i
for ATxmega chips */
EQUBIT(PORTA.OUT,5,i);
Note: The SETBIT, CLRBIT, TGLBIT and EQUBIT macros always perform atomic I/O port bit access for the ATxmega chips.
For non-ATxmega chips, the atomic I/O port bit access using the SETBIT, CLRBIT and EQUBIT macros can be performed only for I/O ports with addresses located in I/O register space in the 0 to 1Fh range.
TSTBIT(port,b)
returns the logic state of bit b of port.
Example:
/* tests bit 5 of PINA (I/O Port A input) for non-ATxmega chips */
if (TSTBIT(PINA,5))
{
/* bit 5 of I/O Port A input is logic 1, do something... */
}
/* tests bit 5 of PORTA.IN (I/O Port A input) for ATxmega chips */
if (TSTBIT(PORTA.IN,5))
{
/* bit 5 of I/O Port A input is logic 1, do something... */
}
The bit level access to the I/O registers can be also accomplished by using bit selectors appended after the name of the I/O register.
Because bit level access to I/O registers is done using the CBI, SBI, SBIC and SBIS instructions, the register address must be in the 0 to 1Fh range for sfrb and in the 0 to 1Eh range for sfrw.
Example:
sfrb PORTA=0x1b;
sfrb DDRA=0x18;
sfrb PINA=0x19;
void main(void) {
/* set bit 0 of I/O Port A as output */
DDRA.0=1;
/* set bit 1 of I/O Port A as input */
DDRA.1=0;
/* set bit 0 of I/O Port A output to logic 1 */
PORTA.0=1;
/* test bit 1 input of Port A */
if (PINA.1) { /* place some code here */ };
/* ....... */
}
The same program for ATxmega chips using the Virtual Port VPORT0:
/* I/O register definitions for the ATxmega128A1 chip */
#include ‹xmega128a1.h›
void main(void) {
/* Map PORTA to virtual port VPORT0 and
PORTB to virtual port VPORT1 */
PORTCFG.VPCTRLA=PORTCFG_VP1MAP_PORTB_gc | PORTCFG_VP0MAP_PORTA_gc;
/* set bit 0 of Port A as output */
VPORT0_DIR.0=1;
/* set bit 1 of Port A as input */
VPORT0_DIR.1=0;
/* set bit 0 of Port A output to logic 1 */
VPORT0_OUT.0=1;
/* test bit 1 input of Port A */
if (VPORT0_IN.1) { /* place some code here */ };
/* ....... */
}
To improve the readability of the program you may wish to #define symbolic names to the bits in I/O registers:
sfrb PINA=0x19;
#define alarm_input PINA.2
void main(void)
{
/* test bit 2 input of Port A */
if (alarm_input) { /* place some code here */ };
/* ....... */
}
Note: Bit selector access to I/O registers located in internal RAM above address 5Fh (like PORTF for the ATmega128 for example) will not work, because the CBI, SBI, SBIC and SBIS instructions can't be used for RAM access. |
Возможно это не совсем правильно с точки зрения "правильных" компиляторов, зато дает оптимальный код (в асме)
|
|
|
Сказали "Спасибо" avtoneru
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 16:59.
|
|