找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2154|回复: 10
收起左侧

stc15f104w单片机输出不同频率波形出现间断问题

[复制链接]
ID:675145 发表于 2020-7-30 10:37 | 显示全部楼层 |阅读模式
定时器2每2ms中断BUZ_count+1,10ms变化一次频率,频率由定时器0使能内部时钟输出到P3.5的波
  1. switch(BUZ_count)
  2. {
  3.         case 5:        INT_CLKO &= 0xFE;        //关闭P3.5内部时钟输出
  4.                         TR0 = 0;                        //定时器0关闭计时
  5.                         TL0 = 0x42;                        //设置定时初值
  6.                         TH0 = 0xEB;                        //设置定时初值                                        /177us/2.8khz
  7.                         TR0 = 1;                        //定时器0开始计时
  8.                         _nop_();
  9.                         _nop_();
  10.                         INT_CLKO |= 0X01;        //打开P3.5内部时钟输出
  11.                         LED=0;
  12.                         break;
  13.         case 10:INT_CLKO &= 0xFE;        //关闭P3.5内部时钟输出
  14.                         TR0 = 0;                        //定时器0关闭计时
  15.                         TL0 = 0xE6;                        //设置定时初值
  16.                         TH0 = 0xEC;                        //设置定时初值                                        /163us/3.05khz
  17.                         TR0 = 1;                        //定时器0开始计时
  18.                         _nop_();
  19.                         _nop_();
  20.                         _nop_();
  21.                         _nop_();
  22.                         INT_CLKO |= 0X01;        //打开P3.5内部时钟输出
  23.                         break;
  24.         case 15:INT_CLKO &= 0xFE;        //关闭P3.5内部时钟输出
  25.                         TR0 = 0;                        //定时器0关闭计时
  26.                         TL0 = 0x8A;                        //设置定时初值
  27.                         TH0 = 0xEE;                        //设置定时初值                                        /149us/3.3khz
  28.                         TR0 = 1;                        //定时器0开始计时
  29.                         INT_CLKO |= 0X01;        //打开P3.5内部时钟输出
  30.                         break;
  31.         case 20:INT_CLKO &= 0xFE;        //关闭P3.5内部时钟输出
  32.                         break;
  33. }
复制代码
每次变化前都有2MS时间的间隔,输出波形前加了_nop_();也没什么效果

大佬帮忙看看是哪里的问题
我怀疑是不是单片机自身开启定时器时需要2ms的稳定时间(盲猜。没有依据)如果是有没有解决的办法
单片机用的是STC15F104W,不可接外部晶振,只有内部晶振,设置的30MHZ


1596075329(1).jpg
回复

使用道具 举报

ID:807591 发表于 2020-7-30 11:41 | 显示全部楼层
每2ms中断一次,不是自己设置的么,,中断了以后执行什么,2ms空缺,就是程序问题
回复

使用道具 举报

ID:675145 发表于 2020-7-30 11:50 | 显示全部楼层
szb314 发表于 2020-7-30 11:41
每2ms中断一次,不是自己设置的么,,中断了以后执行什么,2ms空缺,就是程序问题

定时器2ms中断一次,每次BUZ_count这个变量+1,5次后(就是2ms*5=10MS)变化一次定时器0波形输出的时间
回复

使用道具 举报

ID:807591 发表于 2020-7-30 12:24 | 显示全部楼层
张小不懂 发表于 2020-7-30 11:50
定时器2ms中断一次,每次BUZ_count这个变量+1,5次后(就是2ms*5=10MS)变化一次定时器0波形输出的时间

程序问题,,buz_count 有清零么,,,,定时器不可能需要2ms启动的,想都不用想,,switch 语句 default 有时候有必要加上
回复

使用道具 举报

ID:147710 发表于 2020-7-30 12:29 | 显示全部楼层
把定时器2每2ms中断一次改为3ms中断一次,看空缺是不是跟着变为3ms。

评分

参与人数 1黑币 +10 收起 理由
张小不懂 + 10 很给力!

查看全部评分

回复

使用道具 举报

ID:675145 发表于 2020-7-30 13:21 | 显示全部楼层
XTXB 发表于 2020-7-30 12:29
把定时器2每2ms中断一次改为3ms中断一次,看空缺是不是跟着变为3ms。

老哥正解,已经可以了,改成100us影响不大
回复

使用道具 举报

ID:675145 发表于 2020-7-30 13:22 | 显示全部楼层
szb314 发表于 2020-7-30 12:24
程序问题,,buz_count 有清零么,,,,定时器不可能需要2ms启动的,想都不用想,,switch 语句 default 有时候有 ...

进入这段函数前已经清零过,楼下老哥已经解决了,是把定时器2的中断改小,间隔也小了,还是谢谢你
回复

使用道具 举报

ID:213173 发表于 2020-7-30 14:04 | 显示全部楼层
STC官方例程修改一下即可。
无标题.jpg

回复

使用道具 举报

ID:808485 发表于 2020-7-30 14:42 | 显示全部楼层
间隔随着定时器2的中断时间变化,那显然是定时器2相关代码出了问题。
全部代码也没多少,全贴出来看看吧。
回复

使用道具 举报

ID:675145 发表于 2020-7-30 16:20 | 显示全部楼层
gbchang 发表于 2020-7-30 14:42
间隔随着定时器2的中断时间变化,那显然是定时器2相关代码出了问题。
全部代码也没多少,全贴出来看看吧。

改成100us中断一次,影响不大,还有个问题我开了掉电唤醒功能,sbit KEY_ZD=P3^2;是震动开关经常扫描不到,去掉消抖都不行。不进入掉电模式就能正常扫描到,老哥帮我看看怎么改稳定一点,下面是全部代码
  1. #include "stc15.h"
  2. #include "intrins.h"

  3. typedef unsigned char u8;
  4. typedef unsigned short u16;
  5. typedef unsigned long u32;

  6. sbit LED=P3^0;                //LED灯
  7. sbit KEY_ZD=P3^2;        //震动开关
  8. sbit KEY_GL=P3^3;        //钢缆检测
  9. sbit KEY_SET=P3^4;        //设置开关

  10. u16 idata BUZ_count=0;
  11. u16 idata key_count=0;
  12. bit idata key_count_Flag=0;
  13. u8  idata BUZ_Write_Go=1;
  14. u16 idata T0_Starter=0xD5D0;
  15. void Timer0_Init()          //定时器0初始化函数
  16. {
  17.         AUXR |= 0x80;                //定时器时钟1T模式
  18.         TMOD &= 0xF0;                //设置定时器模式
  19.         TMOD &= ~0x04;                //设置定时器内部时钟输出
  20.         TL0 = T0_Starter&0xff;                        //设置定时初值
  21.         TH0 = (T0_Starter>>8)&0xff;                        //设置定时初值                /360us/1.4khz                                               
  22.         TR0 = 1;                        //定时器0开始计时
  23.         INT_CLKO |= 0X01;        //使能定时器0的时钟输出功能(P3.5)
  24. }
  25. void Timer2_Init()          //定时器2中断初始化函数
  26. {
  27.         AUXR |= 0x04;                //定时器时钟1T模式
  28.         T2L = 0x48;                        //设置定时初值
  29.         T2H = 0xF4;                        //设置定时初值                        /100us
  30.         AUXR |= 0x10;                //定时器2开始计时
  31.         IE2  |= 0x04;                //打开定时器2中断

  32.         EA =1;
  33. }
  34. void Init()
  35. {       
  36.         P3M1=0x00;
  37.         P3M0=0x20;                //P3.5口推挽输出
  38.         Timer0_Init();        //初始化定时器0,P3.5内部时钟输出
  39.         Timer2_Init();        //初始化定时器2,延时2MS
  40.         WKTCL = 30;                //设置唤醒周期488us*(49+1)=24.4ms
  41.         WKTCH = 0X80;        //打开掉电唤醒
  42.         LED=1;                        //LED灯
  43.         KEY_ZD=1;                //震动开关
  44.         KEY_GL=1;                //钢缆检测
  45.         KEY_SET=1;                //设置开关
  46. }
  47. void Timer2_Routine() interrupt 12                //定时器2中断
  48. {
  49.         BUZ_count++;
  50.         if(key_count_Flag)
  51.         {
  52.                 key_count++;
  53.         }
  54.         else
  55.                 key_count=0;
  56. }
  57. void KEY_Scan()
  58. {
  59.         static u8 idata KEY_Flag=0;
  60.         if(BUZ_Write_Go==0 && KEY_Flag==0 && KEY_SET==0)
  61.         {
  62.                 key_count_Flag=1;
  63.                 if(key_count>=500)
  64.                 {
  65.                         key_count_Flag=0;
  66.                         if(KEY_SET==0)
  67.                         {
  68.                                 BUZ_Write_Go=2;
  69.                                 KEY_Flag=1;
  70.                         }
  71.                 }
  72.         }
  73.         if(BUZ_Write_Go==0 && KEY_Flag==1 && KEY_ZD==0)
  74.         {
  75.                 key_count_Flag=1;
  76.                 if(key_count>=100 )
  77.                 {
  78.                         if(KEY_ZD==0)
  79.                         {
  80.                                 key_count_Flag=0;
  81.                                 BUZ_Write_Go=3;
  82.                                 KEY_Flag=2;
  83.                         }
  84.                 }
  85.         }
  86.         if(BUZ_Write_Go==0 && KEY_Flag==2 && KEY_ZD==0)
  87.         {
  88.                 key_count_Flag=1;
  89.                 if(key_count>=100)
  90.                 {
  91.                         key_count_Flag=0;
  92.                         if(KEY_ZD==0)
  93.                         {
  94.                                 BUZ_Write_Go=4;
  95.                         }
  96.                 }
  97.         }
  98.         if(KEY_GL==0)
  99.         {
  100.                 key_count_Flag=1;
  101.                 if(key_count>=500)
  102.                 {
  103.                         key_count_Flag=0;
  104.                         BUZ_Write_Go=4;
  105.                 }
  106.         }
  107. }
  108. void Buz_Ser()
  109. {
  110.         static u8 idata Num=0;
  111.         if(BUZ_Write_Go)
  112.         {
  113.                 switch(BUZ_Write_Go)
  114.                 {
  115.                         case 1:
  116.                         case 2:
  117.                                 {
  118.                                         switch(BUZ_count/20)
  119.                                         {
  120.                                                 case 5:        INT_CLKO |= 0X01;LED=0;break;
  121.                                                 case 30:INT_CLKO &= 0xfe;LED=1;break;
  122.                                                 case 35:BUZ_Write_Go=0;break;
  123.                                         }
  124.                                 }break;
  125.                         case 3:
  126.                                 {
  127.                                         switch(BUZ_count/20)
  128.                                         {
  129.                                                 case 5:
  130.                                                 case 500:
  131.                                                 case 1000:INT_CLKO |= 0X01;LED=0;break;
  132.                                                 case 250:
  133.                                                 case 750:
  134.                                                 case 1250:INT_CLKO &= 0xfe;LED=1;break;
  135.                                                 case 1253:BUZ_Write_Go=0;break;
  136.                                         }
  137.                                 }break;       
  138.                         case 4:
  139.                                 {
  140.                                         if(BUZ_count==90)
  141.                                         {
  142.                                                 BUZ_count=0;
  143.                                                 switch(Num)
  144.                                                 {
  145.                                                         case 0: T0_Starter=0xEB42;break;
  146.                                                         case 1:
  147.                                                         case 2:
  148.                                                         case 3:
  149.                                                         case 4:
  150.                                                         case 5:
  151.                                                         case 6: T0_Starter += 0x01A4;break;
  152.                                                         case 7:
  153.                                                         case 8:
  154.                                                         case 9:
  155.                                                         case 10:
  156.                                                         case 11:T0_Starter -= 0x01A4;break;
  157.                                                 }
  158.                                                 INT_CLKO &= 0xFE;                                //关闭P3.5内部时钟输出
  159.                                                 TR0 = 0;                                                //定时器0关闭计时
  160.                                                 TL0 = T0_Starter & 0xFF;                //设置定时初值
  161.                                                 TH0 = (T0_Starter>>8) & 0xFF;        //设置定时初值               
  162.                                                 TR0 = 1;                                                //定时器0开始计时
  163.                                                 INT_CLKO |= 0X01;                                //打开P3.5内部时钟输出
  164.                                                 if(Num==10)  LED=~LED;
  165.                                                 Num++;
  166.                                                 Num %=12;
  167.                                         }
  168.                                 }break;
  169.                 }
  170.         }
  171.         else
  172.         {
  173.                 BUZ_count=0;       
  174.         }
  175. }
  176. void Power_Down()
  177. {
  178.         if(BUZ_Write_Go==0 && key_count_Flag==0)
  179.         {
  180.                 _nop_();       
  181.                 _nop_();       
  182.                 _nop_();
  183.                 PCON=0X02;                //进入掉电模式
  184.                 _nop_();                //重新上电后现执行此语句,再执行中断
  185.                 _nop_();       
  186.                 _nop_();       
  187.                 _nop_();
  188.         }
  189. }
  190. void main()
  191. {
  192.         Init();
  193.         while(1)
  194.         {
  195.                 Power_Down();
  196.                 KEY_Scan();                //按键扫描
  197.                 Buz_Ser();                //蜂鸣器服务
  198.         }
  199. }
复制代码


回复

使用道具 举报

ID:675145 发表于 2020-7-30 16:29 | 显示全部楼层
发了两遍都通过了。。。。两遍是一样的,请忽略
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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