红外遥控(一)
本实验是采集红外遥控数据,红外信号的协议参考下面连接
https://blog.csdn.net/qq_34244712/article/details/102891082
一、构架解析
使用自定义封装IP采集红外数据,并把红外遥控数据写入BRAM,然后CPU读取红外数据;接着是CPU把红外数据写入BRAM,然后PL端从BRAM读取数据并恢复为红外信号。本实验经过测试,使用小米电视盒和小米遥控器可以正确转发红外遥控信号。
其中数据采集IP①和数据恢复IP⑤为自定义IP。数据采集IP①实现了FPGA的红外采集并把数据缓存在BRAM中,红外数据采集IP需要有一个按键松开的判断逻辑,目前在代码里采用连续采集到150ms的高电平就认为是松开按键。数据恢复IP⑤实现了从BRAM中读取数据并恢复红外信号。整个构架的核心为PS和PL的数据交互,BRAM ip核充当了数据交互的桥梁。
数据流向:
1)、PFGA通过自定义IP采集红外数据(图中①),红外采集模块需要分析红外信号的协议,需要记录电平持续的时间并且把电平状态和电平持续的时间保存在BRAM中。
2)、CPU通过BRAM控制器(图中②)查询到采集完成之后开始读取BRAM中缓存的红外数据。
3)、CPU通过数组缓存从BRAM读取到的数据。
4)、CPU通过BRAM控制器(图中④)把红外数据写入BRAM中缓存。
5)、FPGA通过自定义IP(图中⑤)从BRAM中读取数据,并把数据缓存在自定义IP的FIFO中,防止数据被覆盖。然后模块从FIFO中读取数据并恢复红外信号实现控制红外设备。
二、vitis测试代码
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xbram_hw.h"
#include "xbram.h"
#include "xil_types.h"
#include "xstatus.h"
#include "sleep.h"
#define START_ADDR 0 //RAM 起始地址 范围:0~1023
#define BRAM_DATA_BYTE 4 //BRAM 数据字节个数
//#define PL_RD_BRAM_BASEADDR XPAR_ZDYZ_RD_BRAM_0_S00_AXI_BASEADDR //ZDYZ_RD_BRAM IP核的
#define PL_RD_BRAM_START 0 //RAM读开始寄存器偏移地址
#define PL_RD_BRAM_START_ADDR 4 //RAM 起始寄存器偏移地址
#define PL_RD_BRAM_LEN 8 //PL 读 RAM 的深度寄存器偏移地址
#define PL_WRITE_BRAM_BASEADDR XPAR_PL_WRITE_BRAM2_0_S00_AXI_BASEADDR //自定义IP核PL_WRITE_BRAM2的基地址
#define PL_READ_BRAM_BASEADDR XPAR_PL_READ_BRAM2_0_S00_AXI_BASEADDR //自定义IP核PL_READ_BRAM2的基地址
#define READ_REG(addr) (*((volatile unsigned int *)(addr)))
#define WRITE_REG(addr, value) ((*((volatile unsigned int *)(addr))) = value)
int t = 0;
int k = 0;
int i=4,wr_cnt = 0;
int read_data[]={0};
int main()
{
int num=0;
init_platform();
while(1)
{
//1.获取要读的红外数据个数
while(num==0)
{
num = XBram_ReadReg(XPAR_BRAM_0_BASEADDR,0x00) ;
}
//2.循环从 BRAM 中读出数据
for(k=0; k <= num; k++)
{
read_data[wr_cnt]= XBram_ReadReg(XPAR_BRAM_0_BASEADDR,i) ;
i += 4;
wr_cnt++;
}
k=0;
i = 0;
wr_cnt = 0;
//3.发送清除红外个数脉冲
WRITE_REG(PL_WRITE_BRAM_BASEADDR, 1);
WRITE_REG(PL_WRITE_BRAM_BASEADDR, 0);
//4.每次循环向 BRAM 中写入32bit
for(k=0; k <= num; k++)
{
XBram_WriteReg(XPAR_BRAM_1_BASEADDR,i,read_data[wr_cnt]) ;
i += 4;
wr_cnt++;
}
//5. PL_READ_BRAM IP核从BRAM中读取数据
//5.1 告诉PL_READ_BRAM IP核读BRAM的起始地址(在AXI寄存器1设置读起始地址)
WRITE_REG(PL_READ_BRAM_BASEADDR+4, 0);
//5.2 告诉PL_READ_BRAM IP核读BRAM的数据长度,单位字节(在AXI寄存器2设置读数据长度num*4)
WRITE_REG(PL_READ_BRAM_BASEADDR+8, num*BRAM_DATA_BYTE);
//xil_printf("长度:%d",num*BRAM_DATA_BYTE) ;
//5.3 发送读脉冲,PL_READ_BRAM IP核看到该脉冲就开始从BRAM中读取数据 (在AXI寄存器0发送读脉冲)
WRITE_REG(PL_READ_BRAM_BASEADDR, 1);
WRITE_REG(PL_READ_BRAM_BASEADDR, 0);
//6.把各个参数设置为初始状态
k=0;
i = 4;
wr_cnt = 0;
num = 0;
}
cleanup_platform();
return 0;
}