Объединение разных PINов в один PORT

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Rondo
Открыл глаза
Сообщения: 42
Зарегистрирован: Чт май 05, 2011 19:53:40
Откуда: Харьков
Контактная информация:

Объединение разных PINов в один PORT

Сообщение Rondo »

Доброго времени суток.

Возникла небольшая проблема с портами мк, а точнее их расположением ...

Начну с начала, как я к этому пришел ... Решил сделать подарок девушке в виде светодиодного сердечка (идеей был вдохновлен на хабре). Начал кодить на отладочной плате (самопал), на которой стоит ATmega16 в DIP корпусе.
И тут понеслась ... вроде сделал хорошие наброски кода, баловался с портом В, грациозно делал всякие вундервафли и мигалки с помощью сдвига регистра порта В, аля кусочек из цикла for:

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

PORTB=0x00000001;
PORTB=PORTB<1;
Решил портировать все это на мегу8 и тут понял что не все так просто
Если взглянутьна мегу8 в TQFP корпусе то видим
Изображение
что если ее визуально поделить на пополам (две половинки сердечка) вертикально то получим по 11 пинов на сторону

Слева: PD0, PD1, PD2, PD3, PD4PB6, PB7, PD5, PD6, PD7, PB0
Cправа: PC5, PC4, PC3, PC2, PC1, PC0, PB5, PB4, PB3, PB2, PB1

И так внимание вопрос !
Можно ли эти пины обьеденить в один так называемый 11 битный "порт" что б можно было левой и правой частью управлять как 8ми битным портом, т.е. к примеру LEFT=0b00000000001 и загорается первый (PD0) диод ?

Или быдлокодить и дергать пины через делей ? что щитаю не спортивным

Жду любых коментов по теме и камней в мою сторону
Реклама
Аватара пользователя
Flasher
Мудрый кот
Сообщения: 1802
Зарегистрирован: Ср сен 07, 2011 21:40:30

Re: Объединение разных PINов в один PORT

Сообщение Flasher »

можно завести переменную, а потом разбрасывать битики переменной по битикам порта.
Реклама
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Объединение разных PINов в один PORT

Сообщение zero648 »

Еще как вариант, сделать драйвер на таймере, в обработчике прерывания преобразуем переменные в порты, т.е. запихиваем нужные биты переменных в нужные биты портов, тем самым включая и выключая нужные светодиоды, а в основном коде играем только с двумя переменными, как с "реальными" портами.
Rondo
Открыл глаза
Сообщения: 42
Зарегистрирован: Чт май 05, 2011 19:53:40
Откуда: Харьков
Контактная информация:

Re: Объединение разных PINов в один PORT

Сообщение Rondo »

Хм ... Идея Flasher'a довольно интересна. Можно по подробнее как биты переменной запихивать в биты порта ? Я думал както через массив, но потом понял что затея глупая. Можно про Ваш способ по подробней и если не сложно с примерами кода.

zero648 также буду рад увидеть решение с помощью вашего способа, а то если чесно я немного не допонял как это сделать с таймером.

Заранее вам спасибо.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
s_black
Мучитель микросхем
Сообщения: 411
Зарегистрирован: Вс авг 10, 2008 19:35:49
Откуда: Евпатория
Контактная информация:

Re: Объединение разных PINов в один PORT

Сообщение s_black »

Вот Артём тут выкладывал свои мысли по поводу виртуальных портов.
Реклама
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Объединение разных PINов в один PORT

Сообщение zero648 »

На СИ не практикую уже давно, если устроит на ASMe накидаю.
Реклама
Аватара пользователя
edm2007
Поставщик валерьянки для Кота
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск
Контактная информация:

Re: Объединение разных PINов в один PORT

Сообщение edm2007 »

Rondo, интересная у Вас запись шестнадцатеричного числа. :)) Впрочем, и "сдвиг" такой же...
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Rondo
Открыл глаза
Сообщения: 42
Зарегистрирован: Чт май 05, 2011 19:53:40
Откуда: Харьков
Контактная информация:

Re: Объединение разных PINов в один PORT

Сообщение Rondo »

0b - это двоичные числа, шестнадцатиричные - 0x. А по поводу сдвига - да, пропустил одну стрелочку.
Аватара пользователя
edm2007
Поставщик валерьянки для Кота
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск
Контактная информация:

Re: Объединение разных PINов в один PORT

Сообщение edm2007 »

Rondo писал(а):0b - это двоичные числа, шестнадцатиричные - 0x
Вот именно. :) Потому и определяйтесь: либо 0b00000000 - 0b11111111, либо 0x0 - 0xFF. Например, запись PORTB = 0x10000000 это совсем не установка 7-го бита порта. :wink:
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Rondo
Открыл глаза
Сообщения: 42
Зарегистрирован: Чт май 05, 2011 19:53:40
Откуда: Харьков
Контактная информация:

Re: Объединение разных PINов в один PORT

Сообщение Rondo »

ну не суть :) я быдлокодю в CVAVR (о чем кстати жалею) но продолжаю в нем, а про PORTB = 0x10000000 это ж 8 бит (т.е PORTB.7=1). Ну в кодвижене так :) и вроде работает)
по поводу поста s_black - очень интересно, но я в асме полный ноль =\

Если ктото сможет пару примерчиков привести в Си буду благодарен

Спасибо всем за ответы, надеюсь вы "вдолбите" мне в голову эту фичу с виртуальными портами, а пока буду сам пробовать чтото понять, но надеюсь на примеры Си кода -_-
Аватара пользователя
edm2007
Поставщик валерьянки для Кота
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск
Контактная информация:

Re: Объединение разных PINов в один PORT

Сообщение edm2007 »

Rondo писал(а):0x10000000 это ж 8 бит
Это не 8 бит а 32. Если перевести в десятичную систему 0x10000000 = (1*16^7)+(0*16^6)+(0*16^5)+(0*16^4)+(0*16^3)+(0*16^2)+(0*16^1)+(0*16^0) = 268 435 456 (или 0b10000000000000000000000000000).
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Объединение разных PINов в один PORT

Сообщение Аlex »

Можно создать макрос и "скармливать" ему маску для установки или сброса битов в этом самом "виртуальном порту".
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15571
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Объединение разных PINов в один PORT

Сообщение BOB51 »

поставь табличную подмену текущих данных на требуемые (разновидность табличного декодера) - метод реализации любой из понятных в объёме слово->слово, только при выводе не забудь про "чтение->модификация с данными->модификация с маской(если у портов разное назначение выводов)->запись
:sleep:
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

Re: Объединение разных PINов в один PORT

Сообщение YS »

Можно разделять исходную переменную битовыми операциями (& / |) по маскам, а потом распихивать выковырянное по портам.

Например, есть у нас шестнадцатибитная переменная VPORT - типа виртуальный порт. Пускай первый и третий ниббл надо запихать в PORTA, а второй и четвертый - в PORTB.

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


PORTA=(VPORT & 0x000F) | ((VPORT & 0x0F00) >> 4);
PORTB=((VPORT & 0x00F0) >> 4) | ((VPORT & 0xF000) >> 8);

Странное дело... Тот, у кого есть девушка, обычно не знает, как сделать виртуальный порт. А у того, кто знает, обычно нет девушки... :))) Так что Вы это... Аккуратнее. :)))
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: Объединение разных PINов в один PORT

Сообщение U235 »

Rondo, если нужно управлять пинами по отдельности, можно сделать примерно так.

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

// Массив соответствия виртуальных пинов
unsigned char ptable[11,3]{
    // Порт B      Порт C      Порт D
    {0b00010000, 0b00000000, 0b00000000},   // виртуальный пин 0
    {0b00000000, 0b00100000, 0b00000000},
    {0b00000000, 0b10000000, 0b00000000},
    {0b00001000, 0b00000000, 0b00100000},
    {0b00000000, 0b00000100, 0b00000000},
    {0b00000100, 0b00000000, 0b00000000},
    {0b00000000, 0b00000000, 0b00000000},
    {0b00000000, 0b00000001, 0b00000000},
    {0b00000000, 0b00000000, 0b00001000},
    {0b00000000, 0b00000000, 0b00000010},
    {0b10000000, 0b00000000, 0b00000000}    // виртуальный пин 1
}

// Установка виртульного пина по его номеру
// num от 0 до 10 (в данном случае)
void setBit(unsigned char num)
{
    PORTB|=ptable[num, 0];
    PORTC|=ptable[num, 1];
    PORTD|=ptable[num, 2];
}

// Сброс виртуального пина
void clearBit(unsigned char num)
{
    PORTB&=(~ptable[num, 0]);
    PORTC&=(~ptable[num, 1]);
    PORTD&=(~ptable[num, 2]);
}
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Объединение разных PINов в один PORT

Сообщение zero648 »

Rondo, если есть кто может подружить этот код с СИ, то вот так примерно выглядит драйвер на таймере, индикация здесь у нас получается динамическая, частоту обновления можно изменить, если чё.
В основном цикле MAIN загружаем младшие 8 бит и старшие три бита регистра, в соответствующие переменные для каждой линейки светодиодов, а драйвер нам их конвертирует как мы хотим, старшие пять битов старшего регистра нам побоку,
Как вариант можно задать массив с кучей разных эффектов и тупо прогонять его просто через переменные, должно неплохо получиться.

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


            .include "m8def.inc"     ; Используем ATMega8
 
; ROM ===============

            .CSEG                     ; ROM
            .org $000
            rjmp RESET                ; 
            .org $009
            rjmp TMR0_OVF             ; TIMER0 OVF Переполнение таймера/счетчика Т0
            
; -------------------- R E S E T ---------------------------------------

            .ORG   INT_VECTORS_SIZE   ; Конец таблицы прерываний
RESET:
            cli
            ldi     r16, high(RAMEND) ; Main program start
            out     SPH, r16          ; Set Stack Pointer to top of RAM
            ldi     r16, low(RAMEND)  ;
            out     SPL, r16          ;

            clr     r16
            out     TCCR0, r16        ; Стоп Timer0
            out     TCNT0, r16        ; Сброс Timer/Counter0
            ldi     r16, 0b00000001   ; Используем вектор переполнения TIMER0 OVF
            out     TIMSK, r16        ; 
            sei

            ldi     YL, low(SRAM_START) ; Начало ОЗУ
            ldi     YH, high(SRAM_START);

; При тактовой частоте МК 8 МГц, частота обновления около 30 Гц 

            ldi     r16, 0b00000101   ; Запускаем Timer0 предделитель частоты 1:1024
            out     TCCR0, r16        ; 001=1:1,010=1:8,011=1:64,100=1:256,101=1:1024

;передаем регистры в переменные драйвера

            ldi   r16, 0b11001111     ; LEFT low 0bxxxxxxxx
            std   Y+0, r16            ; 
            ldi   r16, 0b00000101     ; LEFT high 0b?????xxx
            std   Y+1, r16            ; 
            ldi   r16, 0b00011111     ; RIGHT low 0bxxxxxxxx
            std   Y+2, r16            ;
            ldi   r16, 0b00000111     ; RIGHT high 0b?????xxx
            std   Y+3, r16            ;

MAIN:

; Типа бегущие огни для примера

            ldd   r16, Y+0            
            ldd   r17, Y+1            
            lsr   r16
            in    r20, SREG
            lsr   r17
            in    r21, SREG
            sbrc  r21, 0
            sbr   r16, 0x80
            sbrc  r20, 0
            sbr   r17, 0x04
            std   Y+0, r16            ; 
            std   Y+1, r17            ; 

            ldd   r18, Y+2            ; 
            ldd   r19, Y+3            ; 
            lsr   r18
            in    r20, SREG
            lsr   r19
            in    r21, SREG
            sbrc  r21, 0
            sbr   r18, 0x80
            sbrc  r20, 0
            sbr   r19, 0x04
            std   Y+2, r18            ; 
            std   Y+3, r19            ; 
            

            in      r16,MCUCR
            ori     r16, $80
            out     MCUCR, r16
            sleep                     ; Ждем включения драйвера
            rjmp    MAIN              ; Go again               

;-----------------------------------------------------------------------

TMR0_OVF:
            push    r16
            push    r17
            push    r18
            push    r19
            in      r16, SREG
            push    r16

; Очищаем порты
            ldi   r16, 0b00111111
            out   DDRC, r16
            ser   r16
            out   DDRB, r16
            out   DDRD, r16
            clr   r16
            out   PORTB, r16
            out   PORTC, r16
            out   PORTD, r16

; Читаем переменные
            ldd   r16, Y+0            
            ldd   r17, Y+1            
            ldd   r18, Y+2            ; 
            ldd   r19, Y+3            ; 

; И запихиваем в нужные биты портов

; Ряд слева
            sbrc  r16, 0
            sbi   PORTD,0             ; PD0
            sbrc  r16, 1
            sbi   PORTD,1             ; PD1
            sbrc  r16, 2
            sbi   PORTD,2             ; PD2
            sbrc  r16, 3
            sbi   PORTD,3             ; PD3
            sbrc  r16, 4
            sbi   PORTD,4             ; PD4
            sbrc  r16, 5
            sbi   PORTB,6             ; PB6
            sbrc  r16, 6
            sbi   PORTB,7             ; PB7
            sbrc  r16, 7
            sbi   PORTD,5             ; PD5
            sbrc  r17, 0
            sbi   PORTD,6             ; PD6
            sbrc  r17, 1
            sbi   PORTD,7             ; PD7
            sbrc  r17, 2
            sbi   PORTB,0             ; PB0

; Ряд справа
            sbrc  r18, 0
            sbi   PORTC,5             ; PC5
            sbrc  r18, 1
            sbi   PORTC,4             ; PC4
            sbrc  r18, 2
            sbi   PORTC,3             ; PC3
            sbrc  r18, 3
            sbi   PORTC,2             ; PC2
            sbrc  r18, 4
            sbi   PORTC,1             ; PC1
            sbrc  r18, 5
            sbi   PORTC,0             ; PC0
            sbrc  r18, 6
            sbi   PORTB,5             ; PB5
            sbrc  r18, 7
            sbi   PORTB,4             ; PB4
            sbrc  r19, 0
            sbi   PORTB,3             ; PB3
            sbrc  r19, 1
            sbi   PORTB,2             ; PB2
            sbrc  r19, 2
            sbi   PORTB,1             ; PB1

            pop     r16
            out     SREG, r16
            pop     r19
            pop     r18
            pop     r17
            pop     r16

            reti
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15571
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Объединение разных PINов в один PORT

Сообщение BOB51 »

ну Вы zero648 и наворотили... :cry:
кстати, "динамика" даже при регенерации с частотой 50Гц уже не слишком приятно смотрится...
можно конечно для световых эффектов и так "изголяться", но лучше уж табличка, а самый верный способ - правильно кристалл выбрать, тем более , что их сейчас в каждом семействе навалом ... ну, например здесь atmega8515, atmega126 - там простое рядное расположение выводов... :beer:
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Объединение разных PINов в один PORT

Сообщение zero648 »

Ну натворил не натворил, скажем просто накидал для примера, по простому, чтобы читалось проще и понятней для начинающих. Я понимаю, что при частоте 50 Гц это может раздражать, но мы же не выводим информацию, скажем, через один порт на целую матрицу, где частоту для лучшего восприятия делать хотябы не менее 100 Гц, где даже мерцание может быть заметно, а в этом конкретном случае, каждый светодиод подключен к отдельному пину, поэтому, даже при 10 Гц ничего раздражать не должно, у нас просто обновляется состояние портов, тем более, что частоту обновления можно регулировать в том же обработчике прерывания.
А выбирать кристалл у нас нет возможности, как я понял, иначе зачем тогда все эти конвертации понадобились автору темы, т.е. мое решение по условию задачи. :beer:
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15571
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Объединение разных PINов в один PORT

Сообщение BOB51 »

выбор микрух всегда есть... не avr (mega7tiny) так mcs51 или pic10/12/16/18 :roll:
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Объединение разных PINов в один PORT

Сообщение zero648 »

Бум лепить из того, что есть, тем более задача не такая уж и сложная, и такой камень пойдет. Собственно, Я обычно так и делаю, сначала развожу плату, как мне удобнее, а потом под железо пишу код, а не наоборот. Хоть немного моск напрячь, а когда просто, както скучно даже.
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»