Jak posílat v C data na posuvný registr 4094?

Zdravím, potřeboval bych od vás menší pomoc. V Céčku jsem začátečník, ale tak nějaké ty jednodušší programy typu blikání LEDkama, čtení z klávesnice bych už zvládnul. Dřív jsem dost dlouho dělat v Assembleru. Teď jsou, ale mé programy dost dlouhé a ASM je prakticky nepoužitelný, proto jsem přešel na C. Právě řeším, jak napsat funkci, která by posílala 16-ti bitové číslo na posuvné registry 4094 (mám zapojené dva 4094 za sebou). V ASM jsem to řešil přes posouvání registru pomocí instrukce ROL. Nějaké nápady bych měl, ale jde o to jak to napsát co nejefektivněji. Jak byste to tedy řešili vy? Díky.

#define bsf_clk (bsf(PORTD,PD1))
#define bsf_dat (bsf(PORTD,PD2))
//#define bsf_str (bsf(PORTD,PD0))
#define bsf_str (bsf(PORTB,PB6))

#define bcf_clk (bcf(PORTD,PD1))
#define bcf_dat (bcf(PORTD,PD2))
//#define bcf_str (bcf(PORTD,PD0))
#define bcf_str (bcf(PORTB,PB6))

#define bsf(port,pin) port |= 1<<pin //nastav bit
#define bcf(port,pin) port &= ~(1<<pin) //nuluj bit
#define negb(port,pin) port ^= 1<<pin //neguj bit

void prenosLCD (void) //;prenosLCD
{
unsigned char a;

for(a=0b10000000;a>0;a>>=1)
	{
bcf_clk;
bcf_dat;
if	(r1&a)	 
bsf_dat; 
bsf_clk;
	}
		
bsf_str;
_delay_us(2);
bcf_str;
_delay_us(2);
return;
}

prenasane data 8bit su v r1 no upravit na 16b to uz snad zvladnes… alebo mozes posielat 2x po 8 a az potom nahodit STR a tym za zapisu data na vystup 4094

JJ díky moc. Akorád jsem nějak moc nepochopil jak to přesně funguje v tom cyklu for. Mohl bys mě to pls nějak jednoduše vysvětlit pls? Rád bych to pochopil, když se to učím. Dále bych chtěl, aby ty vstupní data nebyly v r1, ale byly parametrem té funkce. To stačí, když si místo r1 deklaruji proměnou a dám ji jako vstupní parametr, že ano? Ještě jsem si všiml, že STR nastavuješ jen na 2uS a dále je v nule. Zůstanou data na výstupu ikdyž bude STR v nule??

no pozri si data sheet od 4094… strobe impulz zapise to co je v reg do vystupych zachytnych registrov… a zostane to tam jaj ked udaju v citaci v nutri sa menia (takto nejako)

FOR… taj jednotka v (a=10000) sa kazdy,m prechodom cyklu posuva do prava (res delenie dvoma)… v tele cyklu sa vykonava sucin cisla (a) s cislom (r1) … tj porovnavaju sa cisla (kedze sa posuva v Acku jednotka v pravo stale sa porovnava jeden bit v R1 a ak je zhoda SDA sa da do log1.
Najprv sa porovna 7bit v R1 potom 6 atd…

co sa tyka delay 2us pri strobe teoreticky nemusi byt zalexi ako rychlo to budes cele prevadzkovat… potom mozno bude treba osetrit aj sda,clk Ale nemyslim si ze dosialhes limitacnu rychlost zapisu do toho IO a ked ho vymenis za 74hc tak uz urcite nie…

jj díky. Už jsem to pochopil. :slight_smile: . Nějak takhle jsem si to upravil pro těch 16 bitů:
#include “avr/io.h”
#include <util/delay.h>

#define bsf_clk (bsf(PORTD,PD1))
#define bsf_dat (bsf(PORTD,PD2))
#define bsf_str (bsf(PORTB,PB6))

#define bcf_clk (bcf(PORTD,PD1))
#define bcf_dat (bcf(PORTD,PD2))
#define bcf_str (bcf(PORTB,PB6))

#define bsf(port,pin) port |= 1<<pin //nastav bit
#define bcf(port,pin) port &= ~(1<<pin) //nuluj bit
#define negb(port,pin) port ^= 1<<pin //neguj bit

void prenos16bit (unsigned int data) //;prenos na posuvné registry
{
unsigned int a;

for(a=0b1000000000000000;a>0;a>>=1)
{
bcf_clk;
bcf_dat;
if (data&a)
bsf_dat;
bsf_clk;
}

bsf_str;
_delay_us(2);
bcf_str;
_delay_us(2);
return;

}
Snad to bude fakat.

Teďkom jsem si všiml, že podle toho kódu se jako první posílá MSB (nejvyšší) bit. Čili když to odešlu na ty posuvné registry tak se z MSB bitu stane LSB bit, že ano??? Já jen abych neudělal chybu.

Nikoli, pořadí zůstane stejné. Když klokneš bit, zapíše se na Q0. Při dalším se tento posune na Q1 a nový ho nahradí na Q0, takže ten, co přišel první bude na nejvyším Q výstupu. Pokud jde první MSB, budou data souhlasit.

jj dík už jsem na to taky přišel. :slight_smile: