Implementacja obsługi klawiatur pojemnościowych w LPC17xx firmy NXP
W następnym etapie programu wykonywana jest kalibracja (funkcja calibrateAllChannels()). Polega ona na oszacowaniu przybliżonej wartości napięcia w każdym z aktywnych kanałów przetwornika A/C w stanie nienaciśnięcia przycisku. Odczyt każdego kanału wykonywany jest 200 razy, po czym obliczana jest wartość średnia pomiaru (listing 3, listing 4).
Listing 3. Wykonywana w pętli kalibracja aktywnych kanałów przetwornika A/C
/* calibration loop function */
void calibrateAllChannels(void)
{
KeypadIdType i;
for(i=KBD1; i< NUM_KPAD; i++)
if (UNUSED_CHANNEL != Kpad2ChMap[i]) _calibrateChannel(Kpad2ChMap[i]);
}
Listing 4. Proces kalibracji pojedynczego kanału przetwornika A/C
/* calibration channel function */
#define CALIBRATION_LOOP (200)
static void _calibrateChannel(ChannelIdType chNum)
{
int calibCntr;
for (calibCntr=0; calibCntr < CALIBRATION_LOOP; calibCntr++)
{
reading[chNum] = (*AdcReadTable[chNum])(chNum);
updateAverage(chNum);
}
}
Po wykonaniu powyższej konfiguracji mikrokontroler rozpoczyna etap pracy właściwej. Polega on na przejściu układu w tryb uśpienia, z którego cyklicznie jest budzony (co 10 ms) pod wpływem przerwania od licznika systemowego Systick (listing 5).
Listing 5.
/* config systick to generate interrupts at 100HZ - 10ms rate */
SysTick_Config(SystemFrequency/100);
while (1)
{
__wfi(); /* processor goes to sleep in between readings */
processKeystrokes(); /* activate keystroke callbacks if key press detected */
}
W momencie wybudzenia mikrokontrolera z trybu uśpienia wywoływana jest funkcja od przerwania - SysTick_Handler() (listing 6).
Listing 6.
void SysTick_Handler(void)
{
/* iterate through the active channel list to perform readings */
processChannels();
/* just simple heartbeat indication, toggle every second */
cntr++;
if(cntr == 49)
{
toggleLed();
cntr=0;
}
}
Umieszczona tam funkcja processChannels() odczytuje wartość napięcia z wyprowadzeń podłączonych do obwodów RC przycisków pojemnościowych. Odczytane wartości zapisywane są do tabeli reading[] (listing 7).
Listing 7.
/* this function iterates through the channels and reads the adc values */
/* result is stored within the reading array */
void processChannels(void)
{
ChannelIdType currentChannel;
if(USE_KBD1)
{
currentChannel = Kpad2ChMap[KBD1];
reading[currentChannel] = (*AdcReadTable[currentChannel])(currentChannel);
};
if(USE_KBD2)
{
currentChannel = Kpad2ChMap[KBD2];
reading[currentChannel] = (*AdcReadTable[currentChannel])(currentChannel);
};
if(USE_KBD3)
{
currentChannel = Kpad2ChMap[KBD3];
reading[currentChannel] = (*AdcReadTable[currentChannel])(currentChannel);
};
if(USE_KBD4)
{
currentChannel = Kpad2ChMap[KBD4];
reading[currentChannel] = (*AdcReadTable[currentChannel])(currentChannel);
};
if(USE_KBD5)
{
currentChannel = Kpad2ChMap[KBD5];
reading[currentChannel] = (*AdcReadTable[currentChannel])(currentChannel);
};
if(USE_KBD6)
{
currentChannel = Kpad2ChMap[KBD6];
reading[currentChannel] = (*AdcReadTable[currentChannel])(currentChannel);
};
if(USE_KBD7)
{
currentChannel = Kpad2ChMap[KBD7];
reading[currentChannel] = (*AdcReadTable[currentChannel])(currentChannel);
};
if(USE_KBD8)
{
currentChannel = Kpad2ChMap[KBD8];
reading[currentChannel] = (*AdcReadTable[currentChannel])(currentChannel);
};
}

Technologie End of Life i bezpieczeństwo sieci – wyzwania Europy związane z tzw. długiem technologicznym
Najczęstsze błędy firm przy wyborze dostawcy energii i jak ich uniknąć
Fotorezystor, czyli czujnik światła dwojakiego działania. Przykład innowacji w automatyce i elektronice możliwej dzięki technologii fotooporników 



