ATmega 168 : definování pinů jako proměné

Ahojte, chtěl bych vás poprosit o pomoc.
potřeboval bych pomocí proměnné číst a měnit hodnoty pinů
načtu si :
static unsigned pin[6] = {PB5,PB4,PB0,PD7,PD4,PD2}; // nejsem si jistej jestli funguje

zapíšu : (tohle fungovat asi určitě nebude, zatím sem nezkoušel)
pin[0] = 0 // nastaví pin PB5 do log.0
pin[1] = 1 // nastaví pin PB4 do log.1

V C to takhle rozhodně nefunguje. Tady je nutné použít bitové operace (nebo je schovat za makra). Šla by napsat funkce, která to zvládne, ale bude to řádově pomalejší než přímo definované makro.
To, co jsi napsal, pouze inicializuje pole konstantami (5, 4, 0, 7, 4, 2) a potom přepíše první dva prvky pole jinými konstantami (0, 1).
Ty piny se stejně v průběhu programu nebudou měnit ne? Na to stačí makra.
definice:
#define LD1ON (PORTB |= 1<<PB3)
#define LD1OFF (PORTB &= 1<<PB3)

použití:
LD1ON; // nastaví pin PB3 na “1”

myslel sem něco takového … ale to nefunguje.
static unsigned pin[6] = {PINB & (1 << PB5), PINB & (1 << PB4), PINB & (1 << PB0), PIND & (1 << PD7), PIND & (1 << PD4), PIND & (1 << PD2)};
potřeboval bych něco abych mohl projet těchto 6 různých stavů smyčkou a rozhodovat zda se něco stane nebo ne
for(i=0,i<6,i++)
if (pin*) proveď_příkaz;
a naopak aby to fungovalo i v případě zápisu:
static unsigned pin[6] = {PORTB & (1 << PB5),…

Lze to nějak rozumně řešit nebo bude rozumnější smyčku vynechat ?*

Je to možné, ale budou třeba 2 pole pointerů (jedno s referencemi PIN a druhé PORT registrů) a třetí s čísly bitů. Když na to nezapomenu, tak se na to odpoledne mrknu.

No jako cvičení požívání pointerů dobré.

Jinak ale nerozumím tomu, proč to chce tadeaš.světluška řešit tak složitě - nota bene při pouhých šesti vstupech.

Já bych se taky vydal (podobnou) cestou jakou původně navrhoval piityy:

[code]#define IN1 PINB.5
#define IN2 PINB.4
#define IN3 PINB.0
#define IN4 PIND.7
#define IN5 PIND.4
#define IN6 PIND.2

#define OUT1 PORTB.3
#define OUT2 PORTB.2
#define OUT3 PORTD.0

void test_vstupu
{
if(IN1) OUT1=1;
else {OUT1=0;OUT2=1;}
if(IN2) OUT2=1;
else {OUT2=0;OUT3=1;}
if(IN3) //neco
else //neco jineho
if(IN4) //neco
else //neco jineho
if(IN5) //neco
else //neco jineho
if(IN6) //neco
else //neco jineho
}[/code]

Zde je ono pointerové cvičení. U 6ti pinů bych se tím taky nezabejval…
Jen poznámka - Louovy definice fungují pouze na překladači CV.

[code]#include <avr/io.h>

void main(void)
{
volatile unsigned char *pOut] = {&PORTB, &PORTB, &PORTB, &PORTD, &PORTD, &PORTD};
volatile unsigned char *pIn] = {&PINB, &PINB, &PINB, &PIND, &PIND, &PIND};
unsigned char pins] = {5, 4, 0, 7, 4, 2};

DDRB |= 1 << PB0;	// PB0 = vystup

for (;;)
{
	if(*pIn[0] & 1<<pins[0]) *pOut[2] |= 1<<pins[2];
	else *pOut[2] &= ~(1<<pins[2]);
}

}[/code]

To je pravda, nechal jsem se unést :slight_smile: - ale ten kód má sloužit hlavně pro ilustraci.

Taky bych měl poznámku - neměl by zápis “0” do příslušného bitu registru vypadat spíš takto: (PORTB &= ~(1<<PB0)) ?

Edit:

:blush: tak je to zápis “1” ne “0” (přece jen to moc nepoužívám - nechal jsem se strhnout - piityy to má taky obráceně :wink:(teď určitě napíše, že pro ledku spíná GND):slight_smile: ) a zjistil jsem, že aspoň ten CV oba zápisy překládá stejně

Díky moc… důvod proč bych to chtěl řešit takto je ten že tu základní podmínku potřebuji ještě jinde a jinak a tak by se podmínky kupily a kupily. Takhle je to mnohem přehlednější, elegantnější a suprovější. A navíc by mi to nic nedalo. A díky vám sem naučil další super věc. Zbývá to otestovat.
Každopádně moc díky.

Lou: tak teď jsem mimo mísu. Podmínka má význam:
if(PINB.5 == 1) PORTB.0 = 1;
else PORTB.0 = 0;

No mělo by to kopírovat stav vstupu (PINB.5) na výstup (PORTB.0) - ale hlubší význam v tom nehledej, chtěj jsem tam pro názornost dát jen nějaké příkazy.