Sound Generation with PIC10F322 NCO and XC8: Emulating the IBM PC/XT Beep

As an enthusiast of both vintage computing and modern microcontroller technology, I thought it would be a fun challenge to generate sound using the microcontroller. Specifically, I decided to emulate the iconic beep sound of the original IBM PC/XT, which has a frequency of 896 Hz. This project uses the Numerically Controlled Oscillator (NCO) module of the PIC10F322, along with the compiler.

The IBM PC/XT Beep

The beep sound from the IBM PC/XT is a simple but nostalgic audio signal that many of us remember from the early days of personal computing. The characteristic beep operates at a frequency of 896 Hz. Recreating this sound using modern microcontroller technology allows us to blend the old with the new and appreciate the advancements in electronic sound generation.

Understanding the NCO (Numerically Controlled Oscillator)

The Numerically Controlled Oscillator (NCO) is a versatile peripheral found in some microcontrollers, including the PIC10F322. The NCO is used to generate precise frequency outputs, making it ideal for applications such as sound generation, signal modulation, and frequency synthesis.

Key Features of the NCO:

  1. Frequency Control: The NCO allows for precise control over the output frequency through digital means. This is achieved by adjusting the value of the increment register, which determines the step size for each clock cycle.
  2. High Resolution: The NCO provides high-resolution frequency output, making it suitable for generating accurate and stable signals.
  3. Output Modes: The NCO can operate in different output modes, including fixed duty cycle and pulse-width modulation (PWM) modes, giving flexibility in the type of signals it can generate.
  4. Ease of Use: The NCO module can be easily configured and controlled using registers, making it straightforward to integrate into various applications.

Implementing the IBM PC/XT Beep with PIC10F322 and XC8

To generate the IBM PC/XT beep using the PIC10F322, follow these steps:

Set Up the Project: Create a new project in X IDE and configure it for the PIC10F322 microcontroller. Ensure that the XC8 compiler is selected.

Configure the NCO:

  • Initialize the NCO module by setting the appropriate registers.
  • Calculate the required increment value to achieve the 896 Hz output frequency. This involves determining the relationship between the desired frequency, the clock source, and the NCO increment register.

Write the Firmware:

  • Set up the main program loop to continuously generate the beep sound.
  • Use the NCO increment register to control the frequency of the output signal.
  • Toggle an output pin connected to a speaker or piezoelectric buzzer to produce the sound.

Test and Debug:

  • Upload the firmware to the PIC10F322 and connect a speaker or buzzer to the designated output pin.
  • Verify that the generated sound matches the 896 Hz frequency of the IBM PC/XT beep.
  • Adjust the increment value if necessary to fine-tune the output frequency.

The Circuit:

Pretty simple – Speaker connects to Ground and port RA.2 on the PIC10F322.

NCO Sound

The Code:

Uses about 10% of the PIC10F322 Resources. You can adjust the defines to make some other sounds.

/****************************************************************************
* Title                 :   NCO IBM PC/XT Beep Sound
* Filename              :   nco_beep.c
* Author                :   Jamie Starling
* Origin Date           :   2024/07/11
* Version               :   1.0.0
* Compiler              :   XC8 
* Target                :   PIC10F322
* Copyright             :   Jamie Starling
* All Rights Reserved
*
* THIS SOFTWARE IS PROVIDED BY JAMIE STARLING "AS IS" AND ANY EXPRESSED
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL JAMIE STARLING OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/


/******************************************************************************
* Includes
*******************************************************************************/
#include <xc.h>
#include <stdint.h>

/******************************************************************************
* Configuration
*******************************************************************************/
//Device Configuration
#pragma config FOSC = INTOSC  // Oscillator Selection 
#pragma config BOREN = ON    // Brown-out Reset
#pragma config WDTE = OFF    // Watchdog Timer
#pragma config PWRTE = ON    // Power-up Timer
#pragma config MCLRE = OFF   // MCLR Pin Function Select bit->MCLR pin function is digital input, MCLR internally tied to VDD
#pragma config CP = OFF      // Code Protection 
#pragma config LVP = OFF     // Low-Voltage Programming 
#pragma config LPBOR = ON    // Brown-out Reset Selection bits
#pragma config BORV = LO    // Brown-out Reset Voltage Selection
#pragma config WRT = OFF    // Flash Memory Self-Write Protection

//Used to calculate the delay time - Change depending on processor Speed
#define _XTAL_FREQ 1000000  //1Mhz


/******************************************************************************
* Constants
*******************************************************************************/
#define __BEEP_NCO_VALUE 1879  //Computed NCO Value
#define __BEEP_TIME_MS 500 //Length of Beep Time in MS
#define __REPEATE_TIME_MS 2000 //How Often it repeats

/******************************************************************************
* Variables
*******************************************************************************/

/******************************************************************************
* Function Prototypes
*******************************************************************************/
void setup(void);
void beep(void);


/******************************************************************************
* Functions
*******************************************************************************/
void main(void){
  
  setup();
  
  while(1){
      beep();
      __delay_ms(__REPEATE_TIME_MS);      
    }
  
}

void setup(void){
  
    OSCCONbits.IRCF = 0b011;  //Set System Clock to 1Mhz 
 
    TRISAbits.TRISA2 = 0; //Make sure to Set A2 to output - otherwise does not work.
    
    NCO1CLKbits.N1CKS = 0b01; //Clock Source Select bits - Set to FOSC
    NCO1INC  = __BEEP_NCO_VALUE; //Adder value 
    NCO1CONbits.N1PFM = 0; //NCO operates in Fixed Duty Cycle mode
    
     NCO1CONbits.N1EN = 1; //Enable NCO     
}

void beep(void){
  NCO1CONbits.N1OE = 1; //Enable Output     
  __delay_ms(__BEEP_TIME_MS);
  NCO1CONbits.N1OE = 0; //Disable Output           
}

/*** End of File **************************************************************/

By leveraging the NCO module of the PIC10F322 and the XC8 compiler, you can successfully recreate the nostalgic beep sound of the IBM PC/XT. This project not only provides a fun way to explore sound generation with microcontrollers but also offers a practical application of the NCO’s capabilities. Whether you’re a vintage computing enthusiast or a microcontroller hobbyist, this project is a great way to merge past and present technologies.


Have a Project or Idea!?

Seeking Bespoke Technology Solutions?

jamie@jamiestarling.com


Pin It on Pinterest

Share This