PIC16C505 - Beep
// TONE_Q.C (PIC16C505), CCS PCB
//
// Intended for possible use with frost alarm in place of serial output
// to serial LCD or to PC Com Port.
//
// When input PORTB3 is at ground, T_threshold is sounded on speaker on output
// PORTC0. When input PORTB3 is not at ground, the current value of T_C is output on
// the speaker.
//
// In sounding the quantity, a long 500 Hz tone indicates a minus. Each digit is
// sounded as a series of 250 ms beeps with an interdigit delay of 1 second.
//
//
// GRD --- \---- PORTB3 (internal weak pull-up)
//
// PORTC0 ---------||--- SPKR --- GRD
// + 47 uFd
//
// Use internal RC oscillator. Internal /MCLR. Debugged using RICE-17A, July 18, '01
//
// copyright, Peter H. Anderson, Elmore, VT, July, '01
#case
#device PIC16C505 *=8
#include <defs_505.h>
#include <delay.h>
#define TRUE !0
#define FALSE 0
void beep(long ms);
void beep_q(byte q, byte minus_flag);
void main(void)
{
byte T_threshold = 34, T_C, minus_flag, n;
byte const T_C_array[5] = {-5, 0, 1, 25, 70}; // some dummy temperatures
DIRB = 0x3f;
DIRC = 0x3f;
not_rbpu = 0;
#asm
MOVF OPTIONS, W
OPTION
#endasm
while(1)
{
if(!portb3) // if switch at ground
{
beep_q(T_threshold, FALSE);
delay_ms(5000);
}
else
{
for (n = 0; n< 5; n++) // beep each temperature
{
T_C = T_C_array[n];
if (T_C & 0x80) // its negative
{
minus_flag = TRUE;
T_C = (~T_C) + 1;
}
else
{
minus_flag = FALSE;
}
beep_q(T_C, minus_flag);
delay_ms(1000);
}
}
delay_ms(5000);
}
}
void beep_q(byte q, byte minus_flag)
{
byte n, digit;
if (minus_flag)
{
beep(500);
delay_ms(1000); // long delay to indicate minus
}
digit = q/10; // number of tens
if (digit) // if non zero
{
for (n=0; n<digit; n++)
{
beep(250);
delay_ms(250);
}
delay_ms(1000); // separation between digits
}
digit = q%10;
if (!digit)
{
digit = 10;
}
for (n=0; n<digit; n++)
{
beep(250);
delay_ms(250);
}
delay_ms(1000); // separation between digits
}
void beep(long ms)
{
byte tmr0_old, tmr0_new;
portc0 = 0;
dirc0 = 0;
#asm
MOVF DIRC, W
TRIS PORTC
#endasm
t0cs = 0; // internal fosc / 4
psa = 0;
ps2 = 0; // prescale of 1:4, thus rollover every ms
ps1 = 0;
ps0 = 1;
#asm
MOVF OPTIONS, W
OPTION
#endasm
TMR0 = 0x00;
tmr0_old = 0;
while(ms)
{
tmr0_new = TMR0;
if ((tmr0_new < 0x80) && (tmr0_old >= 0x80)) // if there was a rollover
{
portc0 = !portc0; // toggle speaker output
--ms;
}
tmr0_old = tmr0_new;
}
portc0 = 0;
}
#include <delay.c>