16.8.2019
Kód je uveden níže a taktéž je možné si ho stáhnout. Použil jsem vývojové prostředí MPLAB X a překladač XC8.
// CONFIG1H
#pragma config FOSC = IRC
#pragma config PLLEN = OFF
#pragma config PCLKEN = ON
#pragma config FCMEN = OFF
#pragma config IESO = OFF
// CONFIG2L
#pragma config PWRTEN = OFF
#pragma config BOREN = SBORDIS
#pragma config BORV = 19
// CONFIG2H
#pragma config WDTEN = OFF
#pragma config WDTPS = 32768
// CONFIG3H
#pragma config HFOFST = ON
#pragma config MCLRE = OFF
// CONFIG4L
#pragma config STVREN = ON
#pragma config LVP = OFF
#pragma config BBSIZ = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
// CONFIG5L
#pragma config CP0 = OFF
#pragma config CP1 = OFF
// CONFIG5H
#pragma config CPB = OFF
#pragma config CPD = OFF
// CONFIG6L
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
// CONFIG6H
#pragma config WRTC = OFF
#pragma config WRTB = OFF
#pragma config WRTD = OFF
// CONFIG7L
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
// CONFIG7H
#pragma config EBTRB = OFF
#define _XTAL_FREQ 2000000
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char BYTE;
volatile unsigned int c512us;
BYTE x[32];
volatile BYTE keypressed;
volatile BYTE data;
void burst9ms()
{
c512us=0;
T0CON=0b11001000;//timer0 ON
T2CON=0b0000100;//timer2 ON
CCP1CON=0b00011100;//pwm ON
INTCONbits.TMR0IF=0;
INTCONbits.GIE=1;
while (c512us<17)
;
INTCONbits.GIE=0;
INTCONbits.TMR0IF=0;
__delay_us(290);
T0CON=0b01001000;//timer0 OFF
T2CON=0b0000000;//timer2 OFF
CCP1CON=0b00010000;//pwm OFF
}
void burst560us()
{
c512us=0;
T0CON=0b11001000;//timer0 ON
T2CON=0b0000100;//timer2 ON
CCP1CON=0b00011100;//pwm ON
INTCONbits.TMR0IF=0;
INTCONbits.GIE=1;
while (c512us<1)
;
INTCONbits.GIE=0;
INTCONbits.TMR0IF=0;
__delay_us(44);
T0CON=0b01001000;//timer0 OFF
T2CON=0b0000000;//timer2 OFF
CCP1CON=0b00010000;//pwm OFF
}
void transmitCode(BYTE *code)
{
memset(x,0,32);
for (BYTE i=0;i<4;i++)
for (BYTE j=0;j<8;j++)
x[i*8+j]=((code[i]>>j)&1);
burst9ms();
__delay_us(4500);
for (BYTE i=0;i<32;i++)
{
burst560us();
if (x[i])
__delay_us(1690);
else
__delay_us(565);
}
burst560us();
__delay_us(1000);
}
void main(void)
{
OSCCON=0b01000000;
TRISB=TRISC=0;
LATB=LATC=0;
ANSEL=0;
TRISA=0x37;
WPUA=0x3F;
INTCON2bits.RABPU=0;
IOCA=0x3F;
RCONbits.IPEN=0;
INTCONbits.GIE=0;
//timer0
T0CON=0b01001000;
INTCONbits.TMR0IE=1;
INTCONbits.TMR0IF=0;
//timer2
//PR2 = (0.000026316 * 2000000)/(4 * 1) - 1 = 12.158
T2CON=0b0000000;
PR2=12;
//pwm
//pulse width = (1/2000000) * PW * prescale
//pulse width = 1/4 period = 6.579 us
//PW = (0.000006759 * 2000000) / 1 = 13.158
CCP1CON=0b00010000;
CCPR1L=0b00000011;
PSTRCON=1;//pwm on RC5
ECCP1AS=0;//autoshutdown off
BYTE key_MUTE[4]={0x00,0xFF,0x19,0xE6};
BYTE key_VOLUME_UP[4]={0x00,0xFF,0x10,0xEF};
BYTE key_VOLUME_DOWN[4]={0x00,0xFF,0x11,0xEE};
BYTE key_CHANNEL_NEXT[4]={0x00,0xFF,0x0B,0xF4};
BYTE key_CHANNEL_PREV[4]={0x00,0xFF,0x0E,0xF1};
BYTE key_INFO[4]={0x00,0xFF,0x44,0xBB};
BYTE *key=NULL;
keypressed=0;
data=0;
INTCONbits.RABIF=0;
INTCONbits.RABIE=1;
INTCONbits.GIE=1;
SLEEP();
while (1)
{
if (keypressed)
{
INTCONbits.GIE=0;
switch (data)
{
case 0x3E:key=key_CHANNEL_NEXT;break;
case 0x3D:key=key_CHANNEL_PREV;break;
case 0x3B:key=key_VOLUME_UP;break;
case 0x37:key=key_VOLUME_DOWN;break;
case 0x2F:key=key_MUTE;break;
case 0x1F:key=key_INFO;break;
default:key=NULL;break;
}
if (key)
transmitCode(key);
__delay_ms(100);
keypressed=0;
data=0;
INTCONbits.RABIF=0;
INTCONbits.GIE=1;
SLEEP();
}
}
}
void interrupt isr(void)
{
if (INTCONbits.TMR0IE && INTCONbits.TMR0IF)//timer0, 512 us passed
{
++c512us;
INTCONbits.TMR0IF=0;
}
if (INTCONbits.RABIE && INTCONbits.RABIF)//interrupt on change
{
data=PORTA;
if (data!=0x3F)
keypressed=1;
INTCONbits.RABIF=0;
}
}