;=============================================================================== ; Title: Audio Signal Transmitter ; ; Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved. ; ; Revision: ; 2022-02-24 : Initial version. ; ; Compiler: jalv25r6 ; ; Description: Generate two audio tones to be recorded on a cassette player. ; The audio tones are 1953 Hz for a '0' and 7812 Hz for a '1'. ; ; Sources: - ; ;=============================================================================== include 12f615 ; target PICmicro ; Use internal clock and internal reset. pragma target OSC INTOSC_NOCLKOUT ; Internal Clock pragma target PWRTE ENABLED ; Power up timer pragma target MCLR INTERNAL ; Reset internal pragma target WDT DISABLED ; No watchdog pragma target BROWNOUT ENABLED ; We use it since the power is not constant pragma target IOSCFS F8MHZ ; Set internal oscillator to 8 MHz pragma target clock 8_000_000 ; Oscillator frequency 8 MHz enable_digital_io() ; make all pins digital I/O _usec_delay(100_000) ; Give the hardware some time to stabilize ; Enable weak pull up for all ports . WPU = 0b0011_0111 OPTION_REG_NGPPU = FALSE ; The MOSFET is directly controller by the hardware PWM output so this is always ; pin CCP1 (P1A) which is pin 5. This output is active LOW. pin_CCP1_direction = output ; Set the PWM port to Output ; Activation pin. It is active low. alias activation is pin_GP5 pin_GP5_direction = input ; Pin 2. ; Specify the pin that is connected trigger. It is active LOW. alias trigger is pin_GP4 pin_GP4_direction = input ; Pin 3. ; ================== Constant and variable declarations ======================= const bit*2 LOW_TONE = 0b01 const bit*2 HIGH_TONE = 0b00 ; ========================= Main program starts here ========================== ; Set the correct Timer 2 value which is used to generate the PWM Period. T2CON_TMR2ON = FALSE ; Timer 2 off T2CON_TOUTPS = 0b0000 ; Postscaler is 1:1 T2CON_T2CKPS = 0b10 ; Prescaler divide by 16 PR2 = 255 ; Set CCP1CON to single output PWM Mode. CCP1CON_P1M = FALSE ; Set CCP1CON to be P1A active low in PWM Mode, audio signal to be recorded. CCP1CON_CCP1M = 0b1111 ; Register PR2 holds the PWM Timer Period using the following formula: ; PWM Period = (PR2 + 1) * 4 * Tosc * Timer2 prescale * Postscale value where ; Tosc = 1/Fosc and Fosc = 8.000.000 Hz. ; Postscale = 1 ; Setting the prescaler at 0b00 (devide by 1) gives for the high tone: ; (255 + 1) * 4 * 1/8.000.000 * 1 * 1 = 128 us Period Cycle (about 7812 Hz) ; Setting the prescaler at 0b01 (devide by 4) gives for the low tone: ; (255 + 1) * 4 * 1/8.000.000 * 4 * 1 = 512 us Period Cycle (about 1953 Hz) ; Set the correct Timer 2 value which is used to generate the PWM Period. ; We initialize with the low tone. T2CON_TMR2ON = FALSE ; Timer 2 off T2CON_TOUTPS = 0b0000 ; Postscaler is 1:1 T2CON_T2CKPS = LOW_TONE PR2 = 255 ; Set CCP1CON to single output PWM Mode. CCP1CON_P1M = FALSE ; Set CCP1CON to be P1A active low in PWM Mode (MOSFET control). CCP1CON_CCP1M = 0b1111 ; The Pulse Width uses the value in CCPR1L and two LSB's in DC1B to get 10 bit ; resolution. We ignore these two LSB's since their significance is small. ; So set the initial value of the Duty cycle in CCPR1L. CCPR1L = 128 ; About 50% duty cycle. forever loop ; When we are inactive, we disable the Timer so no tone is generated. T2CON_TMR2ON = FALSE while !activation loop ; Start Timer 2 (and so the PWM). T2CON_TMR2ON = TRUE ; Check if we need to transmit a low tone or a high tone. if !trigger then ; Active, high tone. T2CON_T2CKPS = HIGH_TONE ; Actual is 7230 Hz. else ; Not active, low tone. T2CON_T2CKPS = LOW_TONE ; Actual is 1230 Hz. end if end loop end loop