基于BK7231T的NEC硬解码程序【未编辑完成】

发布于 2020-06-18 18:29:58
    本帖最后由 lucky_ant 于 2020-6-18 19:19 编辑


[p=30, 2, left]做嵌入式开发,我的原则是能用硬件外设处理的事情,坚决不用软件模拟的方式去处理。由于我们无法直接得到原厂的支持,先做了NEC软解,虽然NEC解码的功能已经实现了,始终觉得不完美。在此要特别感谢RT-Thread的吴总帮忙协调资源,拿到了nec硬解码的相关资料,很快我就调通了NEC硬解,在此我做一个总结,并贴出完整的代码。[/p][p=30, 2, left]BK7231T和BK7251的NEC硬解码接口都是PWM5口,在BK7231T上是P15,在BK7251上是P26,设计电路务必将红外接收头的输出脚接到IRDA这个脚上。[/p][p=30, 2, center]引脚图.png[/p]

[p=30, 2, left]我们使用的是涂鸦SDK,因涂鸦sdk需要烧录授权码才可以,仅供参考,使用目前sdk还存在一些问题,sdk地址如下:[/p]

[p=30, 2, left]BK的代码做了接口统一管理,底层驱动都封装好了,用户只需要通过接口传入对应参数即可访问底层硬件。例如,将某个GPIO设为上拉输入,初始化代码如下:[/p]
 u32 param;
param = GPIO_CFG_PARAM(GPIO9, GMODE_INPUT_PULLUP);
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG,&param);

[p=30, 2, left]读取GPIO的电平状态使用如下代码:[/p]
u8 get_gpio_level(u32 gpio_id)
ret = sddev_control(GPIO_DEV_NAME, CMD_GPIO_INPUT, ¶m);

return ret?1:0;
[indent]}[/indent]


[p=30, 2, left]下面详解NEC硬解码初始化部分,我是写在了irda.c这个文件中[/p]
void irda_init_app(void)
{
UINT32 param;

intc_service_register(IRQ_IRDA, PRI_IRQ_IRDA, irda_isr); //注册irda中断函数
sddev_register_dev(IRDA_DEV_NAME, &irda_op);//注册设备访问接口
param = PCLK_POSI_IRDA;
sddev_control(ICU_DEV_NAME,CMD_CONF_PCLK_26M,&param);//设置IRDA时钟为26M
param = PWD_IRDA_CLK_BIT;
sddev_control(ICU_DEV_NAME, CMD_CLK_PWR_UP, &param);//时钟电源开

//使能第二功能,这是比较诡异的地方,明明BK7231T的IRDA口是GPIO15,
//此处如果传入GPIO15,却无法解码,这个需要拿到寄存器手册才好解释
gpio_config(GPIO26, GMODE_SECOND_FUNC);

irda_set_polarity(0);//设置IRDA极性,低电平有效
irda_active(1);//NEC解码使能
irda_set_clk(0x3921);//irda_clk*562.5 (26*562.5 = 0x3921) 计算时钟,具体怎么计算的还不太清楚,依然需要相关手册作为参考才可以解释
//设置要开启哪些中断,此函数也是参考bk7251的sdk,涂鸦的sdk中不存在此函数,后文给出对应代码
irda_set_int_mask(IRDA_RIGHT_INT_MASK|IRDA_REPEAT_INT_MASK|IRDA_END_INT_MASK);
/*interrupt setting about IRDA*/
intc_enable(IRQ_IRDA);//使能IRDA中断
param = GINTR_IRQ_BIT;
sddev_control(ICU_DEV_NAME, CMD_ICU_GLOBAL_INT_ENABLE, &param);
}


[p=30, 2, left]设置中断掩码的函数,这个函数我是写在irda.c中[/p]

static void irda_set_int_mask(UINT8 int_en_bits)

{

UINT32 value;

value = REG_READ(IRDA_INT_MASK);

value &= ~INT_MASK_EN;

value |= int_en_bits;

REG_WRITE(IRDA_INT_MASK, value);

}



[p=30, 2, left]中断函数的实现[/p]

UINT32 Recv_IR_Code = 0xffffffff;

void irda_isr(void)

{

static UINT16 ValidFlag = 0;

UINT32 irda_int;

UINT32 end_int, right_int, repeat_int;


irda_int = REG_READ(IRDA_INT);

end_int = irda_int&IRDA_END_INT;

right_int = irda_int&IRDA_RIGHT_INT;

repeat_int = irda_int&IRDA_REPEAT_INT;

if(end_int)

{

if (ValidFlag)

{

ValidFlag = 0x0;

Recv_IR_Code = REG_READ(RX_FIFO_DOUT);

//打印出解码的内容,实际上只需要cmd部分,即第2字节

//PR_NOTICE("Recv_IR_Code:%08X",(Recv_IR_Code>>16)&0xff);

}

else

{

Recv_IR_Code=0xFFFFFFFF;

}

irda_int |= IRDA_END_INT;

}

if(right_int)

{

ValidFlag = 1 ;

irda_int |= IRDA_RIGHT_INT;

}

if(repeat_int)

{

irda_int |= IRDA_REPEAT_INT;

}


REG_WRITE(IRDA_INT, irda_int);

}


在主程序中调用irda_app_init();然后开启一个任务处理红外解码的数据
日志.png


以上是我创建的任务里打印的红外解码数据。


查看更多

关注者
0
被浏览
127
2 个回答
bernard
bernard 2020-06-18
emoji表情符,直接出错……

bk7231/7252上RTT支持得挺全的,这块还真得多感谢aozima(也就是文中的吴总哈:D),有问题找他肯定可以搞定
lucky_ant
lucky_ant 2020-06-18
bernard 发表于 2020-6-18 19:27
emoji表情符,直接出错……

bk7231/7252上RTT支持得挺全的,这块还真得多感谢aozima(也就是文中的吴总哈: ...


是的,非常感谢

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友