矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 2740|回复: 16

请教,定时器间循环运行中连续插入一段语句如何实现

[复制链接]
     
发表于 2023-1-31 11:17:09 | 显示全部楼层 |阅读模式
比葫芦画瓢做的,定时器+中断+        switch(ADjisu)的条件判断语句,输出方波空占比50%,方波转换锯齿波用积分电路转换效率低,晶体管电路需要方波空占比低的效果好。原程序运行正常。
方波.png
想在        switch(ADjisu)判断语句没执行完运行OUT3=1 ;__nop__        (); ,形成脉冲空占比低的方波或脉冲波。如何实现。
方波2.png
是在定时器中断程序中加了OUT3=1 ;__nop__        (); 就卡哪了,不知道什么原因,定时器中断程序 ADjisu++;可以流畅运行,为什么OUT3=1 ;__nop__        (); 就卡哪了,如何在 void ADout()运行一个条件语句就调用OUT3=1 ;__nop__        ();,谢谢
     
发表于 2023-1-31 11:24:15 | 显示全部楼层
有可能括号和nop之间有空格。

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2023-1-31 11:58:01 | 显示全部楼层
看不到你的adjisu变量的初始化过程。我怀疑这个变量的初始化出了问题。
我觉得应该把上面一句改为:if((adjisu>7)||(adjisu<0)) adjisu=0;
另外不是太了解单片机的IO机制,不知道OUT=0是否会对应一条将IO端子3
置低电平的指令。
还有,如果是严谨的中断编程,中断函数是要保护现场(寄存器),屏蔽中断和恢复现场的,不知道你的编译器是不是会自动做这些动作(指令)。

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-1-31 12:45:47 | 显示全部楼层
world_all 发表于 2023-1-31 11:24
有可能括号和nop之间有空格。

感谢指教,刚刚核对括号和nop之间有空格,取消空格重新烧录,还是不行。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-1-31 13:00:59 | 显示全部楼层
本帖最后由 pdshyh 于 2023-1-31 13:03 编辑
onesword 发表于 2023-1-31 11:58
看不到你的adjisu变量的初始化过程。我怀疑这个变量的初始化出了问题。
我觉得应该把上面一句改为:if((ad ...


非常感谢指教,主程序有        ADjisu=0; 改为:if((adjisu>7)||(adjisu<0)) adjisu=0;更严谨,前面有sbit OUT3=P1^3;设定OUT3=0对应IO端子3
置低电平。对于“中断函数是要保护现场(寄存器),屏蔽中断和恢复现场的,”手头没有相关实例,不知道怎么做,用的Keil uVision4软件。89C52芯片,相关做法网上在搜搜,应该是中断部分不太会,没弄好。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-1-31 13:31:58 来自手机 | 显示全部楼层
采用延时函数或定时器也可以做出脉冲空占比低的方波或脉冲波,如上在定时器间叉入又连续不知道怎么做。

补充内容 (2023-1-31 16:40):
试了几个都不行...
回复 支持 反对

使用道具 举报

     
发表于 2023-2-1 09:35:26 | 显示全部楼层
不是很明白楼主的意思,是程序编译不通过还是运行程序没有达到自己的目的??

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-2-1 10:02:21 | 显示全部楼层
乙猪 发表于 2023-2-1 09:35
不是很明白楼主的意思,是程序编译不通过还是运行程序没有达到自己的目的??

感谢乙猪老师,运行就是没有达到预想结果,阶梯信号没了,方波信号没了,LED灯亮或不亮,正常LED灯闪烁,估计中断问题,想OUT0/OUT1/        OUT2=0或=1使用定时器控制时长I/O脚输出R2R输出阶梯信号,用定时器或延时函数或 _nop_(void)控制OUT3=0长和=1短输出低占空比方波,这两天考虑实现的方法不少,实际做了几个都是上面说的结果。用延时函数,或固定的一个定时器可以做,已经烧录测量没问题,想通过这个实验学习C51单片机定时器和中断的不同用法,还有关闭中断,用判断TF0=1溢出来使用定时器。不太熟一直卡哪了
回复 支持 反对

使用道具 举报

     
发表于 2023-2-1 11:02:28 | 显示全部楼层
本帖最后由 CXFLBH 于 2023-2-1 11:13 编辑

    直接在每个case大括弧里面将OUT3=1加上,后面再加 NOP 。比如下面:
       case 0:   {
                                   if(dispcount<=280)
                           WB_pl_display(280);
                                           else
                           WB_pl_display(281);
                                           break;
                           }
                         case 1:   {
                                             if(dispcount<=400)
                           WB_pl_display(400);
                                           else
                           WB_pl_display(401);
                                           break;
                           }
                         case 2:   {
                                             if(dispcount<=680)                          
                           WB_pl_display(680);
                                           else
                           WB_pl_display(681);
                                           break;
                           }
                         case 3:   {
                                             if(dispcount<=800)
                           WB_pl_display(800);
                                           else                                                                     
                           WB_pl_display(801);
                                           break;
                           }
                         case 4:   {
                                             if(dispcount<=1200)
                           WB_pl_display(1200);
                                           else                                                                     
                           WB_pl_display(1201);
                                           break;
                           }
                         case 5:   {
                                             if(dispcount<=1300)
                           WB_pl_display(1300);
                                           else                                                                     
                           WB_pl_display(1301);
                                           break;
                           }
                         default:  {
                                   if(dispcount<=280)
                           WB_pl_display(280);
                                           else
                           WB_pl_display(281);
                                           break;
                           }

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2023-2-1 11:11:41 | 显示全部楼层
另外,执行判断语句时,要考虑是不是要关掉中断,像下面的:                        EA = 0;                                                                //关中断
                        switch( Data_buff[1] )                                //功能码
                        {
                                case 0x03:                                                //读保持寄存器 40001-49999 字操作 单个或多个
                                                Modbus_CMD_03(Data_buff);
                                               
                                        break;
                                case 0x06:                                                //写单个保持寄存器 40001-49999 字操作 单个
                                                Modbus_CMD_06(Data_buff);
                                                Show_Debug(116);                //程序调试
                                        break;

                                default:
                                                Modbus_Error(Data_buff,0x01);
                                                Show_Debug(115);
                                        break;
                        }
                        EA = 1;                                                                //开中断

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2023-2-1 11:17:17 | 显示全部楼层
pdshyh 发表于 2023-2-1 10:02
感谢乙猪老师,运行就是没有达到预想结果,阶梯信号没了,方波信号没了,LED灯亮或不亮,正常LED灯闪烁, ...

延续你的思路,用中断和case来做,纯从程序编写来说,可以采取如下方法:
中断ADjisu计数最大值设为15,然后把中断调用频率提高一倍;
…………
case 0:…………
case 2:…………
…………
default: out3=1
…………

这样就可以达到你的要求:第一次中断,输出case0;第二次中断,输出out3;第三次中断,输出case2(原来的case1);第四次中断输出out3。

至于能否实现你的最终目的,还得看你的硬件设计,
用方波模拟数模转换,一直是51单片机的硬伤。

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-2-1 13:23:49 | 显示全部楼层
CXFLBH 发表于 2023-2-1 11:11
另外,执行判断语句时,要考虑是不是要关掉中断,像下面的:                        EA = 0;                                                                //关中断
                        switch( Data_ ...

非常感谢CXFLBH 老师指点,网上也看到了---判断语句关前关闭定时器,在判断语句完成在打开定时器的做法,还没有实验,确实有很多方法可以实现。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-2-1 13:36:31 | 显示全部楼层
乙猪 发表于 2023-2-1 11:17
延续你的思路,用中断和case来做,纯从程序编写来说,可以采取如下方法:
中断ADjisu计数最大值设为15, ...


感谢乙猪老师的建议,使用1个定时器调整case 值间距来实现长短时间响应,非常好,51单片机驱动力弱?用的少还没有体会,这次实验 LEDout=P0^3;没有外置上拉电阻没反应印象深刻。方波和R2R数模转换用的是P1口OUT0~3,结果还行,方波幅度接近5V,阶梯信号接近4V
DS1Z_QuickPrint6.png
方波空占比50%
回复 支持 反对

使用道具 举报

     
发表于 2023-2-1 14:18:16 | 显示全部楼层
其实阶梯波用DA芯片输出最方便,我这个三角波就是由41个阶梯波组成。
捕获.jpg

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-2-1 15:09:58 | 显示全部楼层
CXFLBH 发表于 2023-2-1 14:18
其实阶梯波用DA芯片输出最方便,我这个三角波就是由41个阶梯波组成。

感谢分享非常漂亮的三角波,DA芯片没用过,采用双定时器,交叉启动中断和定时器,三角波和阶梯信号都出来了,三角波反向峰峰值4V正向12V实际只有5V多,阶梯信号峰峰值也小,台阶还重叠了一个
DS1Z_QuickPrint12.png
DS1Z_QuickPrint13.png
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-28 06:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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