WinAvr в вопросах и ответах
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
для всех МК семейства AVR надо настроить порт на вход и отключить встроенную подтяжку, т.е. DDRx = 0; PORTx = 0. как это лучше делать - сложно сказать. когда мне приспичило подключить 15 светодиодов к attiny13 я сделал массив пар чисел, выводя которые в DDRВ и PORTB можно было включить тот или иной светодиод.neon-f писал(а):подскажите, чтоб вывод перевести в z состояние(неопределенное состояние) его нужно просто назначить входом, или есть какой другой способ?
мне нужно на один из портов контролера выводить в произвольном порядке комбинации из 0, 1, z. как это лучше сделать???
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Как перевести порт целиком, или отдельный вывод в 1, 0, или в z я разобрался. Мне нужно выводить на порт комбинации из 0, 1, z в произвольном порядке. например 1100zzzz, z11z0zz1, 01z00zzz. Неужели нужно перед каждой сменой информации переконфигурировать порт на вход\выход, вкл\выкл подтягивающие резисторы.....
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
вы бы еще воскликнули "неужели перед каждым измерением надо АЦП запускать и ждать его готовности?"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;
}
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Запись в память программ.
Требуется записать несколько байт в память программ (с чтением разобрался, работает). Для начала просто решил стереть что-нить в памяти данных - не получается.. Покурив документацию, понял, что код, который пишет/стирает что-то в памяти данных, должен находиться в области NRWW (необязательно в секции загрузчика).
Т.е., на асме нужно было написать что-то вроде .org 0x1000-128 и далее код функции, которая будет работать с памятью данных, а как это написать на Си в WinAVR?
Т.е., на асме нужно было написать что-то вроде .org 0x1000-128 и далее код функции, которая будет работать с памятью данных, а как это написать на Си в WinAVR?
- DOSOFF
- Мучитель микросхем
- Сообщения: 454
- Зарегистрирован: Чт фев 04, 2010 23:20:57
- Откуда: Оренбург
- Контактная информация:
Народ помогите.
Седня ток сел за мегу (ночь безсонная была).
Светодиодами мигал (всеми 7-ю), а вот как создать цикл ожидающий нажатие кнопки? (кнопка например, на PB0)
Сижу под WinAVR
Извиняйте уж, если это было уже, перечитывать все страницы топика неосилил...
Седня ток сел за мегу (ночь безсонная была).
Светодиодами мигал (всеми 7-ю), а вот как создать цикл ожидающий нажатие кнопки? (кнопка например, на PB0)
Сижу под WinAVR
Извиняйте уж, если это было уже, перечитывать все страницы топика неосилил...
Здесь был Вася и Вова...
OpenSUSE 11.2
СОЖГИ ГАЗЕЛЬ - СПАСИ БАЙКЕРА
OpenSUSE 11.2
СОЖГИ ГАЗЕЛЬ - СПАСИ БАЙКЕРА
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Запись в память программ.
задайте атрибут BOOTLOADER_SECTION для вашей функции, вот и все.uchar писал(а):Т.е., на асме нужно было написать что-то вроде .org 0x1000-128 и далее код функции, которая будет работать с памятью данных, а как это написать на Си в WinAVR?
Код: Выделить всё
void BOOTLOADER_SECTION my_flash_write_func(void);если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Запись в память программ.
ARV писал(а):задайте атрибут BOOTLOADER_SECTION для вашей функции, вот и все.uchar писал(а):Т.е., на асме нужно было написать что-то вроде .org 0x1000-128 и далее код функции, которая будет работать с памятью данных, а как это написать на Си в WinAVR?Код: Выделить всё
void BOOTLOADER_SECTION my_flash_write_func(void);
При компиляции выдает ошибку - пишет, что секция .bootloader заходит в секцию .data
Может, надо чего в мэйкфайле прописать?
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
да, надо задать размер секции и адрес ее начала - см. фьюзы МК
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Подскажите кто знает, что не так пишу. нужно чтоб при замыкании любой ноги порта С на землю, на порте 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;
} // конец
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
- Откуда: Новочеркасск
- Контактная информация:
вы привели пример того, как не надо писать на Си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;
}а в чем, собственно, проблема?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
проблема в том что не работает. даже с вашим кодом.
Вроде одна строчка, все понятно, а в протеусе не работает.
вот эту строку я читаю так
if(PINC != 0xFF) PORTD = PINB;
ЕСЛИ ПОРТ С НЕ РАВЕН FF, ТО ВЫВЕСТИ НА ПОРТ D ДАННЫЕ С ПОРТА В
Правильно?
а по поводу бейсика - вы правы. это единственно на чем я пробовал кодить, и то 17 лет назад
Вроде одна строчка, все понятно, а в протеусе не работает.
вот эту строку я читаю так
if(PINC != 0xFF) PORTD = PINB;
ЕСЛИ ПОРТ С НЕ РАВЕН FF, ТО ВЫВЕСТИ НА ПОРТ D ДАННЫЕ С ПОРТА В
Правильно?
а по поводу бейсика - вы правы. это единственно на чем я пробовал кодить, и то 17 лет назад
- Вложения
-
- 1533ир37.rar
- (48.05 КБ) 248 скачиваний
-
DimAlt
- Вымогатель припоя
- Сообщения: 576
- Зарегистрирован: Пт май 19, 2006 05:39:11
- Контактная информация:
Вроде так работает, зы у меня тож бейсик
Хотя в этом конкретном случае лучше сделать так
Код: Выделить всё
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 скачиваний
ну слава богу, а то я покой потерял. Получается вот где я запутался. Те пины которых нет физически равны 0. НО есть и еще одна мина. на этом порте находится еще и вывод RESET , и он всегда равен 1.
Еще такой вопрос. как прочитать число снятое с разных портов . Например мне нужно переменной Х присвоить значение с DO,D1,A1,A0,D2,D3,D4,D5, (именно в таком порядке)
Еще такой вопрос. как прочитать число снятое с разных портов . Например мне нужно переменной Х присвоить значение с DO,D1,A1,A0,D2,D3,D4,D5, (именно в таком порядке)
-
DimAlt
- Вымогатель припоя
- Сообщения: 576
- Зарегистрирован: Пт май 19, 2006 05:39:11
- Контактная информация:
Решение в лоб
а мож еще как можно сделать, вот на бредил :)) (не проверял!)
Код: Выделить всё
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
- Откуда: Новочеркасск
- Контактная информация:
это называется не прочесть, а сформировать число из двух разных значений. вариантов тут 2: красивый внешне и простой для понимания, но громоздкий и малоэффективный для написания, и менее понятный и менее простой, но очень эффективный.
первый способ состоит в описании типа-структуры с битовыми полями, а затем в манипуляции с этими битами структуры.напрямую присваивать структуре числовое значение нельзя, отсюда изврат с преобразованием в указатель и обратно. избежать этого можно при помощи union...
второй способ заключается в том, что вы вручную перетасовываете биты при помощи сдвигов и масок:какой из вариантов вам больше по душе - решать вам 
первый способ состоит в описании типа-структуры с битовыми полями, а затем в манипуляции с этими битами структуры.
Код: Выделить всё
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;
// и так далее все прочие биты в нужном порядке
второй способ заключается в том, что вы вручную перетасовываете биты при помощи сдвигов и масок:
Код: Выделить всё
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); // поставили биты из другого порта
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!