找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 279|回复: 9
打印 上一主题 下一主题
收起左侧

师傅们帮忙看看单片机是STC15F104W怎么不运行呢

[复制链接]
跳转到指定楼层
楼主
ID:63317 发表于 2025-6-13 10:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
按键按一次一分钟定时再按一次是3分钟定时控制P3^3口
单片机是STC15F104W
#include<reg51.h>

#define uchar unsigned char
#define uint unsigned int

sbit key = P3^2; // 按键连接在P3.2引脚
sbit led = P3^3; // LED连接在P3.3引脚
uchar key_press_count = 0; // 按键按下次数
bit timer_running = 0; // 定时器运行状态
uint timer_count = 0; // 定时计数
uchar timer_mode = 0; // 定时模式,0表示未设置,1表示1分钟,2表示3分钟

// 定时器初始化函数
void Timer0Init()
{
    TMOD &= 0xF0; // 清除定时器0的模式位
    TMOD |= 0x01; // 设置定时器0为模式1(16位定时器)
    TH0 = (65536 - 50000) / 256; // 设置定时初值,定时50ms(假设12MHz晶振)
    TL0 = (65536 - 50000) % 256;
    ET0 = 1; // 开启定时器0中断
    TR0 = 0; // 关闭定时器0
}

// 定时器0中断服务函数
void Timer0_ISR() interrupt 1
{
    TH0 = (65536 - 50000) / 256; // 重新加载定时初值
    TL0 = (65536 - 50000) % 256;
    if(timer_running) // 如果定时器正在运行
    {
        timer_count++; // 增加计数
        if(timer_mode == 1 && timer_count >= 120000) // 1分钟定时
        {
            timer_running = 0; // 停止定时器
            timer_count = 0; // 清零计数
            led = 0; // 关闭LED
        }
        else if(timer_mode == 2 && timer_count >= 360000) // 3分钟定时
        {
            timer_running = 0; // 停止定时器
            timer_count = 0; // 清零计数
            led = 0; // 关闭LED
        }
    }
}

// 按键扫描函数
void key_scan()
{
    if(key == 0) // 检测按键是否按下
    {
        delay(10); // 消抖
        if(key == 0)
        {
            while(!key); // 等待按键释放
            key_press_count++; // 增加按键次数
            if(key_press_count == 1) // 第一次按下按键
            {
                timer_mode = 1; // 设置定时模式为1分钟
            }
            else if(key_press_count == 2) // 第二次按下按键
            {
                timer_mode = 2; // 设置定时模式为3分钟
            }
            if(timer_mode > 0) // 如果设置了定时模式
            {
                timer_running = 1; // 启动定时器
                timer_count = 0; // 清零计数
                led = 1; // 打开LED
            }
        }
    }
}

// 延时函数
void delay(uint z)
{
    uint x, y;
    for(x=z; x>0; x--)
        for(y=110; y>0; y--);
}

void main()
{
    Timer0Init(); // 初始化定时器
    EA = 1; // 开启总中断
    led = 0; // 初始化LED状态为关闭
    while(1)
    {
        key_scan(); // 按键扫描
    }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:592807 发表于 2025-6-13 13:55 | 只看该作者
if可以单独用  if...else...可以组合用  if...else if....else也可以组合用,但是呢你if...else if...肯定是不行的,你按一下按键你的key_press_count度不知道变成多少了,

评分

参与人数 1黑币 +11 收起 理由
WFX777888 + 11 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

板凳
ID:1153069 发表于 2025-6-13 16:11 | 只看该作者
key_press_count有清零吗,按两次以上的时候都没有执行语句了
回复

使用道具 举报

地板
ID:1133081 发表于 2025-6-13 17:30 | 只看该作者
  1. //按键按一次一分钟定时再按一次是3分钟定时控制P3^3口
  2. //单片机是STC15F104W
  3. #include<reg51.h>

  4. #define uchar unsigned char
  5. #define uint unsigned int

  6. sbit key = P3^2; // 按键连接在P3.2引脚
  7. sbit led = P3^3; // LED连接在P3.3引脚
  8. uchar key_press_count = 0; // 按键按下次数
  9. //bit timer_running = 0; // 定时器运行状态
  10. uint timer_count = 0; // 定时计数
  11. //uchar timer_mode = 0; // 定时模式,0表示未设置,1表示1分钟,2表示3分钟

  12. // 定时器初始化函数
  13. void Timer0Init()//50ms @11.0592
  14. {
  15.     TMOD = 0x01;
  16.     TH0 = 0x4C;
  17.     TL0 = 0x00;
  18.     EA = 1;
  19.     ET0 = 1;
  20.     TR0 = 1;
  21. }
  22. // 延时函数
  23. void delay(uint z)
  24. {
  25.     uint x, y;
  26.     for(x=z; x>0; x--)
  27.         for(y=110; y>0; y--);
  28. }

  29. // 按键扫描函数
  30. void key_scan()
  31. {
  32.         if(key == 0) // 检测按键是否按下
  33.         {
  34.                 delay(10); // 消抖
  35.                 if(key == 0)
  36.                 {
  37.                         key_press_count++; // 增加按键次数
  38.                         if(key_press_count>2)
  39.                                 key_press_count=0;
  40.                         if(key_press_count>0 && key_press_count<3)
  41.                                 led = 1;
  42.                         else led = 0;
  43.                         while(!key); // 等待按键释放
  44.                 }
  45.         }
  46. }
  47. void main()
  48. {
  49.     Timer0Init(); // 初始化定时器
  50.     led = 0; // 初始化LED状态为关闭
  51.     while(1)
  52.     {
  53.         key_scan(); // 按键扫描
  54.     }
  55. }
  56. // 定时器0中断服务函数
  57. void Timer0Interrupt(void) interrupt 1
  58. {
  59.     TH0 = 0x4C;
  60.     TL0 = 0x00;
  61.     if(key_press_count!=0) // 如果定时器正在运行
  62.     {
  63.         timer_count++; // 增加计数
  64.         if(key_press_count == 1 && timer_count >= 120000) // 1分钟定时
  65.         {
  66.             timer_count = 0; // 清零计数
  67.                                 key_press_count=0;
  68.             led = 0; // 关闭LED
  69.         }
  70.         else if(key_press_count == 2 && timer_count >= 360000) // 3分钟定时
  71.         {
  72.                                 timer_count = 0; // 清零计数
  73.                                 key_press_count=0;
  74.                                 led = 0; // 关闭LED
  75.         }
  76.     }
  77.     else
  78.         {
  79.         timer_count = 0; // 清零计数
  80.         led = 0; // 关闭LED
  81.         }
  82. }
复制代码

评分

参与人数 1黑币 +11 收起 理由
WFX777888 + 11 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

5#
ID:1034262 发表于 2025-6-13 21:17 | 只看该作者
先让定时器中断取反一个IO,示波器观察,看中断正常了没有?
回复

使用道具 举报

6#
ID:63317 发表于 2025-6-14 06:27 | 只看该作者

还是不好用啊感觉定时器没工作呢
回复

使用道具 举报

7#
ID:63317 发表于 2025-6-14 06:28 | 只看该作者
coody_sz 发表于 2025-6-13 21:17
先让定时器中断取反一个IO,示波器观察,看中断正常了没有?

没有示波器师傅
回复

使用道具 举报

8#
ID:1133081 发表于 2025-6-14 17:41 | 只看该作者
WFX777888 发表于 2025-6-14 06:27
还是不好用啊感觉定时器没工作呢

你原来程序里定时器没有打开进不了中断并且还有其他逻辑问题,所以不能正常工作。修改后的程序是经过仿真确认的。如果还不行要查电路是否正确。
回复

使用道具 举报

9#
ID:63317 发表于 2025-6-15 05:29 | 只看该作者
WL0123 发表于 2025-6-14 17:41
你原来程序里定时器没有打开进不了中断并且还有其他逻辑问题,所以不能正常工作。修改后的程序是经过仿真 ...

电路就带个指示灯 按键被按下指示灯亮了 就是没有延时关闭
回复

使用道具 举报

10#
ID:1007932 发表于 2025-6-16 02:16 | 只看该作者
  1. //按键按一次一分钟定时再按一次是3分钟定时控制P3^3口
  2. //单片机是STC15F104W
  3. #include<reg51.h>
  4. #include<intrins.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int

  7. sbit key = P3^2; // 按键连接在P3.2引脚
  8. sbit led = P3^3; // LED连接在P3.3引脚
  9. uchar key_press_count = 0; // 按键按下次数
  10. //bit timer_running = 0; // 定时器运行状态
  11. uint timer_count = 0; // 定时计数
  12. //uchar timer_mode = 0; // 定时模式,0表示未设置,1表示1分钟,2表示3分钟
  13. // 定时器初始化函数
  14. void Timer0Init()//50ms
  15. {
  16.     TMOD = 0xF0;
  17.     TH0 = (65536 - 50000) / 256;
  18.     TL0 = (65536 - 50000) % 256;
  19.     EA         = 1;
  20.     ET0 = 1;
  21.                 TF0        =        0;
  22.     TR0 = 0;
  23. }
  24. // 延时函数50MS
  25. void delay()
  26. {
  27.         unsigned char data i, j, k;
  28.         i = 3;
  29.         j = 72;
  30.         k = 161;
  31.         do
  32.         {
  33.                 do
  34.                 {
  35.                         while (--k);
  36.                 } while (--j);
  37.         } while (--i);
  38. }
  39. // 按键扫描函数
  40. void key_scan()
  41. {
  42.         if(key == 0) // 检测按键是否按下
  43.         {
  44.                 delay(); // 消抖
  45.                 if(key == 0)
  46.                                                                 while(!key); // 等待按键释放
  47.                 {
  48.                         key_press_count++; // 增加按键次数
  49.                         if(key_press_count==1){
  50.                                                                                                                                 timer_count=1200;
  51.                                 led = 1;
  52.                                                                                                                                 TR0 = 1;
  53.                                                                                                         }
  54.                                                                                                 else if(key_press_count==2){
  55.                                                                                                                                 timer_count=3600;
  56.                                 led = 1;
  57.                                                                                                                                 TR0 = 1;
  58.                                                                                                         }
  59.                                                                                                 else        {
  60.                                                                                                                                 key_press_count=0;
  61.                                                                                                                                 timer_count = 0;
  62.                                                                                                                                 led = 0;
  63.                                                                                                                                 TR0 = 0;
  64.                                                                                                         }
  65.                 }
  66.         }
  67. }
  68. void main()
  69. {
  70.     Timer0Init(); // 初始化定时器
  71.     led = 0; // 初始化LED状态为关闭
  72.     while(1)
  73.     {
  74.         key_scan(); // 按键扫描
  75.     }
  76. }
  77. // 定时器0中断服务函数
  78. void Timer0Interrupt(void) interrupt 1
  79. {
  80.                 timer_count--;
  81.                 if(timer_count==0)
  82.                         {
  83.                                         TR0=0;
  84.                                         led=0;
  85.                         }
  86. }
复制代码

代码BUG有点多,定时器是50ms中断一次,1min=60S=1200x50ms,不是120000啊!还有你中断一直没关,就这样吧,我这个是调试时用的,按第二次一直有个短脉冲,可能是杜邦线当按键的原因,你可以把延时消抖可以改小点。然后感觉思路有点问题,中断函数应该尽可能短,建议把定时器设置为16位自动重装模式,使用标志位或者像我那样控制,然后用switch把值给timer_count,定时器的开关一定要准,不然会软件定时一样误差比较大,然后记得给定时器中断关掉,最后建议重构。

评分

参与人数 1黑币 +11 收起 理由
WFX777888 + 11 OK谢谢

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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