Skip to content

Instantly share code, notes, and snippets.

@usbuild
Created Aug 26, 2020
Embed
What would you like to do?
stc8g芯片改装红外控制电器
#include <STC/STC8G.h>
#include <intrins.h>
sbit IR_PIN_IN = P3 ^ 2;
//http://www.51hei.com/bbs/dpj-165191-1.html
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned int u16;
typedef uchar u8;
void Int0Init()
{
IR_PIN_IN = 1;
IT0 = 1; // 下降沿触发
EX0 = 1; // 开启外部中断0
EA = 1; // 开总中断
}
void Timer0Init(void) //100微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
}
static volatile int IR_counter = 0;
uchar state = 0;
uchar bits[32];
volatile uchar irok = 0;
uchar ircode[4];
#define IDLE (0)
#define INIT (1)
#define DATA (2)
#define FINI (4)
void irpros()
{
uchar num, k, i, j;
k = 1;
for(j=0;j<4;j++) // addr ~addr code ~code
{
for(i=0;i<8;i++)
{
num = num >> 1;
if(bits[k])
{
num = num | 0x80;
}
k++;
}
ircode[j] = num;
}
}
int counter;
uchar bitidx = 0;
void Int0 () interrupt 0
{
counter = IR_counter;
IR_counter = 0;
switch (state) {
case IDLE: {
state = INIT;
bitidx = 0;
break;
}
case INIT: {
if (counter > 120 && counter < 150) {
state = DATA;
}
break;
}
case DATA: {
if (counter < 13) { // 1.125, zero
bits[bitidx++] = 0;
} else if (counter > 21) {// 2.225
bits[bitidx++] = 1;
} else {
state = FINI;
}
if (bitidx >= 32) {
irok = 1;
irpros();
state = FINI;
}
break;
}
case FINI: {
state = IDLE;
break;
}
default: break;
}
}
void Timer0() interrupt 1
{
++IR_counter;
if (IR_counter > 200) {
IR_counter = 0;
state= IDLE;
}
}
void Delay1ms(unsigned cnt) //@11.0592MHz
{
unsigned char i, j;
while (cnt--) {
i = 15;
j = 90;
do
{
while (--j);
} while (--i);
}
}
#define IAP_OFFSET 0x2000 //STC8G1K08
void IapIdle()
{
IAP_CONTR = 0; //关闭 IAP 功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非 IAP 区域
IAP_ADDRL = 0;
}
char IapRead(int addr)
{
addr += IAP_OFFSET; //使用 MOVC 读取 EEPROM 需要加上相应的偏移
return *(char code *)(addr); //使用 MOVC 读取数据
}
void IapProgram(int addr, char dat)
{
IAP_CONTR = 0x80; //使能 IAP
IAP_TPS = 12; //设置擦除等待参数 12MHz
IAP_CMD = 2; //设置 IAP 写命令
IAP_ADDRL = addr; //设置 IAP 低地址
IAP_ADDRH = addr >> 8; //设置 IAP 高地址
IAP_DATA = dat; //写 IAP 数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
IapIdle(); //关闭 IAP 功能
}
void IapErase(int addr)
{
IAP_CONTR = 0x80; //使能 IAP
IAP_TPS = 12; //设置擦除等待参数 12MHz
IAP_CMD = 3; //设置 IAP 擦除命令
IAP_ADDRL = addr; //设置 IAP 低地址
IAP_ADDRH = addr >> 8; //设置 IAP 高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IapIdle(); //关闭 IAP 功能
}
uchar learning = 0;
sbit led = P3^3;
sbit btn = P5^5;
sbit btn2 = P5^4;
sbit btn3 = P3^1;
sbit btn4 = P3^0;
u8 check_pin() {
if (!btn) return 1;
if (!btn2) return 2;
if (!btn3) return 3;
if (!btn4) return 4;
return 0;
}
u8 check_act(u8 pin) {
if (pin == 1) return !btn;
if (pin == 2) return !btn2;
if (pin == 3) return !btn3;
if (pin == 4) return !btn4;
return 0;
}
void set_pin(u8 pin, u8 val) {
if (pin == 1) btn = val;
if (pin == 2) btn2 = val;
if (pin == 3) btn3 = val;
if (pin == 4) btn4 = val;
}
unsigned char mcodes[5];
void main()
{
u8 act,idx,btn_times, valid;
P3M1 = 0; P3M0 = 0x08;
P5M1 = 0; P5M0 = 0;
Int0Init();
Timer0Init();
led = 0;
btn = 1;
for(idx = 1; idx <= 4; ++idx) {
mcodes[idx] = IapRead(0x0010 + idx);
}
while(1) {
if (irok) {
irok = 0;
if (learning) {
mcodes[learning] = ircode[2];
led = 0;
IapProgram(0x0010 + learning, mcodes[learning]);
learning = 0;
} else {
for(idx = 1; idx <= 4; ++idx) {
if (mcodes[idx] == ircode[2]) {
led = 1;
set_pin(idx, 0);
Delay1ms(200);
led = 0;
set_pin(idx, 1);
}
}
}
}
act = check_pin();
if (act) {
valid = 1;
for (btn_times = 0; btn_times < 100; ++btn_times) {
Delay1ms(10);
if (!check_act(act)) {
valid = 0;
break;
}
}
if (valid) {
led = 1;
learning = act;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment