We learned how to program the HCS12 timer to generate a user-selected sequence of audio waveforms each with a specific frequency and time duration. We now understand how microcontrollers interact with electromechanical devices.
In this lab, we took a look at the internal speaker on the Dragon Board. We changed the output frequencies to make it play a ‘song’.
The Programmer is able to program specific frequency values that are based off of the internal clock of the microcontroller and in tern make notes. If these frequency notes are paired with a delay cycle, and played in a specific order for the correct length of time, it will sound like a song is being played.
There will be labs and future problems where the programmer needs to change between different preset values. In this lab it was sound frequencies, but it could possibly be LED brightness, radio signal or a number of other things.
Codewarrior v. 5.9.0
Parts:
Speakers use ceramic resonators or electromagnets to drive an acoustic diaphragm. The diaphragm oscillates to produce sound waves. The speaker on your demo board is connected to Port P, pin 5, so we use the channel 5 output from the PWM unit to generate audible sounds (see Figure 1). The pitch of each sound is to closely match that of a note on the 7-tone musical scale (see Table 1). By having the program periodically adjust the value in the PWMPER register, a complete melody can be played.
The small frequency separation between adjacent notes requires a more precise resolution for the programmed waveform period than is possible with an 8-bit PWMPER register. The remedy is to divide a relatively high clock frequency of 12 MHz (after pre-scale) by a 16-bit period value to get 28 times better frequency resolution. This is done in the HCS12 by concatenating two neighboring channels of the PWM in the PWMCTL register, in this case channels 4 and 5.
The higher-indexed channel (5’s) pin is used to output the waveform while the lower-indexed channel (4’s) enable and polarity registers are used to control the functions. The 16-bits for both period and duty cycle are loaded into two consecutive PWMPER and PWMDTY register addresses, starting with the address belonging to the lower-indexed channel (PWMPER4 and PWMDTY4).
Table 1 - Standard Musical Note Frequencies
PROCEDURE
NOTE: YOU MUST SET JUMPER “J26” TO “PP5”ON DRAGON BOARD TO HEAR MUSIC! THIS CONNECTS THE HCS12 PP5 PIN OUTPUT TO THE SPEAKER
// 340_lab7_1 - Part C - Codewarrior v. 5.9.0 - Tested 6-15-2009kj
// Ascending/descending musical (octave) scale, once every 4 sec.
/* common defines and macros */
#include /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dg256b"
//symbols – [pitch = 12MHz/(audio frequency in Hz)]
#define C4 22934
#define D4 20431
#define E4 18202
#define F4 17181
#define G4 15306
#define A4 13636
#define B4 12149
#define C5 11467
#define Q 250
#define H 500
//structure definition, type definition
struct note{ // contains pitch and note length
unsigned short pitch; // name of note (to be converted into frequency)
unsigned int duration; // H = half note, Q = quarter note, E = eighth note
};
typedef struct note note_type;
//global - creates a table called song in memory
note_type song[14] = {{C4,H},{D4,Q},{E4,Q},{F4,Q},{G4,Q},{A4,Q},{B4,Q},
{C5,H},{B4,Q},{A4,Q},{G4,Q},{F4,Q},{E4,Q},{D4,Q}}; {B4,Q},{A4,Q},{G4,Q},{F4,Q},{E4,Q},{D4,Q}}; {B4,Q},{A4,Q},{G4,Q},{F4,Q},{E4,Q},{D4,Q}};
//function prototypes
void init_PWM(void);
void play(unsigned short);
void delay(int);
/************main************/
void main(){
int i;
init_PWM( );
while(1){ // loop to repeat the tune
for(i=0;i<14;i++){
play(song[i].pitch);
delay(song[i].duration); //...keep sounding for full length of note
}
}
}
/*********functions*********/
void init_PWM( ){
PWMCLK = 0x00; // Ch. 4 - Ch. 5 source is clock A
PWMPOL = 0x20; // initial HIGH output on ch. 5
PWMPRCLK = 0x01; // Clk A pre-scale = 2 (PWM clock = 24MHz/2 = 12.0 MHz)
PWMCTL = 0x40; // CON45 = '1': 16-bit PWM counter, period and duty regs.
PWME |= 0x20; // turn-on PWM ch. 5
}
void play(unsigned short notepitch){
PWMPER45 = notepitch; // 12 MHz/note = audio frequency (in Hz)
PWMDTY45 = (notepitch/2); // (squarewave -- 0.50 x notepitch)
}
void delay(int noteduration){ // delay for 'noteduration' msecs
int i,j;
for(i=0; i
for(j=0; j<4000; j++);
}
/********** end of file *******/
Design Project (18 points)
Demonstrate to your instructor (onsite students) your speaker playing a short, recognizable tune that you write (25 notes or so, such as “Mary had a Little Lamb,” “Happy Birthday,” etc.).
The tune should repeat in a loop indefinitely. Comment key lines of code in your program (.c file) and answer the question below. Online students should submit a copy of your code with your lab report.
Lab 7 – Instructor Sign-off______________________
-
TROUBLESHOOTING
Describe any problems encountered and how those problems were solved
The hardest part of this lab is making sure that you place the right notes in the right octave for the correct duration of time. It is not too difficult; it is just something the programmer has to be wary of when writing the code.
-
QUESTION
-
Given C7 = 8372.0 Hz what value would C7 need to be associated with (in #define C7)? Assume all other timer values are the same as in Fig. 4 and show your work.
Using the equation from above for Symbols,
[pitch = 12MHz/(audio frequency in Hz)
//(12M/8372.0)2 = 3866.69
#define C7 3867
Mary Had a Little Lamb code
//jumper J26 to connect speaker to pin PP5
#include /* common defines and macros */
#include /* derivative-specific definitions */
#pragma LINK_INFO DERIVATIVE "mc9s12dg256b"
//symbols
#define C3 45867
#define D3 40863
#define E3 36404
#define F3 34361
#define G3 30613
#define A3 27273
#define B3 24297
#define C4 22934
#define D4 20431
#define E4 18202
#define F4 17181
#define G4 15306
#define A4 13636
#define B4 12149
#define C5 11467
#define Qu 60000
#define Re 20
#define Q 250
#define H 500
#define W 1000
//structure definition
struct note{
unsigned short pitch;
unsigned int duration;
};
typedef struct note note_type;
//global
note_type song[52] = {{B3,Q},{Qu,Re},{A3,Q},{Qu,Re},{G3,Q},{Qu,Re},
{A3,Q},{Qu,Re},{B3,Q},{Qu,Re},{B3,Q},{Qu,Re},
{B3,H},{Qu,Re},{A3,Q},{Qu,Re},{A3,Q},{Qu,Re},
{A3,H},{Qu,Re},{B3,Q},{Qu,Re},{D4,Q},{Qu,Re},
{D4,H},{Qu,Re},{B3,Q},{Qu,Re},{A3,Q},{Qu,Re},
{G3,Q},{Qu,Re},{A3,Q},{Qu,Re},{B3,Q},{Qu,Re},
{B3,Q},{Qu,Re},{B3,Q},{Qu,Re},{B3,Q},{Qu,Re},
{A3,Q},{Qu,Re},{A3,Q},{Qu,Re},{B3,Q},{Qu,Re},
{A3,Q},{Qu,Re},{G3,W},{Qu,Re}};
//funtion prototypes
void init_PWM(void);
void play(unsigned short);
void delay(int);
//MAIN
void main(){
int i;
init_PWM();
while(1){
for (;;){
delay(80);
for(i=0;i<52;i++){
play(song[i].pitch);
delay(song[i].duration);
}
}
}
}
//functions
void init_PWM(){
PWMCLK = 0x00;
PWMPOL = 0x20;
PWMPRCLK = 0x01;
PWMCTL = 0x40;
PWME |= 0x20;
}
void play(unsigned short notepitch){
PWMPER45 = notepitch;
PWMDTY45 = (notepitch/2);
}
void delay(int noteduration){
int i,j;
for(i=0; ifor(j=0; j<4000; j++);
}
ECET-340 DeVry University 7-17-2009 kj
Share with your friends: