/*
Routines
Pros 2007
*/
// Zoek het begin van het volgend woord in de string
char *nxtwrd(char *ptr)
{
while ((*ptr != 0) && (*ptr > ' ')) {
ptr++;
}
if (*ptr == 0) {
return (NULL);
}
while ((*ptr != 0) && (*ptr < '!')) {
ptr++;
}
if (*ptr == 0) {
return (NULL);
} else {
return (ptr);
}
}
void delay_ms(unsigned int ms)
{
for (; ms > 0; ms--) {
_delay_ms(0.998);
}
}
void delay_us(unsigned int us)
{
for (; us > 0; us--) {
_delay_us(0.99);
}
}
// beep aan opgegeven frequentie gedurende een aantal mS
void beep(unsigned int freq, unsigned int dur)
{
unsigned int cnt, del, times;
sbi(DDRD, PD7);
del = 500000UL / freq; // del = wachttijd tussen 2 flanken in µS
dur *= 500; // dur = tijd in uS
times = dur / del;
for (cnt = 0; cnt < times; cnt++) {
sbi(PORTD, PD7);
delay_us(del);
cbi(PORTD, PD7);
delay_us(del);
}
}
// Maak een locaal Fwip-geluid
void fwip(void)
{
unsigned int del = 300;
while (del > 8) {
sbi(PORTD, PD7);
delay_us(del);
cbi(PORTD, PD7);
delay_us(del);
del--;
}
}
// Transformeer een unsigned int (bv. 1234) int naar een ascii-string
// de string wordt voorafgegaan door het opgegeven karakter ( U=1234 )
// en zo nodig van een decimale punt voorzien; dp bepaalt hoeveel cijfers na de punt volgen
void printdec(unsigned int getal, char v, char dp)
{
unsigned int tmp, deeltal = 10000;
char *ptr, cnt, zeroflag = 0;
ptr = txt_buffer;
*ptr = v;
ptr++;
*ptr = '=';
ptr++;
for (cnt = 5; cnt > 0; cnt--) {
if (dp == cnt) { // dp plaatsen?
if (zeroflag == 0) { // reeds cijfers geplaatst??
*ptr = '0'; // nee, dan eerst een 0
ptr++;
}
*ptr = '.';
ptr++;
zeroflag = 1; // na dp alle nullen afdrukken
}
tmp = 0;
while (deeltal > getal) {
getal -= deeltal;
tmp++;
}
if (tmp > 0) { // als dat geen 0 is
zeroflag = 1; // worden alle volgende decaden afgedrukt
*ptr = (unsigned char) tmp + '0'; // ascii-teken verzenden
ptr++;
} else if (zeroflag == 1) { // Is dit de eerste 0?
*ptr = '0'; // nee, dan een 0 plaatsen
ptr++;
}
deeltal /= 10; // deeltal aanpassen voor volgende decade
}
}
// Lees een decimaal getal.
unsigned long get_data(char *ptr)
{
unsigned long result = 0;
while (*ptr < '!') {
ptr++; // spaties en tabs overslaan
}
while ((*ptr > 47) && (*ptr < 58)) {
result *= 10;
result += (*ptr - '0');
ptr++;
}
return (result);
}
// String -> float
double get_float(char *ptr)
{
unsigned long eenheden = 0;
unsigned long honderdsten = 0;
double result, deeltal = 1.0;
while (*ptr < '0') {
if (*ptr == 0) { // Einde string?
return 0.0; // Dan stoppen we
} else {
ptr++; // spaties en tabs overslaan
}
}
while ((*ptr > '/') && (*ptr < ':')) { // eenheden
eenheden *= 10;
eenheden += (*ptr - '0');
ptr++;
}
if (*ptr == '.') { // Komt er nog iets na de dp?
ptr++;
while ((*ptr > '/') && (*ptr < ':')) { // honderdsten
honderdsten *= 10;
deeltal *= 10.0;
honderdsten += (*ptr - '0');
ptr++;
}
}
result = ((double) (eenheden)) + (((double) (honderdsten)) / deeltal);
return (result);
}
// Keyboard-routines
unsigned char check_KB(void)
{
unsigned char A = PA3;
unsigned char cnt;
PORTA |= 0x78;
DDRD &= 0x97;
PORTD |= 0x68; // Pull-up weerstanden v KB-input activeren
delay_us(50);
Key = 0xFF;
for (cnt = 0; cnt < 4; cnt++) {
cbi(PORTA, A); // KB-uitgang laag maken
delay_us(100);
if (bit_is_clear(PIND, PIND3)) {
Key = cnt;
} else if (bit_is_clear(PIND, PIND5)) {
Key = cnt | 4;
} else if (bit_is_clear(PIND, PIND6)) {
Key = cnt | 8;
} else if (bit_is_clear(PINB, PINB5)) {
Key = cnt | 12;
}
sbi(PORTA, A); // KB-uitgang terug hoog maken
if (Key == 0xFF) {
A++; // Volgende keyboard-uitgang
delay_us(100);
} else {
Key = KB[Key];
beep(1000, 20);
if ((Key != 'u') && (Key != 'd')) { // Geen UP- of DOWN-toets?
key_time = 800; // Default-wachttijd voor UP en DOWN resetten
}
return (Key);
}
}
key_time = 800;
return (0xFF);
}
// Ga na, hoelang hoelang de mode-toets wordt ingedrukt
// Resultaat = aantal seconden * 10
#define KB_IN (_BV(PIND3) | _BV(PIND5) | _BV(PIND6))
unsigned int time_KB(void)
{
unsigned int kb_time = 0;
PORTA &= ~(_BV(PA3) | _BV(PA4) | _BV(PA5) | _BV(PA6));
while (bit_is_clear(PINB, PINB5)) {
kb_time++;
delay_ms(100);
}
PORTA |= 0x78;
return (kb_time);
}
#define OVERFLOW 88
#define NO_OV 55
char detect_overflow(unsigned char a)
{
unsigned char b;
b = (a << 1); // b is nu het dubbele van a, tenzij...
if (b < a) { // b KLEINER is dan a!
return (OVERFLOW); // Dat betekent overflow
} else {
return (NO_OV);
}
}
// add_bit() beheert 8 unsigned chars als een 64-bit getal
// Hij schuift bij elke aanroep alle bits 1 plaats naar links op,
// en maakt bit 0 hoog of laag
// Byte[0] is meest-significant
// De routine schuift eerst de bits van Byte[0] naar links. Diens rechtse bit wordt daardoor 0.
// Als het linkse bit van Byte[1] hoog is, moet het rechtse bit van Byte[0] ook hoog gemaakt worden
// Deze bewerking wordt herhaald met Byte[1] ... Byte[6]
// Tot slot wordt het rechtse bit van Byte[7] hoog of laag gemaakt
unsigned char Byte[8];
void add_bitII(unsigned char Bit)
{
unsigned char cnt;
for (cnt = 0; cnt < 7; cnt++) {
Byte[cnt] = Byte[cnt] << 1; // 1 bit opschuiven naar links
if ((Byte[cnt + 1] & 0x80) == 0x80) { // Hoogste bit van lagere byte = 0?
Byte[cnt] |= 0x01; // Dan bit 0 hoog maken
}
}
Byte[7] = Byte[7] << 1;
Byte[7] |= Bit;
}