ok, some news (I hope) mikrobasic about dtmf_out, I didn't try, but teorically, it have to work.....
some theory.....
sin in a circle is:
0 for 0° and 180°
1 for 90°
-1 for 270°
now, the sinusoid is like a circle, only, is open, not close, so, we can know the sin of a sinusoid in ever moment (in microseconds!), knowing how many times it make to close the sinusoid itself,
in dtmf, we can know, dividing 1 for the hz, multipling for 1.000.000, and with an interrupt every x us, we can check the state of 2 sinusoid, and simulate them with a square , now we have 2 different sinusoids, so, if the sum of sin of both in determinate time is >0 then the square at that time is 1, if the sum of both sin of the sinusoind are <=0 then the square is 0
now the code, don't know if it works, but is a beginning.....
'at xtal=4Mhz, interrupt on timer1 ever 50us, we can verify the state of 2 sinusoid
'of dtmf signals, and with portb.0, we cans et 1 if one of sinusoid is
'>0, and set it to 0 if both the sinusoids are <0
'in this way, we can simulate with squares the sum of sinusoid that compose the dtmf signal.....
program dtmf_Test
dim a,b,x,y,z as float
dim out as boolean
dim count as word
dim number as byte
dim col as float[4]
dim row as float[4]
sub procedure interrupt()
if intcon.t0if=1 then
out=true
count=count+50 'breaks ever 50 us.....
intcon.t0if=0
end if
end sub
sub procedure dtmfout(dim n as byte)
select case n
case 1
a=row[0]
b=col[0]
case 2
a=row[0]
b=col[1]
case 3
a=row[0]
b=col[2]
case 4
a=row[1]
b=col[0]
case 5
a=row[1]
b=col[1]
case 6
a=row[1]
b=col[2]
case 7
a=row[2]
b=col[0]
case 8
a=row[2]
b=col[1]
case 9
a=row[2]
b=col[2]
case "*"
a=row[3]
b=col[0]
case 0
a=row[3]
b=col[1]
case "#"
a=row[3]
b=col[2]
end select
x= sin((360*count)/a)
y= sin((360*count)/b)
z=x+y
'option 1
'''if z>=0 then
''' portb.0=1
'''else
''' portb.0=0
'''end if
'option 2 maybe better!
if (x>0) or (y>0) then
portb.0=1
end if
if (x<=0) and (y<=0) then
portb.0=0
end if
end sub
sub procedure select_number
if portb.1=1 then
intcon.t0ie=1
count=0
number=1
end if
if portb.2=1 then
intcon.t0ie=1
count=0
number=2
end if
if portb.3=1 then
intcon.t0ie=1
count=0
number=3
end if
if portb.4=1 then
intcon.t0ie=1
count=0
number=4
end if
if portb.5=1 then
intcon.t0ie=1
count=0
number=5
end if
end sub
sub procedure initmain
' Timer0 Registers:
' Prescaler=1:1; TMR0 Preset=206; Freq=20.000,00Hz; Period=50.000 ns
OPTION_REG.T0CS = 0 ' bit 5 TMR0 Clock Source Select bit:0=Internal Clock (CLKO) / 1=Transition on T0CKI pin
OPTION_REG.T0SE = 0 ' bit 4 TMR0 Source Edge Select bit: 0=low/high / 1=high/low
OPTION_REG.PSA = 1 ' bit 3 Prescaler Assignment bit: 0=Prescaler is assigned to the Timer0
OPTION_REG.PS2 = 0 ' bits 2-0 PS2:PS0: Prescaler Rate Select bits
OPTION_REG.PS1 = 0
OPTION_REG.PS0 = 0
TMR0 = 206 ' preset for timer register
intcon.gie=1
intcon.T0IE=0
count=0
out=false
end sub
sub procedure dtmf_init()
'697hz in us=1/697*1000000=1434.72 us to close the sinusoid.....
row[0]=1434.72
col[0]=827.12
row[1]=1298.70
col[1]=748.50
row[2]=1173.70
col[2]=677.04
row[3]=1062.69
col[3]=612.36
end sub
main:
InitMain()
dtmf_init()
while true
select_number
if (out=true) then
out=false
tmr0=206
dtmfout(number)
end if
'100 ms.....
if count>2000 then
intcon.t0ie=0
TMR0=206
end if
wend
end.
and above of all, how many delays takes the timer0 interrupt?
, maybe there is something to adjust, to have interrupt perfectly ever 50 us to check the sinusoins state.....
every kind of suggestions will be usefull.