4 / 4 / 6
Регистрация: 07.01.2013
Сообщений: 136
1

ATmega8. AVR-GCC в Linux Ubuntu

09.02.2014, 17:49. Показов 3138. Ответов 8
Метки нет (Все метки)

Воспользовался парой известных туториалов по этим микроконтроллерам и столкнулся со следующей проблемой. gcc-avr оказывается собирать код из туториала.

Код

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define F_CPU 1000000UL
 
#include <avr/io.h>
#include <util/delay.h>
 
#define confport(port,conf) DDR##port = conf // Example: confport(D,0xff)
#define set0(port,num) PORT##port &= ~_BV(P##port##num) // Example: set0(D,1);
#define set1(port,num) PORT##port |= _BV(P##port##num) // Example: set1(D,1);
 
int main(void)
{
    confport(D,0xff);
    while(1)
    {
        set1(D,1);
        _delay_ms(500);
        set0(D,1);
    }
}
Ошибка
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
k1-801@Haont-l1:~$ avr-gcc ~/avr.c
In file included from /home/k1-801/avr.c:3:0:
/usr/lib/avr/include/avr/io.h:428:6: warning: #warning "device type not defined" [-Wcpp]
# warning "device type not defined"
^
In file included from /home/k1-801/avr.c:4:0:
/usr/lib/avr/include/util/delay.h:95:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed" [-Wcpp]
# warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
^
/home/k1-801/avr.c: In function ‘main’:
/home/k1-801/avr.c:6:29: error: ‘DDRD’ undeclared (first use in this function)
#define confport(port,conf) DDR##port = conf // Example: confport(D,0xff)
^
/home/k1-801/avr.c:12:2: note: in expansion of macro ‘confport’
confport(D,0xff);
^
/home/k1-801/avr.c:6:29: note: each undeclared identifier is reported only once for each function it appears in
#define confport(port,conf) DDR##port = conf // Example: confport(D,0xff)
^
/home/k1-801/avr.c:12:2: note: in expansion of macro ‘confport’
confport(D,0xff);
^
/home/k1-801/avr.c:8:24: error: ‘PORTD’ undeclared (first use in this function)
#define set1(port,num) PORT##port |= _BV(P##port##num) // Example: set1(D,1);
^
/home/k1-801/avr.c:15:3: note: in expansion of macro ‘set1’
set1(D,1);
^
In file included from /usr/lib/avr/include/avr/io.h:99:0,
from /home/k1-801/avr.c:3:
/home/k1-801/avr.c:8:42: error: ‘PD1’ undeclared (first use in this function)
#define set1(port,num) PORT##port |= _BV(P##port##num) // Example: set1(D,1);
^
/home/k1-801/avr.c:15:3: note: in expansion of macro ‘set1’
set1(D,1);
^


Как я понял, необходимо указать тип контроллера и включить оптимизацию, но ни того, ни другого в туториале сказано не было, и как это сделать, соответственно, тоже.
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.02.2014, 17:49
Ответы с готовыми решениями:

GCC-AVR Linux
Вот такая констукция #asm .equ __y2s_port=0?12 ;PORTD .equ __sda_bit=0 .equ __scl_bit=1...

Define в avr-gcc под linux
Для унификации кода создал макросы #define BUTTONPORT PORTC #define BUTTONPORT1 PORTC1...

компиляция avr-gcc
Народ подскажите как компилировать проекты написанные с помощью LUFA. 1 из командной строки. 2 из...

Asm вставки в AVR GCC
Есть у кого-то описание как писать эти _страшные_ вещи? Конструкция подразумевающая всего лишь swap...

8
6678 / 2661 / 366
Регистрация: 17.02.2013
Сообщений: 3,908
10.02.2014, 03:45 2
Лучший ответ Сообщение было отмечено k1-801 как решение

Решение

Цитата Сообщение от k1-801 Посмотреть сообщение
/usr/lib/avr/include/avr/io.h:428:6: warning: #warning "device type not defined" [-Wcpp]
Смотришь на первую ошибку в листинге, ибо последующие могут порождаться первой. Тут gcc жалуется, что ты ему не сказал под какой конкретно AVR-овский процессор ты компилишь. Ну так скажи. Укажи ему в командной строке опцию -mmcu=atmega8 или что-то вроде того.

Добавлено через 4 минуты
Цитата Сообщение от k1-801 Посмотреть сообщение
Как я понял, необходимо указать тип контроллера и включить оптимизацию, но ни того, ни другого в туториале сказано не было, и как это сделать, соответственно, тоже.
Зато в Гугле сказано. Гуглишь "опции компилятора Си для микроконтроллеров AVR" и находишь http://microsin.net/programmin... tions.html
1
4 / 4 / 6
Регистрация: 07.01.2013
Сообщений: 136
10.02.2014, 14:46  [ТС] 3
Цитата Сообщение от Ethereal Посмотреть сообщение
Укажи ему в командной строке опцию -mmcu=atmega8 или что-то вроде того.
Ну я сам вчера ещё до этого случайно дошёл и как всегда отписать сюда забыл... Тем не менее, спасибо.
Bash
1
2
k1-801@Haont-l1:~$ avr-gcc ~/avr/avr.c -mmcu=atmega8 -Os
k1-801@Haont-l1:~$ avr-objcopy -O ihex ~/avr/avr.out ~/avr/avr.hex
Добавлено через 16 минут
Остался один вопрос.
В коде у меня установка состояния порта работает через макросы. В данной ситуации это НЕ будет работать если номер порта или пина задан не строго буквой а какой-либо переменной. Следовательно, нужно понять, какого типа указанные PORTx и DDRx чтобы сделать это функциями.

Добавлено через 14 минут
Облом. Это нечто задаваемое через #define в файлах библиотеки.
0
4 / 4 / 6
Регистрация: 07.01.2013
Сообщений: 136
12.02.2014, 17:30  [ТС] 4
Тот же контроллер, тот же компилятор.

Ошибка
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
k1-801@Haont-l1:~$ usbcompile
In file included from ./avr.c:11:0:
./crutch.h:35:37: error: unknown type name ‘bool’
 void digitalWrite(unsigned char pin,bool mode)
                                     ^
./avr.c: In function ‘loop’:
./crutch.h:19:14: error: ‘true’ undeclared (first use in this function)
 #define HIGH true
              ^
./avr.c:20:17: note: in expansion of macro ‘HIGH’
  digitalWrite(0,HIGH);
                 ^
./crutch.h:19:14: note: each undeclared identifier is reported only once for each function it appears in
 #define HIGH true
              ^
./avr.c:20:17: note: in expansion of macro ‘HIGH’
  digitalWrite(0,HIGH);
                 ^
Незаконченный crutch.h
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**
 * AVR "crutch" to use Atmel microcontrollers as arduino (difference only in #include)
 * by k1-801
 */
 
#pragma once
#ifndef ARDUINO_CRUTCH
#define ARDUINO_CRUTCH
 
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
 
#include <avr/io.h>
#include <util/delay.h>
 
#include "pinconfig.h"
 
#define HIGH true
#define LOW false
 
#define delay(ms) _delay_ms(ms)
#define confport(port,conf) DDR##port = conf // Example: confport(D,0xff)
 
void init();
void loop();
 
int main()
{
    init();
    while(1)
        loop();
}
 
void digitalWrite(unsigned char pin,bool mode)
{
    switch(pin)
    {
/** Definition to shorten the switch */
#define __case_set_(num) case num:\
            if(mode==HIGH)\
                __port_pin##num|=1<<__offset_pin##num;\
            else\
                __port_pin##num&|=~(1<<__offset_pin##num)\
            break;
/** Definition ended */
/** Shitcode, repeated 20 imes */
        __case_set(0);
        __case_set(1);
        __case_set(2);
        __case_set(3);
        __case_set(4);
        __case_set(5);
        __case_set(6);
        __case_set(7);
        __case_set(8);
        __case_set(9);
        __case_set(10);
        __case_set(11);
        __case_set(12);
        __case_set(13);
        __case_set(14);
        __case_set(15);
        __case_set(16);
        __case_set(17);
        __case_set(18);
        __case_set(19);
/** This shit ended */
#undef __case_set
        default:
            break;
    }
}
#endif


Не знает типа bool, не определено true.

Добавлено через 40 минут
Нашёл какое-то исправление...

Ошибка
Bash
1
2
3
4
5
6
7
8
k1-801@Haont-l1:~$ usbcompile
In file included from ./avr.c:11:0:
./crutch.h:19:13: error: expected identifier before numeric constant
 #define LOW 0
             ^
./crutch.h:22:14: note: in expansion of macro ‘LOW’
 typedef enum{LOW,HIGH} power_level;
              ^
crutch.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
 * AVR "crutch" to use Atmel microcontrollers as arduino (difference only in #include "crutch.h")
 * by k1-801
 */
 
#pragma once
#ifndef ARDUINO_CRUTCH
#define ARDUINO_CRUTCH
 
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
 
#include <avr/io.h>
#include <util/delay.h>
 
#include "pinconfig.h"
 
#define LOW 0
#define HIGH 1
 
typedef enum{LOW,HIGH} power_level;
 
#define delay(ms) _delay_ms(ms)
#define confport(port,conf) DDR##port = conf // Example: confport(D,0xff)
 
void init();
void loop();
 
int main()
{
    init();
    while(1)
        loop();
}
 
void digitalWrite(unsigned char pin, power_level mode)
{
    switch(pin)
    {
/** Definition to shorten the switch */
#define __case_set_(num) case num:\
            if(mode==HIGH)\
                __port_pin##num|=1<<__offset_pin##num;\
            else\
                __port_pin##num&|=~(1<<__offset_pin##num)\
            break;
/** Definition ended */
/** Shitcode, repeated 20 times */
        __case_set(0);
        __case_set(1);
        __case_set(2);
        __case_set(3);
        __case_set(4);
        __case_set(5);
        __case_set(6);
        __case_set(7);
        __case_set(8);
        __case_set(9);
        __case_set(10);
        __case_set(11);
        __case_set(12);
        __case_set(13);
        __case_set(14);
        __case_set(15);
        __case_set(16);
        __case_set(17);
        __case_set(18);
        __case_set(19);
/** This shit ended */
#undef __case_set
        default:
            break;
    }
}
#endif


Добавлено через 1 час 8 минут
Решил проблему убрав дефайны перед энумом.
0
4 / 4 / 6
Регистрация: 07.01.2013
Сообщений: 136
19.02.2014, 13:49  [ТС] 5
Вот какая фигня на этот раз. Ругается на lcd.h

Ошибка
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
k1-801@Haont-l1:~$ usbcompile
./avr.c: At top level:
./avr.c:13:2: error: неверная директива препроцессора: #asm
 #asm
  ^
./avr.c:14:2: error: expected identifier or ‘(’ before ‘.’ token
  .equ __lcd_port=0x12; PORTD
  ^
In file included from /usr/lib/avr/include/avr/io.h:99:0,
                 from ./crutch.h:14,
                 from ./avr.c:11:
./avr.c:14:24: error: expected identifier or ‘(’ before ‘volatile’
  .equ __lcd_port=0x12; PORTD
                        ^
./avr.c:14:24: error: expected ‘)’ before ‘(’ token
  .equ __lcd_port=0x12; PORTD
                        ^
./avr.c:15:2: error: неверная директива препроцессора: #endasm
 #endasm
  ^
In file included from ./avr.c:16:0:
/usr/lib/avr/include/lcd.h:39:27: error: expected ‘;’, ‘,’ or ‘)’ before ‘*’ token
 void lcd_putsf(char flash *str);
                           ^
avr.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
 * AVR test code
 * by k1-801
 * 
 * to compile use:
 *  avr-gcc ~/avr/avr.c -o ~/avr/avr.out -mmcu=atmega8 -Os
 *  avr-objcopy -O ihex ~/avr/avr.out ~/avr/avr.hex
 * if sources are in ~/avr directory
 */
 
#include "crutch.h"
 
#asm
    .equ __lcd_port=0x12; PORTD
#endasm
#include <lcd.h>
 
void init()
{
    pinMode(OUTPUT,0);
}
 
void loop()
{
    int i,j;
    for(i=0;i<3;++i)
    {
        for(j=0;j<3;++j)
        {
            if(i==j)
                digitalWrite(j,HIGH);
            else
                digitalWrite(j,LOW);
        }
        delay(500);
    }
}


lcd.h - стандартный.

Добавлено через 31 минуту
Люди, кто может всё-таки ответить?

Добавлено через 16 минут
Не понимает директиву #asm. Почему - не понятно.
C
1
2
3
4
#asm
    .equ __lcd_port=0x12; PORTD
#endasm
#include <lcd.h>
Bash
1
2
3
./avr.c:13:2: error: неверная директива препроцессора: #asm
 #asm
  ^
0
1930 / 1245 / 124
Регистрация: 04.01.2010
Сообщений: 4,482
19.02.2014, 17:12 6
Лучший ответ Сообщение было отмечено raxp как решение

Решение

k1-801, все потому что вы пытаетесь использовать код от CodeVision не в своем компиляторе. Директивы flashнету в GCC. Нужно читать из флешки вручную. Второе - вставка кода в ассемблерный вариант. Эти строчки задают в библиотеку к lcd ассемблерный дефайн. Как это делается в GCC, я не знаю. И знаю, что либы GCC и CodeVision отличаются методом передачи параметров в функции - их придется переделывать, если хотите использовать.
Как вариант - ищите подходящие исходники для GCC. Ну, или учите Си.
0
4 / 4 / 6
Регистрация: 07.01.2013
Сообщений: 136
20.02.2014, 11:40  [ТС] 7
Цитата Сообщение от Voland_ Посмотреть сообщение
k1-801, все потому что вы пытаетесь использовать код от CodeVision не в своем компиляторе. Директивы flashнету в GCC. Нужно читать из флешки вручную. Второе - вставка кода в ассемблерный вариант. Эти строчки задают в библиотеку к lcd ассемблерный дефайн. Как это делается в GCC, я не знаю. И знаю, что либы GCC и CodeVision отличаются методом передачи параметров в функции - их придется переделывать, если хотите использовать.
Как вариант - ищите подходящие исходники для GCC. Ну, или учите Си.
Ну, "не в своём компиляторе"... Я CodeVision не пользовался.
Можно какую-нибудь "примитивную" библиотеку для LCD при использовании с компилятором avr-gcc? Использовать буду только порт D, 4-битный режим (ног мало, а разницы особой не будет).

Фото этого самого индикатора прилагается.
Фото индикатора
0
1930 / 1245 / 124
Регистрация: 04.01.2010
Сообщений: 4,482
20.02.2014, 13:12 8
Цитата Сообщение от k1-801 Посмотреть сообщение
Можно какую-нибудь "примитивную" библиотеку для LCD
вы какие-нить поисковики знаете в Сети? Первый же запрос дал такой результат. Я его даже не изучал. Но в чем сложность поискать?
0
4 / 4 / 6
Регистрация: 07.01.2013
Сообщений: 136
20.02.2014, 22:54  [ТС] 9
Цитата Сообщение от Voland_ Посмотреть сообщение
вы какие-нить поисковики знаете в Сети? Первый же запрос дал такой результат. Я его даже не изучал. Но в чем сложность поискать?
Криво, видимо, ищу. Не находил этого. Сейчас проверим, есть вероятность что не работает.
UPD: Не взлетит.

Добавлено через 38 минут
Ещё поковырял. Нет, не работает это. Ощущение что выдернули откуда-то половину библиотеки... При компиляции программы с GLUT без опции -lglut примерно тот же эффект.

Добавлено через 2 часа 10 минут
Так, сейчас будет большой и жЫрный говнокод.

Ошибка
Bash
1
2
3
4
5
6
7
8
9
10
11
12
k1-801@Haont-l1:~$ usbcompile
In file included from /usr/lib/avr/include/avr/io.h:99:0,
                 from ./crutch.h:14,
                 from ./avr.c:12:
./lcd.h: In function ‘LCD_putchar’:
./lcd.h:35:2: error: called object is not a function or function pointer
  DDRD = 0xFF;
  ^
./avr.c: In function ‘loop’:
./avr.c:27:3: warning: incompatible implicit declaration of built-in function ‘sprintf’ [enabled by default]
   sprintf(string,"%d",i);
   ^
lcd.h
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#pragma once
#ifndef LCD_H_INCLUDED
#define LCD_H_INCLUDED
 
#include <avr/io.h>
#include <util/delay.h>
 
#define LCD_RS 0
#define LCD_RW 1
#define LCD_E 2
 
// LCD_getaddress reads the address counter and busy flag.
char LCD_getaddr()
{
    char address;
    DDRD = 0;
    PORTC |= ((1<<LCD_RW)|(1<<LCD_E));
    asm volatile ("nop");
    asm volatile ("nop");
    address = PIND;
    PORTC &= ~((1<<LCD_RW)|(1<<LCD_E));
    return address;
}
 
// LCD_wait reads the address counter (which contains the busy flag) and loops until the busy flag is cleared.
void LCD_wait()
{
    while((LCD_getaddr() & 0x80) == 0x80){}
}
 
// usage: LCD_putchar('A'); or LCD_putchar(0x55);
void LCD_putchar(char data)
{
    LCD_wait()
    DDRD = 0xFF;
    PORTD = data;
    PORTC &= ~((1<<LCD_RW)|(1<<LCD_E));
    PORTC |= ((1<<LCD_RS)|(1<<LCD_E));
    asm volatile ("nop");
    PORTC &= ~((1<<LCD_RS)|(1<<LCD_E));
    DDRD = 0;
}
 
void LCD_command(char command)
{
    LCD_wait();
    DDRD = 0xFF;
    PORTD = command;
    PORTC &= ~((1<<LCD_RS)|(1<<LCD_RW)|(1<<LCD_E));
    PORTC |= (1<<LCD_E);
    asm volatile ("nop");
    PORTC &= ~(1<<LCD_E);
    DDRD = 0;
}
 
/**
 * LCD_init initialises the LCD with the following paramters:
 * 8 bit mode, 5*7 font, 2 lines (also for 4 lines)
 * auto-inc cursor after write and read
 * cursor and didsplay on, cursor blinking.
 */
void LCD_init()
{
    // Setup the LCD control signals on PortC
    DDRC |= ((1<<LCD_RS)|(1<<LCD_RW)|(1<<LCD_E));
    PORTC = 0x00;
 
    _delay_loop_2(0xFFFF);
 
    LCD_command(0x20); // 4 bit interface, 1 line
//  LCD_command(0x28); // 4 bit interface, 2 lines
//  LCD_command(0x30); // 8 bit interface, 1 line
//  LCD_command(0x38); // 8 bit interface, 2 lines
 
    LCD_wait();
 
//  LCD_command(0x0C); // Display on, cursor off
//  LCD_command(0x0D); // Display on, cursor blinking
//  LCD_command(0x0E); // Display on, cursor underlined
    LCD_command(0x0F); // Display on, cursor blinking and underlined
 
    LCD_wait();
 
    LCD_command(0x01); // Clear the display, cursor home
    LCD_wait();
 
    LCD_command(0x06); // Cursor auto-move
}
 
// Usage : LCD_write("Hello World!");
void LCD_puts(char* dstring)
{
    while(*dstring)
    {
        LCD_putchar(*dstring++);
    }
}
 
LCD_putnum(int num)
{
    int i,j[16],n=0;
    while(num>0)
    {
        j[n]=num%10;
        ++n;
        num/=10;
    }
    for(i=0;i<n;i++)
    {
        LCD_putchar(j[i]+48);
    }
}
 
void LCD_move(int posx, int posy)
{
    LCD_wait();
    posx%=16;
    posy%=2;
    LCD_commsnd(16*posy+posx);
}
#endif
avr.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * AVR test code
 * by k1-801
 * 
 * to compile use:
 *  avr-gcc ~/avr/avr.c -o ~/avr/avr.out -mmcu=atmega8 -Os
 *  avr-objcopy -O ihex ~/avr/avr.out ~/avr/avr.hex
 * if sources are in ~/avr directory
 */
 
#include "pinconfig.h"
#include "crutch.h"
#include "lcd.h"
 
void setup()
{
    pinMode(OUTPUT,0);
}
 
void loop()
{
    int i;
    char string[16];
    LCD_init();
    for(i=0;i<256;++i)
    {
        sprintf(string,"%d",i);
        LCD_puts(string);
        delay(500);
    }
}


А суть в прямом присвоении значения регистру... Чем заменить?

Добавлено через 4 часа 56 минут
Прошу хоть кого-нибудь ответить, идеи стремительно заканчиваются...

Добавлено через 24 минуты
Грр. Забыл точку с запятой.
Первая проблема решилась.

Вторая (с sprintf) так и осталась.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.02.2014, 22:54

забавное поведение avr-gcc
Решил тут запилить маленький проектик на mega8 (измеряем пару напряжений и отправляем по uart на...

2 byte into 1 int? (AVR GCC)
2 байта лежат в массиве unsykned char Buf, причем Buf = MSB, Buf = LSB. Их необходимо слепить в int...

AVR GCC проблема с UART
решил вот лампочками помигать - ambilight сделать - и вот на грабли наткнулся -какая то неведомая...

avr gcc, ds18b20, lcd3310
Добрый день. Есть у меня программа, которая выводит на дисплей от нокии 3310 показания температуры...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.