精选文章 FPGA红外遥控

FPGA红外遥控

作者:星空之火 时间: 2019-11-04 10:51:59
星空之火 2019-11-04 10:51:59

这个程序写了大概快一周了,每天大概花两个小时左右。

第一次写这种通讯的协议,自己写代码能力不够强,经验不足。犯了很多的错误。下面是我自己对这次的总结:

1.第一:写程序不能写的太多,写一点验证一点。初期,你不要太相信自己的代码水平。

2.第二:要花时间去验证你写的代码,比如用sigaltap去调试你的代码,或者用led,或者是数码管

3.第三:先把通信协议的原理看懂,这个所谓的看懂,是在你不断的思考,和实践中理解的。

4.第四:在简单的东西,也要练习,除非你是大佬。

 

首先:了解通讯的过程:

FPGA红外遥控1

1.红外遥控器发出红外光,这个红外光是经过调制的,就是下面的第三个线

2.在FPGA开发板有个红外接收头,对接收的数据进行解码,就是下面第四条线

FPGA红外遥控2

这里有个小细节:起始发射的不是高电平9ms吗,为什么接收时是低电平呢,这和红外接收头内部的结构有关,在内部有个三极管,当解调器(Demodulator)接收到高电平时,OUT输出为低电平.

红外内部结构如下图所示:FPGA红外遥控3

我们分析一下:发过来的数据,FPGA代码如何解析其中的数据

1.下面是遥控器发射的数据:

发射的数据:40位数据,地址码,地址反码,数据吗,数据反码(其中数据码就是对应按键的值,不同的按键,数据吗不同)

FPGA红外遥控4

2.其中发射的数据‘“1”,时间大概是2.25ms,“0”大概1.12ms

FPGA红外遥控5

3.下面是遥控器重复发射的数据

FPGA红外遥控6

FPGA红外遥控7

如何区分是否重复按键呢:

可以检测9ms之后的这个信号是2.25ms还是4.5ms,如果是4.5ms,就是发数据,如果是2.25ms,就是重复码

 

4.下面是红外接收头收到的数据

FPGA红外遥控8

 

FPGA写程序的思路:

1.先检测下降沿,如果检测到下降沿,则开始对9ms这段数据进行记时,直到等到上升沿到来之后,停止计时,我们假设计时为t,判断时间是否大概在9ms左右,(t>8ms&&t<10ms),这点非常重要,千万别写t==9ms,判断,这样绝对是错的,只要t在9ms左右就可以,则进入下个状态,那如果t远远小于9ms,这数据无效,回到状态机空闲状态

FPGA红外遥控9

2.我们继续对下个状态记时,然后判断t大概是多少,如果t在4.5左右,这进入接收数据状态,如果t在2.25ms左右,这进入重复码状态,如果都不是,这数据无效,回到状态机空闲状态

FPGA红外遥控10

3.如果状态是接收数据状态,我们要对40个数据保存,数据是0,还是1,通过t的时间来判断,如果是0则是560us的低电平+1.12ms的高电平,如果是1则是560us的低电平+2.25ms的高电平,

FPGA红外遥控11

FPGA红外遥控12

 

代码如下:

//做了一周的程序,终于成功了
//学会了signaltap的调试
//要学会分解一个大的工程
module red_receive(
    input               clk,          //系统时钟 
    input               rst_n,        //系统复位信号,低电平有效
    input               remote_in,    //红外接收信号
    output  reg [7:0]   data,         //接收的数据
    output  reg         led    
);

//状态机状态
parameter  IDLE                 = 6'b00000;
parameter  START_9MS            = 6'b00001;
parameter  START_4_5MS_OR_2_5MS = 6'b00010;
parameter  START_RECEIVE_DATA   = 6'b00011;
parameter  START_REPEAT         = 6'b00100;

//状态机
reg [5:0] state_c;
reg [5:0] state_n;              //自己真的应该注意
wire sidle29ms_start;           //检测到9ms的那个时刻的下降沿开始了
reg  s9ms2s4_5ms_or_2_5ms_start; //检测到开始4.5ms的那个时刻的上升沿开始了
reg  s9ms2idle_start;           //检测出错
reg  s4_5ms2receive_data_start; //开始接收数据
reg  s4_5ms2repeat_code_start;  //重复码
reg  s4_5ms2idle;               //检测出错,回到起点
wire sreceive_data2idle_start;  //接受数据完成
wire srepeat2idle_start;        //重复码接收完成 

//接收数据
reg [31:0] receive_data;       //接收的数据
reg [6:0] cnt;
wire add_cnt;
wire end_cnt;

//上升沿,下降沿
wire  pos_remote_in,neg_remote_in;
reg   remote_in_d0,remote_in_d1;

//led控制
reg led_flag;
wire add_cnt1;
wire end_cnt1;
reg [23:0]   cnt1;
//计时
reg  [19:0]  neg_cnt,pos_cnt;

//20ns 50个是1us=1000*50
//9ms
parameter TIME_10MS   = 20'd500_000;  //50000*10
parameter TIME_8MS    = 20'd400_000; 
//4.5ms
parameter TIME_4MS    = 20'd200_000;  
parameter TIME_5MS    = 20'd250_000;
//2.25 逻辑‘1’
parameter TIME_1_4MS  = 20'd70_000;  
parameter TIME_3MS    = 20'd150_000;


//上升沿检测,下降沿检测,很常规的一种方法
assign  pos_remote_in = (~remote_in_d1) & remote_in_d0;    //上升沿检测,如果检测到上升沿,有0到1,之后下个周期为0
assign  neg_remote_in =  remote_in_d1 & (~remote_in_d0);   //下降沿

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        remote_in_d0<=1'b0;
        remote_in_d1<=1'b0;
    end
    else  begin
        remote_in_d0<=remote_in;
        remote_in_d1<=remote_in_d0;
    end
end

//状态机初值
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        state_c <= IDLE;
    end
    else begin
        state_c <= state_n;
    end
end

//在接收数据的各种状态
always@(*)begin
    case(state_c)
        IDLE:begin
            if(sidle29ms_start)begin   //9ms的下降沿开始,准备开始计数
                state_n = START_9MS;
            end
            else begin
                state_n = state_c;
            end
        end
        START_9MS:begin
            if(s9ms2s4_5ms_or_2_5ms_start)begin
                state_n = START_4_5MS_OR_2_5MS;
            end
            else if(s9ms2idle_start)begin
                state_n = IDLE;  //计数出错了
            end
            else begin
                state_n = state_c;
            end
        end
         START_4_5MS_OR_2_5MS:begin
            if(s4_5ms2receive_data_start)begin
                state_n = START_RECEIVE_DATA; //开始接收数据
            end
            else if(s4_5ms2repeat_code_start)begin
                state_n = START_REPEAT;  //重复码
            end
            else if(s4_5ms2idle)begin
                state_n = IDLE;  //计数出错了
            end
            else begin
                state_n = state_c;
            end
        end
        START_RECEIVE_DATA:begin
            if(sreceive_data2idle_start)begin
                state_n = IDLE;  //回到空闲状态
            end
            else begin
                state_n = state_c;
            end
        end
		  START_REPEAT:begin
            if(srepeat2idle_start)begin
                state_n = IDLE;  //回到空闲状态
            end
            else begin
                state_n = state_c;
            end
        end
        default:begin
            state_n = IDLE;
        end
    endcase
end

assign sidle29ms_start             =state_c==IDLE               && neg_remote_in;   //检测到下降沿,准备开始对9ms低电平计时
assign sreceive_data2idle_start    =state_c==START_RECEIVE_DATA && end_cnt;         //40位数据接收完成
assign srepeat2idle_start          =state_c==START_REPEAT       && pos_remote_in;   //重复码结束标志位
//9MS
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        s9ms2s4_5ms_or_2_5ms_start<=0;
        s9ms2idle_start<=0;
    end
    else if(state_c==START_9MS && pos_remote_in) begin  //下降沿开始接收数据
        if(neg_cnt>TIME_8MS && neg_cntTIME_4MS&&pos_cntTIME_1_4MS&&pos_cntTIME_1_4MS&&pos_cnt

最后:一定要注意对定时的判断,最后你自己去用sigaltap去测试一下t大概在什么范围,就比如你判断接收的数据“1”

t>2ms&&t<2.5ms,你判断t是在2.25ms左右,但是在实际中,很可能     1.5ms<3ms,这个范围内,多用siganltap调试<><3ms,这个范围内,多用siganltap调试<>

如果还有疑问:可以看看正点原子的FPGA课程,里面讲了关于红外遥控的课程

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:[算法系列之十三]Rabin-Karp字符串查找算法

下一篇:05_7_可变参数

您可能感兴趣

  • BATH围猎新基建,后浪“TMD”集体缺席

    最近,美国《福布斯》杂志公布了今年“全球上市企业2000强”榜单,其中,中国上榜企业数量已经连续七年稳居全球第二,仅次于霸榜的美国之后。 不过企业数量占优是一方面,短板也很明显。比如,美国上榜企业总市值达到了25.9万亿美元,中国上榜企业总市值却是7.74万亿美元,不到美国总市值的1/3。 在美国587家上榜企业中,包括芯片巨头英特尔、IC设计全球前三博通、高通、英伟达、基础装备动力巨头通用...

  • 硬不硬你说了算!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题

    每日一句英语学习,每天进步一点点: 前言 不管面试 Java 、C/C++、Python 等开发岗位, TCP 的知识点可以说是的必问的了。 任 TCP 虐我千百遍,我仍待 TCP 如初恋。 遥想小林当年校招时常因 TCP 面试题被刷,真是又爱又狠…. 过去不会没关系,今天就让我们来消除这份恐惧,微笑着勇敢的面对它吧! 所以小林整理了关于 TCP 三次握手和四次挥手的面试题型,跟大家一起探讨...

  • 如何利用Social Listening从社会化媒体中“提炼”有价值的信息?

    温馨提示:文章篇幅过长,字数12000+,兼顾理论和实战,干货满满。若图片看不清,可点击图片,即可看到高清大图。 背景 “大数据”一直是最近几年全球很火的概念,从下图Google Trends的最近5年的热度趋势图和热度搜索地域分布可以看出,在这5年中,中国在大数据方面的热度一路攀升,“居高不下”。 然而,即使这样,大数据(分析)对于绝大部分人来说仍停留在概念层面,或者是给人很“高大上”、不...

  • ESP8266_19MQTT协议接入ONENET平台_订阅主题

    ESP8266_01搭建开发环境 ESP8266_02程序的编译与下载 ESP8266_03SDK与Makefile的基本用法 ESP8266_04管脚控制与软件定时器 ESP8266_05 ESP8266有几个串口? ESP8266_06硬件定时器与IO中断 ESP8266_07基于PWM的呼吸灯 ESP8266_08基于flash的数据掉电保护 ESP8266_09基于IIC控制的OLE...

  • 新疆连桥物流园铁路专用线项目电气火灾监控系统的设计及应用

    安科瑞 戴玥 摘要:本文简述了电气火灾监控系统的组成原理,分析了电气火灾监控系统在应用中的设计依据和相关规范。通过安科瑞剩余电流式电气火灾监控系统在新疆连桥物流园铁路专用线项目中的实例介绍,阐述了电气火灾监控系统功能的实现及其重要意义。 关键词: 电气火灾;剩余电流式电气火灾监控探测器;电气火灾监控设备;Acrel-6000/B;新疆连桥物流园。 0 概述   新疆连桥物流有限责任公司铁路专...

  • 深度:养老康复基础设施快速普及,新渠道+新品类红利催生医疗器械新头部品牌!

    传统上主要应用于医院、养老院场景的医疗康复器械,正在加快进入中国亿万普通家庭。   对中国4.2亿50岁以上的中老年群体来说,健康始终是他们内心最大的焦虑。一旦有产品能够解决他们的健康需求,其强大的付费能力足以支撑许多细分方向的上市公司。   前20年的机会主要体现在监测型、小型化的医疗器械,比如在血糖仪上诞生了上市公司三诺生物,在血压计上诞生了上市公司九安医疗,在制氧机上诞生了上市公司鱼跃...

  • 上云十年:阿里云的奇幻漂流

    现代人的生活是不缺乏刺激的。我们总能在电影院或化身“沙发土豆”,作为旁观者,与凤凰社、夜魔侠、蜘蛛侠等诸多主角们经历了一场场“安全的冒险”,体会他们挣脱束缚的破釜沉舟,欣赏他们踏上未知冒险的勇气。 回到真实的商业故事中,很少有人会将阿里与“困境”这样的字眼联系在一起,尤其是在花团锦簇、全民狂欢的双十一之后。 但少有人知道,这场剁手党的“春晚”,却是技术人眼中冰峰林立、人迹罕至的“珠穆朗玛峰”...

  • 德勤全球AI发展白皮书:八大新趋势+三个关键技术

    关注ITValue,看企业级最新鲜、最具价值报道! 图片来源@视觉中国 | 文章来源@世界人工智能大会 | 前沿导读:目前AI已在金融、医疗、安防等多个领域实现技术落地,且应用场景也愈来愈丰富,正在实现全方位的商业化,引发了各个行业的深刻变革,这对加速企业数字化、改善产业链结构、提高信息利用效率等方面都起到了积极作用。与此同时,AI也已全面进入机器学习时代,未来AI的发展将是关键技术与产业的...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。