Das Pulswahlverfahren ist nur noch für Bastler interessant. Dieser Artikel basiert auf einer alten Idee, einen PWV - MFV Umsetzer zu bauen. Siehe Artikel DTMF
Da der Kontakt des Pulswahlschalters stark prellt, war eine elegante Entprellung gefragt. Natürlich kann man hardwareseitig mit Operationsverstärker und RC Glied wunderbar entprellen, ich bevorzuge aber immer Softwarelösungen.
Der Kontakt wird eingelesen, der Zustand in ein Schieberegister geschickt und zu einem bestimmten Zeitpunkt wird dieses Schieberegister genau 1000000 sein, dan ist eine Flanke von 1 nach 0 erkannt.
Umgedreht wird irgendwann 01111111 im Schieberegister stehen - das ist eine Flanke von 0 nach 1.
längere Pausen (gezählt über Variable si) löschen die gewählte Nummer.
if(si<33) si++;
if(si==32)
{
nummer=nu;
nu=0;
}
schubs=rl(schubs);
schubs.0=PORTC.0;
if(schubs==127)
{
PORTA.1=1; //steigende Flanke
si=0;
}
if(schubs==128)
{
PORTA.1=0; //fallende Flanke
nu++;
si=0;
}

das Wunder - es hat sofort funktioniert
Hier noch das Testprogramm, am PortC.0, der über einen Schmidt Trigger verfügt wird das Pulssignal eingekoppelt (nicht höher als Vpp!!!). An PortA.1 erfolgt die Kontrolle, die Flanken flattern die LED, nach erkannter Nummer wird vom Hauptprogramm die Zahl durch eindeutiges Blinken signalisiert.
// AMA
// 18.02.2010
// Compiler CC5x
// IWV Test 16F876
// IWV Pulszählung
//; Copyright (C) 2010 Andreas Mascheck, mascheck55@hotmail.de
/*
This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <16F876.h> // Prozessor-Typ definieren
#include <conf16F876.inc> // _CONFIG aus assembler Beispielen
#include <int16CXX.h> // interrupt handling
#pragma config = _BODEN_ON&_CP_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC&_LVP_OFF
#pragma origin 4
#pragma interruptSaveCheck n // no warning or error
//--- DTMF interrupt Variable ---
int16 kk1,kk2,kk4,kk5,zz;
int8 k2,k3,k5,k6,min,z;
uns8 wert;
//--- IWV interrup Variable ---
uns8 schubs, si, nummer, nu;
interrupt int_server(void)
{
int_save_registers // W, STATUS (and PCLATH) - Register retten (8 Zyklen)
//die Definition ist im include file <int16CXX.h>
//auseinanderdröseln der interrupts
if (T0IF==1) // (1 Zyklus)
{
// Berechnung der Amplitude für die PWM
T0IF=0; //reset timer0 overflow flag Rücksetzen des Interrupt Ereignisses (1 Zyklus)
//------------------------------------------------------------------
TMR0=102; //nach 256-102+2=156 16tel OSCI Takten erfolgt der nächste Interrupt
// es sind jetzt noch 256-111+2= 147 * 16 Oszi Takte Zeit bis zum nächsten Interrupt
// das sind gleich 147 * 4 = 588 Zyklen
// fxmul(); // ((min 181; mid 327; max 349) Zyklen)
//------------------------------------------------------------------
}
else
{
// Handling für TMR1
TMR1IF=0;
TMR1H=237;
// PORTA.1=PORTC.0;
if(si<33) si++;
if(si==32)
{
nummer=nu;
nu=0;
}
schubs=rl(schubs);
schubs.0=PORTC.0;
if(schubs==127)
{
PORTA.1=1; //steigende Flanke
si=0;
}
if(schubs==128)
{
PORTA.1=0; //fallende Flanke
nu++;
si=0;
}
}
int_restore_registers // W, STATUS (and PCLATH) - Register zurückschreiben (8 Zyklen)
/*
* verbleiben 588 - 349 -9 = 230 Zyklen zwischen den Interrupts, um beispielsweise
* die Dauer des auszusendenden DTMF Signals in einer Zeitschleife zu steuern (durch
* Erlauben des Interruptsnur in einer gewissen Zeit
*/
}
#include <math16m.h> // schnelle 16=16*16 Multiplikation
#include <math16.h> // int 8 un 16 signed / unsigned
void P_1ms(void); //Deklaration
void pausexms(int16 ms)
{
int16 i;
for(i=0;i<ms;i++) P_1ms();
}
//________________________________________________________________________
//_____________________ Hauptprogramm ____________________________________
//________________________________________________________________________
void main()
{
int i,j,z,a;
CCP1CON=0;
CCP2CON=0;
T1OSCEN=0;
TMR1CS=0;
T1CKPS1=1;
T1CKPS0=0;
TMR1H=237;
TMR1L=0;
TMR1ON=1;
TMR1IE=1;
GIE=1;
PEIE=1;
PORTA=0;
TRISA.1=0;
PORTA.1=1;
PORTC=0;
TRISC=0b00000001;//Trisc.0=Eingang
pausexms(1000);
PORTA.1=0;
pausexms(1000);
PORTA.1=1;
nummer=0;
for(;;) // forever do nothing
{
P_1ms();
pausexms(1000);
if(nummer!=0)
{
for (i=0;i<nummer;i++)
{pausexms(300);
PORTA.1=0;
pausexms(300);
PORTA.1=1;
}
nummer=0;
}
}
}
//________________________________________________________________________
//_____________________ 1 ms Generator ___________________________________
//________________________________________________________________________
page3 void P_1ms(void)
{
uns8 i;
for(i=0;i<249;i++)
{
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
}
}