芯片为义隆EM78P468N,代码用义隆的C来写
#include "em78x468xx.h"
#include "iic.h"
#include "lcd.h"
#define OSC_4000K
#define OSC_4260K
//#define MIN_TEMP 16
//#define MAX_TEMP 31
#define MIN_COOL_TEMP 26
#define MAX_COOL_TEMP 30
#define MIN_HOT_TEMP 16
#define MAX_HOT_TEMP 20
//制冷16-31度存在0-15
//制热16-31度存在16-31
#define ON_INDEX 5
#define OFF_INDEX 6
#define MFX_INDEX 7
#define AFX_INDEX 8
#define FS_INDEX 16
#define ADJ_TIME_OUT 30
#define SET_TIME_OUT 60
#define IR_CODE_ADDR 66
#define KEY_LEARN 0
#define KEY_SET 1
#define KEY_POWER 2
#define KEY_MODE 4
#define KEY_MFX 5
#define KEY_AFX 6
#define KEY_FS 7
#define KEY_UP 8
#define KEY_DOWN 9
#define KEY_CLOCK 10
#define KEY_CLEAR 11
#define KEY_NOKEY 0xff
#define DISI() _asm{disi}
#define ENI() _asm{eni}
#define SLEP() _asm{slep}
#define NOP() _asm{nop}
#define WDTC() _asm{wdtc}
#define HIGH(n) (*(1 + (unsigned char *)&n))
#define LOW(n) (*((unsigned char *)&n))
#define ASM_TIME_OVER 0x1d,0
#define ASM_REC_OK 0x1d,3
#define ASM_TCIF 0xf,0
#define ASM_CNT1F 0xf,3
#define zero 3,2
#define carry 3,0
#define IR_PIN R57
#define ir_power_on() R56 = 0
#define ir_power_off() R56 = 1
unsigned char wr0 @ 0x1f: rpage 0;
unsigned char wr1 @ 0x1e: rpage 0;
static unsigned char flag @0x1d: rpage 0;
static bit time_over @0x1d@0:rpage 0;
static bit low_time_ok @0x1d@1:rpage 0;
static bit high_time_ok @0x1d@2:rpage 0;
static bit rec_ok @0x1d@3:rpage 0;
static bit wait @0x1d@4:rpage 0;
static bit fg_delay10ms @0x1d@5:rpage 0;
static bit fg_cnt1_int @0x1d@6:rpage 0;
static bit fg_250ms @0x1d@7:rpage 0;
static unsigned char lt0 @ 0x1c: rpage 0;
static unsigned char lt1 @ 0x1b: rpage 0;
static unsigned char ht0 @ 0x1a: rpage 0;
static unsigned char ht1 @ 0x19: rpage 0;
static unsigned char th @ 0x18: rpage 0;
unsigned char key_dat;
//unsigned char key_buf,key_cnt;
unsigned char hour @ bank 1;
unsigned char min @ bank 1;
unsigned char sec @ bank 1;
unsigned char half_sec @ bank 1;
unsigned char mode_buf @ bank 1; //空调工作模式,0---制冷,1---制热
unsigned char temp_buf @ bank 1;
unsigned char fx_fs_buf @ bank 1; //0--自动,1---微风,2---中风,3--高风
//bit7: 0---手动风 1---自动风
unsigned char work_mode @ bank 1; //本遥控器工作模式
//0---正常工作模式
//1---设置模式
//2---调整时钟分位
//3---调整时钟时位
unsigned char power_buf @ bank 1; //0---关, 学习关机信号
//1---开, 学习开机信号
//2---学习温度
//3---学习风速
//4---学习手动风向
//5---学习自动风向
unsigned char time_out @ bank 1;
unsigned char key_time @ bank 1;
unsigned char room_temp @0x07:rpage 0; //PORT7 没用到, 在这里用一下
unsigned char room_temp_delay @ bank 1;
unsigned char cool_temp,hot_temp;
unsigned char low_time_buf[30] @ 0x20: bank 2;
unsigned char lr0 @ bank 2;
unsigned char lr1 @ bank 2;
unsigned char high_time_buf[30] @ 0x20: bank 3;
unsigned char hr0 @ bank 3;
unsigned char hr1 @ bank 3;
extern void Delay10ms();
//================================================================
void sys_init()
{
DISI();
SBPCR = 0x09; //pll 4.26mhz
P5CR = 0x33;
P6CR = 0x0f; //0-3=input
P7CR = 0x00; //all output
P8CR = 0x00; //all output
CNT1PR = 0xff; //---->clock
CNT2PR = 0x0;
HPWTPR = 0x1b; //38K
LPWTPR = 0x1b;
IMR = 0; //ICIE LPWTE HPWTE CNT2E CNT1E INT1E INT0E TCIE
WUCR = 0x0e;
TCCCR = 0x0c; //1:32 = 16US
WDTCR = 0x0d; //enable 128--->2 sec
//101--->0.5sec
CNT12CR = 0x04; //counter 1 --->0.25SEC interrupt
HLPWTCR = 0x88; //1:2 1:2
P6PH = 0x0f;
P6OD = 0xf0;
P8PH = 0x00;
P6PL = 0x00;
PORT5 = 0x70;
PORT6 = 0x0f;
PORT7 = 0x00;
PORT8 = 0x1c;
LCDCR = 0xf0;
CNTER = 0x01; //enable cnt1
IRCR = 0x03;
}
//================================================================
void init_var()
{
flag = 0;
hour = 0;
min = 0;
sec = 0;
half_sec = 0;
work_mode = 0;
cool_temp = 28;
hot_temp = 18;
temp_buf = 28;
mode_buf = 0;
fx_fs_buf = 0;
power_buf = 0;
room_temp_delay = 5 *4;
}
//================================================================
void delay_n_4us(unsigned char n)
{
do{
NOP();
NOP();
NOP();
NOP();
WDTC();
}while(--n);
}
//================================================================
void calc_key(unsigned char k)
{
unsigned char i = 4;
do{
if((k & 1) == 0)
{
key_dat = wr0;
wr1 ++;
}
wr0 ++;
k >>= 1;
}while(--i);
}
//================================================================
unsigned char read_key()
{
wr0 = 0;
wr1 = 0;
PORT6 = 0x6f;
delay_n_4us(2);
calc_key(PORT6);
PORT6 = 0x5f;
delay_n_4us(2);
calc_key(PORT6);
PORT6 = 0x3f;
delay_n_4us(2);
calc_key(PORT6);
PORT6 = 0x0f;
return wr1;
}
//================================================================
void sleep_mode()
{
WDTCR = 0; //disable
SBPCR = 0x08; //32K
_asm{mov 6,6}
IMR = 0x08; //ICIE LPWTE HPWTE CNT2E CNT1E INT1E INT0E TCIE
SLEP();
NOP();
NOP();
WDTC();
SBPCR = 0x09; //pll 4.26mhz
WDTCR = 0x0d; //enable
WDTC();
}
//================================================================
void temp_tab()
{
_asm{
mov a,%wr0
ADD 0x02, A
RETL @0xBA ;0
RETL @0xB2 ;1
RETL @0xAA ;2
RETL @0xA3 ;3
RETL @0x9C ;4
RETL @0x95 ;5
RETL @0x8F ;6
RETL @0x89 ;7
RETL @0x83 ;8
RETL @0x7D ;9
RETL @0x78 ;10
RETL @0x73 ;11
RETL @0x6E ;12
RETL @0x6A ;13
RETL @0x66 ;14
RETL @0x61 ;15
RETL @0x5D ;16
RETL @0x5A ;17
RETL @0x56 ;18
RETL @0x53 ;19
RETL @0x4F ;20
RETL @0x4C ;21
RETL @0x49 ;22
RETL @0x47 ;23
RETL @0x44 ;24
RETL @0x41 ;25
RETL @0x3F ;26
RETL @0x3C ;27
RETL @0x3A ;28
RETL @0x38 ;29
RETL @0x36 ;30
RETL @0x34 ;31
RETL @0x32 ;32
RETL @0x30 ;33
RETL @0x2E ;34
RETL @0x2D ;35
RETL @0x2B ;36
RETL @0x2A ;37
RETL @0x28 ;38
RETL @0x27 ;39
RETL @0x25 ;40
RETL @0x24 ;41
RETL @0x23 ;42
RETL @0x22 ;43
RETL @0x20 ;44
RETL @0x1F ;45
RETL @0x1E ;46
RETL @0x1D ;47
RETL @0x1C ;48
RETL @0x1B ;49
RETL @0x1A ;50
}
}
//================================================================
void temp_count()
{
_asm{
clr %wr0
ll011:
nop
nop
nop
nop
nop
nop
nop
nop
WDTC
jbc 8,5
jmp ll010
jz %wr0
jmp ll011
com %wr0
bs ASM_TIME_OVER
ll010:
}
P8CR = 0x00; //all output
PORT8 = 0x1c;
}
//================================================================
void get_std_res()
{
P8CR = 0x60;
PORT8 = 0x9c;
temp_count();
}
//================================================================
void get_temp_res()
{
P8CR = 0xa0;
PORT8 = 0x5c;
temp_count();
}
//================================================================
void get_temp()
{
unsigned char i;
unsigned short t1 = 0,t2 = 0;
time_over = 0;
i = 2;
do
{
delay_n_4us(128);
get_std_res();
t1 += wr0;
}while(--i);
if(time_over) {room_temp = 0xff;return;}
i = 32;
do
{
delay_n_4us(128);
get_temp_res();
t2 += wr0;
}while(--i);
if(time_over) {room_temp = 0xff;return;}
t2 *= 2;
t2 *= 2;
_asm{
clr %wr1
ll0025:
mov a,%t1
sub %t2,a
jbc carry
jmp ll0023
mov a,@0x01
sub %t2+1,a
jbs carry
jmp ll0024
ll0023:
mov a,%t1+1
sub %t2+1,a
jbs carry
jmp ll0024
jz %wr1
jmp ll0025
com %wr1
ll0024:
}
if(wr1 >= 0xc2) {room_temp = 0xff;return;}
_asm{
clr %wr0
ll0031:
call %temp_tab
sub a,%wr1
jbc carry
jmp ll0030
inc %wr0
mov a,@51
sub a,%wr0
jbs carry
jmp ll0031
ll0030:
}
room_temp = wr0;
}
//================================================================
void cnt1_int()
{
WDTC();
_asm
{
jbs %flag,6
ret
bc %flag,6
inc %half_sec
bc %half_sec,2
}
fg_250ms = 1;
if(key_time < 255) key_time++;
if(room_temp_delay) room_temp_delay--;
if(half_sec == 2)
{
if(++sec >= 60)
{
sec = 0;
if(++min >= 60)
{
min = 0;
if(++hour >= 24) hour = 0;
}
}
}
if(half_sec & 1) return;
if(time_out) time_out--;
switch(work_mode)
{
case 0: lcd_disp_clock();
break;
case 1:
break;
case 2:
lcd_disp_clock();
if(time_out == 0) {work_mode = 0;break;}
if((half_sec & 2) == 0) lcd_clear_min();
break;
case 3:
lcd_disp_clock();
if(time_out == 0) {work_mode = 0;break;}
if((half_sec & 2) == 0) lcd_clear_hour();
break;
}
}
//================================================================
void send_low()
{
while(!time_over) WDTC();
IRCR = 0x8b;
CNTER = 0x0d;
TCC = ~wr1;
th = wr0 ^ 0x7f;
time_over = 0;
}
//================================================================
void send_high()
{
while(!time_over) WDTC();
IRCR = 0x03;
CNTER = 0x01;
IR_PIN = 0;
TCC = ~wr1;
th = wr0 ^ 0x7f;
time_over = 0;
}
//================================================================
void learn()
{
unsigned short start_addr;
unsigned char key_index;
unsigned char p1=0,p2=0;
ir_power_on();
lcd_or(LCDR12,2); //发射符号
while(1)
{
cnt1_int();
if(read_key() != 0 ) continue;
Delay10ms();
if(read_key() == 0 ) break;
}
RAM_ADDR = 0;
RAM_DB = 0xff;
for(wr0 = 0;wr0 < sizeof(low_time_buf);wr0++) low_time_buf[wr0] = 0xff;
switch(power_buf)
{
case 0:
key_index = OFF_INDEX;
break;
case 1:
key_index = ON_INDEX;
break;
case 2:
key_index = temp_buf - MIN_HOT_TEMP;
break;
case 3:
key_index = FS_INDEX + (fx_fs_buf & 0x03);
break;
case 4:
key_index = MFX_INDEX;
break;
case 5:
key_index = AFX_INDEX;
break;
}
LOW(start_addr) = IR_CODE_ADDR;
HIGH(start_addr) = key_index << 1;
wait = 0;
rec_ok = 1;
low_time_ok = 0;
high_time_ok = 0;
time_over = 0;
TCC = 0;
th = 0;
IMR = 0x0f; //ICIE LPWTE HPWTE CNT2E CNT1E INT1E INT0E TCIE
time_out = SET_TIME_OUT;
while(high_time_ok == 0)
{
cnt1_int();
if(time_out == 0) goto ll0022;
if(read_key() != 1 ) continue;
Delay10ms();
if(read_key() == 1 )
{
if(key_dat == KEY_LEARN)
{
time_out = SET_TIME_OUT;
ll0022:
IMR = 0x08; //ICIE LPWTE HPWTE CNT2E CNT1E INT1E INT0E TCIE
lcd_and(LCDR12,0xd); //发射符号
ir_power_off();
return;
}
}
}
time_over = 0;
high_time_ok = 0;
// IMR = 0x0f; //ICIE LPWTE HPWTE CNT2E CNT1E INT1E INT0E TCIE
WP = 0;
while(1)
{
Start();
if(!SendChar(0xa0)) continue;
SendChar( HIGH(start_addr) );
SendChar( LOW(start_addr) );
break;
}
while(1)
{
cnt1_int();
if(time_over)
{
time_over = 0;
wait = 1;
IMR = 0x08; //ICIE LPWTE HPWTE CNT2E CNT1E INT1E INT0E TCIE
if(low_time_ok)
{high_time_ok = 1;
ht0 = 0x71;
ht1 = 0x02; //10ms
}
}
if(high_time_ok)
{
high_time_ok = 0;
low_time_ok = 0;
_asm{
mov a,%lt0
mov %wr0,a
mov a,%lt1
mov %wr1,a
mov a,@%low_time_buf;
mov 4,a
ll003:
jbc 0,7
jmp ll004 ;没有找到
mov a,0
sub a,%wr1
mov %lr1,a
inc 4
mov a,0
sub a,%wr0
mov %lr0,a
jbs 3,0 ;C
dec %lr1
jbs %lr1,7
jmp ll001
com %lr0
com %lr1
ll001:
mov a,@0xf8
and a,%lr0
or a,%lr1
jbs 3,2 ;Z
jmp FIND_MATCH_TIME_NEXT
dec 4
bank @3
mov a,0
sub a,%ht1
mov %hr1,a
inc 4
mov a,0
sub a,%ht0
mov %hr0,a
jbs 3,0 ;C
dec %hr1
jbs %hr1,7
jmp ll002
com %hr0
com %hr1
ll002:
mov a,@0xf8
and a,%hr0
or a,%hr1
jbs 3,2 ;Z
jmp FIND_MATCH_TIME_NEXT
dec 4
bank @2
jmp ll005
FIND_MATCH_TIME_NEXT:
bank @2
inc 4
mov a,@(%low_time_buf+30)
sub a,4
jbs zero
jmp ll003
;error
bc ASM_REC_OK
bs ASM_TIME_OVER
mov a,@0xf
mov %wr0,a
jmp ll006
ll004:
mov a,%wr1
mov 0,a
inc 4
mov a,%wr0
mov 0,a
dec 4
bank @3
mov a,%ht1
mov 0,a
inc 4
mov a,%ht0
mov 0,a
dec 4
bank @2
ll005:
mov a,@%low_time_buf
sub a,4
mov %wr0,a
bc 3,0
rrc %wr0
ll006:
mov a,%p1
iow %RAM_ADDR
ior %RAM_DB
xor a,@0xff
jbs zero
jmp ll007
mov a,%wr0
or a,@0xf0
iow %RAM_DB
jmp ll008
ll007:
swapa %wr0
or a,@0x0f
mov %wr0,a
ior %RAM_DB
and a,%wr0
iow %RAM_DB
inc %p1 |