pic microcontroller circuits
The only way you can really do it is to send pulse trains to a single bit port. You can connect this to an amp, or even drive a high impedance speaker or transducer directly, if it is just for low level sounds. A single tone would be just switching the port on/off at a predetermined rate, usually by doing it in a loop. You even have pulsed tones by running a loop within another loop. Here is a little program I did with my son, several years ago, there are some sound loops within it, and it is written in CCS C.
/* Program by Chris Gill, Rastrick High "With help from Dad"
Little game for PIC 16F84 MCU (CCS C Compiler)
When the Green Led lights, you have to press the button
to raise up a column of leds. Pressing the button while the
Green Led is OFF will result in a lose. Pressing while the Green
Led is ON will result in another Red Led lighting (from the bottom up)
You win when all the Red Leds are lit. Losing and winning set off different
sounds and lights. Press then Release button to start. */
#include <16F84.h> // Contains Pin/Port Delay Definitions Etc
#USE STANDARD_IO (b) // Standard Port B Settings
#fuses XT,NOWDT,NOPROTECT // MCU Setup
#use delay(clock=4000000) // Osc 4MHZ
#define Tower output_b // Tower Assigned to Port B
#define Button PIN_A0 // Play Button
#define SS PIN_A1 // Speed Switch
#define Sounder PIN_A2 // Speaker O/P
#define GoLed PIN_A3 // Ready/Start Led
static unsigned char Loop,Loop2,Accum,Delay,Speed; // Global Variables
static int1 Flag; // Button Pressed Indicator
//FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////////
// You LOSE Function
void Lose(void)
{
unsigned char SoundLoop;
for(SoundLoop=0;SoundLoop<100;SoundLoop++) // Low Tone
{output_high(Sounder);delay_ms(8);output_low(Sounder);delay_ms(8);}
Tower(0xff);
delay_ms(100); // Collapses Tower
Tower(0x7f);
delay_ms(100); // Decimal 255,127,63,31,15,7,3,0
Tower(0x3f);
delay_ms(100);
Tower(0x1f);
delay_ms(100);
Added after 3 minutes:
Sorry for some reason all of it was not sent. Let me know if it is useful, and I will send the rest. You can do a similar thing in basic, or any other language of course.
Added after 54 minutes:
I Have sent it again for completeness. Hope it helps. Sorry, not very well structured. Done mostly by my son when he was around 13. May need slight alterations for later compilers. You should get the idea how sounds are made though. I did once find an article by googling, on playing tunes on a pic. This was done from data tables I think. MCUs tend not to have sound generation facilities built in, so all rather crude really, but it works after a fashion.
#include <16F84.h> // Contains Pin/Port Delay Definitions Etc
#USE STANDARD_IO (b) // Standard Port B Settings
#fuses XT,NOWDT,NOPROTECT // MCU Setup
#use delay(clock=4000000) // Osc 4MHZ
#define Tower output_b // Tower Assigned to Port B
#define Button PIN_A0 // Play Button
#define SS PIN_A1 // Speed Switch
#define Sounder PIN_A2 // Speaker O/P
#define GoLed PIN_A3 // Ready/Start Led
static unsigned char Loop,Loop2,Accum,Delay,Speed; // Global Variables
static int1 Flag; // Button Pressed Indicator
//FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////////
// You LOSE Function
void Lose(void)
{
unsigned char SoundLoop;
for(SoundLoop=0;SoundLoop<100;SoundLoop++) // Low Tone
{output_high(Sounder);delay_ms(8);output_low(Sounder);delay_ms(8);}
Tower(0xff);
delay_ms(100); // Collapses Tower
Tower(0x7f);
delay_ms(100); // Decimal 255,127,63,31,15,7,3,0
Tower(0x3f);
delay_ms(100);
Tower(0x1f);
delay_ms(100);
Tower(0x0f);
delay_ms(100);
Tower(0x07);
delay_ms(100);
Tower(0x03);
delay_ms(100);
Tower(0x00);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// You WIN Function
void Win(void)
{
unsigned char SoundLoop; // 3 Ascending Tones
for(SoundLoop=0;SoundLoop<100;SoundLoop++)
{output_high(Sounder);delay_ms(3);output_low(Sounder);delay_ms(3);}
for(SoundLoop=0;SoundLoop<150;SoundLoop++)
{output_high(Sounder);delay_ms(2);output_low(Sounder);delay_ms(2);}
for(SoundLoop=0;SoundLoop<200;SoundLoop++)
{output_high(Sounder);delay_ms(1);output_low(Sounder);delay_ms(1);}
Tower(0xff); // 3 Tower Flashes All Leds
delay_ms(900); // Decimal 255 then Zero
Tower(0x00);
delay_ms(900);
Tower(0xff);
delay_ms(900);
Tower(0x00);
delay_ms(900);
Tower(0xff);
delay_ms(900);
Tower(0x00);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
void main(void)
{ // Start of Main Loop
output_high(GoLed); // Flashes Leds @ Power Up
Tower(0xff);
delay_ms(2000);
output_low(GoLed);
Tower(0x00);
while(true)
{
// While Runs Forever
while (input(Button)); // Wait for Button Press(0)
while (!input(Button)); // Wait For Button Release(1) to Start
if (!input(SS)) Speed = 35; // Fast (Switch Open HIGH)
if (input(SS)) Speed = 70; // Slow (Switch Closed LOW)
Accum=0; // Initial States
Delay=0;
Flag=0;
output_low(GoLed); // Led OFF
for (Loop=0;Loop<8;Loop++) // Repeat 8 Times for 8 Tower Leds
{
Delay=250; // Psuedo Random Routine
delay_ms(Delay);
delay_ms(Delay);
delay_ms(Delay);
delay_ms(Delay);
delay_ms(Delay);
delay_ms(Delay);
delay_ms(Delay);
delay_ms(Delay);
Delay=Delay+50; // Increased GO Led, OFF Periods
if(!input(Button)) {Lose();break;} // Prevents Button Being Pressed Prematurely(0)
output_high(GoLed); // Press Button NOW. GO Led ON
for (Loop2=0;Loop2<(Speed);Loop2++)
{delay_ms(5); if(!input(Button))Flag=1;} // Button Active Time for a Win
output_low(GoLed); // Led OFF
if (Flag==0) {Lose(); break;} // Did Not Press Button in Time
Accum=((Accum+Accum)+1);
Tower(Accum);
while (!input(Button)); // Wait For Button Release(1)
if(Accum==0xff)Win(); // Win Routine
Flag=0;
} // End of For Loop
} // End of Main While Loop
} // End of Main Function