Ohjelmointikysymykset ja vastaukset.
Ohjelmointiin liittyviä kysymyksiä ja toivottavasti myös vastauksia.
Lcdohjelmointi
Pieni ja yksinkertainen PC-tehtävä
== tehtävä #1 ==
-Tee pieni viiveohjelma jolle voi antaa parametrejä sekunteina.
Esim. Delay 10
Tätä voi käyttää lähettämään määrävälein kamerankuvaa ftp:llä internettiin .bat-komentojonossa.
Ympäristö esim W98/2k/XP
Lisäosa 1
jos parametrina on +S ohjelma voisi antaa äänimerkin kun tehtävä on tehty
ja -S jos ei haluta kuunnella ääniä
OH3GDO
[muokkaa] Esimerkkivastaus
/**======================================================================== Projekti : esimerkkejä C-kielen harjoittelua varten
Date: 2.2.2007
file: Viive.c
Name: OH2GDO Pekka Ritamäki
Compiler: Borlandc 5.02 , myös muut käyvät
Output viive.exe
Usage : viive 20 antaa 20 sekunin viiveen
Function: tee viiveohjelma xxxxx s ftp lähetystä varten
Ohjelmalle voi antaa parametriksi ajan sekunteina 0- 4000000000s
ja -S ( ei merkkiäääntä) tai +S ( merkkiäänet)
jos parametria ei anneta, ohjelma näyttää ohjeen 10 sekuntia ja demoaa toimintaa
Huomaa käytä Sleep(x) funktiota, älä sleep(x)
Merkiäänet : käytä windos perusääniä
MessageBeep(MB_ICONASTERISK);
MessageBeep(uType parametri):
Parameteri tyypit uType
registrysssä on [sounds] kohta
arvo Sound on :
0xFFFFFFFF vakioäni PC kaiuttimella
MB_ICONASTERISK SystemAsterisk
MB_ICONEXCLAMATION SystemExclamation
MB_ICONHAND SystemHand
MB_ICONQUESTION SystemQuestion
MB_OK SystemDefault
* /
1. include <windows.h> // Win32 console application
1. include <stdio.h>
// ohjelmaan tarvitaan parametreja komentoriviltä tai .bat tiedostosta
void main ( int argc, char* argv[]) {
int i ;
int sound =1; // äänet ovat valittu perusarvoksi päälle
int sec=10; // viiveen peruasrvo
if ( argc>2) // jos ohjelman paramtereja on ainakin kaksi
if( argv[2][0] =='-') // ja toisen paramtrin enimmäinen merkki on -
sound =0; // ei ääntä
if (argc >1 ){ // jos vähintään yksi parametri
sec= atoi( argv[1]); // muuta paramtri merkkijono luvuksi
printf("\r\n Parameter =%ds\n\r",sec); // tulosta paramtrin arvo
}
else { // ei paramtreja, anna pieni help
printf("\r\nDelay for batch files by OH3GDO %s \n\r Cntrl/C break\n\r, -S no sound, +S default
sound at end",DATE);
printf("\r\n No parameters delay=%ds\n\r", sec);
}
//
printf("\rn\nSound=%d\r\n",sound); // tulosta äänimerkin tila
if( sound) // jos äänimerkki on valittu
MessageBeep(MB_ICONASTERISK); // tulosta perusääni
for (i=0; i<sec; i++) { // käy läpi viiveet
Sleep(1000) ;// huom ei sleep() , odota 1000ms
printf("\rDelay=%4ds",sec-i); // tulosta jäljellä oleva viive
}
if(sound) // tehdäänkö loppu ääni ?
MessageBeep(0xFFFFFFFF); // Windows default ääni
}
/Loppu viive.c **/
[muokkaa] osoitin kysymys ( Oh3GMZ)
while (ch != EOF) /* Pyöritetään silmukkaa, kunnes tiedoston loppu tulee vastaan */
{
ch = getc(input); /* Lukee yhden kirjaimen kerrallaan */
* cptr++= ch; /* print on screen */
luettu++; /* Lisää globaaliin muuttujaan yhden jokaisella kierroksella */
}
Mitä tekee rivi *cptr++ = ch ?
[muokkaa] Osoitin vastaus
ch on funktion sisäinen muuttuja "char ch;" luettu on globaali muuttuja.
* cptr++ = ch
ch on luettu merkki ( char)
cptr 0n osoitin muistipaikka minne talletetaan ( tai mistä luetaan)
* muuttujan edessä takoitaa sijoitusta eli ch sijoitetaan cptr osoittamaan muistipaikkan
tarkoittaa, että kun muutos on tehty osoitinta siirretään eteenpäin yhden
osoittimen tyypin mukaisen elementin verran.
Koska osoitin on varattu char *cptr merkinnällä se siirtyy
vain yhden byten verran eteen päin.
Osoittimista on hyötyä kun osoitetaan struktuureita, joissa on epämääräinen ( ainakin ohjemoijalle)
määrä muistipaikkoja. Osoitin kyllä tietä hypätä oikean määrän muistipaikkoja eteen tai taaksepäin.
esim.
struct helnkiloStruct {
char nimi[50];
float tuntipalkka;
int tyotunnit;
dateStruct syntymaAika;
dateStruct tullutPalvelukseen;
double kokonaisPalkka;
}; struct helnkiloStruct henkilokunta [ 200];
Kuka osaa sanoa miten monta muistipaikkaa yllä olevaan yhteen henkilään kuluu?
struct henkiloStruct *henkiloPtr, henkilö;
aluksi kiinnitettaan osoitin ensimmäiseen henkilöön
henkiloPtr = henkilokunta[0];
sitten siirretään henkilokunnan ensimmäisen henkilön tiedot kasittelyä varten.
henkilo =*henkiloPtr;
Nyt voidaan lisätä tämän henkilön palkkaa 10 e tunti
henkilo.tuntipalkka += 10.0;
ja lopuksi tehdään talletus tietokantaan takaisin
henkilokunta[0] = *henkiloPtr;
Osoittimia pitää hieman harjoitella
—Oh3gdo 9. helmikuuta 2007 kello 22.08 (EET)
[muokkaa] Debug ohjelmointi
Jokaisessa DOS/Windows- tietokoneessa on ohjelma nimeltään Debug
Sitä voi käyttää tutkimaan tietokoneen rekistereitä ja tehdä pieniä apuohjelmia
Kokeile Debug-ohjelmaa
Kirjoita komenotoriville CMD ( run .. )ja sen jälkeen debug
Saat pienen viivan
Kirjoita ?
Saat kevyen helpin
Kokeile display- (Displa =näytä muisti) komentoa
d 40:0
40 on muistin segmenttiosoite ja 0 on offset.
Tuloksesta näkyy, että tässä koneessa on neljä sarjaporttia, joiden osoitteet ovat
03F8
02F8
03E8
02E8
Seuraavan on rinnakkaisportit
03BC
0378
0278
9F80
Huomaa että Intelin tietokoneissa on käytössä [ http://en.wikipedia.org/wiki/Endianness#Big-endian Big Endian] osoitejärjestelmä. Siinä esitetään ensin hibyte ja sitten lobytet. Motorola käyttää toisenlaista järjestelmää Littel Endian.
Kokeile mitä portteja on omassa tietokoneessasi
Kokeile R komentoa
Tee debug ohjelma helposti
Kopio alla oleva linkin viive.txt
notepadin avulla viive.txt tiedostoksi.
Lopeta debug Q komenolla
Komentotilassa kirjoita
debug < viive.txt
N Viive.COM
A 100
MOV SI,0082
MOV AX,[SI]
XCHG AH,AL
XOR AX,3030
MOV BL,AL
MOV AL,0A
MUL AH
ADD AX,BX
MOV SI,AX
MOV AH,2C
INT 21
MOV BL,DH
MOV AX,SI
AAM
OR AX,3030
XCHG AH,AL
MOV [0160],AX
MOV AH,09
MOV DX,0160
INT 21
MOV AH,06
MOV DL,FF
INT 21
JZ 014C
OR AL,AL
JNZ 013F
MOV AH,08
INT 21
MOV AL,FF
MOV DX,016C
PUSH AX
MOV AH,09
INT 21
POP AX
MOV AH,4C
INT 21
MOV AH,2C
INT 21
CMP BL,DH
JZ 012D
MOV BL,DH
DEC SI
JNZ 011A
SUB AL,AL
MOV DX,016C
JMP 0142
DB "XX SECONDS", D, 24
DB " ", D, A, 24
RCX
79
W
Q
Ohjelma on valmiina viive.com nimisenä .
Kokeile sitä viive 10
10 tarkoittaa sekunnin viivettä
Katso ohjelman pituutta ja vertaa sitä aikasemmin tekemääsi viiveohjelmaa
[muokkaa] Debug komennot
Käynnistä debug menemällä ensin komentotilaan Start/Run komennolla
Sen jälkeen kirjoita debug ja mahdollisesti tiedostonimi, jota haluat tarkastella tai muuttaa
[muokkaa] D DISPLAY ja E Enter komennot
d tarkoittaa muistin katselua. Parametriksi annetaan segmenttiosoite:offsetosoite
Esim. D 40:0 näyttää muistia PC:n muistisegmentistä 40 ja sen offsetosoitteesta 0
Jos segmenttiosoitetta ei anneta käytetään oletussegmenttiä.
Esimerkki: Haluat tarkastaa onko koe.txt-tiedostossa tiedoston loppumerkin Cntrl/z =0x1A vai ei.
Kirjoita debug koe.txt - d 100
Tämä komento tulostaa tiedoston alusta merkit HEX muodossa. Merkit ovat 12345. Vsemmalla on osoite alkaen segmenttiosoitteesta 0c91 ja sen jälkeen offset osoiteet alkaen 100:sta. segmenttiosoiteessta 09c1 ei tässä tarvitse välittää, käyttöjärjestelmä latasi tiedoston seuraavaan vapaaseen muistipaikkaan joka tällä kerralla sattui olemaan 0x09c1. Offset osoite on 16 bitin luku joka pystyy liikkuman 16-bitin muistiavaruudessa ( 0-65535).
Offset ja segmentti rekisteri
Segmenttiosoite ottaa käyttöön suurempia ryhmiä muista. Segmetti- ja offsetosoitteet menevät osittain päällekkäin. Offsetmuistilla voi muuttaa alempia muistipaikkoja, mutta ei ylempiä. Segmenttiosoitteella taas päinvastoin.
Offsetin neljää alinta bittiä ei voi muuttaa segmenttiosoitteella ja offset osoitteella ei voi muuttaa segmenttiosoitteen neljää ylintä bittiä.
Miksi näin monimutkainen asia? Intelin prosessorit ovat olleet aina ohjelmallisesti alaspäin yhteensopivia.
Kun muisti oli vain 16 bitin levyinen (tyyppi 8080 vuonna 1972), kaikki muistiosoitukset tehtiin pelkästään offset osoitteilla. Ohjelmoijan tai käyttöjärjestelmän pitää koko ajan huolehtia offset muistin rajoista. No tämähän on muutenkin ohjelmoijan tehtävä. Vain sovelluskehittimillä hiiriohjelmia tekevät voivat unohtaa muistin olemassaolon. Edelleen monissa sulautetuissa järjestelmissä muistia on vain muutaman tavu, ei sitä turhuuteen tuhlata.
Kun muistiavaruus kasvoi 4 bittiä, vanhat ohjelmat toimivat edelleen uusissa prosessoreissa. Sama menetelmä on toiminut vaikka osoitebittejä on tullut lisää 30 vuotta. Motorola luotti siihen, että ohjelmoijat saavat tehdä kaikki ohjelmat aina uudestaan kun sen prosessorien muistiavaruus kasvoi.
Palataan takaisin debug ohjelmointiin
Muisti näytetään HEX merkkeinä 16 byten ryhminä kuvan keskellä ja oikeassa reunassa ASCII merkkeinä. Ei-näkyvät ASCII-merkit näytetään pisteinä.
Viiden merkin tiedostossa ei ole 1A eli CNTL/z merkkiä. Se pitää lisätä sinne debug ohjelman avulla.
Kuinka monta merkkiä on tässä tiedostossa? Näet sen RCX rekisteristä
Kirjoita R
Näet kaikki Intelin 16-bittiset perusrekisterit AX,BX, CX jne. Näiden merkitys riippuu ohjelmasta ja ohjelmoijasta. Microsoftin ( =Charles Simoni) käyttöjärjestelmässä on kuiten tarkkaan määritelty rekisterien käyttö kun levytiedosto on ladattu muistiin. Tiedoston pituus Microsofitilla on CX- rekisterissä. CS näyttää segmettiosoitteen. Sitä ei tarvitse muuttaa tällä kertaa.
Tiedoston pituus (CX=5) on aluksi 5 merkkiä. Kirjoita CX:n 6. RCX <ENTER> kuvan mukaan. Tiedoston pituus on nyt 6 merkkiä, mutta loppumerkki pitää vielä lisätä.
Kirjoita e 106 eli enter muistipaikka 106 (hex). Ohjelma näyttää muistipaikan 106 vanhan arvon ja voit nyt muuttaa sitä. Kirjoita 1A <ENTER>. Jos et anna enteriä vaan välilyönnin saat seuraavan merkin jota voit taas muuttaa.
Kohtuullisen helppoa ilman monimutkaista HEX-editoreia, eikö totta?
Tarkista tiedoston sisältö komennolla d 100 <Enter>. Lopuksi voit tallettaa muutokset levylle kirjoittamalla W <ENTER>
Lopeta debug ohjelma kirjoittamalla Q <Enter>
Avaa tiedosto tavallisella Notepad tai Word-editorilla. Näkyykö sinun laittamasi tiedoston loppumerkki?
Ei näy, etkä voi sitä lukea tai muuttaa tavallisella editorilla. Tiedoston loppumerkkiä ei enää tarvita monestikaan. Tämä oli vain esimerkki kuinka helppoa debugilla on muuttaa binäärimerkkejä tiedostoon.
[muokkaa] I ja O komennot
I komennolla luetaan Intelin muistiavaruuden IO-portista byte. Esim. I 378 Debug ohjelma näyttää mitä kirjoitinportin rekisterissä on dataa - AA Kirjoita uusi data FF porttin 378H O eli output komennolla O 378 W Lue uudestaan portti I 378 - FF
Sama asia assemblyllä tehdään näin
MOV DX,378
IN AL,DX
Tulos saadaan AL rekisteristä IO-porttia ei voi kutsua suoraan vaan DX rekisteriä käytetään apurekisterinä.
Vastaavasti IO-porttiin 378H kirjoitetaan data FF
MOV DX,378
MOV AL,FF
OUT DX,AL
Kirjoittamisessa pitää data ja osoite olla tallessa etukäteen
[muokkaa] L Load N New ja W komennot
[muokkaa] P proceed ja T trace komennot
—Oh3gdo 18. helmikuuta 2007 kello 14.00 (EET)
[muokkaa] Uusi c-kielen harjoitustehtävä
Tee ohjelma joka lukee tiedoston muuttaa sen salatuksi ja tallettaa sen salattuna.
Kun ohjelma luetaan uudestaan, se purkaa tiedoston alkuperäiseksi. Käytä tasan 100*8 bitin salasanaa.
Käyttö
salaa.exe salasana infile outfile
Siis anna kolme parametria ohjelmalle salaustiedosto muutettava ja muutettu tiedosto
[muokkaa] ASSEMBLER ohjelmointi
; esimerkki WIN/DOS/PC assemblerohjelmasta.
;Kirjoita tämä esim.asm tiedostoon
; Valmis ohjelma kirjoittaa kuvaruudun keskelle tekstiä CMD tilassa
; XP/WIN/DOS ympäristö
; TASMin pisteet ovat helppokäyttöisiä pikaohjeita kääntäjälle
; puolipiste on kommentin alku
; käännä TASM /z esim BORLAND C assembler ohjelma -> esim.obj
; linkkaa TLINK esim BORLAND C Linkkeri -> esim.exe
.model small ; pieni muistimalli: koodi, data ja pino samassa 64k
; muistisegmentissä
.stack 100h ; pino alkaa kohdasta 100 hex segmentin alusta
.data ;ohjelma data-alueen täyttö TXT on tunnus, jota käytetään ohjemassa
TXT db 'Esim ASSEMBLER TESTI by OH3GDO$' ; loppuun aina $ merkki
.code ; koodi alkaa
.startup ; ohje kääntäjälle; laita tähän tarpeelliset aloitustiedot
MOV DH,12 ; kirjoita riville 12
MOV DL,30 ; alkaen sarakkeesta 30
MOV AH,2 ; kirjoita merkkijono BIOS funktio #2
INT 10h ; käynnistä kursorin asetusfunktio INT10h
MOV DX, OFFSET TXT ; tekstin alku Data alueella laitetaan DX-rekisteriin
MOV AH,9 ; Tulostusfunktio 9 BIOS keskeytys
INT 21h ; DOS funktiot ovat INT 21H on ohjelman loputusfunktio
.exit ; Borlandc Tasm ohjelmalle tieto koodin loppumisesta END ; lopeta asm-ohjelma, tieto kääntäjälle
DSP ohjelmoinnista
DSP tarkoittaa digitaalista signaalin käsittelyllä tapahtuvaa tiedon muokkausta.
============================
Esimerkkejä radioamatööri laitteista:
Analogista tietoa voidaan tuottaa digitaalisesti, esim. toistimella olevat asematunnistusäänet ja vaihdettavat väliäänet on tehty suoraan prosessorin sisälle. Analogista tietoa voidaan lukea prosessorille ja käsitellä sitä digitaalisesti kuten aliäänitunnistimissa, jossa toistimen radion signaalia käsitellään DSP-tekniikalla ja tutkitaan onko signaalissa tukittava aliääni. Aliäänet ovat 52-250Hz alueella. Normaalisti aliääntä pitää olla 10% modulaatiosta.
Analogisesta tiedosta voidaan tunnistaa määrättyä taajuutta kuten esim. toistimien logiikoissa tunnistetaan 1750Hz ääni.
Mitä erikoista on DSP:ssä verrattuna tavalliseen ohjelmointiin? Teoreettisesti ei mitään, mutta käytännössä teoria ei ole sama kuin käytäntö. Tunnistettaessa kohinaisesta signaalista määräräittyä taajuutta kerrotaan mitattava tulosignaali, joka on saatu ADC:lta, tutkittavalla sini- ja kosinisignaalilla. Näiden signaalien neliöiden summan neliöjuuri edustaa tutkittavaa taajuuskomponenttia tasavirtatasona. Tätä menetelmää kutsutaan DFT menetelmäksi eli Discrete Fourier Transfer. Toinen vastaava menetelmä on FFT eli Fast Fourier Trasfer. Matematiikasta kiinnostuneet voivat tukia kaavoja tästä kirjasta
Fast Fourier Transforms: Algorithms Elliot, D.F. and Rao, K.R. Academic Press, New York, 1982
Kaikki DPS-ohjelmointi voidaan tehdä tavallisellakin prosessorilla, mutta käytännössä jos mittaukset tehdään reaaliaikaisesti, tarvitaan pitkiä, monibittisiä kertolaskuja, yhteenlaskuja tiedon siirtoja muistipaikkojen välillä. Näissä laskuissa tapahtuu helposti ylivuotoja jos bittimäärä ei ole tarpeeksi suuri. Ja tärkein asia: aikaa kuluu liian paljon! DSP-prosessoreissa on tätä ns. rumpulaskentaa varten yksi tai useampi erikoinen monibittinen rekisteri ja siihen liittyvät käskyt. Yhdellä DSP käskyllä voidaan tehdä kerto- tai yhteenlasku jonka tulos menee 48-bittiseen rekisteriin. Laskujen parametrien osoitteet muuttuvat automaattisesti eteenpäin. Ylivuotoa ei helposti tapahdu pitkissä 48-bittisissä rekistereissä. DSP prosessoreita on kokonaislukutyyppisiä ja liukuvan pilkun laskentaan pystyviä. Useimmiten reaalimaailmassa riittää kokonaisluku laskenta. Fort-kielen luojalta Charles Moorelta kysyttiin miksi Fortissa ei ole liukuvan pilkun matematiikkarutiineja. Moore vastasi: Liukuvan pilkun matematiikkaa kuuluu matematiikkatieteen alaan. Minä teen laitteitta joilla ratkaistaan oikeita ongelmia kuten teleskooppien ohjauksia ja siellä ei missään esiinny liukuvanpilkun matematiikan tarpeita.
Texas Instruments väittää tehneensä ensimmäisen kaupallisen DSP-prosessorin vuonna 1987. Texas Intrumentsin DSP-prosessorit alkava TMS320-merkinnällä. Nykyään DSP-valmistajia on paljon. Motorola teki paljon erilaisia malleja 1990-luvulla. Nykyään Freescale-niminen yhtiö jatkaa tätä DSP 5680x- sarjaa.
Itse tunnen parhaiten Microchipin ja TI:n DSP prosessorit. TI:n TSM320C6211 toimii 1300 Mipsillä eikä se ole läheskään nopein. Sitä käytetään kuvan käsittelyssä ns. älykamerassa. Microchipin DSP mallit sisältävät myös kaikki tavallisten IO-prosessoreiden ominaisuudet kuten Flash datamuistit, laskurit, ADC ja PWM-muuntimet, UARTit jne. Näitä PIC30Fxxxx ja PIC33Fxxx malleja saa myös ilman DSP ominaisuuksia. Silloin ne ovat PIC24Fxxxx tyyppejä. DSP-rekisterien leveys on yleensä 16-32-bittiä. DSP-prosessorit eivät ole sen vaikeampia kuin muutkaan prosessorit, oikeastaan on helpompaa tehdä sama asia DSP:llä kuin ilman. Toinen asia on sitten matematiikka jota kuitenkin tarvitaan silloin kun DSP:llä tehdään sovelluksia. Se pitää hallita ensin ennen kuin voi tehdä mitään DSP-töitä.
Sovelluksia: -Modeemien modulointi ja demodulointi. -Laakerivikojen ennakointi. -Radioamatöörien Mars-luotaimen signaalin etsintä kohinan alta. -synteettisesti luodut äänet ravikilpailujen lähetyksessä. -FFT signaalin taajuuserittely -signaaligeneraattori puhelimen taajuusvasteen tutkimiseen -Rautatien maan kantavuuden tutkiminen -Hälyäänien vaimentaminen aktiivisesti autoissa -Särön mittaus GSM-puhelimissa
Kiinnostaako asia lisää? Kysy.
OH3GDO
Directx ohjelmoinnista
Directx on ohjelmiston ja raudan välinen rajapinta Windows maailmassa. Sitä käytetään nopeuttamaan ohjelmia, jotka käsittelevät PC:n laitteitta erityisesti grafiikan, äänen ja peliohjaimien kanssa. Ilman tätä rajapintaa jokaisen ohjelmoijan pitäisi osata käyttää jokaista äänikorttia, grafiikkakorttia jne. suoraan. Tätä tehtiin DOS aikakaudella. Ei kai enää missään käyttöjärjestelmässä ole samoja ongelmia laitteiden asennuksessa? USB -ääni ja -grafiikkalaitteet liittyvät samalla periaatteella käyttöjärjestelmään kuin kiinteät laitteetkin. Nykyään on helppo lisätä hyvälaatuinen (Softrock40 varten) äänikortti PC:lle USB:n ja FireWire kautta. Samoin useita näyttökortteja voidaan käyttää yhtä aikaa. Aikaisemmin vain paremmissa CAD-ohjelmissa oli tuki kahdelle monitorille. Nykyään se kuuluu jo käyttöjärjestelmään.
Itse olen kiinnostutut äänikortin käyttämisestä mittauksissa. Olenkin jo hieman edistynyt ja pystyn lukemaan kaksikanavaista dataa äänikortilta ja samanaikaisesti tuottamaan ääntä halutulla nopeudella, taajuudella, tarkkuudella, voimakkuudella ja kanavamäärällä. Samoin pystyn esittämään sitä graafisesti PC:llä kuten oskilloskoopilla. (OH3GDO 1.2.2008) Alla eräs testikuva.
Alla ohjelman laiteosuus:Mistä pääsee alkuun? Microsoftin sivulta voit ladata ilmaiseksi 450 MB paketin DirectX SDK (November 2007 versio)
http://www.microsoft.com/downloads/details.aspx?familyid=4b78a58a-e672-4b83-a28e-72b5e93bd60a
Pekka OH3GDO