ATMega32 LED Lights and Sound

Here is my example C code that blinks an LED and produces a sound in the form of a musical note. The program sends a binary 1 to the port to light the LED, plays a note, and then sends a binary 0 to the port to switch OFF the LED. It repeats his for each note in the scale, and the video above shows the working code.

Blinking LED and Sound Program Code

Here is the program listing and the source code file.

 lightandsound.c

This program is a combination of two earlier programs, one blinked LEDs and the other produced notes. Both of those programs combine in this code. One function sent a binary 1 to any pin thereby lighting a LED, and the other function played a note.

  1: /*********************************************
  2: Author: Peter J. Vis
  3: First Written: 8 Dec 1999
  4: Title: R2D2 with lights
  5: 
  6: PURPOSE: To light LEDs and generate sound.
  7: 
  8: Microcontroller: ATmega32
  9: Crystal: 16 MHz
 10: Platform: Development System
 11: 
 12: URL: https://www.petervis.com
 13: 
 14: LIMITATIONS:
 15: Copyright protected. No part of this
 16: work my be reproduced on the Internet. This
 17: work cannot be used by bloggers.
 18: 
 19: CIRCUIT:
 20: Piezo Speaker connected to PortC pin PC7
 21: 
 22: 
 23: THEORY:
 24: 
 25: Note 	Frequency
 26: ----	---------
 27: A 		880 
 28: A# 	932 
 29: B 		988 
 30: C 		1047 
 31: C# 	1109 
 32: D 		1175 
 33: D# 	1244 
 34: E 		1319 
 35: F 		1397 
 36: F# 	1480 
 37: G 		1568 
 38: G# 	1660 
 39: 
 40: Sound is produced by a rapidly switching
 41: square wave. The ATmega32 can output a square 
 42: wave from any of its pins.The rate at which the
 43: square wave is switched determines the frequency
 44: of the note.
 45: 
 46: A signal has a wavelength w and frequency f
 47: w = 1/f
 48: 
 49: 
 50:  speaker on off on
 51:          ____________               ________
 52:         |            |             |
 53: ________| 	          |_____________|
 54:         |            |             |
 55:         | ½ period |             |
 56:         |                          |
 57:         |<----(w) wavelength ----->| 
 58: 
 59: 
 60: **********************************************/
 61:  
 62:  
 63: #define F_CPU 16000000UL
 64:  
 65: #include <avr/io.h>
 66: #include <util/delay.h>
 67:  
 68:  
 69: #define SPEAKER_PORT PORTC
 70: #define SPEAKER_DDR DDRC
 71: #define SPEAKER_PIN 7
 72:  
 73: // My Prototype used.
 74: void PLAYNOTE(float duration, float frequency);
 75: int 
 76: Set_PortA_Bit_Position(int position, int value);
 77:  
 78: int main(void)
 79: {
 80:  
 81: // Set all the Data Direction Register
 82: // bits to 1 which means all bits in Port A will 
 83: // be sending data out.
 84: 
 85:  
 86: DDRA = 0b11111111;
 87:  
 88:  
 89:   Set_PortA_Bit_Position(0, 1); 
 90:   PLAYNOTE(400,880);
 91:   Set_PortA_Bit_Position(0, 0); 
 92:  
 93:   Set_PortA_Bit_Position(1, 1); 
 94:   PLAYNOTE(400,932);
 95:   Set_PortA_Bit_Position(1, 0); 
 96:  
 97:   Set_PortA_Bit_Position(2, 1); 
 98:   PLAYNOTE(400,988);
 99:   Set_PortA_Bit_Position(2, 0); 
 100:  
 101:  Set_PortA_Bit_Position(3, 1); 
 102:  PLAYNOTE(400,1047);
 103:  Set_PortA_Bit_Position(3, 0); 
 104:  
 105:  Set_PortA_Bit_Position(4, 1); 
 106:  PLAYNOTE(400,1109);
 107:  Set_PortA_Bit_Position(4, 0); 
 108:  
 109:  Set_PortA_Bit_Position(5, 1); 
 110:  PLAYNOTE(400,1175);
 111:  Set_PortA_Bit_Position(5, 0);
 112:  
 113:  Set_PortA_Bit_Position(6, 1); 
 114:  PLAYNOTE(400,1244);
 115:  Set_PortA_Bit_Position(6, 0); 
 116:  
 117:  Set_PortA_Bit_Position(7, 1); 
 118:  PLAYNOTE(400,1319);
 119:  Set_PortA_Bit_Position(7, 0); 
 120:  
 121:  Set_PortA_Bit_Position(0, 1); 
 122:  PLAYNOTE(400,1397);
 123:  Set_PortA_Bit_Position(0, 0); 
 124:  
 125:  Set_PortA_Bit_Position(1, 1); 
 126:  PLAYNOTE(400,1480);
 127:  Set_PortA_Bit_Position(1, 0); 
 128:  
 129:  Set_PortA_Bit_Position(2, 1); 
 130:  PLAYNOTE(400,1568);
 131:  Set_PortA_Bit_Position(2, 0); 
 132:  
 133:  Set_PortA_Bit_Position(3, 1); 
 134:  PLAYNOTE(400,1660);
 135:  Set_PortA_Bit_Position(3, 0); 
 136: }
 137:  
 138:  
 139:  
 140: // Function to play a note given the duration 
 141: // and frequency.
 142: // This part generates the actual sound by
 143: // toggling the bit rapidly.
 144:  
 145: {
 146:  // Physics variables mentioned above.
 147:  long int i,cycles;
 148:  float half_period; 
 149:  float wavelength;
 150:  
 151:  wavelength=(1/frequency)*1000; 
 152:  cycles=duration/wavelength;
 153:  half_period = wavelength/2; 
 154:  
 155:  // Data Direction register Pin 7 is
 156:  // set for output mode.
 157:  SPEAKER_DDR |= (1 << SPEAKER_PIN);
 158:  
 159:  for (i=0;i<cycles;i++) 
 160:  {
 161:  _delay_ms(half_period); 
 162:  SPEAKER_PORT |= (1 << SPEAKER_PIN); 
 163:  _delay_ms(half_period); 
 164:  SPEAKER_PORT &= ~(1 << SPEAKER_PIN); 
 165:  }
 166:  
 167:  return;
 168: }
 169:  
 170:  
 171: // Function to set the LED bit High or
 172: // Low as called by the main program.
 173: // -----------------------------------
 174:  
 175:  
 176: int Set_PortA_Bit_Position
 177: (int position, int value){
 178: 
 179: // Sets or clears the bit in 'position'
 180: // to either High or Low to match 'value'.
 181: // Leave the other bits in PORT A unchanged.
 182: 
 183:  
 184:  if (value == 0)
 185:  {
 186:  PORTA &= ~(1 << position); 
 187:  }
 188:  else
 189:  {
 190:  PORTA |= (1 << position); 
 191:  }
 192:  return 1;
 193: }