veiner.eu
ÚVODZAPOJENÍ
PROGRAM

Náhradní dálkový TV ovladač - program

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;
  }
}