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

 
 
 
Reply to this topicStart new topic
> #define - как применить правильно ?
Shurmas
сообщение Aug 17 2006, 14:58
Сообщение #1


Местный
***

Группа: Новичок
Сообщений: 232
Регистрация: 24-06-06
Пользователь №: 18 332



прошу совета.

Мне нужно управлять (подавать "1" или "0") 6-ю приборами с 6 ног мега16.

Хочу чтоб в верху программы были дефайны типа

#define PRIBOR(1) (тут порт и номер ноги к которой подключен)
и так 6 строчек. Но не могу понять что там писать ? Ведь нужна возможность писать и разные порты. И как потом в программе управлять DDR - хотя бы раз чтоб сделать соотв. ножки выходами ?
если я в дефайнах пропишу PORTx.x то как управлять DDRx ? или только 12 дефайнами решается ?

Компилер IAR или WinAVR но можно и под другой.

в идеале нужно чтоб можно бы так управлять

PRIBOR(переменная номер нужного прибора) = 1;
// выдать "1" на прибор номер как значение переменной.


PRIBOR(переменная номер нужного прибора) = OUT ;
// включить на выход ножку к прибору номер как значение переменной.

это возможно ? не могу придумать как.

Подскажите пожалуйста.
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 17 2006, 16:29
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Как я понял вам нужно выполнять не одну операцию, а несколько, поэтому лучше оформить это как функцию с передачей номера прибора и типа действия в качестве параметров. Это будет проще и доступнее для восприятия, чем супернавороченный макрос.
Если же вам "ни в жить" именно с помощью define нужно обозначить, то см. главу "А12.3. Макроопределение и макрорасширение" в книге K&R.
Go to the top of the page
 
+Quote Post
Shurmas
сообщение Aug 17 2006, 18:07
Сообщение #3


Местный
***

Группа: Новичок
Сообщений: 232
Регистрация: 24-06-06
Пользователь №: 18 332



мне в принципе все равно как, но хочется чтоб гдето в начале можно было компактно переназначить выводы МК для приборов.

я и подумал про дефайн. Как например определяют какой то параметр, а потом легко его меняют в одном месте а не по всей програме.
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 18 2006, 03:44
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Shurmas @ Aug 18 2006, 00:07) *
мне в принципе все равно как, но хочется чтоб гдето в начале можно было компактно переназначить выводы МК для приборов.

я и подумал про дефайн. Как например определяют какой то параметр, а потом легко его меняют в одном месте а не по всей програме.

Дык обозначить пины это нормально, но ведь вам, как я понял, нужны макросы управления этими "ножками", а не просто их символьные обозначения? Это уже функция получается, будь она inline-функцией или обычной.
P.S. вы бы уточнили эти пины относятся к одному порту или к разным?

Сообщение отредактировал rezident - Aug 18 2006, 03:48
Go to the top of the page
 
+Quote Post
spf
сообщение Aug 18 2006, 04:26
Сообщение #5


Странник
****

Группа: Свой
Сообщений: 766
Регистрация: 29-08-05
Из: Екатеринбург
Пользователь №: 8 051



Цитата(Shurmas @ Aug 18 2006, 00:07) *
мне в принципе все равно как, но хочется чтоб гдето в начале можно было компактно переназначить выводы МК для приборов.

я и подумал про дефайн. Как например определяют какой то параметр, а потом легко его меняют в одном месте а не по всей програме.

Глянь pin_macros (for MB90xxx). Надо что-то типа этого?
Где-то ходит вариант и для AVR.

Определяешь нужные пины и работаешь через макросы при прямых операциях. Если необходимо обращение через "переменную" то придется оформить функцию со switch...


--------------------
"Как много есть на свете вещей, которые мне не нужны!" Сократ
Go to the top of the page
 
+Quote Post
AVR
сообщение Aug 18 2006, 20:30
Сообщение #6


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(Shurmas @ Aug 17 2006, 18:58) *
Мне нужно управлять (подавать "1" или "0") 6-ю приборами с 6 ног мега16.
Хочу чтоб в верху программы были дефайны типа
#define PRIBOR(1) (тут порт и номер ноги к которой подключен)
и так 6 строчек. Но не могу понять что там писать ? Ведь нужна возможность писать и разные порты

Вроде так:
Код
#define PRIBOR(Port, N, V) \
{ \
  *(Port - 1) |= (1<<N); \ //Делаем выходом вывод порта
  if(V) Port |= (1<<N); \ //Устанавливаем в V (1 или 0) соотвествующий вывод
  else Port &= ~(1<<N); \
}
//Далее
#define S1 PRIBOR(PORTA, 2, 1)
#define C1 PRIBOR(PORTA, 2, 0)


Сообщение отредактировал AVR - Aug 18 2006, 20:34


--------------------
Go to the top of the page
 
+Quote Post
_Bill
сообщение Aug 19 2006, 16:29
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(Shurmas @ Aug 17 2006, 21:07) *
мне в принципе все равно как, но хочется чтоб гдето в начале можно было компактно переназначить выводы МК для приборов.

я и подумал про дефайн. Как например определяют какой то параметр, а потом легко его меняют в одном месте а не по всей програме.

В общем, правильно подумали. Я, например, так делаю:
Код
//
// LCD port and bit definitions
//
#define        LCD_DATA         PORTA        // PORTA is LCD data port
#define        LCD_CTRL         PORTA        // PORTA is LCD control port
#define        DATA_MASK        0xF0         // Data have to be at high nibble
#define        LCD_E            (1<<2)       // LCD E control signal
#define        LCD_RS           (1<<1)       // LCD RS control signal
Go to the top of the page
 
+Quote Post
Terminator
сообщение Aug 21 2006, 03:13
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 209
Регистрация: 7-12-04
Из: Томск
Пользователь №: 1 382



Где-то видел красивый макрос для IAR, но уже на найду sad.gif
Для gcc делал следующим образом:
Написал "прогу" для awk которая из файла с описаниями типа
LED_R A 1 1
генерила .h с кучей #define на все случаи жизни, типа
#define LED_R_HIGH (PORTA |= _BV(1))
#define LED_R_LOW (PORTA &= ~_BV(1))
и т.п.
Go to the top of the page
 
+Quote Post
AlexOr
сообщение Aug 21 2006, 06:01
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 89
Регистрация: 30-12-04
Из: Санкт-Петербург
Пользователь №: 1 754



Можно так.
Прикрепленные файлы
Прикрепленный файл  IO.rar ( 5.4 килобайт ) Кол-во скачиваний: 106
 
Go to the top of the page
 
+Quote Post
Evgeny_CD
сообщение Aug 21 2006, 07:17
Сообщение #10


Гуру
******

Группа: СуперМодераторы
Сообщений: 2 065
Регистрация: 11-01-05
Из: Москва
Пользователь №: 1 892



Для генерации таких вещей COG идеально подходит
http://www.nedbatchelder.com/code/cog/index_ru.html
http://www.onembedding.com/articles/cog-n-make/
http://www.onembedding.com/articles/cog-n-make/examples.htm
Go to the top of the page
 
+Quote Post
Дон Амброзио
сообщение Mar 9 2008, 11:11
Сообщение #11


Местный
***

Группа: Участник*
Сообщений: 323
Регистрация: 11-02-08
Пользователь №: 34 947



Подскажите по использованию препроцессорной директиве #define в AVR Studio в программе на АССЕМБЛЕРЕ при использовании её не для определения константы, а для определения макроса-функции.

В общем виде определение препроцессорного макроса-функции выглядит так: #define prepMacrosName (список аргументов) (определение функции)

Вопрос №1

В хелпе приводиться такой пример:
#define SQR(X) ((X)*(X))

Т.е. если я вызову

ldi ZL , low SQR(17)

, то компилятор вместо SQR(17) напишет"

ldi ZL , low ((17) x (17)) или ldi ZL , low (289) ???

Вопрос №2

Обязательно ли в качестве аргументов "функции" макроса числовые переменные? Или можно и куски текстовых строк?
Могу ли я например использовать такой макрос:
#define Command (InstructionType) (InstructionType)

в строке программы

Command (and)i R16 , 0b01001000 // эквивалетно andi R16, 0b01001000
Command (or)i R16 , 0b01001110 // эквивалетно ori R16, 0b01001110


Замечание: как это сделано в СИ-компиляторах НЕ ИНТЕРЕСУЕТ. Интересует как это сделано для ассемблера в AVR Studio


--------------------
После устранения бага в программе она стала работать....хуже
Go to the top of the page
 
+Quote Post
Дон Амброзио
сообщение Mar 9 2008, 12:54
Сообщение #12


Местный
***

Группа: Участник*
Сообщений: 323
Регистрация: 11-02-08
Пользователь №: 34 947



Цитата(Дон Амброзио @ Mar 9 2008, 14:11) *
Вопрос №2

Обязательно ли в качестве аргументов "функции" макроса числовые переменные? Или можно и куски текстовых строк?
Могу ли я например использовать такой макрос:
#define Command (InstructionType) (InstructionType)

в строке программы

Command (and)i R16 , 0b01001000 // эквивалетно andi R16, 0b01001000
Command (or)i R16 , 0b01001110 // эквивалетно ori R16, 0b01001110
Замечание: как это сделано в СИ-компиляторах НЕ ИНТЕРЕСУЕТ. Интересует как это сделано для ассемблера в AVR Studio


Проблему решил. Кому интересно посмотрите в Хэлпе AVR Studio. Ключевые слова «Stringification» и «Concatenation»


--------------------
После устранения бага в программе она стала работать....хуже
Go to the top of the page
 
+Quote Post
Guest_Цыкетчик_*
сообщение Sep 24 2008, 10:37
Сообщение #13





Guests






Цитата(Shurmas @ Aug 17 2006, 18:58) *
прошу совета.

Мне нужно управлять (подавать "1" или "0") 6-ю приборами с 6 ног мега16.

Хочу чтоб в верху программы были дефайны типа

#define PRIBOR(1) (тут порт и номер ноги к которой подключен)
и так 6 строчек. Но не могу понять что там писать ? Ведь нужна возможность писать и разные порты. И как потом в программе управлять DDR - хотя бы раз чтоб сделать соотв. ножки выходами ?
если я в дефайнах пропишу PORTx.x то как управлять DDRx ? или только 12 дефайнами решается ?

Компилер IAR или WinAVR но можно и под другой.

в идеале нужно чтоб можно бы так управлять

PRIBOR(переменная номер нужного прибора) = 1;
// выдать "1" на прибор номер как значение переменной.
PRIBOR(переменная номер нужного прибора) = OUT ;
// включить на выход ножку к прибору номер как значение переменной.

это возможно ? не могу придумать как.

Подскажите пожалуйста.

Тут лучше использовать не препроцессорные, а обычные макросы.
Примерно так biggrin.gif
.macro Pribor
; Пример для ATmega128 у которой некоторые регистры управления портами
; расположены в пространстве дополнительных РВВ
; Номера разрядов и имена портов взяты произвольно (так как автор темы не указал их)
; @0 - номер прибора
; @1 - требуемое состояние пина, управляющего прибором

.if @0 > 6
.error "Ошибка: номер прибора больше 6-ти."
.endif

.if @0 == 1
.set Number_of_Digit = 6
.set DDR_Addres = DDRF
.set PORT_Addres = PORTF
.endif

.if @0 == 2
.set Number_of_Digit = 3
.set DDR_Addres = DDRF
.set PORT_Addres = PORTF
.endif

.if @0 == 3
.set Number_of_Digit = 5
.set DDR_Addres = PORTF
.set PORT_Addres = PORTF
.endif

.if @0 == 4
.set Number_of_Digit = 0
.set DDR_Addres = DDRD + $20
.set PORT_Addres = PORTD + $20
.endif

.if @0 == 5
.set Number_of_Digit = 4
.set DDR_Addres = DDRD + $20
.set PORT_Addres = PORTD + $20
.endif

.if @0 == 6
.set Number_of_Digit = 1
.set DDR_Addres = DDRD + $20
.set PORT_Addres = PORTD + $20
.endif

; Запрограммировать пин на вывод
lds R16 , DDR_Addres
sbr R16 , ( 1 << Number_of_Digit )
sts DDR_Addres , R16

; Установить нужный логический уровень на пине
lds R16 , PORT_Addres
.if @1 = 0
cbr R16 , ( 1 << Number_of_Digit ) ; Выставили '0' на пине
.else
sbr R16 , ( 1 << Number_of_Digit ) ; Выставили '1' на пине
.endif
sts PORT_Addres , R16

.endmacro

.........................
.........................
.........................

; Установить '1' на пине, управляющем прибором №3
Pribor 3, 1

.........................
.........................
; Установить '0' на пине, управляющем прибором №6
Pribor 6, 0


Сообщение отредактировал Цыкетчик - Sep 24 2008, 10:43
Go to the top of the page
 
+Quote Post

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

 


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


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