i7gly 发表于 2015-11-26 09:47:30

吐槽义隆单片机,顺便送上超轻红外解码程序.

本帖最后由 i7gly 于 2015-11-26 11:41 编辑

最近有个案子要使用义隆153芯片,1K ROM 32Byte RAM,模拟5路PWM,红外解码,IIC,资源勉强够用.这款芯片大家都推荐汇编语言来编程,可我偏偏要用C,然后就被啪啪啪的打脸了,,,
路漫漫其修远兮,写好构架,编译,RAM不够?我明明只用了23Byte!!!然后上网查了下,编译器本身要占16Byte RAM,所以只能用32-16 = 16Byte RAM.我擦.竟然还有如此厚颜无耻的编译器!好吧,我忍了,谁叫我汇编不精.优化优化后,嘿嘿,刚刚好16Byte,编译,,,艹,当时我就想摔电脑了!!!编译器苦苦哀求:哥,再留3字节给我,中断时我还要保存保存状态寄存器呢!我当时就火大了,你TM的明明已经占用了16Byte了,你竟然出入栈都还向我要,你拿RAM去勾引妹子吗!!!
啪啪啪,脸被打肿后我只能忍着巨痛使用13Byte的RAM写完了这个案子.汇编不好真是苦逼,连编译器都欺负人.

下面送上这个案子使用的红外解码程序,只占用3.5Byte的RAM

采用轮询方式,例子是0.2ms轮询一次,修改时间参数可改动轮询时间.


#define READ_IR        R62                                //定义红外接收管脚

unsigned char        ir_step;                                //解码步
unsigned char        ir_code_cnt;                        //解码计时
unsigned char        ir_table;                                //解码值

bit         ir_status;                                        //状态
bit         ir_pin_old;                                        //管脚
bit         ir_pin_now;                                        //管脚
bit         ir_bit_ok;                                        //接收到1 BIT

void Ir_Code(void)
{
        if(ir_code_cnt<255)
                ir_code_cnt ++;                        //脉宽计时
        ir_pin_now = READ_IR;                        //读取IO状态

        if((ir_pin_now) && (ir_pin_now != ir_pin_old))                //捕捉脉冲上升沿
        {
                if(ir_code_cnt < 8)                                                        //脉冲1.125ms, -> 0
                {
                        ir_bit_ok = 1;                                                        //读取到1 bit
                        ir_pin_old = 0;                                                        //此处为借用变量
                }
                else if(ir_code_cnt < 16)                                        //脉冲2.25ms, -> 1
                {
                        ir_bit_ok = 1;
                        ir_pin_old = 1;       
                }          
                if(ir_code_cnt > 56)                                                //脉冲13.5ms, -> 包头
                {                                                                                //计时时间一定要适当放宽
                        ir_step=0;                                                        //解码步复位
                }
                ir_code_cnt = 0;                                                        //计时复位
        }
        if(ir_bit_ok)                                                                        //有读取到内容
        {
                ir_bit_ok = 0;                                                                //先复位
                if(ir_step < 24)                                                        //只接收24bit
                {
                        ir_table >>= 1;                                                //移位
                        if(ir_pin_old)        ir_table+= 0x80;
                }

                if(ir_step == 7)                                                        //第一个字节数据
                {
                        if(ir_table !=0x80)                ir_step = 0;                 //如果用户码为0x80,允许继续
                }
                if(ir_step == 15)
                {
                        if(ir_table !=0x7f)                ir_step = 0;                 //如果用户反码为0x7f,允许继续
                }
                if(ir_step == 23)                                                        //好了,接收到按键值了
                {
                        ir_status = 1;                                                        //置位状态,标识可读取
                }
                if(ir_step < 255)                                                        //接收步计数
                        ir_step ++;
        }
       
        ir_pin_old = ir_pin_now;                                                //管脚状态
}

void main()
{
        while(1)
        {
                if(ir_status)                                                //如果有接收标识
                {
                        ir_status = 0;                                        //复位标识
                        switch(ir_table)                                //键值使用
                        {
                                case 0x01:
                                        ......
                                break;
                        }
                }
        }
}

//0.2ms中断
void _intcall interrupt(void) @ int
{
        Ir_Code();                                                                        //中断里调用
}




修改理由:修改代码注释

Excellence 发表于 2015-11-26 09:51:41

{:lol:}{:lol:}{:lol:}{:lol:}{:lol:}

mangocity 发表于 2015-11-26 09:54:52

佩服用白菜MCU也能做出牛叉应用的人。{:handshake:}

mcujack 发表于 2015-11-26 09:55:38

不错,以前天天搞153的东西

tenx 发表于 2015-11-26 10:10:39

在中断中解红外,软P W M性能不好,要不频率不高

i7gly 发表于 2015-11-26 10:16:26

tenx 发表于 2015-11-26 10:10
在中断中解红外,软P W M性能不好,要不频率不高

频率不高,300HZ,所以影响不大.

tenx 发表于 2015-11-26 10:21:09

8位精度的P WM,300H Z频率可已不错了

wanderhope 发表于 2015-11-26 10:27:40

目前正在做的就是移植以前的汇编程序,>2000行,头都大了

shower.xu 发表于 2015-11-26 10:31:33

台系这些从不用C,目前手上4bit机无中断无堆栈的更折腾

i7gly 发表于 2015-11-26 10:39:41

shower.xu 发表于 2015-11-26 10:31
台系这些从不用C,目前手上4bit机无中断无堆栈的更折腾

没有堆栈还可以理解,没有中断就太鸡肋了吧,还在用4位机做什么应用?

shower.xu 发表于 2015-11-26 10:42:38

i7gly 发表于 2015-11-26 10:39
没有堆栈还可以理解,没有中断就太鸡肋了吧,还在用4位机做什么应用?

玩具,低端红外遥控语音玩具。。

有个baseTimer,但不触发中断,要自己去查标志位。NND

Firman 发表于 2015-11-26 10:45:34

之前用过C写这个IC控制IO口,莫名其秒的问题出现.没办法只能改汇编.
查了一下,这个IC的编译器对C编译很差.

zjk 发表于 2015-11-26 10:46:57

LZ水平很好哈,嘿嘿

i7gly 发表于 2015-11-26 10:54:14

Firman 发表于 2015-11-26 10:45
之前用过C写这个IC控制IO口,莫名其秒的问题出现.没办法只能改汇编.
查了一下,这个IC的编译器对C编译很差. ...

编译器倒不是很差,同样的程序,我在51上验证时,Keil编译出1.5K ROM.这个编译器编译0.9K ROM, 只是RAM占用太明显...

rainbow 发表于 2015-11-26 10:56:29

同感,经常把一个8位变量拆成2-3个来用.

i7gly 发表于 2015-11-26 10:56:41

shower.xu 发表于 2015-11-26 10:42
玩具,低端红外遥控语音玩具。。

有个baseTimer,但不触发中断,要自己去查标志位。NND ...

我猜是中颖的单片机...

Firman 发表于 2015-11-26 11:02:41

i7gly 发表于 2015-11-26 10:54
编译器倒不是很差,同样的程序,我在51上验证时,Keil编译出1.5K ROM.这个编译器编译0.9K ROM, 只是RAM占用 ...

用153写遥控器,土豪呀!
2K ROM我们用ABOV ADAM26/27的MCU,两毛钱,还不用外部晶振.

kebaojun305 发表于 2015-11-26 11:14:53

shower.xu 发表于 2015-11-26 10:31
台系这些从不用C,目前手上4bit机无中断无堆栈的更折腾

台系 一直用C,除非没有C编译器。楼主这还算是好的,我第一次用义隆,那个C编译器真的是第一个版本,那把我折腾了,最后都是发源代码到义隆原厂,找问题的。就折腾了一次,后面就很熟练了。

见入佳境 发表于 2015-11-26 11:15:39

if((ir_pin_now) && (ir_pin_now != ir_pin_old))                //捕捉脉冲下降沿,               
这里是不是有错误啊,不应该是捕捉到上升沿吗 ?

shower.xu 发表于 2015-11-26 11:23:23

i7gly 发表于 2015-11-26 10:56
我猜是中颖的单片机...

是九齐的,其实台系都差不多

见入佳境 发表于 2015-11-26 11:23:30

不错,标记下

shower.xu 发表于 2015-11-26 11:25:09

kebaojun305 发表于 2015-11-26 11:14
台系 一直用C,除非没有C编译器。楼主这还算是好的,我第一次用义隆,那个C编译器真的是第一个版本,那 ...

就那点RAM和ROM,都是一位位扣的,C怕不够用,还各种坑

shower.xu 发表于 2015-11-26 11:29:14

Firman 发表于 2015-11-26 11:02
用153写遥控器,土豪呀!
2K ROM我们用ABOV ADAM26/27的MCU,两毛钱,还不用外部晶振. ...

没搜到资料,能发个datasheet上来么,简单的就行

i7gly 发表于 2015-11-26 11:36:33

shower.xu 发表于 2015-11-26 11:29
没搜到资料,能发个datasheet上来么,简单的就行

http://www.abov.co.kr/chn/index.php?Depth1=3&Depth2=1&Depth3=1&Depth4=3

i7gly 发表于 2015-11-26 11:43:54

见入佳境 发表于 2015-11-26 11:15
if((ir_pin_now) && (ir_pin_now != ir_pin_old))                //捕捉脉冲下降沿,               
这 ...

注释是随便敲上去的,多谢提醒,已修改过来了.

shower.xu 发表于 2015-11-26 11:49:00

i7gly 发表于 2015-11-26 11:36
http://www.abov.co.kr/chn/index.php?Depth1=3&Depth2=1&Depth3=1&Depth4=3

谢谢,原来是现代

liufabing 发表于 2015-11-26 11:59:53

楼主牛B

liufabing 发表于 2015-11-26 13:29:38

Firman 发表于 2015-11-26 11:02
用153写遥控器,土豪呀!
2K ROM我们用ABOV ADAM26/27的MCU,两毛钱,还不用外部晶振. ...

2K ROM还只要2毛钱,这么便宜.
也是8脚么?

kebaojun305 发表于 2015-11-26 13:50:03

shower.xu 发表于 2015-11-26 11:29
没搜到资料,能发个datasheet上来么,简单的就行

坑多了,就习惯了。

Firman 发表于 2015-11-26 16:28:38

liufabing 发表于 2015-11-26 13:29
2K ROM还只要2毛钱,这么便宜.
也是8脚么?

脚的个数与价格有多大联系吗?
我们一般谈价格与ROM大小关系较大.
它是特定为遥控器做的MCU,肯定能满足基本要求.
8个脚能做什么?

1125526801 发表于 2015-12-2 15:00:36

楼主,问你个问题:义隆C的unsigned int 和unsigned char一样都是8位数据吗?我做12位ADC转换,是用了unsigned short int定义才是16位的数据!之前用unsigned int定义都是只有8位!

epwwm 发表于 2015-12-2 15:19:28

{:titter:}{:titter:}{:titter:}高人,PIC汇编,C不会飘过

i7gly 发表于 2015-12-2 17:19:05

1125526801 发表于 2015-12-2 15:00
楼主,问你个问题:义隆C的unsigned int 和unsigned char一样都是8位数据吗?我做12位ADC转换,是用了unsig ...

是的,义隆的char跟int都是8位的,short是16位的.
松翰的char跟int是8位的,long是16位的

1125526801 发表于 2015-12-2 18:14:42

i7gly 发表于 2015-12-2 17:19
是的,义隆的char跟int都是8位的,short是16位的.
松翰的char跟int是8位的,long是16位的 ...

明白了,谢谢。我前入手义隆的仿真器才几天。我只会用C

就在今天 发表于 2015-12-2 19:26:40

{:smile:}学习了,现代有2毛的单片机啊

yoursnemo 发表于 2015-12-25 12:29:06

这个红外解码蛮简练的~

zmh169 发表于 2015-12-25 13:13:12

成本敏感的东东不好做啊

yangbo18416 发表于 2016-12-26 11:31:08

mark,寻找思路中,解码RC-6

summer2017 发表于 2017-6-22 08:16:09

像遥控器这种通用的、大批量生产的东西,应该有专有芯片吧?

nuncle 发表于 2017-11-11 15:02:18

你好, 想请教下 红外遥控器按键一直长按, 怎么判断?

rainbow 发表于 2017-11-11 20:45:03

nuncle 发表于 2017-11-11 15:02
你好, 想请教下 红外遥控器按键一直长按, 怎么判断?

长按的时候,发出的“重复”编码,很好判断的。

kukudi 发表于 2017-11-12 08:18:27

楼主的代码很简洁明了,学习中。

jingmeidz 发表于 2017-11-13 13:04:45

rainbow 发表于 2017-11-11 20:45
长按的时候,发出的“重复”编码,很好判断的。

楼主代码中没有连发码的判断,NEC格式编码的
页: [1]
查看完整版本: 吐槽义隆单片机,顺便送上超轻红外解码程序.