Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WinAvr бит установить?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
UserM
Подскажите плз. Что делаю не правильно. Взял пример кода здесь:
http://www.ars.yet.ru/union/mk/mk06.html

Код
  int main(void)              
  {
   sbi (DDRD ,PD5);              
       while (1) {              
               cbi (PORTD,PD5);  
               delay_ms(500);  
               sbi (PORTD,PD5);  
               delay_ms(500);  
          }
  }

Но при компиляции возникает ошибка , что делаю не правильно?
Версия WinAVR - 20050214

Compiling: test.c
avr-gcc -c -mmcu=at90s4433 -I. -gstabs -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=test.lst -std=gnu99 -MD -MP -MF .dep/test.o.d test.c -o test.o
test.c: In function `main':
test.c:31: warning: implicit declaration of function `sbi'
test.c:33: warning: implicit declaration of function `cbi'
test.c:38:5: warning: no newline at end of file

Linking: test.elf
avr-gcc -mmcu=at90s4433 -I. -gstabs -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=test.o -std=gnu99 -MD -MP -MF .dep/test.elf.d test.o --output test.elf -Wl,-Map=test.map,--cref -lm
test.o(.text+0x2e): In function `main':
test.c:31: undefined reference to `sbi'
test.o(.text+0x38):test.c:33: undefined reference to `cbi'
test.o(.text+0x48):test.c:35: undefined reference to `sbi'
make: *** [test.elf] Error 1
standpoint
Хидеры для

undefined reference to `cbi'
undefined reference to `sbi'

забыл добавить.
GedasL
В WinAVR - 20050214 нет cbi и sbi О том что их небудет предупреждали уже давно.

#define bit_set(p,m) ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define BIT(x) (0x01 << (x))

bit_set(PORTD,BIT(0));
bit_clear(PORTD, BIT(0));
UserM
GedasL, Спасибо, понял, всё работает.
ViktorK
Цитата(UserM @ May 8 2005, 21:40)
GedasL, Спасибо, понял, всё работает.
*


Делай так:

Код
while (1) {           //Бесконечный цикл
       PORTB |= 1<<2;     //set PORTB.2 high
       delay_ms(500);     // Ждем 0.5 сек.
       PORTB &= ~(1<<2); //set PORTB.2 low
       delay_ms(500);     // Ждем 0.5 сек.
UserM
ViktorK, Спасибо! Понял.

Я наверно не прав , но по моему мнению запись:

cbi (PORTD,5);
sbi (PORTD,5);

Была намного понятней, чем:

PORTD &= ~(1<<5);
PORTD |= 1<<5;
GedasL
Цитата(UserM @ May 9 2005, 20:57)
ViktorK, Спасибо! Понял.

Я наверно не прав , но по моему мнению запись:

cbi (PORTD,5); 
sbi (PORTD,5);

Была намного понятней, чем:

PORTD &= ~(1<<5);
PORTD |= 1<<5;
*


Но
PORTD &= ~(1<<5);
PORTD |= 1<<5;

переносимо на любои компилятор
Ljubitel
Цитата(GedasL @ May 9 2005, 21:31)
Цитата(UserM @ May 9 2005, 20:57)
ViktorK, Спасибо! Понял.

Я наверно не прав , но по моему мнению запись:

cbi (PORTD,5); 
sbi (PORTD,5);

Была намного понятней, чем:

PORTD &= ~(1<<5);
PORTD |= 1<<5;
*


Но
PORTD &= ~(1<<5);
PORTD |= 1<<5;

переносимо на любои компилятор
*



Я,когда после IAR,пробовал писать на GCC написал себе хидер такого
вида:
Код
/*
================================================================================
============
    Задаем структуру (битовое поле) чтобы иметь возможность обращаться к битам переменных.
================================================================================
============
*/
typedef struct    _bit_struct    {
       unsigned char    Bit0:1,
           Bit1:1,
           Bit2:1,
           Bit3:1,
           Bit4:1,
           Bit5:1,
           Bit6:1,
           Bit7:1;
         }bit_field;

/*
================================================================================
============
    Определяем PORTB.
================================================================================
============
*/
#ifdef    PORTB
    
    #define    PORTB_Bit0    (*((volatile bit_field*) (0x38))).Bit0
    #define    PORTB_Bit1    (*((volatile bit_field*) (0x38))).Bit1
    #define    PORTB_Bit2    (*((volatile bit_field*) (0x38))).Bit2
    #define    PORTB_Bit3    (*((volatile bit_field*) (0x38))).Bit3
    #define    PORTB_Bit4    (*((volatile bit_field*) (0x38))).Bit4
    #define    PORTB_Bit5    (*((volatile bit_field*) (0x38))).Bit5
    #define    PORTB_Bit6    (*((volatile bit_field*) (0x38))).Bit6
    #define    PORTB_Bit7    (*((volatile bit_field*) (0x38))).Bit7
    
    #define    DDRB_Bit0    (*((volatile bit_field*) (0x37))).Bit0
    #define    DDRB_Bit1    (*((volatile bit_field*) (0x37))).Bit1
    #define    DDRB_Bit2    (*((volatile bit_field*) (0x37))).Bit2
    #define    DDRB_Bit3    (*((volatile bit_field*) (0x37))).Bit3
    #define    DDRB_Bit4    (*((volatile bit_field*) (0x37))).Bit4
    #define    DDRB_Bit5    (*((volatile bit_field*) (0x37))).Bit5
    #define    DDRB_Bit6    (*((volatile bit_field*) (0x37))).Bit6
    #define    DDRB_Bit7    (*((volatile bit_field*) (0x37))).Bit7
    
    #define    PINB_Bit0    (*((volatile bit_field*) (0x36))).Bit0
    #define    PINB_Bit1    (*((volatile bit_field*) (0x36))).Bit1
    #define    PINB_Bit2    (*((volatile bit_field*) (0x36))).Bit2
    #define    PINB_Bit3    (*((volatile bit_field*) (0x36))).Bit3
    #define    PINB_Bit4    (*((volatile bit_field*) (0x36))).Bit4
    #define    PINB_Bit5    (*((volatile bit_field*) (0x36))).Bit5
    #define    PINB_Bit6    (*((volatile bit_field*) (0x36))).Bit6
    #define    PINB_Bit7    (*((volatile bit_field*) (0x36))).Bit7

#endif

Ну и так далее...
Потом в программе можно писать "в стиле IAR"

PORTB_Bit5 = 1; // Установить бит
PORTB_Bit5 = 0; // Сбросить бит
if (PORTB_Bit5) // Если бит != 0

Привык к IARу :-)
UserM
Добрый, день!
Подскажите плз. почему не правильно работает внутренний цикл, переменная outer1 уменьшается не на еденицу ,а на 32h !
Код
unsigned short outer1;
while (ms--)
    {    
    outer1 = 100;
    while (outer1)
 {
 outer1--;
 }
    }

Код дисассемблера
Цитата
24:            outer1 = 100;
+00000033:  E624        LDI    R18,0x64        Load immediate
+00000034:  E030        LDI    R19,0x00        Load immediate
27:              outer1--;
+00000035:  5322        SUBI    R18,0x32        Subtract immediate
---- No Source ------------------------------------------------------------------------------
+00000036:  4030        SBCI    R19,0x00        Subtract immediate with carry
+00000037:  F7E9        BRNE    PC-0x02          Branch if not equal
+00000038:  CFF5        RJMP    PC-0x000A        Relative jump
+00000039:  9508        RET                      Subroutine return


Если добавляю еще одну переменную тогда работает правильно.

Код
unsigned short outer1, k;
while (ms--)
{    
    outer1 = 100;
    while (outer1)
 {
 outer1--;
 k++;
 }
}


Цитата
24:            outer1 = 100;
+00000033:  E624        LDI    R18,0x64        Load immediate
+00000034:  E030        LDI    R19,0x00        Load immediate
27:              outer1--;
+00000035:  5021        SUBI    R18,0x01        Subtract immediate
+00000036:  4030        SBCI    R19,0x00        Subtract immediate with carry
28:              k++;
+00000037:  F7E9        BRNE    PC-0x02          Branch if not equal
---- No Source ------------------------------------------------------------------------------
+00000038:  CFF5        RJMP    PC-0x000A        Relative jump
+00000039:  9508        RET                      Subroutine return

Версия WinAVR - 20050214
UserM
Попробовал написать цикл for и тоже компилируется и работает не правильно.
Переменная должна увеличиваться с каждым шагом , а она уменьшается. sad.gif

Код
while (1) {              

unsigned short k;        
for(k=0; k<100; k++)
{
PORTD &= ~(1<<5);
PORTD |= (1<<5)
}
}

Цитата
--- test1.c --------------------------------------------------------------------------------------
17:          int main(void)              
18:          {
+0000002E:   E5CF        LDI     R28,0x5F         Load immediate
+0000002F:   E0D4        LDI     R29,0x04         Load immediate
+00000030:   BFDE        OUT     0x3E,R29         Out to I/O location
+00000031:   BFCD        OUT     0x3D,R28         Out to I/O location
19:           bit_set(DDRD,BIT(5));        
+00000032:   9A8D        SBI     0x11,5           Set bit in I/O register
+00000033:   E683        LDI     R24,0x63         Load immediate
+00000034:   E090        LDI     R25,0x00         Load immediate
27:            PORTD &= ~(1<<5);
+00000035:   9895        CBI     0x12,5           Clear bit in I/O register
28:            PORTD |= (1<<5);
+00000036:   9A95        SBI     0x12,5           Set bit in I/O register
25:            for(k=0; k<100; k++)
+00000037:   9701         SBIW    R24,0x01         Subtract immediate from word
---- No Source -----------------------------------------------------------------------------
+00000038:   FF97        SBRS    R25,7            Skip if bit in register set
+00000039:   CFFB        RJMP    PC-0x0004        Relative jump
+0000003A:   CFF8        RJMP    PC-0x0007        Relative jump

Может в makefile , что-то не верно указал?
GedasL
А какая тебе разнича. Тебе нужно 100 циклов вот компилятор и делает их. А то что он уменшает переменную ето его дело.
vet
Цитата
unsigned short outer1;

Возможно, проблему решит такое объявление:
Код
volatile unsigned short outer1;
UserM
Цитата(GedasL @ May 14 2005, 21:15)
А какая тебе разнича.  Тебе нужно 100 циклов вот компилятор и делает их. А то что он уменшает переменную ето его дело.
*

Видимо Вы правы, но обидно, кто в доме хозяин. unsure.gif
UserM
Цитата(vet @ May 14 2005, 22:50)
Цитата
unsigned short outer1;

Возможно, проблему решит такое объявление:
Код
volatile unsigned short outer1;

*


Да, так работает , спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.