Morse Code Power-Up counter is a program that uses Flash to keep track of the number of times the device is started. It blips the LED on P1.0 and sends a tone on P1.1 to send out this count. So, with a modification to the Development Stick that brings a wire out from the first discrete output pin, you can actually have audio. In my setup I used two resistors (1k & 330) to voltage divide the discrete output and feed the resultant signal into my computers AUX audio input. A filter cap might help, but the tone sounds pretty good to me.
Unlike the Morse Code thermometer I am using the PWM output for the audio output.
//******************************************************************************
// MSP430F20xx Demo - Timer_A, Toggle P1.0, CCR0 Cont. Mode ISR, DCO SMCLK
//
// Description: Clear the next bit in Segment C of Flash Memory every time
// the program begins to execute. This way it keeps track of each power up.
// Form the power-up count into CW and send out by flashing LED on p1.0 and
// making a tone (via TA) on p1.1
// By Bryon Wiscons
// June, 2007
//******************************************************************************
#include <msp430x20x3.h>
//Place the Morse codes into constant memory
// A Morse Code consists of one word allowing up to 8 dots and/or dashes
// a dot/dash occupies two bits 11 indicates a dash, 01 is a dot,
// 00 indicates no-more-dot/dash
/*
0 ----- 1111,1111,1100,0000 FFC0
1 .---- 0111,1111,1100,0000 7FC0
2 ..--- 0101,1111,1100,0000 5FC0
3 ...-- 0101,0111,1100,0000 57C0
4 ....- 0101,0101,1100,0000 55C0
5 ..... 0101,0101,0100,0000 5540
6 -.... 1101,0101,0100,0000 D540
7 --... 1111,0101,0100,0000 F540
8 ---.. 1111,1101,0100,0000 FD40
9 ----. 1111,1111,0100,0000 FF40
*/
#define interval 0x0020C49B // corresponds to 32.768
const unsigned int MorseDigit[10] = {0xFFC0,0x7FC0,0x5FC0,0x57C0,0x55C0,
0x5540,0xD540,0xF540,0xFD40,0xFF40};
int seccnt,PUcnt;
unsigned long lcnt;
unsigned int codeInProg;
int whichdig;
void write_SegC (char value,unsigned char adr);
void erase_SegC (int Val);
char refbit(int i);
void clrbit(int i);
unsigned int nextCode(void);
void main(void)
{
unsigned int i;
WDTCTL = WDTPW | WDTTMSEL; // Puts in interval time mode
BCSCTL1=CALBC1_1MHZ;
DCOCTL=CALDCO_1MHZ;
P1DIR |= 0x03; // Set P1.0&P1.1 to output direction
P1OUT &= 0xFE; // Clear P1.0 LED off
IE1 |= WDTIE; //for F2013, WDTIE bit is in IE1
P1SEL |= 0x02; // P1.1 option select
CCTL0 = OUTMOD_4; // CCR0 toggle mode
CCR0 = 62;
TACTL = TASSEL_2; // SMCLK, off mode
FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator
// Now determine the previous PUcnt (Power Up count) by scanning Flash Memory
// for the first non-zero bit.
for (i=0; i<512; i++)
if (refbit(i))
{
PUcnt=i;
break;
}
//Having found PUcnt, clear that bit for next time.
clrbit(PUcnt);
//whichdig = 100 indicates that the 100's digit should be returned first.
whichdig=100;
//nextCode will then set whichfig to 10 and eventually to 1
seccnt=PUcnt;
codeInProg=nextCode();
__bis_SR_register(LPM0_bits|GIE); // CPU off so enter LPM0 w/ interrupt
}
unsigned int Pausecnt,soundON;
#pragma vector=WDT_VECTOR
__interrupt void inthandler_ (void)
{
lcnt +=interval;
if (soundON)
{
TACTL = TASSEL_2 + MC_3; // SMCLK, up-downmode
P1OUT = 0x01; // Turn ON P1.0
}
else
{
P1OUT = 0x00; // Turn OFF P1.0
TACTL = TASSEL_2; // SMCLK, off mode
}
if (lcnt > 0x00640000) //corresponds to 100.0000
{
lcnt-=0x00640000;
if (Pausecnt)
{
Pausecnt--;
if (!codeInProg)
__bis_SR_register(LPM4_bits);
return;
}
}
else return;
if (codeInProg&0xC000)
{
soundON=codeInProg&0xC000;
codeInProg=(codeInProg&0x3FFF)| ((codeInProg-0x4000)&0xC000);
}
else
{
soundON=0;
codeInProg=codeInProg<<2;
if (!(codeInProg&0xC000))
{
Pausecnt=3;
codeInProg=nextCode();
}
}
}
void write_SegC (char value,unsigned char adr)
{
char *Flash_ptr; // Flash pointer
Flash_ptr = (char *) 0x1040; // Initialize Flash pointer
FCTL3 = FWKEY; // Clear Lock bit
Flash_ptr += adr; // Initialize Flash pointer
FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
*Flash_ptr = value; // Write value to flash
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCK; // Set LOCK bit
}
void erase_SegC (int Val)
{
char *Flash_ptr; // Flash pointer
Flash_ptr = (char *) 0x1040; // Initialize Flash pointer
FCTL1 = FWKEY + ERASE; // Set Erase bit
FCTL3 = FWKEY; // Clear Lock bit
*Flash_ptr = 0; // Dummy write to erase Flash segment
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCK; // Set LOCK bit
}
char refbit(int i)
{
char w,b;
char *Flash_ptr; // Flash pointer
w=i >>3;
b=1<<(i-(w*8));
Flash_ptr = (char *) 0x1040+w;
return *Flash_ptr&b;
}
void clrbit(int i)
{
char w,b;
w=i >>3;
b=0xFE<<(i-(w*8));
write_SegC(b,w);
}
unsigned int nextCode(void)
{
int stat,result=0;
if (whichdig==100)
if (seccnt>=100)
stat=1;
else
if (seccnt>10)
stat=2;
else
stat=3;
else
if (whichdig==10)
stat=2;
else
if (whichdig==1)
stat=3;
switch (stat)
{case 1 :
{
whichdig=10;
result= seccnt / 100;
seccnt = seccnt-result*100;
break;
}
case 2:
{
whichdig=1;
result=seccnt/10;
seccnt=seccnt-result*10;
break;
}
case 3 :
{
whichdig=0;
result=seccnt;
seccnt=0;
break;
}
default :
return 0;
}
return MorseDigit[result];
}
|