找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1896|回复: 11
收起左侧

应广单片机边沿中断触发改主程序循环执行,求帮忙分析

[复制链接]
ID:835574 发表于 2022-7-8 16:40 | 显示全部楼层 |阅读模式
右边为例程的,但是是边沿触发中断。我这硬件的是是普通引脚没法使用。于是改参考例子,改主程序循环。
但是解出来的值不同,求指点
a.jpg
回复

使用道具 举报

ID:401564 发表于 2022-7-8 23:28 | 显示全部楼层
应广的没法指导
一是应广好像都是OTP的,工作中用不到的话,几乎没人学,烧录器贵上天,没法验证
二是应广用的不是标准C,迷你C估计学的人不多
回复

使用道具 举报

ID:887371 发表于 2022-7-9 17:18 | 显示全部楼层
我也没用过应广的。不会应广的语法。
我发现右图代码是有些问题。
假设左图的代码正常。
假设右图中的变量RF_LV为RF的暂存值。

  1. void main()
  2. {
  3.         while(1){
  4.                 if(RF!=RF_LV)
  5.                 {
  6.                         //RF不等于RF_LV,表示发生了跳变。
  7.                         RF_LV=RF;//RF_LV=0表示为下降沿 RF_LV=1表示为上升沿
  8.                         RF_Receive();//左图代码(边沿触发中断的),注意把所有的RF要替换为RF_LV。                       
  9.                 }
  10.         }
  11. }
复制代码
回复

使用道具 举报

ID:962286 发表于 2022-7-9 18:34 | 显示全部楼层
用读IO的方式代替用边沿中断,只需要读到IO跟原来不一样,然后执行应广的例程即可:
  1. RF_RECEIVE        expand
  2.         static        Byte        Icnt;
  3.         if(RF == 0)
  4.         {
  5.                 if(RF_LV == 0)
  6.                 {
  7.                         Timer_250us = 0;
  8.                 }
  9.                 RF_LV = 1;
  10.         }
  11.         else
  12.         {
  13.                 if(RF_LV == 1)
  14.                 {
  15.                         if(RF_Start == 0)
  16.                         {
  17.                                 if((Timer_250us >= 32) && (Timer_250us <= 48))
  18.                                 {
  19.                                         RF_Start = 1;
  20.                                         Data_In = 0;
  21.                                         Icnt = 0;
  22.                                 }
  23.                         }
  24.                         else
  25.                         {
  26.                                 Icnt ++;
  27.                                 if((Timer_250us >= 3) && (Timer_250us <= 5))
  28.                                 {
  29.                                         CF = 1;
  30.                                         Data_In <<<= 1;
  31.                                 }
  32.                                 else if((Timer_250us >= 1) && (Timer_250us <= 2))
  33.                                 {
  34.                                         CF = 0;
  35.                                         Data_In <<<= 1;
  36.                                 }
  37.                                 else
  38.                                 {
  39.                                         Icnt = 0;
  40.                                         RF_Start = 0;
  41.                                 }
  42.                         }
  43.                         if(Icnt >= 24)
  44.                         {
  45.                                 Icnt = 0;
  46.                                 RF_End = 1;
  47.                                 RF_Start = 0;
  48.                                 .printf("ÂëÖμ:%03X\n",Data_In)
  49.                         }
  50.                 }
  51.                 RF_LV = 0;
  52.         }
  53. endm
复制代码
回复

使用道具 举报

ID:161164 发表于 2022-7-9 22:33 | 显示全部楼层
要留意主循环的周期要少于信号电平保持时间的1/3
如信号中低电平时间最短为250us
那么主循环时间就应少于83us
否则会掉侦
回复

使用道具 举报

ID:835574 发表于 2022-7-10 11:24 | 显示全部楼层
Y_G_G 发表于 2022-7-8 23:28
应广的没法指导
一是应广好像都是OTP的,工作中用不到的话,几乎没人学,烧录器贵上天,没法验证
二是应广用 ...

应广的确实是如你所说的这样.。我刚刚好工作需要/.
回复

使用道具 举报

ID:835574 发表于 2022-7-10 11:37 | 显示全部楼层
datouyuan 发表于 2022-7-9 17:18
我也没用过应广的。不会应广的语法。
我发现右图代码是有些问题。
假设左图的代码正常。

看了下,发现搞错了。原谅我左右不分。尴尬
左右是示例代码(中断触发)。右边是我的转换的普通引脚的
RF_LV 我本来是用来标志,是想让电平刚改变时执行一次,后面电平相同的时间不再执行这里面的代码.

大佬,get到我的点了,我改下试试先。感谢建议
回复

使用道具 举报

ID:835574 发表于 2022-7-10 11:43 | 显示全部楼层
MCU_FANS 发表于 2022-7-9 18:34
用读IO的方式代替用边沿中断,只需要读到IO跟原来不一样,然后执行应广的例程即可:

思路是用读IO的值来替换,电平改变的时候执行一次,然后开启计数器算时间,否则波形解出来不对,然后我加了各种判断。把我自己给绕晕了。。。
回复

使用道具 举报

ID:835574 发表于 2022-7-10 11:50 | 显示全部楼层
MCU_FANS 发表于 2022-7-9 18:34
用读IO的方式代替用边沿中断,只需要读到IO跟原来不一样,然后执行应广的例程即可:

因为函数是在main里面循环的。如果RF=0的时候,时间有900us. 那么timer_250us 就一直清0 ,无法计算时间。和中断触发有差异了
回复

使用道具 举报

ID:835574 发表于 2022-7-10 11:53 | 显示全部楼层
lkc8210 发表于 2022-7-9 22:33
要留意主循环的周期要少于信号电平保持时间的1/3
如信号中低电平时间最短为250us
那么主循环时间就应少于 ...

我也怀疑过是否因为主程序执行时间过长,然后导致时间线出错。然后我搞了个例子,主循环里面什么都做,就只执行这函数,然后一样的问题。我就怀疑是不是我判断的条件和中断双边沿触发的对不上,而不是时间线
回复

使用道具 举报

ID:835574 发表于 2022-7-11 09:24 | 显示全部楼层
datouyuan 发表于 2022-7-9 17:18
我也没用过应广的。不会应广的语法。
我发现右图代码是有些问题。
假设左图的代码正常。

这方面实测可以了。。感谢大佬.
就是应广的引脚不能直接判断,需要迂回下
        while (1)
        {
                if(RF){
                        RF_TEMP = 1;
                }else{
                        RF_TEMP = 0;
                }

                if(RF_TEMP != RF_LV){ //RF不等于RF_LV,表示发生了跳变。
                        RF_LV=RF_TEMP; //RF_LV=0表示为下降沿 RF_LV=1表示为上升沿
                        RF_Receive;
                }
        }
回复

使用道具 举报

ID:887371 发表于 2022-7-11 10:58 | 显示全部楼层
刚仔细分析了下左图代码,这段代码是用于315M433MHz无线接收模块解码的,代码写得非常好,可适用于各种单片机,值得收藏。

这段代码同其它常见代码比,占用mcu实践极短,几乎是0耗时,非常方便的嵌入到各种项目中,对项目的其它模块无任何影响。缺点是需要使用外中断或引脚变动中断+定时器中断,全局变量也多了几个。

初学者逛论坛,应该多收集这类优秀代码,并分析理解。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表