Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
OSCCON = $60 ' Set up internal oscillator
x var byte
dtmf var byte
CS var portb.4 'Enable or disable MT8888
RD var portb.5 'Read Microprocessor input
WR var portb.6 'Write Microprocessor input
RS var portb.7 'Register Select
data @1,8,7,0,7,3,7,5
TRISB = %00000000
portb = %11000000
portb = %10100000
portb = %10100000
portb = %10101000
portb = %10100000
portb = %11000000
pause 10
Send_DTMF:
portb = %10101101 'Send Control Register A
portb = %10100000 'Send Control Register B
portb = %10100110 'Send digit = 7
portb = %10100100 ' Send digit = 5
Goto Send_DTMF
I'm not familiar with PIC basic but:This is how it is wired and here is some code I have tried.
Code:Send_DTMF: portb = %10101101 'Send Control Register A portb = %10100000 'Send Control Register B portb = %10100110 'Send digit = 7 portb = %10100100 ' Send digit = 5
You need to setup the D0-D3, RSO and CS pins first while maintaining WR and RD high.
When setting up the control registers or read the status register, you set RS0 high.What do I do with RS0? I thought it was just used in conjunction with RD and WR to set up the control registers A and B.
Yes, you could tie it low to ground permanently in this application. It is typically used when interfacing the MT8888 to a microprocessor's data buss where there are multiple devices on the same buss. When it is high, D0-D3, RSO, WR & RD have no effect.Do I set CS low to enable the MT8888? and leave it low?
No problem.Thanks for jumping in, Don
OSCCON = $60 ' Set up internal oscillator
CS var portb.4 'Enable or disable MT8888 tied to ground
RD var portb.5 'Read Microprocessor input
WR var portb.6 'Write Microprocessor input
RS var portb.7 'Register Select
TRISB = %00000000 'Set portb to output
portb = %11000000
portb = %10100000
portb = %10100000
portb = %10101000
portb = %10100000
portb = %11000000
pause 10
Send_DTMF:
portb = %10101101 'Set up Control Register A
pause 1 'Wait 1 millisecond
portb = %10100000 'Set up Control Register B
pause 1 'Wait 1 millisecond
portb = %01100000 'Set WR, RD high CS and RS0 and rest of portb low
pause 1 'Wait 1 millisecond
portb = %00000110 'Send digit = 6
pause 10 'wait 10 milliseconds
low WR 'Take portb pin 6 low
pause 10 'wait 10 milliseconds
high WR 'take portb pin 6 high
Goto Send_DTMF 'loop forever
End
portb = %11000000
portb = %10100000
portb = %10100000
portb = %10101000
portb = %10100000
portb = %11000000
It's not going to work. I suggest that you create a subroutine for writing commands to the MT8888. Syntax will be wrong, but this is the idea:I am going to try this, how do you think it looks?
sub WriteControlRegister(command)
command = command AND 0x0F 'Mask off upper 4 bits with Logical AND
portb = command OR %11100000 'Set upper 3 bits with Logical OR and send to portb
pause 1 'Wait 1 millisecond (may not be needed)
low WR 'Take portb pin 6 low
pause 1 'Wait 1 millisecond (may not be needed)
high WR 'take portb pin 6 high
end sub
WriteControlRegister(%1101) 'Write to Control Register A (tone out, DTMF, IRQ, Select Control Register B)
WriteControlRegister(%0000) 'Write to Control Register B (burst mode)
command = command AND 0x0F 'Mask off upper 4 bits with Logical AND
portb = command OR %11100000 'Set upper 3 bits with Logical OR and send to portb
portb = %10101101
or
portb = %10100000
WriteControlRegister(%1101) 'Write to Control Register A (tone out, DTMF, IRQ, Select Control Register B)
WriteControlRegister(%0000) 'Write to Control Register B (burst mode)
OSCCON = $60 ' Set up internal oscillator
CS var portb.4 'Enable or disable MT8888 tied to ground
RD var portb.5 'Read Microprocessor input
WR var portb.6 'Write Microprocessor input
RS var portb.7 'Register Select
TRISB = %00000000 'Set portb to output
command var byte
data @4,%1101,%0000'Data starting at position #4
data @6,8,7,0,7,3,7,5
WriteControlRegister:
command = command & $0F 'Mask off upper 4 bits with Logical AND
portb = command | %11100000 'Set upper 3 bits with Logical OR and send to portb
pause 1 'Wait 1 millisecond (may not be needed)
low WR 'Take portb pin 6 low
pause 1 'Wait 1 millisecond (may not be needed)
high WR 'take portb pin 6 high
Return
WritetransmitRegister:
command = command & $0F 'Mask off upper 4 bits with Logical AND
portb = command | %11100000 'Set upper 3 bits with Logical OR and send to portb
pause 1 'Wait 1 millisecond (may not be needed)
low WR 'Take portb pin 6 low
pause 1 'Wait 1 millisecond (may not be needed)
high WR 'take portb pin 6 high
return
SetupAandB:
for x = 4 to 5
read x, command 'Read data statement starting at location #4 and put in command
gosub writecontrolregister
next x
gosub Setuptransmitregister
Setuptransmitregister:
for x = 6 to 12
read x, command 'Read data statement starting at location #6 and put in command
gosub writetransmitregister
next x
End
I highly recommend that you do so. It will make writing our code much easier to understand and you will be less prone to making mistakes. Once the SUBs are written, you'll no longer have to think about the hardware interface with the MT8888 much. ie: you won't have to remember to toggle WR every time you write a nibble to the MT8888.Unless, you think subroutines would be the best way from the outset.
Because this:What is the reason I can't just write - portb = %10101101?
WriteControlRegister(%[COLOR="Red"]1101[/COLOR]) 'Write to Control Register A (tone out, DTMF, IRQ, Select Control Register B)
WriteControlRegister(%[COLOR="Blue"]0000[/COLOR]) 'Write to Control Register B (burst mode)
portb = %1110[COLOR="Red"]1101[/COLOR]
pause 1 'Wait 1 millisecond (may not be needed)
portb = %1010[COLOR="Red"]1101[/COLOR] 'Take portb bit 6 low
pause 1 'Wait 1 millisecond (may not be needed)
portb = %1110[COLOR="Red"]1101[/COLOR] 'take portb bit 6 high
' Small delay here due to routine above returning
' and the routine below being called.
portb = %1110[COLOR="Blue"]0000[/COLOR]
pause 1 'Wait 1 millisecond (may not be needed)
portb = %1010[COLOR="Blue"]0000[/COLOR] 'Take portb bit 6 low
pause 1 'Wait 1 millisecond (may not be needed)
portb = %1110[COLOR="Blue"]0000[/COLOR] 'take portb bit 6 high
OSCCON = $60 'Set up internal oscillator
CS var portb.4 'Enable or disable MT8888 tied to ground
RD var portb.5 'Read Microprocessor input
WR var portb.6 'Write Microprocessor input
RS var portb.7 'Register Select
TRISB = %00000000 'Set portb to output
Init var byte
Control var byte
Dtmf var byte
Status var byte
w var byte
X var byte
y var byte
z var byte
data @1,%11000000,%10100000,%10101000,%10100000,%10101101,%10100000,%00001000,%00001110,%00000001,%00001110,%00000011,%00001110,%00000110 'Data starting at position #1
Gosub Initialization
gosub SetupControlRegister
gosub WriteTransmitRegister
Initialization:
Gosub ReadStatusRegister
for w = 2 to 4
read w, Init 'Read data statement starting at location #2 and put in Init
Init = Init & $0F 'Mask off upper 4 bits with Logical AND
portb = Init | %11100000 'Set upper 3 bits with Logical OR and send to portb
pause 10 'Wait 1 millisecond (may not be needed)
low WR 'Take portb pin 6 low
pause 10 'Wait 1 millisecond (may not be needed)
high WR 'take portb pin 6 high
pause 10
Next w
Return
ReadstatusRegister:
read 1, Status 'Read data statement starting at location #1 and put in Status
Status = Status & $0F 'Mask off upper 4 bits with Logical AND
portb = Status | %11100000 'Set upper 3 bits with Logical OR and send to portb
pause 10 'Wait 1 millisecond (may not be needed)
low RD 'Take portb pin 5 low
pause 10 'Wait 1 millisecond (may not be needed)
high RD 'take portb pin 5 high
pause 10
Return
SetupControlRegister:
for x = 5 to 6
read x, Control 'Read data statement starting at location #6 and put in Control
Control = Control & $0F 'Mask off upper 4 bits with Logical AND
portb = Control | %11100000 'Set upper 3 bits with Logical OR and send to portb
pause 10 'Wait 1 millisecond (may not be needed)
low WR 'Take portb pin 6 low
pause 10 'Wait 1 millisecond (may not be needed)
high WR 'take portb pin 6 high
pause 10
Next X
Return
WriteTransmitRegister:
for y = 7 to 13
read y, Dtmf 'Read data statement starting at location #9 and put in Dtmf
Dtmf = Dtmf & $0F 'Mask off upper 4 bits with Logical AND
portb = Dtmf | %11100000 'Set upper 3 bits with Logical OR and send to portb
pause 10 'Wait 1 millisecond (may not be needed)
high RD 'Take portb pin 5 high
pause 10 'Wait 1 millisecond (may not be needed)
low RD 'take portb pin 5 low
pause 10
Next y
Return
End
' Listing 1. Stamp-Based Autodialer
' Program: DIAL.SRC (Sends a string of DTMF tones via the 8880)
' This program demonstrates how to use the CM8880 as a DTMF tone
' generator. All that's required is to initialize the 8880 properly,
' then write the number of the desired DTMF tone to the 8880's
' 4-bit bus.
' The symbols below are the pin numbers to which the 8880's
' control inputs are connected, and one variable used to read
' digits out of a lookup table.
SYMBOL RS_p = 4 ' Register-select pin (0=data).
SYMBOL RW_p = 5 ' Read/Write pin (0=write).
SYMBOL CS_p = 6 ' Chip-select pin (0=active).
SYMBOL digit = b2 ' Index of digits to dial.
' This code initializes the 8880 for dialing by writing to its
' internal control registers CRA and CRB. The write occurs when
' CS (pin 6) is taken low, then returned high. See the accompanying
' article for an explanation of the 8880's registers.
let pins = 255 ' All pins high to deselect 8880.
let dirs = 255 ' Set up to write to 8880 (all outputs).
let pins = %00011011 ' Set up register A, next write to register B.
high CS_p
let pins = %00010000 ' Clear register B; ready to send DTMF.
high CS_p
Stamp Applications no. 7, September 1995
7
' This for/next loop dials the seven digits of my fax number. For
' simplicity, it writes the digit to be dialed directly to the output
' pins. Since valid digits are between 0 and 15, this also takes RS,
' RW, and CS low--perfect for writing data to the 8880. To complete
' the write, the CS line is returned high. The initialization above
' sets the 8880 for tone bursts of 200 ms duration, so we pause
' 250 ms between digits. Note: in the DTMF code as used by the phone
' system, zero is represented by ten (1010 binary) not 0. That's why
' the phone number 459-0623 is coded 4,5,9,10,6,2,3.
for digit = 0 to 6
lookup digit,(4,5,9,10,6,2,3),pins ' Write current digit to pins.
high CS_p ' Done with write.
pause 250 ' Wait to dial next digit.
next digit
end
' Listing 2.