Generating a Sound with PIC - Assembly

Thread Starter

Sgt.Incontro

Joined Dec 5, 2012
50
Hi all,

So I need to generate a sound (tune) for a project I am doing now, using a PIC microcontroller (PIC16F84A) programmed in Assembly ONLY.

A speaker will be attached to one of the ports in order to play the sound.

I just need some guidance on how to start this, how exactly are sound tones generated in assembly?

Thanks. :)

EDIT: (I think you need to toggle a port on and off rapidly, but not quite sure how to proceed with this...)
 

MrChips

Joined Oct 2, 2009
30,821
A simple tone can be created using a digital square wave output.
You can use an internal timer to set the frequency or you can use a PWM feature to set the duty cycle to 50% but vary the period of the PWM output.
 

Thread Starter

Sgt.Incontro

Joined Dec 5, 2012
50
A simple tone can be created using a digital square wave output.
You can use an internal timer to set the frequency or you can use a PWM feature to set the duty cycle to 50% but vary the period of the PWM output.
Any idea how to get started on this?

How exactly would I use the internal timer to set the frequency? Do you mean TMR0?

I am still in the basic stages of learning PIC Assembly, so please excuse my questions if they are obvious.
 

MrChips

Joined Oct 2, 2009
30,821
I am not the most experienced user of PICs around here. But since you are now learning, here is something easy you can do.

Set up TMR0 timer and get it running.
Read the 8-bit value of TMR0 and output it to PORTB. Do this in a tight program loop.

Now output the square wave signal from each of the PORTB pins to a loudspeaker or an audio amplifier (such as a PC audio amplifier). Try each of the PORTB pins in turn, starting with RB7 and working your way up to RB0.
 

Markd77

Joined Sep 7, 2009
2,806
Thanks for your reply again pal.

I also found this tutorial online, which I am trying to understand:

http://www.mastincrosbie.com/mark/electronics/pic/fastflash.html

After editing the values to obtain say a 500Hz wave, would this method also work?
Ignore the section in the code with:
CNT dt 0
etc.
It doesn't clear the variables, which was probably his intention. It just creates some program instructions which never get executed.
<ed>In fact the delay is wrong too, for 100kHz with 4Mhz PIC, a single cycle instruction is 1 microsecond, so you need 5 of them in between each toggle of the pin. It is indeed
not very accurate
</ed>
 
Last edited:

THE_RB

Joined Feb 11, 2008
5,438

Thread Starter

Sgt.Incontro

Joined Dec 5, 2012
50
Thanks for the replies guys.

Markd77 mentioned that accuracy of the page wasn't up to standard, so I found a new example that is easier to understand:

; Start Program ********************************************

; Initialize (Default  Input) .............................
MOVLW b’00000000’ ;Define Port B outputs
TRIS PORTB ; and set bit direction
GOTO check

; Delay Subroutine ........................................
delay MOVLW 0FF ; Standard Routine
MOVWF Count
down DECFSZ Count
GOTO down
RETURN

; Main Loop ...............................................
check BTFSC PORTA,Input ;Check Input Button
GOTO check ; and wait if not ‘on’
BSF PORTB,Buzzer ; Output High
CALL delay ; run delay subroutine
BCF PORTB,Buzzer ; Output Low
CALL delay ; run delay subroutine
GOTO check ; repeat always

END ; Terminate source code
 

THE_RB

Joined Feb 11, 2008
5,438
So you want to make musical notes using assembler code?

Instead of nested delays (which are clunky in ASM) one good old technique was to use the 16bit timer.

Here's the method;
1. toggle the output pin
2. load timer with value 65536-x (x is the period) and clr the timer overflow flag
3. wait for timer roll (overflow flag is set)
4. repeat

This is easier to implement as there is just one value (x) which sets the note that is playing. x is the half-period of the frequency as it takes two "x" periods to make a full squarewave output cycle.

If your code needs to do other things while the note is playing, you can do other (short) tasks during step 3, while the PIC is waiting for the timer overflow flag to be set.
 
Top