Emily GianottiJason DongRachel GuJonathan Thomas
Published

Whack arRay

Ever feel the need to vent your frustration with ELEC 220? Well Whack arRay is here to help!

BeginnerFull instructions provided30 minutes73
Whack arRay

Things used in this project

Hardware components

EK-TM4C123GXL TM4C Tiva LaunchPad
Texas Instruments EK-TM4C123GXL TM4C Tiva LaunchPad
×2
Breadboard (generic)
Breadboard (generic)
×2
Jumper wires (generic)
Jumper wires (generic)
×25
Buzzer, Piezo
Buzzer, Piezo
×2
Tilt Switch, SPST
Tilt Switch, SPST
×1
7 Segment LED Display, InfoVue
7 Segment LED Display, InfoVue
×1
Pushbutton switch 12mm
SparkFun Pushbutton switch 12mm
×3
LED (generic)
LED (generic)
×3
Resistor 1k ohm
Resistor 1k ohm
×3

Software apps and online services

Code Composer Studio
Texas Instruments Code Composer Studio

Story

Read more

Schematics

Music

7 segment display

Game

Code

portDefinitions

C/C++
Sets up the ports used for the game.
// Base addresses of each port
#define PortA       0x40004000
#define PortB       0x40005000
#define PortC       0x40006000
#define PortD       0x40007000
#define PortE       0x40024000
#define PortF       0x40025000

//  General-Purpose Input/Output Run Mode Clock Gating Control. Each bit corresponds to a Port.
#define RCGCGPIO    0x400FE608
#define ClocksA     0x01
#define ClocksB     0x02
#define ClocksC     0x04
#define ClocksD     0x08
#define ClocksE     0x10
#define ClocksF     0x20

// Define the bitmask for each pin
#define pin0     0x01
#define pin1     0x02
#define pin2     0x04
#define pin3     0x08
#define pin4     0x10
#define pin5     0x20
#define pin6     0x40
#define pin7     0x80

//Other defines for code readability
#define OUTPUT  1
#define INPUT   0
#define INTERRUPT    1
#define NoINTERRUPT  0
#define ON  1
#define OFF 0

// Offsets corresponding to registers we may need to configure
#define GPIODATA    0x3FC   // pg662 : GPIO Data
#define GPIODIR     0x400   // pg663 : GPIO Direction
#define GPIOIS      ?????   // pg664 : GPIO Interrupt Sense
#define GPIOIBE     ?????   // pg665 : GPIO Interrupt Both Edges
#define GPIOIEV     ?????   // pg666 : GPIO Interrupt Event     -   0: falling edge or Low level is trigger.    1: rising edge or High level is trigger
#define GPIOIM      ?????   // pg667 : GPIO Interrupt Mask      -   0: the pin is masked.                       1: the interrupt is sent to the controller
#define GPIOICR     ?????   // pg670 : GPIO Interrupt Clear     -   0: no affect                                1: the corresponding interrupt is cleared
#define GPIOAFSEL   0x420   // pg671 : GPIO Alternative Function Select - 0: pin functions as GPIO              1: Function as something else depending on port
#define GPIOPUR     0x510   // pg677 : GPIO Pull-Up Select      -   0: turn off pull up resistor                1: turn on pull up for corresponding pin
#define GPIOPDR     0x514   // pg679 : GPIO Pull-Down Select    -   0: turn off pull down resistor              1: turn on pull down for corresponding pin
#define GPIODEN     0x51C   // pg682 : GPIO Digital Enable      -   0: disable digital functions                1: enable pin's digital functions
#define GPIOLOCK    0x520   // pg684 : GPIO Lock. A write of the value 0x4C4F.434B unlocks the GPIO Commit (GPIOCR) register for write access.
#define GPIOKEY     0x4C4F434B // pg684. Special key for the GPIOLOCK register
#define GPIOCR      0x524   // pg685 : GPIO Commit              -   0: Corresponding GPIOAFSEL, GPIOPUR, GPIOPDR, or GPIODEN bits cannot be written. 1: They can

main.c

C/C++
Runs the game.
#include <time.h>
#include <stdlib.h>
#include <portDefinitions>
#include <math.h>

void SetupDigitalGPIO(unsigned int port, unsigned int pinMask, int direction)
{
    /*Function for setting up a digital GPIO Pin

     This function will do all the register configs for a give port and pin.

     Examples
     -------
     SetupOnDigitalGPIO(PortF, pin3, INPUT, INTERRUPT) // Set up an input with interrupts on PF3.
     SetupOnDigitalGPIO(PortE, pin4, OUTPUT, NoINTERRUPT) // Set up an output with no interrupts on PE4.
     Notes
     -----
     We assume a pullup resistor.
     We also assume an edge based trigger.
     It is best the header with the #defines for each port and pin are included.

     Inputs
     ------
     (*((volatile unsigned long *) port  - Base address of the port being used.
     (*((volatile unsigned long *) pin   - Bit mask of the pin being used
     int direction - Boolean flag for direction of the pin. 1 = Output. 0 = input
     int UseInterrupts - Boolean flag to use interrupts. 1 = use them. 0 = don't
     */

    //Define the generic pointers
    unsigned int volatile *pRCGCGPIO = (unsigned int *) RCGCGPIO;
    unsigned int volatile *pGPIOLOCK = (unsigned int *) (port + GPIOLOCK);
    unsigned int volatile *pGPIOCR = (unsigned int *) (port + GPIOCR);
    unsigned int volatile *pGPIODIR = (unsigned int *) (port + GPIODIR);
    unsigned int volatile *pGPIOAFSEL = (unsigned int *) (port + GPIOAFSEL);
    unsigned int volatile *pGPIOPUR = (unsigned int *) (port + GPIOPUR);
    unsigned int volatile *pGPIODEN = (unsigned int *) (port + GPIODEN);
    unsigned int volatile *pGPIODATA = (unsigned int *) (port + GPIODATA);

    // activate the clocks for the port
    int clocks;
    switch ((int) port)
    {
    case PortA:
        clocks = ClocksA; break;
    case PortB:
        clocks = ClocksB; break;
    case PortC:
        clocks = ClocksC; break;
    case PortD:
        clocks = ClocksD; break;
    case PortE:
        clocks = ClocksE; break;
    case PortF:
        clocks = ClocksF; break;
    default:
        clocks = ClocksF; //ERROR. TODO: Add an exception to handle this. Send to Error ISR or something
    }

    *pRCGCGPIO |= clocks;
    while ((*pRCGCGPIO & clocks) == 0);
    if(port == PortF){
        *pGPIOLOCK = GPIOKEY;
        *pGPIOCR |= pinMask;
    }
    if (direction == 0)
    {
        *pGPIODIR &= ~pinMask;
        *pGPIOPUR |= pinMask;
    }
    else if (direction == 1)
    {
        *pGPIODIR |= pinMask;
    }

    *pGPIOAFSEL &= ~pinMask;
    *pGPIODEN |= pinMask;
    *pGPIODATA |= pinMask;
}
// portPin is an array of unsigned integers
// portPin[0] is the port base address
// portPin[1] is the pin mask
void turnOn(unsigned int portPin[2])
{
    unsigned int volatile *pGPIODATA = (unsigned int *) (portPin[0] + GPIODATA);
    *pGPIODATA = *pGPIODATA |portPin[1];
}

void turnOff(unsigned int portPin[2])
{
    unsigned int volatile *pGPIODATA = (unsigned int *) (portPin[0] + GPIODATA);
    *pGPIODATA = *pGPIODATA & ~portPin[1];
}

void setupBoard(){
        SetupDigitalGPIO(PortA, pin2, OUTPUT);
        SetupDigitalGPIO(PortA, pin3, OUTPUT);
        SetupDigitalGPIO(PortA, pin4, OUTPUT);
        SetupDigitalGPIO(PortA, pin5, OUTPUT);
        SetupDigitalGPIO(PortA, pin6, OUTPUT);
        SetupDigitalGPIO(PortA, pin7, OUTPUT);
        SetupDigitalGPIO(PortB, pin0, OUTPUT);
}

void displayNum (int num) {
    //Define segments of 7 segment display

    unsigned int segA[2] = {PortA, pin6};
    unsigned int segB[2] = {PortA, pin5};
    unsigned int segC[2] = {PortA, pin4};
    unsigned int segD[2] = {PortA, pin3};
    unsigned int segE[2] = {PortA, pin2};
    unsigned int segF[2] = {PortA, pin7};
    unsigned int segG[2] = {PortB, pin0};

    turnOff(segA);
    turnOff(segB);
    turnOff(segC);
    turnOff(segD);
    turnOff(segE);
    turnOff(segF);
    turnOff(segG);

    switch(num)
        {
            case 8 :
                turnOn(segG);
            case 0 :
                turnOn(segA);
                turnOn(segB);
                turnOn(segC);
                turnOn(segD);
                turnOn(segE);
                turnOn(segF);
                break;
            case 2:
                turnOn(segA);
                turnOn(segB);
                turnOn(segD);
                turnOn(segE);
                turnOn(segG);
                break;
            case 3:
                turnOn(segD);
                turnOn(segG);
            case 7:
                turnOn(segA);
                turnOn(segB);
                turnOn(segC);
                break;
            case 6:
                turnOn(segE);
            case 5:
                turnOn(segA);
                turnOn(segC);
                turnOn(segD);
                turnOn(segF);
                turnOn(segG);
                break;
            case 9:
                turnOn(segA);
            case 4:
                turnOn(segF);
                turnOn(segG);
            case 1:
                turnOn(segB);
                turnOn(segC);
                break;

        }
        return;
}
//Controls the length of the delay between lights, delay decreases as the score decreases
void sleep(int delay){
    int i =0;
    float delayFraction = pow(.8,delay);
    for(i = 0; i < 1000000*delayFraction; i++){}
    }

int randInt(int num){
    // returns a random integer from low up to but not including high
   int randomNumber = rand()%num;
   return randomNumber;
}

void turnOnNextLight(int delay, unsigned int light[2]){
    //This function turns on the next light and returns the the time the light will time out
    unsigned int lightRed[2] = {PortE, pin5};
    unsigned int lightBlue[2] = {PortB, pin5};
    unsigned int lightGreen[2] = {PortB, pin3};

    sleep(delay);
    turnOn(light);
}

//checks to see if a button is pressed or not
int checkbutton(unsigned int portPin[2])
{
    unsigned int volatile *pGPIODATA = (unsigned int *) (portPin[0] + GPIODATA);
    return (*pGPIODATA & portPin[1]);

}

//sets up each button by assigning it to the appropriate port
void setUpButton(unsigned int port, unsigned int pinMask)
{
    unsigned int volatile *pRCGCGPIO = (unsigned int *) (RCGCGPIO);
    unsigned int volatile *pGPIODEN_port = (unsigned int *) (port + GPIODEN);

    *pRCGCGPIO = *pRCGCGPIO | pinMask;

    *pGPIODEN_port = *pGPIODEN_port | pinMask;
}

//increments the point value for each correct button hit
//uses rounds to keep count of double digit scores
void incrementPoints(int *pointsAddress, int *roundRoundsAddress, int increment)
{
    *pointsAddress += increment;
    if(*pointsAddress > 9)
    {
        *pointsAddress = 0;
        *roundRoundsAddress += 1;
    }
    if(*pointsAddress < 0)
    {
        if(*roundRoundsAddress > 0){
            *pointsAddress = 9;
        }
        else
        {
            *pointsAddress = 0;
        }
        *roundRoundsAddress -= 1;
        if(*roundRoundsAddress < 0)
            {
                *roundRoundsAddress = 0;
            }
    }
}



int main(void) {
    unsigned int volatile *pRCGCGPIO = (unsigned int *) (RCGCGPIO);

    int volatile switch_position;

    // points is the number of points the player scored in the current round, and ranges from 0 -9
    // clicked records whether or not the player pressed any button since the last go through the loop, 1 for a button press and 0 for no button press
    // timeOutSeconds stores the number of seconds a light can be left on before it times out and another light is randomly selected, because
    //                time(NULL) only returns integer number of seconds and this is used to check how long the light has been on this number must
    //                be a postive integer
    // round is the number of times the player has scored more than 9 points and thus reset the display to 0
    int points = 0, clicked = 0, timeOutSeconds = 1, round = 0;

    // offTime is the time the light will time out
    time_t currentTime, offTime;

    currentTime = time(NULL);

    // the time the light will be turned off
    offTime = currentTime + timeOutSeconds;


    setupBoard();
    displayNum(points);
    //RED LIGHT
    SetupDigitalGPIO(PortE, pin5, OUTPUT);
    unsigned int lightRed[2] = {PortE, pin5};

    setUpButton(PortE, pin4);
    unsigned int buttonRed[2] = {PortE, pin4};

    //BLUE LIGHT
    SetupDigitalGPIO(PortB, pin5, OUTPUT);
    unsigned int lightBlue[2] = {PortB, pin5};

    setUpButton(PortB, pin4);
    unsigned int buttonBlue[2] = {PortB, pin4};

    //GREEN LIGHT
    SetupDigitalGPIO(PortB, pin3, OUTPUT);
    unsigned int lightGreen[2] = {PortB, pin3};

    //Green Button Setup
    unsigned int volatile *pGPIODEN_PortE = (unsigned int *) (PortE + 0x51C);
    unsigned int volatile *pGPIODATA_PortE = (unsigned int *) (PortE + 0x3FC);
    unsigned int volatile *pGPIOPDR_PortE = (unsigned int *) (PortE + 0x514);
    *pGPIOPDR_PortE = *pGPIOPDR_PortE | 0x0010;
    *pGPIODEN_PortE = *pGPIODEN_PortE | 0x08;

    unsigned int buttonGreen[2] = {pGPIODATA_PortE, 0x08};


    turnOff(lightBlue);
    turnOff(lightGreen);
    turnOff(lightRed);

    // making arrays containg the lights and buttons to be randomly chosen from
    unsigned int lights[3] = {lightRed, lightBlue, lightGreen};
    unsigned int buttons[3] = {buttonRed, buttonBlue, buttonGreen};

    // initalizing the current light to green
    unsigned int currentLight = 2, randNum = 12342352345;

    //turns on the current light for the round
    turnOn(lights[currentLight]);

    //initalizes the array recording the button positions to all "up"
    unsigned int butonPositions[3] = {0,0,0};

    //initializes the number of wrong presses to 0
    int wrongPresses = 0;
    //start of game
    while (1)
    {
        // recording the time at the start of each loop
        currentTime = time(NULL);

        // turns off the light if it has been on longer than offtime, the maximum time a light cen be left unpressed before it times out
        if (currentTime >= offTime){
            turnOff(lights[currentLight]);

            //selects the next light randomly
            currentLight = randInt(3);

            // the "points + round*10" term is the factor by which to scale the delay until the next light turns on
            turnOnNextLight(points+ round*10, lights[currentLight]);

            // resets the time by which the light should time out
            offTime = time(NULL) + timeOutSeconds;

            // records whether or not button was pressed
            clicked = 0;

        }

        // (re)read the switch position...

        //if the current light is green
        if(currentLight == 2){
            //sets the switch position to the current position of the green light
            switch_position = *pGPIODATA_PortE & 0x08;
        }
        //if the current light is red or blue
        else{
            //sets the switch position to that of the current light
            switch_position = checkbutton(buttons[currentLight]);
        }

        // recording which buttons are currently pressed
        int index = 0;
        for(index = 0; index <3; index++){
            // if the button is red or blue
            if(index != 2){
                // stores 16 for pressed or 0 for not pressed in corresponding index for the red or blue button in butonPositions
                butonPositions[index] = checkbutton(buttons[index]);
            }
            // if the button is green
            else{
                // stores 8 for pressed or 0 for not pressed in corresponding index for the green button in butonPositions
                butonPositions[index] = *pGPIODATA_PortE & 0x08;
            }
        }

        wrongPresses = 0;
        // loops through the indexes of the lights
        for(index = 0; index < 3; index ++){
            //if a light is not the current light but its button is pressed, i.e. if the wrong button is pressed
            if(index != currentLight && butonPositions[index] != 0){
                wrongPresses += 1;
            }
        }

        // if the current light is pressed
        if (butonPositions[currentLight] != 0){
            // if the current light has not timed out and the player has not been recored clicking the corresponding button

            if (currentTime < offTime && clicked == 0){
                //turn off the current light
                turnOff(lights[currentLight]);

                //randomly chooses the next light
                currentLight = randInt(3);

                // record that the player presed a button
                clicked = 1;

                //increment the point count by 1
                incrementPoints(&points, &round, 1);

                //update the display with the new point count
                displayNum(points);

                turnOnNextLight(points + round*10,lights[currentLight]);

                offTime = time(NULL) + timeOutSeconds;

                // new light has light so reseting
                clicked = 0;

                // halts the program for 1-2 seconds then turns on the light again
            }
            else{
                incrementPoints(&points, &round, -1*wrongPresses);

                displayNum(points);
            }
        }
        else{
            incrementPoints(&points, &round, -1*wrongPresses);
            displayNum(points);
        }
    }

    return 0;
}

Music.c

C/C++
Use this to play music on a piezo buzzer.
/**
 * main.c
 */
int main(void)
{

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4_1 260
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978

    /*
     * First, define the pointers to the key registers needed for configuring
     * the general purpose I/Os for Port F.  Note that the use of volatile ensures that
     * the compiler always carries out the memory accesses, rather than optimizing
     * them out (for example, if the access is in a loop).
     */

    // pRCGCGPIO is a pointer to the General-Purpose Input/Output Run Mode Clock
    // Gating Control Register (p 340)
    unsigned int volatile *pRCGCGPIO = (unsigned int *) (0x400FE000 + 0x608);

    // pGPIOLOCK_PortF is a pointer to the GPIO Lock register for port F (p 684)
    unsigned int volatile *pGPIOLOCK_PortE = (unsigned int *)(0x40024000 + 0x520);

    // pGPIOCR_PortF is a pointer to the GPIO Commit register for port F (p 685)
    unsigned int volatile *pGPIOCR_PortE = (unsigned int *)(0x40024000 + 0x524);

    // pGPIODIR_PortF is a pointer to the GPIO Direction register for port F (p 663)
    unsigned int volatile *pGPIODIR_PortE = (unsigned int *) (0x40024000 + 0x400);

    // pGPIOAFSEL is a pointer to the GPIO Alternate Function Select register for port F (p 672)
    unsigned int volatile *pGPIOAFSEL_PortE = (unsigned int *) (0x40024000 + 0x420);

    // pGPIODEN is a pointer to the GPIO Digital Enable register for port F (p 683)
    unsigned int volatile *pGPIODEN_PortE = (unsigned int *) (0x40024000 + 0x51C);

    // pGPIODATA is a pointer to the GPIO Data register for port F (p 662)
    unsigned int volatile *pGPIODATA_PortE = (unsigned int *) (0x40024000 + 0x3FC);

    unsigned int volatile *pGPIOPDR_PortE = (unsigned int *) (0x40024000 + 0x514);

    /*
     * Now step through the cook book of steps.
     */

    // Step 1a: Turn on the clocks for port F.
    //  Note:   port F clocks are controlled by bit 5 (R5) of *pRCGCGPIO.
    //          In _binary_ this would correspond to a mask of 0b10.0000.
    //          In _hex_ this would correspond to a mask of 0x20
    *pRCGCGPIO = *pRCGCGPIO | 0x0010;

    // Step 1b: Check to be sure the clocks have started.
    //          This can take a few clock cycles.
    //          Keep checking bit 5 until it is no longer 0.
    while ( (*pRCGCGPIO & 0x0010) == 0 ) ; // Good thing this is volatile!

    // Step 2a: Unlock Port F
    //          Port F has NMI connected to PF0.  The M4 thus has a lock on this.
    //          The key to the lock is to write the value 0x4C4F434B to GPIOLOCK.
    // *pGPIOLOCK_PortE    = 0x4C4F434B;

    // Step 2b: Enable us to commit to all controls in Port F for PF[4:0]
    // *pGPIOCR_PortF = *pGPIOCR_PortF | 0x1F;

    // Let's use PF3 to control the green LED.  Therefore it should be
    // an output.

    // Step 3:  Set the direction of the pin to be used.  The pins
    //          can be configured as either input or output.
    //          In _binary_ this would correspond to a mask of 0b1000
    //          In _hex_ this would correspond ot a mask of 0x08;
    //output
    *pGPIODIR_PortE = *pGPIODIR_PortE | 0x08;
    //input
    *pGPIODIR_PortE = *pGPIODIR_PortE & 0xEF;
    *pGPIOPDR_PortE = *pGPIOPDR_PortE | 0x10;

    // Step 4:  Set the pin to be used as a general purpose I/O pin.
    //          This means we clear the bit corresponding to PF3.
    *pGPIOAFSEL_PortE = *pGPIOAFSEL_PortE & ~0x18;

    // Step 5:  Enable the pin
    *pGPIODEN_PortE = *pGPIODEN_PortE | 0x18;

    // Done!

    // Write a 1 to turn the LED on!
    //*pGPIODATA_PortE = *pGPIODATA_PortE | 0x08;
     int note;
     int time_counter;
     int pause;
     int pitch;
     int duration;
     int current_note;
     int melody[] =
     {
     NOTE_A4, NOTE_E4, NOTE_C4, NOTE_D4, NOTE_G4, NOTE_E4, NOTE_C4, NOTE_D4,
     NOTE_A4, NOTE_E4, NOTE_C4, NOTE_D4, NOTE_G4, NOTE_E4, NOTE_C4, NOTE_D4,
     NOTE_A4, NOTE_C4, NOTE_E4, NOTE_G4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_D4,
     NOTE_E4, NOTE_F4, NOTE_E4, NOTE_F4, NOTE_C4
     };
     int rhythm[] =
     {
     4, 4, 4, 4, 4, 4, 4, 4,
     4, 4, 4, 4, 4, 4, 4, 4,
     4, 4, 4, 4, 4, 4, 4, 4,
     4, 4, 4, 4, 1
     };
        while(1)
            {
            int size = sizeof(melody) / sizeof(int);
            for (current_note = 0; current_note < size; current_note++)
                {
                duration = 1000 / rhythm[current_note];
                for (time_counter=0; time_counter<duration*melody[current_note]/600; time_counter++) //time has to be adjusted for the pitch and modified by a factor of 300
                    {
                    pitch = melody[current_note];
                    //Square wave, pitch is hertz so dividing constant by pitch
                    for (note=0; note<200000/pitch; note++)
                        {
                        *pGPIODATA_PortE = *pGPIODATA_PortE | 0x08;
                        }
                    for (note=0; note<200000/pitch; note++)
                        {
                        *pGPIODATA_PortE = *pGPIODATA_PortE & ~0x08;
                        }
                    }
                }
            }
	return 0;
}

Credits

Emily Gianotti

Emily Gianotti

1 project • 2 followers
Jason Dong

Jason Dong

1 project • 1 follower
Rachel Gu

Rachel Gu

2 projects • 3 followers
Jonathan Thomas

Jonathan Thomas

1 project • 3 followers

Comments