PDA

View Full Version : Pule up, pulse down ...+ve & -ve pulses based around 2.5V



HankMcSpank
- 14th May 2009, 11:18
I would like to drive a small audio amp chip which has a simple digital volume control (or more excatly...a digital attenuator). Essentially, the spec says (http://www.nxp.com/acrobat_download/datasheets/TDA8551_T_2.pdf) that to turn the volume up, the chip needs a positive pulse & to turn the volume down it needs a negative pulse...this thing is, it only uses one pin to control the volume...therefore I need find away, of having two pins on a PIC, combine into one, & with the quiescent mid point @2.5V.

When the PIC sends a positive pulse, the quiescent 2.5V goes to 5V & when the PIC sends a negative pulse, the 2.5V goes to 0V

Any ideas or schematics to hand?

Many thanks,
Hank.

aratti
- 14th May 2009, 11:55
From what I can see volume pin (1) must be left floting to do nothing. To increase volume you must pulse from floting to +5V and every pulse will increment the volume by one step. On the contrary if you pulse from floating to ground then volume decrease.

One simple solution to the problem could be with two transistors (one PNP & one NPN) connected as the schematic attached. transistors should work in on/off with negligible current, so dependig from your selection selection calculate R1; R2; & R3.

In standby both transistors must be off.

Al.

Melanie
- 14th May 2009, 15:33
Way too complex a solution!!!

Two Resistors (say 330R each but probably you might get away with 1K, 4K7 or even 10K but you will have to try and see). The Resistors are connected in series. One chain end to +5v, the other end to 0v. The mid-point is connected to both your PIC pin and your chip pin.

With the PIC pin set to INPUT (high impedance), the mid point will be 2.5v (idle state).

PIC pin toggles between INPUT and OUTPUT-LOW, the pin will toggle between 2.5v and 0v (Negative going pulses).

PIC pin toggles between INPUT and OUTPUT-HIGH, the pin will toggle between 2.5v and 5v (Positive going pulses).

aratti
- 14th May 2009, 16:51
Clever!

Al.

HankMcSpank
- 14th May 2009, 19:31
Way too complex a solution!!!

Two Resistors (say 330R each but probably you might get away with 1K, 4K7 or even 10K but you will have to try and see). The Resistors are connected in series. One chain end to +5v, the other end to 0v. The mid-point is connected to both your PIC pin and your chip pin.

With the PIC pin set to INPUT (high impedance), the mid point will be 2.5v (idle state).

PIC pin toggles between INPUT and OUTPUT-LOW, the pin will toggle between 2.5v and 0v (Negative going pulses).

PIC pin toggles between INPUT and OUTPUT-HIGH, the pin will toggle between 2.5v and 5v (Positive going pulses).

Thank you to both of you for trying to help.

Melanie...that sounds very simple, but inevitably I have some questions!

I had envisaged using the pulsout command to erhm pulse my output pins....if I'm reading your solution correctly, then I need to configure these output pins as input pins? (& then ouputs when it comes to pulse them out)

Could you please expand on "PIC pin toggles between INPUT and OUTPUT-HIGH," ...I'm figuring that none of this involves the pulsout command, but more switching of pins from 'input' to 'output' & then followed by a low or high setting depending on whether I want a postive pulse of negative pulse?

Sorry for appearing bit slow, but will this add much of a processing cycle overhead vs the pulsout command? (I'll be monitoing six pins AtoD wise & then have to have the PIC act quickly on the results of each input level with a pulse to the following audio amp IC). There'll be an awful lot of pulsing going on (it's not really a set & forget situation, as I'll be using the PIC as a digitial AGC)...I'm just a little worried, that for doing AtoD on six input pins, then constantly changing the ouput from 'input to ouput' & 'low to to high', (then back again to get to the quiescent state) ...might be a little bit taxing for the PIC?

I'm still in my PIC programming infancy, so would the code look like...something like this...

Pre pulse:
TRISC.0 = 0 ' Make PORTC.0 an input
PORTC.0 = 0 ' and set it low (0V)
TRISC.1 = 0 ' Make PORTC.1 an input
PORTC.1 = 1 ' and set it high(5V)

'mid point therefore 2.5V....

pulse up:
TRISC.0 = 1 ' Make PORTC.0 an output
PORTC.0 = 1 ' and set it high (5V)

The mid point between the resistors therefore goes up to 5V.

I'm quite happy to use trannies/opamps if it allows me to keep the code simpler (or more to the point - processing the incoming signal levels with corresponding pulses out faster)

Melanie
- 15th May 2009, 02:01
A PIC can switch it's I/O in only a few uS - probably a lot faster than your Audio Chip can handle. You need to refer to the Datasheet of your Audio Chip to see how big or small those control pulses need to be.

You pretty much got the code, except I would set the pin High or Low BEFORE setting the TRIS... Here's an example to send a 250uS Pulse...




SoundUp con 1
SoundDown con 0
ChAVol var PortC.1
ChATris var TRISC.1

' Assumes ChATris=1 previously initialised...

'
' Subroutine Pulses Channel-A Sound UP
' ------------------------------------
ChASoundUp:
ChAVol=SoundUp
ChAPulse:
ChATris=0
PauseUS 250
ChATris=1
Return

'
' Subroutine Pulses Channel-A Sound DOWN
' ----------------------------------------
ChASoundDown:
ChAVol=SoundDown
Goto ChAPulse


If there is a minimum time BETWEEN consecutive pulses specified in the Datasheet, you may need a suitable PAUSE (or PauseUS) just before the RETURN statement.

HankMcSpank
- 15th May 2009, 11:12
A PIC can switch it's I/O in only a few uS - probably a lot faster than your Audio Chip can handle. You need to refer to the Datasheet of your Audio Chip to see how big or small those control pulses need to be.

You pretty much got the code, except I would set the pin High or Low BEFORE setting the TRIS... Here's an example to send a 250uS Pulse...




SoundUp con 1
SoundDown con 0
ChAVol var PortC.1
ChATris var TRISC.1

' Assumes ChATris=1 previously initialised...

'
' Subroutine Pulses Channel-A Sound UP
' ------------------------------------
ChASoundUp:
ChAVol=SoundUp
ChAPulse:
ChATris=0
PauseUS 250
ChATris=1
Return

'
' Subroutine Pulses Channel-A Sound DOWN
' ----------------------------------------
ChASoundDown:
ChAVol=SoundDown
Goto ChAPulse


If there is a minimum time BETWEEN consecutive pulses specified in the Datasheet, you may need a suitable PAUSE (or PauseUS) just before the RETURN statement.

Many thanks Melanie - superb stuff (I didn't even know the PauseUS existed - fantastic!)

HankMcSpank
- 26th October 2009, 01:26
Ok, it took me a while to get around to it, but I just had a chance to try this 'floating 2.5V...switchable to 5V or 0V' - it didn't work!

Here's the code (when the IC I'm driving - a TDA8551 - powers up, its digital volume control is at its lowest setting, so it needs to be initialised with 32 pulses - this being the halfway volume point)...



@MyConfig = _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON
@MyConfig = MyConfig & _MCLRE_OFF & _BOR_OFF
@ __config MyConfig
DEFINE OSC 4
DEFINE DEBUG_REG PORTA
DEFINE DEBUG_BIT 0 ' RA0 = TX out to PICKit2 programmer USART tool
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true
DEFINE ADC_BITS 10 ' Set number of bits in result
DEFINE ADC_CLOCK 1 ' Set clock source Fosc/8 "2uS"
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS

OSCCON = %01100000 ' 4MHz internal osc
ANSEL = %00000100 ' RA2 = A/D in, rest digital
ANSELH = 0
ADCON0 = %10001001 ' Right justify, channel AN2, A/D enabled
CM1CON0 = 0
CM2CON0 = 0
PORTA = %00000001 ' serial out pin idles high
TRISA = %00000100 ' RA2 in, rest out
TRISC=%00000010 -set all as output except portC1.1
SoundUp con 1
SoundDown con 0
ChAVol var PortC.1
ChATris var TRISC.1
counter var byte
counter = 0


vol_middle:
HIGH PortC.1 ‘ set port.C1 high
ChATris=0 ‘change portC.1 it to an output (2.5V-> 5V)
counter = counter +1
if counter > 31 then goto finish
Pause 1 'delay 1mS
ChATris=1 'Change PortC.1 back to an input (high impedance)
goto vol_middle

finish:
End


What I got was an initial 2.5V at startup (ie mid point between 2 x 330R resistors in series betrween 5V & ground - the junction connected to my port C.1) - then once pin C.1 was set to an output, the pin's level jumped to 5V as expected - all good , *but* it stayed there (at 5V). I'd thought that by setting pin C.1 back to an input, that the underlying 2.5V would return ....what have I done wrong?

Melanie
- 26th October 2009, 09:54
You're permanently in your vol_middle loop, which at the beginning sets the pin output HIGH. If you put a scope on that pin you would see it continuously pulsing between 5v and 2.5v. Instead of this...

goto vol_middle
finish:
End

Remove the goto vol_middle and end your program with...

finish:
Pause 100
Goto Finish

That way it will loop permanently at the finish point and your last vol_middle instruction of ChATris=1 (ie 2.5v) is what you will observe on the PICs pin.

HankMcSpank
- 26th October 2009, 19:38
Thanks Melanie...that did it (my feeble excuse was that it was very late when I posted - UK time - & my brain was frazzled after a good few intensive hours at the bench) ...the ironic end to this little saga, is that having gotten the PIC to pulse that particular audio amplifier IC up & down - I'd overlooked that fact that the IC's digital volume control wasn't linear, but logarithmic (as all volume controls are - doh!) - & for my purposes, I actually need linear!

Oh well, looks like a digital POT feeding an audio amplifier IC will now come firmly into focus!

thanks once again Melanie - the bit you taught me about three levels from one pin will stand me in good stead for future circuits.