Tak właściwie to po co nam ta UNIA ?
Korzyści z UE dla mnie też są dyskusyjne ale unia jako typ danych w języku C jest bardzo silnym i przydatnym narzędziem. Dobrym przykładem zastosowania może być funkcja wysyłania obliczonej nastawy FTW [int32] do układu DDS.
W tym wątku zastosowano metodę maskowania pojedynczego bitu danych na 4 bajtowej zmiennej FTW, metoda mocno obciążająca procesor.
Kod:
void ftw_DDS(unsigned long int FTW)
{
bajt_DDS(0x04);
unsigned char i;
for(i=0; i<32; i+=1) // pętla wykonująca polecenia 32 razy - czyli tyle ile bitów ma "słowo częstotliwości"
{
if(FTW&0x80000000)
{ DDS_PORT = DDS_PORT|(1<<DDS_SDIO); }
else
{ DDS_PORT = DDS_PORT&~(1<<DDS_SDIO); }
DDS_PORT = DDS_PORT|(1<<DDS_SCLK);
DDS_PORT = DDS_PORT&~(1<<DDS_SCLK);
if(i==15) { DDS_PORT = DDS_PORT&~(1<<DDS_UPDATE); } // I/O UPDATE w stan niski
if(i==31) { DDS_PORT = DDS_PORT|(1<<DDS_UPDATE); } // I/O UPDATE w stan wysoki
FTW = FTW << 1;
}
}
Inna metodą jest użycie funkcji wysyłającej pojedyncze bajty do DDSa. Najczęściej dostęp do kolejnych bajtów jest realizowany poprzez przesuwanie zmiennej FTW o 24,16,8 bitów, metoda zdecydowanie lepsza ale również kosztowna dla procesora.
Kod:
SPI_MasterTransmit(0x04);
SPI_MasterTransmit(FTW>>24);
SPI_MasterTransmit(tFTW>>16);
SPI_MasterTransmit(FTW>>8);
SPI_MasterTransmit(FTW);
Najszybszą metodą dostępu do wybranych bajtów zmiennej FTW jest zdefiniowanie unii.
Kod:
union // unia dla FTW
{
unsigned long int reg32;
unsigned char reg8[4];
} FTW;
Najogólniej powyższa
unia FTW to taka zmienna, która ma dwa różne formaty danych w tym samym miejscu pamięci, raz jest to
integer na 32bitach oraz ta sama zmienna ale jako
4 oddzielne bajty danych. Po obliczeniach wartość
FTW[32] przypisujemy do
FTW.reg32 a w funkcji wysyłania pobieramy bajty z 4 bajtowej tablicy
FTW.reg8[x] podając numer interesującego nas bajtu.
Jeśli już uczymy się języka C to warto wykorzystywać "jego dobrodziejstwa" bo np. Bascom tego nie potrafi.