WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
РобоКОТ
Открыл глаза
Сообщения: 57
Зарегистрирован: Вс мар 01, 2009 16:41:36
Контактная информация:

Сообщение РобоКОТ »

Ну никаких нот фаундов в *.lss не видно- может и все нормально. Узнаю, похоже, только когда плату изготовят и прошью ее :)
neon-f
Потрогал лапой паяльник
Сообщения: 392
Зарегистрирован: Сб дек 12, 2009 02:15:45

Сообщение neon-f »

подскажите, чтоб вывод перевести в z состояние(неопределенное состояние) его нужно просто назначить входом, или есть какой другой способ?

мне нужно на один из портов контролера выводить в произвольном порядке комбинации из 0, 1, z. как это лучше сделать???
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

neon-f писал(а):подскажите, чтоб вывод перевести в z состояние(неопределенное состояние) его нужно просто назначить входом, или есть какой другой способ?

мне нужно на один из портов контролера выводить в произвольном порядке комбинации из 0, 1, z. как это лучше сделать???
для всех МК семейства AVR надо настроить порт на вход и отключить встроенную подтяжку, т.е. DDRx = 0; PORTx = 0. как это лучше делать - сложно сказать. когда мне приспичило подключить 15 светодиодов к attiny13 я сделал массив пар чисел, выводя которые в DDRВ и PORTB можно было включить тот или иной светодиод.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
neon-f
Потрогал лапой паяльник
Сообщения: 392
Зарегистрирован: Сб дек 12, 2009 02:15:45

Сообщение neon-f »

Как перевести порт целиком, или отдельный вывод в 1, 0, или в z я разобрался. Мне нужно выводить на порт комбинации из 0, 1, z в произвольном порядке. например 1100zzzz, z11z0zz1, 01z00zzz. Неужели нужно перед каждой сменой информации переконфигурировать порт на вход\выход, вкл\выкл подтягивающие резисторы.....
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

neon-f писал(а):Как перевести порт целиком, или отдельный вывод в 1, 0, или в z я разобрался. Мне нужно выводить на порт комбинации из 0, 1, z в произвольном порядке. например 1100zzzz, z11z0zz1, 01z00zzz. Неужели нужно перед каждой сменой информации переконфигурировать порт на вход\выход, вкл\выкл подтягивающие резисторы.....
вы бы еще воскликнули "неужели перед каждым измерением надо АЦП запускать и ждать его готовности?" :)))
да, всякий раз надо переконфигурировать порт, меняя значения в обоих регистрах. в некоторых случаях хватит и изменения только одного, но это исключение, т.к. число таких вариантов не исчерпывающее.

Код: Выделить всё

typedef struct{
   char ddr;
   char port;
} led_cfg_type; // тип для описателя портов

// массив описателей для включения каждого светодиода отдельно
led_cfg_type leds[] = {
   {0x80, 0x40}, // для включения 1-го светодиода
   {0x40, 0x10}, // для включения 2-го
   {0x10, 0x10} // для включения третьего
   // и так далее
}

// включение указанного светодиода
void led_on(char led_num){
   PORTD = leds[ led_num ].port;
   DDRD = leds[ led_num ].ddr;
}
примерно вот так я делал
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
uchar
Родился
Сообщения: 8
Зарегистрирован: Чт янв 28, 2010 16:27:21

Запись в память программ.

Сообщение uchar »

Требуется записать несколько байт в память программ (с чтением разобрался, работает). Для начала просто решил стереть что-нить в памяти данных - не получается.. Покурив документацию, понял, что код, который пишет/стирает что-то в памяти данных, должен находиться в области NRWW (необязательно в секции загрузчика).
Т.е., на асме нужно было написать что-то вроде .org 0x1000-128 и далее код функции, которая будет работать с памятью данных, а как это написать на Си в WinAVR?
Аватара пользователя
DOSOFF
Мучитель микросхем
Сообщения: 454
Зарегистрирован: Чт фев 04, 2010 23:20:57
Откуда: Оренбург
Контактная информация:

Сообщение DOSOFF »

Народ помогите.
Седня ток сел за мегу (ночь безсонная была).
Светодиодами мигал (всеми 7-ю), а вот как создать цикл ожидающий нажатие кнопки? (кнопка например, на PB0)
Сижу под WinAVR

Извиняйте уж, если это было уже, перечитывать все страницы топика неосилил...
Здесь был Вася и Вова...

OpenSUSE 11.2

СОЖГИ ГАЗЕЛЬ - СПАСИ БАЙКЕРА
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Запись в память программ.

Сообщение ARV »

uchar писал(а):Т.е., на асме нужно было написать что-то вроде .org 0x1000-128 и далее код функции, которая будет работать с памятью данных, а как это написать на Си в WinAVR?
задайте атрибут BOOTLOADER_SECTION для вашей функции, вот и все.

Код: Выделить всё

void BOOTLOADER_SECTION my_flash_write_func(void);
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
DOSOFF
Мучитель микросхем
Сообщения: 454
Зарегистрирован: Чт фев 04, 2010 23:20:57
Откуда: Оренбург
Контактная информация:

Сообщение DOSOFF »

vМой вопрос снят. Путем нетрезвого мышления и нестандартного подхода, победил.
Блин, интересное это дело :)
Здесь был Вася и Вова...

OpenSUSE 11.2

СОЖГИ ГАЗЕЛЬ - СПАСИ БАЙКЕРА
uchar
Родился
Сообщения: 8
Зарегистрирован: Чт янв 28, 2010 16:27:21

Re: Запись в память программ.

Сообщение uchar »

ARV писал(а):
uchar писал(а):Т.е., на асме нужно было написать что-то вроде .org 0x1000-128 и далее код функции, которая будет работать с памятью данных, а как это написать на Си в WinAVR?
задайте атрибут BOOTLOADER_SECTION для вашей функции, вот и все.

Код: Выделить всё

void BOOTLOADER_SECTION my_flash_write_func(void);


При компиляции выдает ошибку - пишет, что секция .bootloader заходит в секцию .data :(
Может, надо чего в мэйкфайле прописать?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

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

Мой уютный бложик... заходите!
neon-f
Потрогал лапой паяльник
Сообщения: 392
Зарегистрирован: Сб дек 12, 2009 02:15:45

Сообщение neon-f »

Подскажите кто знает, что не так пишу. нужно чтоб при замыкании любой ноги порта С на землю, на порте D появлялось и оставалось то что есть на В ???
int main(void) // начало
{
DDRB = 0X00; // ПОРТ B НАЗНАЧЕН ВХОДОМ
PORTB = 0xff; // ВКЛЮЧЕНЫ ПОДТЯГИВАЮЩИЕ РЕЗИСТОРЫ ПОРТА B
DDRD = 0xff; // ПОРТ D НАЗНАЧЕН ВЫХОДОМ
DDRC = 0X00; // ПОРТ C НАЗНАЧЕН ВХОДОМ
PORTC = 0xff; // ВКЛЮЧЕНЫ ПОДТЯГИВАЮЩИЕ РЕЗИСТОРЫ ПОРТА C


start:
if (PINC = 0xff) goto start; else PORTD = PINB;
goto start;
} // конец
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

neon-f писал(а):Подскажите кто знает, что не так пишу. нужно чтоб при замыкании любой ноги порта С на землю, на порте D появлялось и оставалось то что есть на В ???
int main(void) // начало
{
DDRB = 0X00; // ПОРТ B НАЗНАЧЕН ВХОДОМ
PORTB = 0xff; // ВКЛЮЧЕНЫ ПОДТЯГИВАЮЩИЕ РЕЗИСТОРЫ ПОРТА B
DDRD = 0xff; // ПОРТ D НАЗНАЧЕН ВЫХОДОМ
DDRC = 0X00; // ПОРТ C НАЗНАЧЕН ВХОДОМ
PORTC = 0xff; // ВКЛЮЧЕНЫ ПОДТЯГИВАЮЩИЕ РЕЗИСТОРЫ ПОРТА C


start:
if (PINC = 0xff) goto start; else PORTD = PINB;
goto start;
} // конец
вы привели пример того, как не надо писать на Си :) скажем так, программа в худших традициях бейсика....

Код: Выделить всё

while(1){
   if(PINC != 0xFF)
      PORTD = PINB;
}
вот так записывается на Си то, что вы хотели.

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

Мой уютный бложик... заходите!
neon-f
Потрогал лапой паяльник
Сообщения: 392
Зарегистрирован: Сб дек 12, 2009 02:15:45

Сообщение neon-f »

проблема в том что не работает. даже с вашим кодом.
Вроде одна строчка, все понятно, а в протеусе не работает.
вот эту строку я читаю так
if(PINC != 0xFF) PORTD = PINB;
ЕСЛИ ПОРТ С НЕ РАВЕН FF, ТО ВЫВЕСТИ НА ПОРТ D ДАННЫЕ С ПОРТА В
Правильно?

а по поводу бейсика - вы правы. это единственно на чем я пробовал кодить, и то 17 лет назад :))
Вложения
1533ир37.rar
(48.05 КБ) 248 скачиваний
DimAlt
Вымогатель припоя
Сообщения: 576
Зарегистрирован: Пт май 19, 2006 05:39:11
Контактная информация:

Сообщение DimAlt »

Вроде так работает, зы у меня тож бейсик :cry: :))

Код: Выделить всё

   while(1){
   if ( (PINC&MASKPIN) != MASKPIN ){
      _delay_us(100);//типа антидребезг
      if ( (PINC&MASKPIN) != MASKPIN ) PORTD = PINB;
      }
   }


Хотя в этом конкретном случае лучше сделать так
if ( (PINC&_BV(0)) == 0 ) //опрос одной линии РС0
...
Вложения
1533ир37.rar
(49.49 КБ) 229 скачиваний
neon-f
Потрогал лапой паяльник
Сообщения: 392
Зарегистрирован: Сб дек 12, 2009 02:15:45

Сообщение neon-f »

Ваш вариант работает. Но почему мой не работает. Не могу успокоится пока не разберусь. Вроде все верно, все элементарно - а не работает. Может кто подскажет где ошибка.
DimAlt
Вымогатель припоя
Сообщения: 576
Зарегистрирован: Пт май 19, 2006 05:39:11
Контактная информация:

Сообщение DimAlt »

neon-f писал(а):Ваш вариант работает. Но почему мой не работает. Не могу успокоится пока не разберусь. Вроде все верно, все элементарно - а не работает. Может кто подскажет где ошибка.


У мега8 нет РС7 поэтому чтение PINC возвращает 0x7F, а не 0xFF.

if(PINC != 0x7F) PORTD = PINB;
neon-f
Потрогал лапой паяльник
Сообщения: 392
Зарегистрирован: Сб дек 12, 2009 02:15:45

Сообщение neon-f »

ну слава богу, а то я покой потерял. Получается вот где я запутался. Те пины которых нет физически равны 0. НО есть и еще одна мина. на этом порте находится еще и вывод RESET , и он всегда равен 1.

Еще такой вопрос. как прочитать число снятое с разных портов . Например мне нужно переменной Х присвоить значение с DO,D1,A1,A0,D2,D3,D4,D5, (именно в таком порядке)
DimAlt
Вымогатель припоя
Сообщения: 576
Зарегистрирован: Пт май 19, 2006 05:39:11
Контактная информация:

Сообщение DimAlt »

Решение в лоб

Код: Выделить всё

x=0;
if (PIND & _BV(0)) x=_BV(0);
if (PIND & _BV(1)) x|=_BV(1);
if (PINA & _BV(1)) x|=_BV(2);
if (PINA & _BV(0)) x|=_BV(3);
if (PIND & _BV(2)) x|=_BV(4);
if (PIND & _BV(3)) x|=_BV(5);
if (PIND & _BV(4)) x|=_BV(6);
if (PIND & _BV(5)) x|=_BV(7);


а мож еще как можно сделать, вот на бредил :)) (не проверял!)

Код: Выделить всё

x=0;
p=PIND;
x=p&(_BV(0)|_BV(1));
x|=( p&(_BV(2)|_BV(3)|_BV(4)|_BV(5)) )<<2;
if (PINA & _BV(1)) x|=_BV(2);
if (PINA & _BV(0)) x|=_BV(3);
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

это называется не прочесть, а сформировать число из двух разных значений. вариантов тут 2: красивый внешне и простой для понимания, но громоздкий и малоэффективный для написания, и менее понятный и менее простой, но очень эффективный.

первый способ состоит в описании типа-структуры с битовыми полями, а затем в манипуляции с этими битами структуры.

Код: Выделить всё

typedef struct{
   uint8_t B0 : 1;
   uint8_t B1 : 1;
   // и так далее до
   uint8_t B7 : 1;
} bit_struct;

bit_struct port_d, port_a, result;

port_a = *(bit_struct*)&PINA;
port_d = *(bit_struct*)&PIND;
result.B0 = port_d.B0;
result.B1 = port_d.B1;
result.B2 = port_a.B0;
// и так далее все прочие биты в нужном порядке
напрямую присваивать структуре числовое значение нельзя, отсюда изврат с преобразованием в указатель и обратно. избежать этого можно при помощи union...

второй способ заключается в том, что вы вручную перетасовываете биты при помощи сдвигов и масок:

Код: Выделить всё

uint8_t port_a, port_d, result;

port_a = PINA;
port_d = PIND;
result = (port_d & 0x03) | (port_d << 2); // расставили биты из порта В
result |=((port_a & 0x01) << 3) | ((port_a & 0x02) << 1); // поставили биты из другого порта
какой из вариантов вам больше по душе - решать вам :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Ответить

Вернуться в «AVR»