реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Массив портов ввода PINx, вопрос к знатокам GCC
singlskv
сообщение Nov 28 2006, 17:25
Сообщение #16


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(aesok @ Nov 28 2006, 00:35) *
Цитата(Lem @ Nov 28 2006, 01:06) *

сделайте структуру
Код
typedef struct
{
   unsigned char *pinr;
  .....
} PIN;

НЕВЕРНО. pinr, port и ddr - ДОЛЖНЫ обязательно быть volatile!!!


Цитата(aesok @ Nov 28 2006, 01:04) *
Цитата(singlskv @ Nov 28 2006, 01:55) *

Цитата(aesok @ Nov 28 2006, 00:35) *

Он выкинит первую запись в порт. Оставит только вторую. Для обычных переменых это правильная оптимизация, но доступ к портам оптимизироваться не должен.

а должно ли PINx быть volatile ?

???
avr/port_def.h
....
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define _SFR_MEM8(mem_addr) _MMIO_BYTE(mem_addr)
.....

Как видете все SFR обявлены как volatile.

Обявлять структуру или массив в которых хранятся адреса портов volatile НЕТ никакой необходимости.
И даже более того вредно.
Нужно обявлять доступ к порту как volatile, то есть так как сделано в _SFR...
(*(volatile uint8_t *)(mem_addr))
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Nov 28 2006, 18:05
Сообщение #17


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(singlskv @ Nov 28 2006, 13:40) *
Цитата(aesok @ Nov 28 2006, 00:04) *

Я бы сделал чтото вроде этого:

1. Объявил структуру.
struct __port {
volatile uint8_t *port;
unsigned char pin;
};

Такая структура занимает 3 байта.
Адрес порта <0x100, поэтому достаточно 2 байт.
Если массив будет большим, это серьезная экономия.

Чтобы указатель был однобайтовым, он должен указывать на tiny память.
В IAR это __tiny, а как в GCC не знаю.
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 28 2006, 18:10
Сообщение #18


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(singlskv @ Nov 28 2006, 18:25) *
Обявлять структуру или массив в которых хранятся адреса портов volatile НЕТ никакой необходимости.
И даже более того вредно.



В чем вред? Пример.

ADD:
Не правильно прочитал вашу фразу.

Я не предлагал обьявлять структуру как volatile, а только те члены структуры в которых храняться ссылки на порты.


Цитата
Нужно обявлять доступ к порту как volatile, то есть так как сделано в _SFR...
(*(volatile uint8_t *)(mem_addr))


Главное чтобы весь доступ к портам был помечен как 'volatile'. А как - это без разницы.

Анатолий.

Сообщение отредактировал aesok - Nov 28 2006, 18:25
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 28 2006, 18:23
Сообщение #19


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(aesok @ Nov 28 2006, 18:10) *
Цитата(singlskv @ Nov 28 2006, 18:25) *

Обявлять структуру или массив в которых хранятся адреса портов volatile НЕТ никакой необходимости.
И даже более того вредно.

В чем вред? Пример.

Вам какой результат компиляции нравится больше ?

Вот этот, с volatile при объявлении массива
Код
volatile BYTE PIN_[2]={
    (BYTE)(&PINB),
    (BYTE)(&PIND)
  };

  tmp1= *(volatile BYTE *)((WORD)PIN_[0]);
  tmp2= *(volatile BYTE *)((WORD)PIN_[0]);

результат компиляции
Код
160:        tmp1= *(volatile BYTE *)((WORD)PIN_[0]);
+0000020A:   91800100    LDS     R24,0x0100       Load direct from data space
+0000020C:   2FE8        MOV     R30,R24          Copy register
+0000020D:   27FF        CLR     R31              Clear Register
+0000020E:   8180        LDD     R24,Z+0          Load indirect with displacement
161:        tmp2= *(volatile BYTE *)((WORD)PIN_[0]);
+0000020F:   91800100    LDS     R24,0x0100       Load direct from data space
+00000211:   2FE8        MOV     R30,R24          Copy register
+00000212:   27FF        CLR     R31              Clear Register
+00000213:   8180        LDD     R24,Z+0          Load indirect with displacement


или этот, без volatile ?
Код
BYTE PIN_[2]={
    (BYTE)(&PINB),
    (BYTE)(&PIND)
  };

  tmp1= *(volatile BYTE *)((WORD)PIN_[0]);
  tmp2= *(volatile BYTE *)((WORD)PIN_[0]);

результат компиляции
Код
160:        tmp1= *(volatile BYTE *)((WORD)PIN_[0]);
+0000020A:   91800100    LDS     R24,0x0100       Load direct from data space
+0000020C:   2FE8        MOV     R30,R24          Copy register
+0000020D:   27FF        CLR     R31              Clear Register
+0000020E:   8180        LDD     R24,Z+0          Load indirect with displacement
161:        tmp2= *(volatile BYTE *)((WORD)PIN_[0]);
+0000020F:   8180        LDD     R24,Z+0          Load indirect with displacement
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 28 2006, 18:49
Сообщение #20


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Созрело 2 решения:

1. Ваше.
BYTE PIN_[2]={
(BYTE)(&PINB),
(BYTE)(&PIND)
};

tmp1= *(volatile BYTE *)((WORD)PIN_[0]);
tmp2= *(volatile BYTE *)((WORD)PIN_[0]);

Минусы: Не забывать писать "*(volatile..." при каждом обращении к порту!!!
Плюсы: Экономия 1 байта RAM на каждий порт.

2. Моё.

struct __port {
volatile uint8_t *port;
unsigned char pin;
};


struct __port ports[3] = {
{&PINB, 1<<PINB5},
{&PINF, 1<<PINF2},
{&PING, 1<<PING1}
};


PIN_tmp=*(ports[0].port);
tmp=PIN_tmp & ports[0].pin;

Минусы: Потеря 1 байта RAM на каждий порт.
Плюсы: Более понятная и постая запись. (моё личное мнение)



Анатолий.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 28 2006, 19:08
Сообщение #21


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(aesok @ Nov 28 2006, 18:49) *
Созрело 2 решения:
2. Моё.

struct __port {
volatile uint8_t *port;
unsigned char pin;
};


struct __port ports[3] = {
{&PINB, 1<<PINB5},
{&PINF, 1<<PINF2},
{&PING, 1<<PING1}
};


PIN_tmp=*(ports[0].port);
tmp=PIN_tmp & ports[0].pin;

Минусы: Потеря 1 байта RAM на каждий порт.
Плюсы: Более понятная и постая запись. (моё личное мнение)

к Вашему варианту добавим еще один минусик
при компиляции:
PIN_tmp1=*(ports[0].port);
PIN_tmp2=*(ports[0].port);
будем опять же иметь лишний код
а если доступ к одному и тому же порту будет в цикле,
будем иметь кучу лишнего кода sad.gif
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 15th July 2025 - 12:49
Рейтинг@Mail.ru


Страница сгенерированна за 0.0143 секунд с 7
ELECTRONIX ©2004-2016