Ratkaistu: / tehtävää

Funktiot C-kielessä

Aloitetaan funktioihin tutustuminen laatimalla muutama funktion prototyyppi ja sitten tehdään bittioperaatioita toteuttavia funktiota.
Itseasiassa, tässä materiaalissa olevat tehtävistä saat valmiita funktioita lopputyötä varten, joilla luetaan SensorTagin eri antureilta dataa. Tehtävien yhteydeen on sen vuoksi laitettu vastaavan sensorin datakirjasta sen datarekisterin sisällön kuvaus. Tästä datarekisterin arvosta sitten saamme bittioperaatioilla ulos varsinaisen sensorin mittausarvon. Ok, funktiot eivät ole aivan täydellisiä vielä, kuten datakirjasta sattaa huomata. Mutta jatkamme tästä myöhemmin..
Tehtävien yhteydessä selvitetään miten rekisterin kuvaukset tulee lukea. Kurssilla ei tarvitse osata lukea datakirjoja, selvitys komponenttien käyttämiseen annetaan materiaalissa.

C-kääntäjän asennus

Katso ohjeet C-kääntäjän asentamiseen kotikoneelle / käyttöön työasemaluokassa luentomateriaalista Kootut Ohjeet Ohjelmointiin.

Tehtävien palauttaminen

Funktio-tehtävien vastauksiin ei tarvitse tehdä main-funktiota, ellei sitä erityisesti pyydetä.
Omaa funktiotasi voit testata kuitenkin main-funktion avulla seuraavasti:
#include <stdio.h>
// #include <tehtävässä halutut>

// Prototyyppi tähän
... tehtavan_funktio(sen_argumentit);

int main() {

    tulos = tehtavan_funktio(sen_argumentit);
    printf("...",tulos);

    return 0;
}

// Funktion toteutus tänne..
... tehtavan_funktio(sen_argumentit) {
...
}
Jokaisessa tehtävässä annetaan testausta varten esimerkkiargumentit ja niillä saatava lopputulos.
Tehtävän vastauksena riittää yksi C-kooditiedosto, jossa on kolme asiaa:
  1. Tehtävän vaatimat #include-käskyt
  2. Funktion prototyyppi
    • Please, include all arguments in the same line.
  3. Funktion toteutus.
    • Lopullisessa vastauksessasi älä tulosta printf:llä mitään ellei tehtävä sitä edellytä. Tästä seuraa usein tarkistimen kaatuminen tms virhe.
C-kielisen kooditiedoston nimeämiskäytäntö on tiedosto.c
Voit esimerkiksi kommentoida ulos ( /* .. */ tai //) testikoodista main-funktion, ettei tarvitse tehdä uutta tiedostoa.
Jos kääntäjässä on varoituksia tai virheitä, tarkistus ei edes käynnisty. Tällöin näet käännösvirheet punaisella. Ole hyvä ja varmista, että testaat koodisi kehitysympäristössäsi. Älä lähetä Lovelaceen koodia, jota et ole onnistuneesti kääntänyt ja ajanut.
Tärkeä huomautus edistyneille käyttäjille: malloc- ja free-operaatioita ei sallita koodissa.
HUOM : Kun käännät koodiasi C-harjoituksia varten, varmista, että käännät C99-standardille (-std=c99) lipulla gcc-komennossa.

Ilmankosteus (1p)

Alla SensorTag:n ilmankosteus-anturin (HDC1000) datarekisterin kuvaus. Datalehdestä voimme nähdä, että rekisteri on 16-bittinen. Kosteus-% saadaan kaavalla kosteus = HUMIDITY[15:0] / 2**16 * 100. (Merkintätapa [15:0] tarkoittaa 16-bittisen rekisterin kaikkia bittejä.)
"HDC1000"
Tehtävä: Laadi funktio, joka tekee konversion 16-bittisestä rekisterinarvosta ja palauttaa kosteus-% liukulukuna.
Käytä prototyyppiä float kosteus(uint16_t rekisteri);
Tarvitset otsikkotiedoston inttypes.h, muutoin johdetut muuttujatyypit eivät toimi. Lisäksi otsikkotiedostolla math.h, saat käyttöön tarvittaessa pow-funktion potenssilaskuja varten. gcc:llä koodia kääntäessä voit tarvita lisäparametrin -lm käännöskutsuun, joka liittää matikkakirjaston ohjelmaasi.
Tarkistus: rekisteriarvoilla 0x8000 tuloksena pitäisi olla 50 %.
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Lämpötilasensori (1p)

Alla SensorTag:n lämpötila-anturin (TMP0007) datarekisterin kuvaus. Datalehdestä voimme nähdä, että rekisterin koko, johon lämpötila tallennetaan, on 16-bittinen binääriluku (bitin järjestysnumero 0..15 keltaisella). Osalle rekisterin biteistä on annettu nimet, eli T0-T13, joita vastaavat bittien järjestysnumerot (lue kahden potenssit) ovat 2-15. Näistä biteistä saadaan itse lämpötila-arvo am. operaatiolla:
  1. Bitit T0-T13 pitää irroittaa rekisteristä muuttujaan sopivalla bittioperaatiolla
  2. Kertomalla muuttuja (irroitetut bitit) kertoimella 0.03125 saadaan lämpötila Celsius-asteina
"TMP007"
Tehtävä: Laadi funktio, joka tekee konversion rekisterinarvosta celsius-asteiksi ja palauttaa asteet liukulukuna. Funktiolle annetaan yhden parametrin: 16-bittinen rekisterin arvo.
Käytä prototyyppiä float lampotila(uint16_t rekisteri);
Tarvitset otsikkotiedoston inttypes.h, muutoin johdetut muuttujatyypit eivät toimi.
Tarkistus: 16-bittisellä rekisteriarvolla 0b0011001000000000 tuloksena pitäisi olla 100.00C
Pikakorjaus!: Jos saat pyöristysvirheitä vastauksessasi, käytä Kaksinkertaisen tarkkuuden liukuluku
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Valosensori (1p)

Alla SensorTag:n valoisuus-anturin (OPT3001) datarekisterin kuvaus. Sivulla 20 datalehdestä kerrotaan, että rekisterin koko on 16-bittiä (keltaisella numeroidut bitit 0..15). Tässä tehtävässä kiinnostaa kaksi eri bittiryhmää E0-E3 ja R0-R11. Nämä molemmat ryhmät pitää erottaa rekisteristä sopivilla bittioperaatioilla. Sen jälkeen valaistusvoimakkuus luksi saadaan alareunan kaavalla lux = 0.01 * 2**E[3:0] * R[11:0]. Kaavassa esitykset E[3:0] ja R[11:0] tarkoittavat vastaavia rekisteristä haettuja binäärilukuja.
"OPT3001"
Tehtävä: Laadi funktio, joka tekee konversion 16-bittisestä rekisterinarvosta lukseihin ja palauttaa tämän arvo liukulukuna.
Käytä prototyyppiä float valoisuus(uint16_t rekisteri);
Tarvitset otsikkotiedoston inttypes.h, muutoin johdetut muuttujatyypit eivät toimi. Lisäksi otsikkotiedostolla math.h, saat käyttöön tarvittaessa pow-funktion potenssilaskuja varten. gcc:llä koodia kääntäessä voit tarvita lisäparametrin -lm käännöskutsuun, joka liittää matikkakirjaston ohjelmaasi.
Tarkistus: rekisteriarvoilla 0b0110110000110101 tuloksena pitäisi olla 2000 Luksia.
Tässä tehtävässä on bittimaskista hyötyä.
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Ilmanpaineanturi (1p)

Alla SensorTag:n ilmanpaine-anturin (BMP280) datarekisterien kuvaus, joka on hieman erilainen kuin aiemmissa tehtävissä. Sivulla 24 datalehdestä kerrotaan, että ilmanpaineen arvo koostuu kolmesta 8-bittisestä rekisterinarvosta nimeltään: press_msb, press_lsb ja press_xlsb.
Ilmanpaine (hPa) saadaan näistä 20-bittisenä binäärilukuna koostuen ym rekisterien arvoista: press_msb[7:0],press_lsb[7:0],press_xlsb[7:4] Tässä siis msb-rekisteristä tulee 8 ylintä bittiä, lsb-rekisteristä seuraavat 8 ja loput 4 xlsb-rekisteristä.
Alla kuvassa 8-bittisten rekisterien bittien tarkoitukset. Huomaa rekisterien kuvausjärjestys on tässä "alimmasta ylimpään".
"BMP280"
Tehtävä: Laadi funktio, joka tekee konversion näistä kolmesta 8-bittisestä rekisterinarvosta msb,lsb ja xlsb ilmanpainearvoon.
Käytä prototyyppiä uint32_t ilmanpaine(uint8_t xlsb, uint8_t lsb, uint8_t msb);
Tarvitset otsikkotiedoston inttypes.h, muutoin johdetut muuttujatyypit eivät toimi.
Tarkistus: rekisteriarvoilla xlsb=-34, lsb=-68, msb=24 tuloksena pitäisi olla 101325 hPa.
Tässä tehtävässä pitää tehdä useita eri siirto-operaatiota, joilla asetat eri rekisteriarvot paikoilleen 20-bittiseksi binääriluvuksi.
Varoitus: Et ole kirjautunut sisään. Et voi vastata.
?