Electronic Circuits and Projects Forum



PIC Sound Generator

  1. #1
    EN0 EN0 is offline

    PIC Sound Generator

    Hey Everyone,

    I hope you enjoy this project I just completed!

    Project:

    I just began programming with PICs and have run through a series of projects to exercise my skill level in programming; this particular project is entitled a "PIC Sound Generator" in which it will generate notes at my command.

    Theory & Operation:

    I begin with all my header files, definings, etc. until I reach my first function. This function allows me to enter a note that I previously stored into an array, and then define how long of a duration I wish it to play for.

    My frequency is set by Timer0 on the PIC, in which I rapidly turn RA0 on and off depending on my TMR0L and TMR0H values, and furthermore, my array value. TMR0H and TMR0L enable me to use 16-bit mode since my lowest note is 1515μS. Remember that I wish to know my lowest frequency note since the delay is longer. If I were to use 8-bit, my maximum delay would be 128μS. Thus, equation for 16-Bit timer:



    Which simplifies to:



    It has already been noted to me that Timer2 would be a better choice, but I wish to become more familliar with all the PICs abilities and attributes, so I will eventually learn about Timer2 as well.

    In the main() function, you see I have a long list of the playNote function commands. These, as I mentioned, give me what note I want and for how long I wish to play it. The latter statement is based on whole notes (actually quarter notes) and half notes (actually eighth notes). The music for the third song is depicted here, as an example:

    http://upload.wikimedia.org/wikipedi.../4/49/Gstk.png

    The time signature is 3/4; meaning there are 3 quarter (1/4) notes per measure; or section in my comments. Therefore, to make the music even, a section must eventually add up to 3 quarter notes. Otherwise, the music becomes convoluted and not very pleasant to listen to. I can, at my disposal, change how fast I want my music to play if I change my WHOLE or HALF values previously defined at the beginning. Note that they correlate with one another; if I have 800 as the WHOLE, I must have half of that for the HALF value. I was fortunate to have experience in this regard (I play classical guitar), so that made things much easier.


    Code:


    * Using PIC18F1320, with C18 compiler

    C - MUFnet PASTE - The name says it all.

    Code :
       1. //
       2. // CreatingSound3.C
       3. //
       4. #include <p18f1320.h>
       5. #include <delays.h>
       6. #include <adc.h>
       7. #pragma config OSC=INTIO2, WDT=OFF, LVP=OFF, DEBUG=ON
       8. #define PAUSE Delay1KTCYx(50);
       9. rom const unsigned int songs[6][80] = {
      10. {0, 5, 7, 8, 10, 8, 0, 0, 5, 7, 8, 0, 8, 5, 12, 10, 12, 17, 19, 20, 22, 20, 12, 12, 17, 19, 20, 12, 20, 17, 24, 22, 12, 12, 17, 19, 20, 17, 24, 20, 29, 17, 17, 20, 19, 17, 24, 20, 17, 12, 12, 17, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      11. {500, 1000, 1500, 250, 250, 1000, 500, 500, 1500, 250, 250, 250, 250, 250, 250, 1500, 500, 1000, 1500, 250, 250, 1000, 500, 500, 1500, 250, 250, 250, 250, 250, 250, 1500, 250, 250, 500, 250, 250, 250, 250, 250, 1000, 250, 250, 250, 250, 250, 1500, 250, 250, 500, 500, 1500, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      12. {7, 9, 10, 9, 10, 12, 14, 15, 14, 12, 10, 14, 15, 14, 19, 17, 19, 12, 14, 15, 14, 30, 10, 12, 14, 12, 10, 14, 9, 10, 9, 9, 10, 12, 10, 9, 7, 9, 7, 6, 10, 9, 10, 9, 7, 6, 14, 7, 12, 10, 9, 14, 15, 17, 15, 14, 12, 9, 7, 6, 7, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      13. {500, 500, 500, 250, 500, 500, 500, 500, 500, 250, 500, 500, 500, 500, 500, 250, 500, 500, 500, 500, 1500, 500, 500, 500, 500, 250, 500, 1500, 500, 250, 500, 500, 500, 500, 500, 250, 500, 500, 500, 500, 1000, 500, 500, 250, 500, 1000, 500, 500, 250, 500, 1500, 500, 250, 500, 500, 250, 500, 1500, 250, 500, 1500, 5000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      14. {5, 5, 5, 3, 5, 7, 9, 9, 10, 7, 9, 10, 14, 2, 14, 9, 10, 12, 14, 14, 158, 12, 12, 14, 7, 3, 5, 5, 12, 12, 12, 12, 10, 9, 10, 10, 10, 10, 9, 7, 7, 9, 9, 2, 17, 17, 17, 17, 15, 14, 15, 15, 15, 15, 14, 12, 9, 10, 9, 7, 5, 9, 10, 12, 14, 7, 5, 5, 14, 15, 14, 12, 10, 9, 7, 5, 7, 9, 9, 20},
      15. {500, 500, 500, 1500, 250, 500, 500, 500, 500, 1500, 250, 500, 500, 500, 500, 1500, 250, 500, 500, 500, 500, 1500, 250, 500, 500, 1000, 250, 1500, 500, 500, 500, 1500, 250, 500, 500, 500, 500, 1500, 250, 500, 500, 500, 250, 1500, 500, 500, 500, 1500, 250, 500, 500, 500, 500, 1500, 250, 500, 500, 250, 250, 250, 250, 1500, 250, 500, 500, 1500, 250, 1500, 500, 250, 250, 250, 250, 1500, 250, 500, 500, 1500, 250, 1500}
      16. };
      17. void playNote(unsigned int note, unsigned int timer) // Note & Timer driver; determines which note will be played and for how long
      18. {
      19. unsigned int times, freq, notes[] = {58725, 59107, 59468, 59809, 60131, 60434, 60720, 60990, 61245, 61486, 61714, 61928, 62131, 62322, 62502, 62672, 62833, 62985, 63128, 63263, 63391, 63511, 63625, 63732, 63833, 63929, 64019, 64104, 64104, 64184, 64260, 65536};
      20. freq = notes[note]; // Determine frequency based on array value
      21. INTCONbits.TMR0IF = 0; // Clear OVF Flag
      22. LATA = 0x01; // Initialize LATA
      23. TMR0L = freq & 0xFF;
      24. TMR0H = (freq >> 8) & 0xFF;
      25. T0CON|=0x80;
      26. for(times=timer;times>0;times--) // Duration of playing
      27. {
      28. TMR0H = (freq >> 8) & 0xFF; //Load TMR0H byte first
      29. TMR0L = freq & 0xFF; // Load TMR0L byte next
      30. while(!INTCONbits.TMR0IF); // Wait for timer
      31. ` INTCONbits.TMR0IF = 0; // Clear OVF Flag
      32. LATA = ~LATA; // Invert output
      33. }
      34. PAUSE;
      35. }
      36. void playSong(unsigned int song)
      37. {
      38. int time, note, counter;
      39. while(1)
      40. {
      41. if(song==0) // Song 1
      42. {
      43. for(counter=0;counter<53;counter++)
      44. {
      45. note = songs[0][counter]; // Song 1 notes
      46. time = songs[1][counter]; // Song 1 time values
      47. playNote(note, time); // Play through notes and times
      48. }
      49. break; // When song 1 finishes, break
      50. }
      51. else if(song==1) // Song 2
      52. {
      53. for(counter=0;counter<63;counter++)
      54. {
      55. note = songs[2][counter]; // Song 2 notes
      56. time = songs[3][counter]; // Song 2 time values
      57. playNote(note, time); // Play through notes and times
      58. }
      59. break; // When song 2 finishes, break
      60. }
      61. else if(song==2) // Song 3
      62. {
      63. for(counter=0;counter<80;counter++)
      64. {
      65. note = songs[4][counter]; // Song 3 notes
      66. time = songs[5][counter]; // Song 3 time values
      67. playNote(note, time); // Play through notes and times
      68. }
      69. break; // When song 3 finishes, break
      70. }
      71. else
      72. {
      73. LATB = 0x08; // Otherwise, LED 4
      74. }
      75. }
      76. }
      77. void main()
      78. {
      79. ADCON1 = 0x0E; // ADC Settings as digital inputs from RA1-RA3
      80. OSCCONbits.IRCF0=1;
      81. OSCCONbits.IRCF1=1;
      82. OSCCONbits.IRCF2=1;
      83. T0CONbits.TMR0ON = 0; // Don't turn timer on yet
      84. T0CONbits.T08BIT = 0; // Timer0 is configured as 16-bit timer
      85. T0CONbits.T0CS = 0; // Use internal clock
      86. T0CONbits.PSA = 1; // Prescaler is not assigned
      87. T0CONbits.T0PS2 = 0;
      88. T0CONbits.T0PS1 = 0;
      89. T0CONbits.T0PS0 = 0;
      90. while(!OSCCONbits.IOFS);
      91. TRISA = 0xFE;
      92. TRISB = 0xF0;
      93. while(1)
      94. {
      95. switch(PORTA & 0x0E)
      96. {
      97. case 0x0C:
      98. LATB = 0x01;
      99. playSong(0);
     100. break;
     101. case 0x0A:
     102. LATB = 0x02;
     103. playSong(1);
     104. break;
     105. case 0x06:
     106. LATB = 0x04;
     107. playSong(2);
     108. break;
     109. default:
     110. LATB = 0x08;
     111. }
     112. }
     113. }

    Video in action:

    uC Project :: CreatingSound3.C video by ElectroNerdy - Photobucket

    I'd like to thank 3v0 and Hayato for their support!

    Thanks,

    Austin
    Attached Images
    Last edited by EN0; 14th September 2010 at 10:05 PM.

Tags
Similar Threads
Thread Starter Forum Replies Last Post
RC jet sound effect generator project FMD Electronic Projects Design/Ideas/Reviews 42 9th January 2010, 09:47 AM
Duck sound generator a21 Electronic Projects Design/Ideas/Reviews 0 5th March 2009, 07:55 PM
Simple flatulence sound generator circuit? HarveyH42 Electronic Projects Design/Ideas/Reviews 4 29th July 2006, 05:37 PM
Need Circuit Cricket Sound Generator E2K Electronic Projects Design/Ideas/Reviews 0 25th June 2006, 09:47 AM
Sound Generator rod Electronic Projects Design/Ideas/Reviews 4 16th May 2003, 01:38 AM
Electronic Circuits  |  Learning Electronics

Join our community with over 100,000 Members! It's free, easy and when you're logged in you have many more features! Click to register.
Page Time: 0.03542 seconds      Memory: 6,834 KB      Queries: 17      Templates: 0