Der Nachfolger des WDR-Computerclub mit Wolfgang Back und Wolfgang Rudolph - ...und immer ein Bit übrigbehalten!


Das Forum zur C-Control-1
Welche C-Control-Varianten existieren?
Übersicht - Suchen - Neueste 50 Beiträge - Neuer Beitrag - Login - Registrieren
INFO - FAQ - CC2-Forum - CCPro-Forum 

 Demoprogramm: DTMF-Signale mittels PWM Kategorie: Open-Micro/Open-Mini/Open-Midi/Open-Macro/Open-Maxi (von Dietmar, Homepage - 1.08.2020 0:13)
Dietmar nutzt:  Open-Micro, Open-Mini, Open-Midi, Open-Macro, Open-Maxi, Open-Mini Station
' ===========================================================================
' DTMF-Signale mittels PWM mit 25 kHz Taktfrequenz und 7 Bit Werteauflösung
' In OCBASIC 1.11a für Open-Maxi von Dietmar Harlos am 01. August 2020
' ===========================================================================

' Es werden an DA[1] einer Open-Maxi DTMF-Signale ausgegeben. Es kann ein
' Piezotöner ohne Elektronik direkt angeschlossen werden.

' DTMF-Signale werden beim Mehrfrequenzwahlverfahren eingesetzt:

' https://de.wikipedia.org/wiki/Mehrfrequenzwahlverfahren

' Dieses Programm geht zurück auf DTMFBPWM.BAS im ZIP-Archiv zum OCBASIC-
' Compiler. Dort werden DTMF-Signale mit den kleinen OM-Controllern erzeugt.

' An dieser Stelle möchte ich mich bei Norbert Klein und bei Dirk vom L-Team
' für ihre Unterstützung bedanken.

' --- Definitionen ----------------------------------------------------------

INCLUDE "omax.def"        'Definitionen für die Open-Maxi

DIM a,b,c BYTE            'temporäre Variablen

DIM char BYTE

DIM z1h BYTE              'zum Datenaustausch mit Assembler-Interruptroutinen
DIM z1l BYTE
DIM i1h BYTE
DIM i1l BYTE
DIM z2h BYTE
DIM z2l BYTE
DIM i2h BYTE
DIM i2l BYTE

' --- Unsere eigene Assembler-Interruptroutine ------------------------------

' Die folgende Assembler-Interruptroutine befindet sich im "Timer/PWM-Module
' 2 - Overflow (TPM2OVF)"-Interrupt und wird gestartet, wenn ein Overflow
' im PWM-Modul stattfindet; die PWM also einen neuen Wert benötigt.

' Die folgenden Subroutinen sollten sinnvollerweise in einer INCLUDE-Datei
' untergebracht werden.

' Das Schlüsselwort INLASM kennzeichnet die folgende PROCEDURE als
' Assemblerroutine (IAR). Dadurch, und daß sie unmittelbar am Anfang
' des Programms steht, wird sie zu einer IIAR, also zu einer Assembler-
' Interruptroutine, die bei einem aktivierten User-Interrupt gestartet wird.

' Der OCBASIC-Compiler setzt automatisch ein "GOTO main" vor diese Routine.

PROC iiar_tpm2ofl INLASM

! cbeqa #iTPM2OFL,is_tpm2ofl
! jmp iiar_tpm2ofl_next+2   'zur nächsten IIAR springen

#is_tpm2ofl
! ldx z1h
! lda sin,x     '-63..63
! ldx z2h
! add sin,x     '-126..126

! add #128      '2..254

! ldx #3
! mul           '6..762

! stx TPM2C0VH  'darf bis 799
! sta TPM2C0VL

! lda z1l       'die beiden Zeiger inkrementieren
! add i1l       '(für bessere Frequenzauflösung muß mit 16 Bit gearbeitet
! sta z1l       ' werden, aber nur das Highbyte wird als Zeiger verwendet)
! lda z1h
! adc i1h
! sta z1h

! lda z2l
! add i2l
! sta z2l
! lda z2h
! adc i2h
! sta z2h

! clc           'Betriebssystemfunktion soll aktiviert bleiben
! rts           'Rücksprung zum Betriebssystem

END PROC


' Tabelle mit den Werten einer Sinusschwingung - 7 Bit Auflösung

TABLE sin BYTE

  0 2 3 5 6 8 9 11 12 14 15 17 18 20 21 23 24 26 27 28 30 31 32 34 35 36 38
  39 40 41 42 43 45 46 47 48 49 50 51 52 52 53 54 55 56 56 57 58 58 59 59 60
  60 61 61 61 62 62 62 63 63 63 63 63 63 63 63 63 63 63 62 62 62 61 61 61 60
  60 59 59 58 58 57 56 56 55 54 53 52 52 51 50 49 48 47 46 45 43 42 41 40 39
  38 36 35 34 32 31 30 28 27 26 24 23 21 20 18 17 15 14 12 11 9 8 6 5 3 2 0
  -2 -3 -5 -6 -8 -9 -11 -12 -14 -15 -17 -18 -20 -21 -23 -24 -26 -27 -28 -30
  -31 -32 -34 -35 -36 -38 -39 -40 -41 -42 -43 -45 -46 -47 -48 -49 -50 -51
  -52 -52 -53 -54 -55 -56 -56 -57 -58 -58 -59 -59 -60 -60 -61 -61 -61 -62
  -62 -62 -63 -63 -63 -63 -63 -63 -63 -63 -63 -63 -63 -62 -62 -62 -61 -61
  -61 -60 -60 -59 -59 -58 -58 -57 -56 -56 -55 -54 -53 -52 -52 -51 -50 -49
  -48 -47 -46 -45 -43 -42 -41 -40 -39 -38 -36 -35 -34 -32 -31 -30 -28 -27
  -26 -24 -23 -21 -20 -18 -17 -15 -14 -12 -11 -9 -8 -6 -5 -3 -2

END TABLE


' Das TPM2-Modul für DTMF-Ausgabe konfigurieren

' DA[1] liegt an TPM2CH0
' DA[2] liegt an TPM2CH1

PROC inittpm2 INLASM
! mov #%01001000,TPM2SC   'TPM clock input = 20e6/1 = 20 MHz & Timer Overflow Interrupt Enable
! ldhx #799               'Timer 2 Counter Modulo Registers (TPMxMODH:TPMxMODL)
! sthx TPM2MODH           'von 0 bis inklusive 799 zählen (also Modulo 800) - (kein 100% duty cycle)
! lda #%00101000          'PWM-Frequenz: 20e6/1/800 = 25.0 kHz
! sta TPM2C0SC            'Timer 2 Channel 0 Status and Control Register \ Edge-aligned PWM
! sta TPM2C1SC            'Timer 2 Channel 1 Status and Control Register /  High-true pulses
! rts
END PROC


' Das TPM2-Modul wieder so konfigurieren, wie vom OS erwartet

' DA[1] liegt an TPM2CH0
' DA[2] liegt an TPM2CH1

PROC resettpm2 INLASM
! mov #%00001101,TPM2SC   'TPM clock input = 20e6/32 = 625 kHz -> PWM-Frequenz 2441 Hz
! ldhx #$00ff             'Timer 2 Counter Modulo Registers (TPMxMODH:TPMxMODL)
! sthx TPM2MODH           'von 0 bis inklusive 255 zählen (also Modulo 256) - (kein 100% duty cycle)
! lda #%00101000          'PWM-Frequenz: 20e6/32/256 = 2441.40625 Hz
! sta TPM2C0SC            'Timer 2 Channel 0 Status and Control Register \ Edge-aligned PWM
! sta TPM2C1SC            'Timer 2 Channel 1 Status and Control Register /  High-true pulses
! clrh
! clrx
! sthx TPM2C0VH           'Timer 2 Channel Value Registers (TPM2CnVH:TPM2CnVL)
! sthx TPM2C1VH
! rts
END PROC


' Tabelle mit den Konstanten zur Erzeugung von DTMF-Signalen

TABLE dtmf_tab WORD

  2467, 3502  ' "0"
  1827, 3169  ' "1"       ' Hz 1209 1336 1477 1633
  1827, 3502  ' "2"       '697   1    2    3    A
  1827, 3872  ' "3"       '770   4    5    6    B
  2019, 3169  ' "4"       '852   7    8    9    C
  2019, 3502  ' "5"       '941   *    0    #    D
  2019, 3872  ' "6"
  2233, 3169  ' "7"       'f[Hz] = 25000*N/65536
  2233, 3502  ' "8"       'N     = 65536*f/25000
  2233, 3872  ' "9"
  2467, 3169  ' "*"
  2467, 3872  ' "#"
  1827, 4281  ' "A"
  2019, 4281  ' "B"
  2233, 4281  ' "C"
  2467, 4281  ' "D"
'     1,    1  ' unbekannt
  2621, 2621  ' 1 kHz zum Testen

END TABLE


' IIAR-Variablen passend laden, um DTMF-Signal zu einem Zeichen zu erzeugen
' benutzte Variablen: char, a, i1h, i1l, i2h, i2l, z1h, z1l, z2h, z2l

PROC dtmf(char)

  ' Offset in der Tabelle berechnen

  IF char>="0" AND char<="9" THEN
    a=char-"0"
  ELSEIF char="*" THEN
    a=10
  ELSEIF char="#" THEN
    a=11
  ELSEIF char>="A" AND char<="D" THEN
    a=char-"A"+12
  ELSE
    a=16
  END IF
  a=a*4

  ' Variablen für Interruptroutine laden

  i1h=LOOKTABBYTE(dtmf_tab,a)
  i1l=LOOKTABBYTE(dtmf_tab,a+1)
  i2h=LOOKTABBYTE(dtmf_tab,a+2)
  i2l=LOOKTABBYTE(dtmf_tab,a+3)
  z1h=0 : z1l=0
  z2h=0 : z2h=0

  ' IIAR-Assemblerroutine in den TOFL-Interrupt hängen und aktivieren

  UIRTpm2Ofl=ON
  inittpm2

  ' Die Töne werden jetzt generiert. Das Programm läuft normal weiter.

  PUT char
  PAUSE 10

  ' alles wieder rückgängig machen

  resettpm2
  UIRTpm2Ofl=OFF

  ' 100 ms Break-Time

  PAUSE 5

RETURN

#iiar_tpm2ofl_next

' --- Hauptprogramm ---------------------------------------------------------

#main        'durch die IIAR am Programmbeginn wird ein "GOTO main" erzeugt

'dtmf "E" : goto main   'Test: 1 kHz-Signal

' Subroutine zum Erzeugen von DTMF-Signalen aufrufen

dtmf "0"
dtmf "1"
dtmf "2"
dtmf "3"
dtmf "4"
dtmf "5"
dtmf "6"
dtmf "7"
dtmf "8"
dtmf "9"
dtmf "*"
dtmf "#"
dtmf "A"
dtmf "B"
dtmf "C"
dtmf "D"
PAUSE 50

' Lied: "Merrily We Go Along"

dtmf "9" : dtmf "5" : dtmf "1" : dtmf "5" : PAUSE 2
dtmf "9" : dtmf "9" : dtmf "9" : PAUSE 5
dtmf "5" : dtmf "5" : dtmf "5" : PAUSE 5
dtmf "9" : dtmf "9" : dtmf "9" : PAUSE 5

dtmf "9" : dtmf "5" : dtmf "1" : dtmf "5" : PAUSE 2
dtmf "9" : dtmf "9" : dtmf "9" : PAUSE 5
dtmf "9" : dtmf "5" : dtmf "5" : PAUSE 5
dtmf "9" : dtmf "5" : dtmf "1" : PAUSE 5

' Zurück in den Hostmodus. Neustart mit RETURN-Taste.

PRINT
PRINT "Programmende."

End2Host=ON
END

' --- Programmende ---------------------------------------------------------


Passender Link: Infosite zu den OM-Mikrocontrollern

Meine Homepage: http://ccintern.dharlos.de

 Antwort schreiben

Bisherige Antworten:

Re: Demoprogramm: DTMF-Signale mittels PWM (von das |_ Team - 1.08.2020 19:34)
    Re: Demoprogramm: DTMF-Signale mittels PWM (von Dietmar - 2.08.2020 1:29)