#include <pic.h>
void Device_Init(void)
{
//--Инициализация портов ввода/вывода--//
TRISA=0b00001111; //RA0,RA1,RA2,RA3 - входы
TRISB=0b00000001; //RB0 - выход
ANSEL=0x0;
ANSELH=0x0;
TRISC=0x0; //PORTC - выходы
PORTA=0x0; //запись нулей в PORTA
PORTB=0x0; //запись нулей в PORTB
PORTC=0x0; //запись нулей в PORTC
//--------------------------------------//
//--Инициализация модуля ШИМ--//
CCP1CON=0b00001100;
T2CON=0x0;
CCPR1L=0b00000111;
PR2=28; //частота 36 кГц
TMR2ON=1;
//----------------------------//
//--Настройка прерывания--//
GIE=0; //глобальное выключение прерываний
PEIE=0; //выключить все прерывания от перефирии
TMR2IE=1; //включить прерывание от таймера
PEIE=1; //включить прерывания от периферии
RBIE=1;
RBIF=0;
IOCB0=1; //включить прерывание
GIE=1; //включить глобальные прерывания
//------------------------//
}.
Содержимое файла main.c.
#include <pic.h>
unsigned int one_ms,keycode,block_keyboard,scan_state,bit_transfer=0;
unsigned int button_pressed,keycode_BUFF,keyboard_delay;
unsigned int start_scan,cycle_counter=0,half_bit=1,shift_counter=0;
unsigned int teach=0,button,ON_flag;
long data_out=0;
long data_out_0,data_out_1,data_out_2,data_out_3;
long data_in,r_data;
unsigned int protocol_RC5=0,protocol_SIRC=0,protocol_SAM=1;
unsigned int RC5_cycle_counter=0,SIRC_cycle_counter=0;
unsigned int RC5_input_bits_counter=0,SIRC_input_bits_counter=0;
unsigned int SAM_input_bits_counter=0,receive_bits=0,receive_bits_counter=0;
unsigned int RC5_shift_flag=0;
unsigned int bit_out,SIRC_shift_flag=0,SAM_shift_flag=0;
//--Прототипы функций--//
void Device_Init(void);
void keyboard(void);
void timer(void);
void execute_keycode(void);
void eprom_write(unsigned char,unsigned char);
eprom_read(unsigned char);
void transmitt_data(void);
//-----------------------------------
void main(void)
{
Device_Init(); //инициализация устройства
for(;;)
{
keyboard();
}
}
void interrupt TMR(void) //подпрограмма прерывания
{
if(TMR2IF)
{
if(teach==0)
{
if(protocol_RC5==1)
{
if(RC5_shift_flag==1)
{
bit_out=data_out_RC5>>shift_counter&1;
RC5_shift_flag=0;
shift_counter++;
if(shift_counter>14)
shift_counter=0;
}
if(bit_out==1)
{
if(cycle_counter<32)
TRISC2=0;
else if(cycle_counter>32&&cycle_counter<64)
TRISC2=1;
if(cycle_counter>32)
{
cycle_counter=0;
RC5_shift_flag=1;
}
}
if(bit_out==0)
{
if(cycle_counter<32)
TRISC2=1;
else if(cycle_counter>32&&cycle_counter<64)
TRISC2=0;
if(cycle_counter>32)
{
cycle_counter=0;
RC5_shift_flag=1;
}
}
}
if(protocol_SIRC==1)
{
if(SIRC_shift_flag==1)
{
bit_out=data_out_SIRC>>shift_counter&1;
SIRC_shift_flag=0;
shift_counter++;
if(shift_counter>12)
shift_counter=0;
}
if(bit_out==1)
{
if(cycle_counter<43)
TRISC2=1;
else if(cycle_counter>43&&cycle_counter<64)
TRISC2=0;
if(cycle_counter>64)
{
cycle_counter=0;
SIRC_shift_flag=1;
}
}
if(bit_out==0)
{
if(cycle_counter<21)
TRISC2=1;
else if(cycle_counter>21&&cycle_counter<42)
TRISC2=0;
if(cycle_counter>42)
{
cycle_counter=0;
SIRC_shift_flag=1;
}
}
}
if(protocol_SAM==1)
{
if(SAM_shift_flag==1)
{
bit_out=data_out_SAM>>shift_counter&1;
SAM_shift_flag=0;
shift_counter++;
if(shift_counter>=32)
shift_counter=0;
}
if(bit_out==1)
{
if(cycle_counter<23)
TRISC2=1;
else if(cycle_counter>23&&cycle_counter<77)
TRISC2=1;
if(cycle_counter>77)
{
cycle_counter=0;
SAM_shift_flag=1;
}
}
else if(bit_out==0)
{
if(cycle_counter<23)
TRISC2=1;
else if(cycle_counter>=23&&cycle_counter<46)
TRISC2=0;
if(cycle_counter>=46)
{
cycle_counter=0;
SAM_shift_flag=1;
}
}
}
TMR2IF=0;
cycle_counter++;
}
if(teach==1)
{
if(protocol_RC5)
{
receive_bits_counter++;
if(receive_bits_counter>2)
{
RC5_input_bits_counter++;
if(RC5_input_bits_counter>14)
{
RC5_input_bits_counter=0;
data_in_flag=1;
data_in_0=data_in&0xFF;
data_in_1=(data_in>>8)&0xFF;
}
if(receive_bits==0b01)
data_in=data_in+(1<<(14-RC5_input_bits_counter));
else if(receive_bits==0b10)
data_in=data_in+(0<<(14-RC5_input_bits_counter));
receive_bits=0;
}
receive_bits=receive_bits+RB0<<(2-receive_bits_counter);
}
if(protocol_SIRC==1)
{
receive_bits_counter++;
if(receive_bits_counter>2)
{
SIRC_input_bits_counter++;
if(SIRC_input_bits_counter>12)
{
SIRC_input_bits_counter=0;
data_in_flag=1;
data_in_0=data_in&0xFF;
data_in_1=(data_in>>8)&0xFF;
}
if(receive_bits==0b11)
data_in=data_in+(1<<(12-SIRC_input_bits_counter));
else if(receive_bits==0b10)
data_in=data_in+(0<<(12-SIRC_input_bits_counter));
receive_bits=0;
}
receive_bits=receive_bits+RB0<<(2-receive_bits_counter);
}
if(protocol_SAM==1)
{
receive_bits_counter++;
if(receive_bits_counter>2)
{
SAM_input_bits_counter++;
if(SAM_input_bits_counter>32)
{
SIRC_input_bits_counter=0;
data_in_flag=1;
data_in_0=data_in&0xFF;
data_in_1=(data_in>>8)&0xFF;
data_in_2=(data_in>>16)&0xFF;
data_in_3=(data_in>>24)&0xFF;
}
if(receive_bits==0b100)
data_in=data_in+(1<<(32-SIRC_input_bits_counter));
else if(receive_bits==0b101)
data_in=data_in+(0<<(32-SIRC_input_bits_counter));
receive_bits=0;
}
receive_bits=receive_bits+RB0<<(2-receive_bits_counter);
}
}
}
if(RBIF && teach)
{
RBIF=0;
RBIE=0;
if(protocol_RC5)
PR2=889;
else if(protocol_SIRC)
PR2=600;
else if(protocol_SAM)
PR2=650;
TMR2IE=1;
}
}
void keyboard(void)
{
int y;
//----------------------------------
// RA7-1,5,9,P+ - выход
// RA3-1 - вход
// RA2-5 - вход
// RA1-9 - вход
// RA0-P+ - вход
//----------------------------------
// RA6-2,6,0,P- - выход
// RA3-2 - вход
// RA2-6 - вход
// RA1-0 - вход
// RA0-P- - вход
//----------------------------------
// RA5-3,7,vol+,on - выход
// RA3-3 - вход
// RA2-7 - вход
// RA1-vol+ - вход
// RA0-on - вход
//----------------------------------
// RA4-4,8,vol-,teach - выход
// RA3-4 - вход
// RA2-8 - вход
// RA1-vol- - вход
// RA0-teach - вход
//----------------------------------
RA7=1; //выставить единицу порт RA7
RA6=1;
RA5=1;
RA4=1;
start_scan=1;
for(y=0;y<10000;y++); //временная задержка
if(PORTA==0xF0)
block_keyboard=0;
if(block_keyboard==0&&PORTA!=0xF0) //если кнопка нажата, начать //сканирование
{
block_keyboard=1;
}
if(start_scan==1) //сканирование клавиатуры
{
switch(scan_state){
case 0:
RA7=1;
RA6=0;
RA5=0;
RA4=0;
for(y=0;y<10000;y++);
break;
case 1:
RA7=0;
RA6=1;
RA5=0;
RA4=0;
for(y=0;y<10000;y++);
break;
case 2:
RA7=0;
RA6=0;
RA5=1;
RA4=0;
for(y=0;y<10000;y++);
break;
case 3:
RA7=0;
RA6=0;
RA5=0;
RA4=1;
for(y=0;y<10000;y++);
scan_state=-1;
start_scan=0;
break;
}
keycode=(PORTA<<1)+(RB0>>1)&1; //получить код кнопки
execute_keycode(); //выполнить код кнопки
scan_state++;
}
}
void execute_keycode(void)
{
if(keycode==0x110) //1
{
if(teach==0)
{
data_out_0=eprom_read(0x0);
data_out_1=eprom_read(0x1);
data_out_2=eprom_read(0x2);
data_out_3=eprom_read(0x3);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x0);
eprom_write(data_in_1,0x1);
eprom_write(data_in_2,0x2);
eprom_write(data_in_3,0x3);
data_in_flag=0;
}
}
else if(keycode==0x90) //2
{
if(teach==0)
{
data_out_0=eprom_read(0x4);
data_out_1=eprom_read(0x5);
data_out_2=eprom_read(0x6);
data_out_3=eprom_read(0x7);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x4);
eprom_write(data_in_1,0x5);
eprom_write(data_in_2,0x6);
eprom_write(data_in_3,0x7);
data_in_flag=0;
}
}
else if(keycode==0x50) //3
{
if(teach==0)
{
data_out_0=eprom_read(0x8);
data_out_1=eprom_read(0x9);
data_out_2=eprom_read(0xa);
data_out_3=eprom_read(0xb);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x8);
eprom_write(data_in_1,0x9);
eprom_write(data_in_2,0xa);
eprom_write(data_in_3,0xb);
data_in_flag=0;
}
}
else if(keycode==0x30) //4
{
if(teach==0)
{
data_out_0=eprom_read(0xc);
data_out_1=eprom_read(0xd);
data_out_2=eprom_read(0xe);
data_out_3=eprom_read(0xf);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0xc);
eprom_write(data_in_1,0xd);
eprom_write(data_in_2,0xe);
eprom_write(data_in_3,0xf);
data_in_flag=0;
}
}
else if(keycode==0x108) //5
{
if(teach==0)
{
data_out_0=eprom_read(0x10);
data_out_1=eprom_read(0x11);
data_out_2=eprom_read(0x12);
data_out_3=eprom_read(0x13);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x10);
eprom_write(data_in_1,0x11);
eprom_write(data_in_2,0x12);
eprom_write(data_in_3,0x13);
data_in_flag=0;
}
}
else if(keycode==0x88) //6
{
if(teach==0)
{
data_out_0=eprom_read(0x14);
data_out_1=eprom_read(0x15);
data_out_2=eprom_read(0x16);
data_out_3=eprom_read(0x17);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x14);
eprom_write(data_in_1,0x15);
eprom_write(data_in_2,0x16);
eprom_write(data_in_3,0x17);
data_in_flag=0;
}
}
else if(keycode==0x48) //7
{
if(teach==0)
{
data_out_0=eprom_read(0x18);
data_out_1=eprom_read(0x19);
data_out_2=eprom_read(0x1A);
data_out_3=eprom_read(0x1B);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x18);
eprom_write(data_in_1,0x19);
eprom_write(data_in_2,0x1A);
eprom_write(data_in_3,0x1B);
data_in_flag=0;
}
}
else if(keycode==0x28) //8
{
if(teach==0)
{
data_out_0=eprom_read(0x1c);
data_out_1=eprom_read(0x1D);
data_out_2=eprom_read(0x1E);
data_out_3=eprom_read(0x1F);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x1c);
eprom_write(data_in_1,0x1d);
eprom_write(data_in_2,0x1e);
eprom_write(data_in_3,0x1f);
data_in_flag=0;
}
}
else if(keycode==0x104) //9
{
if(teach==0)
{
data_out_0=eprom_read(0x20);
data_out_1=eprom_read(0x21);
data_out_2=eprom_read(0x22);
data_out_3=eprom_read(0x23);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x20);
eprom_write(data_in_1,0x21);
eprom_write(data_in_2,0x22);
eprom_write(data_in_3,0x23);
data_in_flag=0;
}
}
else if(keycode==0x84) //0
{
if(teach==0)
{
data_out_0=eprom_read(0x24);
data_out_1=eprom_read(0x25);
data_out_2=eprom_read(0x26);
data_out_3=eprom_read(0x27);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x24);
eprom_write(data_in_1,0x25);
eprom_write(data_in_2,0x26);
eprom_write(data_in_3,0x27);
data_in_flag=0;
}
}
else if(keycode==0x44) //vol+
{
if(teach==0)
{
data_out_0=eprom_read(0x28);
data_out_1=eprom_read(0x29);
data_out_2=eprom_read(0x2A);
data_out_3=eprom_read(0x2B);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x28);
eprom_write(data_in_1,0x29);
eprom_write(data_in_2,0x2A);
eprom_write(data_in_3,0x2B);
data_in_flag=0;
}
}
else if(keycode==0x24) //vol-
{
if(teach==0)
{
data_out_0=eprom_read(0x2c);
data_out_1=eprom_read(0x2D);
data_out_2=eprom_read(0x2E);
data_out_3=eprom_read(0x2F);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x2c);
eprom_write(data_in_1,0x2d);
eprom_write(data_in_2,0x2e);
eprom_write(data_in_3,0x2f);
data_in_flag=0;
}
}
else if(keycode==0x102) //P+
{
if(teach==0)
{
data_out_0=eprom_read(0x30);
data_out_1=eprom_read(0x31);
data_out_2=eprom_read(0x32);
data_out_3=eprom_read(0x33);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x30);
eprom_write(data_in_1,0x31);
eprom_write(data_in_2,0x32);
eprom_write(data_in_3,0x33);
data_in_flag=0;
}
}
else if(keycode==0x82) //P-
{
if(teach==0)
{
data_out_0=eprom_read(0x34);
data_out_1=eprom_read(0x35);
data_out_2=eprom_read(0x36);
data_out_3=eprom_read(0x37);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x34);
eprom_write(data_in_1,0x35);
eprom_write(data_in_2,0x36);
eprom_write(data_in_3,0x37);
data_in_flag=0;
}
}
else if(keycode==0x42) //ON
{
if(teach==0 && ON_flag)
{
data_out_0=eprom_read(0x38);
data_out_1=eprom_read(0x39);
data_out_2=eprom_read(0x3A);
data_out_3=eprom_read(0x3B);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
ON_flag=0;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x38);
eprom_write(data_in_1,0x39);
eprom_write(data_in_2,0x3A);
eprom_write(data_in_3,0x3B);
data_in_flag=0;
}
else if(teach==0 && !ON_flag)
{
data_out_0=eprom_read(0x3C);
data_out_1=eprom_read(0x3D);
data_out_2=eprom_read(0x3E);
data_out_3=eprom_read(0x3F);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
ON_flag=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x3C);
eprom_write(data_in_1,0x3D);
eprom_write(data_in_2,0x3E);
eprom_write(data_in_3,0x3F);
data_in_flag=0;
}
}
else if(keycode==0x22) //teach
{
if(teach==1)
{
teach=0;
CCP1CON=0b00001100;
RBIE=0;
PR2=28;
}
else
{
teach=1;
CCP1CON=0x0; //выключить ШИМ
RBIE=1;
}
}
else if(keycode==0x101) //RC5
{
protocol_RC5=1;
protocol_SIRC=0;
protocol_SAM=0;
}
else if(keycode==0x81) //SIRC
{
protocol_RC5=0;
protocol_SIRC=1;
protocol_SAM=0;
}
else if(keycode==0x41) //SAM
{
protocol_RC5=0;
protocol_SIRC=0;
protocol_SAM=1;
}
else if(keycode==0x21) //OFF
{
if(teach==0 && ON_flag)
{
data_out_0=eprom_read(0x38);
data_out_1=eprom_read(0x39);
data_out_2=eprom_read(0x3A);
data_out_3=eprom_read(0x3B);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
ON_flag=0;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x38);
eprom_write(data_in_1,0x39);
eprom_write(data_in_2,0x3A);
eprom_write(data_in_3,0x3B);
data_in_flag=0;
}
else if(teach==0 && !ON_flag)
{
data_out_0=eprom_read(0x3C);
data_out_1=eprom_read(0x3D);
data_out_2=eprom_read(0x3E);
data_out_3=eprom_read(0x3F);
data_out=(data_out_0<<24)+(data_out_1<<16)+(data_out_2<<8)+data_out_3;
TMR2ON=1;
ON_flag=1;
}
else if(data_in_flag)
{
eprom_write(data_in_0,0x3C);
eprom_write(data_in_1,0x3D);
eprom_write(data_in_2,0x3E);
eprom_write(data_in_3,0x3F);
data_in_flag=0;
}
}
}
void eprom_write(unsigned char data,unsigned char adr) //запись в eeprom
{
if(!WR)
{
EEADR=adr;
EEDATA=data;
EEPGD=0;
WREN=1;
GIE=0;
EECON2=0x55;
EECON2=0xaa;
WR=1;
WREN=0;
GIE=1;
}
}
eprom_read(unsigned char adr) //чтение eeprom
{
EEADR=adr;
EEPGD=0;
RD=1;
r_data=EEDATA;
}