#include <system.h>
//Target PIC16F628A configuration word
#pragma DATA _CONFIG, _CP_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTOSC_OSC_NOCLKOUT
//Set clock frequency
#pragma CLOCK_FREQ 4000000
// Period = CCP1Period * PreScaler * clock
// 3.2 ms = 200 * 16 *1
// Duty Cycle
// Period * Duty% / 4 * Osc
// 3.2 * .5 = 1.6
// 1600 / 4 = 400
// 3.2 ms
/*
#define CCP1Period 199
#define CCP1DutyCy 399
*/
// 1.6 ms
/*
#define CCP1Period 99
#define CCP1DutyCy 199
*/
// 1.25 ms = 800 hz
/*
#define CCP1Period 77
#define CCP1DutyCy 155
*/
// Set Prescaler to 1:1
// 32 khz
/*
#define CCP1Period 30
#define CCP1DutyCy 63
*/
// 38 khz
#define CCP1Period 25
#define CCP1DutyCy 51
/*
// 40 khz
#define CCP1Period 24
#define CCP1DutyCy 49
*/
bit running = 0;
unsigned char turnon[6] = { 0x40, 4, 1, 0, 0xbc, 0xbd};
void interrupt( void )
{
// Handle timer1 interrupt
// Used to time the length of pulses
if( pir1.TMR1IF )
{
running = 0;
t1con.TMR1ON = 0; // Turn TIMER1 off
pir1.TMR1IF = 0; //clear timer 1 interrupt bit
}
}
void xmit_pulse(short micro_pulse)
{
static short clock_count;
clock_count = 65536 - micro_pulse;
LOBYTE( tmr1l, clock_count);
HIBYTE( tmr1h, clock_count);
pir1.TMR1IF = 0; // Reset overflow bit
t1con.TMR1ON = 1; // Turn TIMER1 on
running = 1;
trisb.3 = 0;
t2con.TMR2ON = 1;
while (running) ; // Wait for pulse time to end
t2con.TMR2ON = 0;
tmr2 = 0;
portb.3 = 0;
trisb.3 = 1;
}
void send_on(void) {
static char i;
static char j;
static char t;
static unsigned char *ovalue;
static unsigned char k;
// Send it 3 times
for (k = 0; k < 3; k++) {
ovalue = &turnon;
xmit_pulse(3550); // 4 ms header
delay_100us(10); // 1 ms
delay_10us(6); // .6 ms
for (i = 0; i < 6; i++) {
for (j = 8; j > 0; j--) {
t = j - 1;
if (test_bit(*ovalue, t)) {
// A one
xmit_pulse(512); // 400 micro s
delay_100us(10); // 1 ms
delay_10us(2); // .2 ms
}
else {
// A zero
xmit_pulse(512); // 400 micro s
delay_100us(3); // 400 micro s
}
}
ovalue++;
}
// End bit
xmit_pulse(400);
delay_ms(70);
}
}
void main( void )
{
static unsigned char Low;
static unsigned char High;
static unsigned int Duty = CCP1DutyCy;
ccp1con = 0; // CCP Module off
tmr2 = 0; // Clear Timer 2
//Configure port B
trisb = 0x00;
trisb.3 = 1;
option_reg.NOT_RBPU = 0;
//Initialize port B
portb = 0;
cmcon = 7; //disable comparators
//Set timer 1
//prescaler rate 1:1
//Internal clock (FOSC/4)
t1con = 00001000b;
// Configure Capture/Compare/PWM for PWM
// at 38khz.
//Set timer 2 prescaler rate
// T2CPS = 1:1
t2con = 01001000b;
//t2con = 0;
pr2 = CCP1Period;
Low = Duty & 3;
High = Duty >> 2;
ccpr1l = High;
ccp1con = 00001100b;
ccp1con.5 = Low.1;
ccp1con.4 = Low.0;
intcon.PEIE = 1; // Enable peripheral interrupts
intcon.GIE = 1; // Enable global interrupt
pie1.TMR1IE = 1; // Enable Timer 1 interrupts
// Main Loop
send_on();
while (1) {
}
}