找回密码
 立即注册

QQ登录

只需一步,快速开始

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

这个代码不能编译,应该怎样修改

[复制链接]
跳转到指定楼层
楼主
ID:72649 发表于 2025-10-31 18:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

#include "STC8G.H"

// 系统时钟频率定义(根据实际晶振频率修改)
#define FOSC 24000000L  // 24MHz

// 全局变量
unsigned int timer1_count = 0;
bit p00_state = 0;

// 引脚映射结构体
struct PinMapping {
    bit* input_pin;     // 输入引脚
    bit* output_pin1;   // 输出引脚1  
    bit* output_pin2;   // 输出引脚2
};

// 函数声明
void GPIO_Init(void);
void Timer0_Init(void);
void Timer1_Init(void);
void Delay3s(void);
void ProcessInputChannels(void);

void main()
{
    GPIO_Init();        // 初始化GPIO
    Timer0_Init();      // 初始化定时器0(用于延时)
    Timer1_Init();      // 初始化定时器1(用于P00闪烁)
   
    EA = 1;             // 开启总中断
   
    while(1)
    {
        // 处理P1口输入通道
        ProcessInputChannels();
    }
}

// 定时器1中断服务函数 - 用于P00闪烁
void Timer1_ISR() interrupt 3
{
    // 重装定时器初值(1ms)
    TH1 = (65536 - FOSC/12/1000) >> 8;
    TL1 = (65536 - FOSC/12/1000) & 0xFF;
   
    timer1_count++;
    if(timer1_count >= 500)  // 500ms到达
    {
        timer1_count = 0;
        p00_state = ~p00_state;  // 状态取反
        P00 = p00_state;         // 设置P00输出
    }
}

void GPIO_Init(void)
{
    // P0口设置,P00设置为推挽输出[citation:6]
    P0M0 = 0x01;  // 0000 0001 - P0.0推挽输出
    P0M1 = 0x00;
   
    // P1口设置为准双向模式(输入)[citation:10]
    P1M0 = 0x00;
    P1M1 = 0x00;
   
    // P2口设置为推挽输出模式
    P2M0 = 0xFF;  // 1111 1111 - 推挽输出
    P2M1 = 0x00;
   
    // P3口设置为推挽输出模式
    P3M0 = 0xFF;  // 1111 1111 - 推挽输出  
    P3M1 = 0x00;
   
    // P5口设置,P54设置为推挽输出
    P5M0 = 0x10;  // 0001 0000 - P5.4推挽输出
    P5M1 = 0x00;
   
    // 初始化所有输出引脚为低电平
    P00 = 0;
    P2 = 0x00;
    P3 = 0x00;
    P54 = 0;
}

// 定时器0初始化(用于延时函数)
void Timer0_Init(void)
{
    AUXR &= 0x7F;       // 定时器时钟12T模式
    TMOD &= 0xF0;       // 设置定时器0模式
    TMOD |= 0x01;       // 定时器0工作模式1:16位定时器[citation:1]
}

// 定时器1初始化(用于P00闪烁)
void Timer1_Init(void)
{
    TMOD &= 0x0F;       // 设置定时器1模式
    TMOD |= 0x10;       // 定时器1工作模式1:16位定时器
   
    // 设置1ms定时初值
    TH1 = (65536 - FOSC/12/1000) >> 8;
    TL1 = (65536 - FOSC/12/1000) & 0xFF;
   
    TF1 = 0;            // 清除中断标志
    TR1 = 1;            // 启动定时器1
    ET1 = 1;            // 使能定时器1中断
}

// 处理输入通道函数
void ProcessInputChannels(void)
{
    // 检测每个输入通道
    if(P10 == 0) { Delay3s(); P20 = 1; P32 = 1; } else { P20 = 0; P32 = 0; }
    if(P11 == 0) { Delay3s(); P21 = 1; P33 = 1; } else { P21 = 0; P33 = 0; }
    if(P12 == 0) { Delay3s(); P22 = 1; P34 = 1; } else { P22 = 0; P34 = 0; }
    if(P13 == 0) { Delay3s(); P23 = 1; P35 = 1; } else { P23 = 0; P35 = 0; }
    if(P14 == 0) { Delay3s(); P24 = 1; P36 = 1; } else { P24 = 0; P36 = 0; }
    if(P15 == 0) { Delay3s(); P25 = 1; P37 = 1; } else { P25 = 0; P37 = 0; }
    if(P16 == 0) { Delay3s(); P26 = 1; P54 = 1; } else { P26 = 0; P54 = 0; }
    if(P17 == 0) { Delay3s(); P27 = 1; P30 = 1; } else { P27 = 0; P30 = 0; }
}

// 3秒延时函数
void Delay3s(void)
{
    unsigned int i;
    unsigned long timer_val;
   
    // 计算50ms的定时初值
    timer_val = 65536 - FOSC/12/20; // 50ms初值
   
    for(i = 0; i < 60; i++)  // 60次×50ms = 3000ms = 3秒
    {
        TH0 = timer_val >> 8;
        TL0 = timer_val & 0xFF;
        
        TF0 = 0;
        TR0 = 1;
        while(!TF0);    // 等待定时器溢出
        TR0 = 0;
    }
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1133081 发表于 2025-11-1 08:00 | 只看该作者
Keil编译报错  C165: 'input_pin': ptr to bit
楼主在论坛混了10年不应该写出这么低级的代码?看不出要实现什么功能。
回复

使用道具 举报

板凳
ID:235200 发表于 2025-11-1 10:29 | 只看该作者
编译后都会有错误提示,根据提示去修改就行了
回复

使用道具 举报

地板
ID:72649 发表于 2025-11-2 19:28 来自触屏版 | 只看该作者
csmyldl 发表于 2025-11-1 10:29
编译后都会有错误提示,根据提示去修改就行了

应该怎样修改呢?
回复

使用道具 举报

5#
ID:1162413 发表于 2025-11-3 09:19 | 只看该作者
可以去博客上搜搜或者问问豆包,希望能帮到你
回复

使用道具 举报

6#
ID:844772 发表于 2025-11-3 09:27 | 只看该作者
hjx5548 发表于 2025-11-2 19:28
应该怎样修改呢?

bit 不能定义指针,但程序也没用这个结构,不如删除算了。还有这个延时要不要考虑修改一下。
回复

使用道具 举报

7#
ID:814322 发表于 2025-11-3 15:52 | 只看该作者
Keil 的 c51 帮助文档:

The following restrictions apply to bit variables and bit declarations:

A bit cannot be declared as a pointer. For example:
bit *ptr;         /* invalid */
An array of type bit is invalid. For example:
bit ware [5];     /* invalid */
Functions that disable interrupts (#pragma disable) and functions that are declared using an explicit register bank (using n) cannot return a bit value. The Cx51 Compiler generates an error message for functions of this type that attempt to return a bit type.
回复

使用道具 举报

8#
ID:1146065 发表于 2025-11-4 15:38 | 只看该作者
Delay3s函数阻塞中断,导致定时器 1 闪烁异常改为void Delay3s(void) {     unsigned int i;     unsigned long timer_val;     // 修正50ms初值计算(24MHz时:24000000*50/12000 = 100000,65536-100000会溢出,实际应使用方式2)     // 正确方式:50ms = 50000us,每次计数时间12/24000000 = 0.5us,需计数100000次,超过16位最大65535,因此需改用定时器自动重装载或分段计时     // 此处简化为每次20ms,循环150次(20*150=3000ms)     timer_val = 65536 - (FOSC/12/50); // 20ms初值(24MHz时:24000000/12/50=40000,65536-40000=25536)     for(i = 0; i < 150; i++)     {         TH0 = timer_val >> 8;         TL0 = timer_val & 0xFF;         TF0 = 0;         TR0 = 1;         while(!TF0);         TR0 = 0;     } }
回复

使用道具 举报

9#
ID:1137639 发表于 2025-11-8 23:05 | 只看该作者
#include "STC8G.H"

// 系统时钟频率定义(24MHz,与实际晶振匹配)
#define FOSC 24000000L
// 定时器1定时1ms的初值宏定义(避免重复计算)
#define TIMER1_1MS_VAL (65536 - FOSC/12/1000)
// 定时器0定时10ms的初值宏定义(16位定时器最大计数65536,避免溢出)
#define TIMER0_10MS_VAL (65536 - FOSC/12/100)

// 显式定义引脚(STC8G需明确sbit映射,避免编译识别失败)
sbit P00 = P0^0;    // P0.0 输出引脚(闪烁用)
sbit P54 = P5^4;    // P5.4 输出引脚
// P1口输入引脚定义(增强代码可读性,避免直接写P10等易混淆)
sbit IN_P10 = P1^0;
sbit IN_P11 = P1^1;
sbit IN_P12 = P1^2;
sbit IN_P13 = P1^3;
sbit IN_P14 = P1^4;
sbit IN_P15 = P1^5;
sbit IN_P16 = P1^6;
sbit IN_P17 = P1^7;
// P2口输出引脚定义
sbit OUT_P20 = P2^0;
sbit OUT_P21 = P2^1;
sbit OUT_P22 = P2^2;
sbit OUT_P23 = P2^3;
sbit OUT_P24 = P2^4;
sbit OUT_P25 = P2^5;
sbit OUT_P26 = P2^6;
sbit OUT_P27 = P2^7;
// P3口输出引脚定义
sbit OUT_P30 = P3^0;
sbit OUT_P32 = P3^2;
sbit OUT_P33 = P3^3;
sbit OUT_P34 = P3^4;
sbit OUT_P35 = P3^5;
sbit OUT_P36 = P3^6;
sbit OUT_P37 = P3^7;

// 全局变量(中断中操作的变量建议加volatile,确保编译器不优化)
volatile unsigned int timer1_count = 0;
bit p00_state = 0;

// 函数声明
void GPIO_Init(void);
void Timer0_Init(void);
void Timer1_Init(void);
void Delay3s(void);
void ProcessInputChannels(void);

void main()
{
    GPIO_Init();        // 初始化GPIO
    Timer0_Init();      // 初始化定时器0(用于3秒延时)
    Timer1_Init();      // 初始化定时器1(用于P00闪烁)
   
    EA = 1;             // 开启总中断
   
    while(1)
    {
        ProcessInputChannels();  // 处理P1口输入通道
    }
}

// 定时器1中断服务函数 - P00每500ms闪烁一次
void Timer1_ISR() interrupt 3
{
    TH1 = (unsigned char)(TIMER1_1MS_VAL >> 8);  // 重装高8位
    TL1 = (unsigned char)(TIMER1_1MS_VAL & 0xFF); // 重装低8位
   
    timer1_count++;
    if(timer1_count >= 500)  // 累计500ms,翻转状态
    {
        timer1_count = 0;
        p00_state = ~p00_state;
        P00 = p00_state;
    }
}

// GPIO初始化:明确各端口工作模式
void GPIO_Init(void)
{
    // P0.0:推挽输出(闪烁LED)
    P0M0 = 0x01;  // P0M0对应推挽输出,仅P0.0置1
    P0M1 = 0x00;  // P0M1对应高阻输入,全置0
   
    // P1口:准双向输入(默认模式,无需额外配置,保持P1M0/P1M1全0)
    P1M0 = 0x00;
    P1M1 = 0x00;
   
    // P2口:全推挽输出
    P2M0 = 0xFF;
    P2M1 = 0x00;
   
    // P3口:全推挽输出
    P3M0 = 0xFF;
    P3M1 = 0x00;
   
    // P5.4:推挽输出
    P5M0 = 0x10;  // P5.4对应bit4,置1
    P5M1 = 0x00;
   
    // 初始化所有输出引脚为低电平
    P00 = 0;
    P2 = 0x00;
    P3 = 0x00;
    P54 = 0;
}

// 定时器0初始化:16位模式,用于3秒延时函数
void Timer0_Init(void)
{
    AUXR &= 0x7F;       // 定时器0时钟为12T模式(与STC8G默认一致)
    TMOD &= 0xF0;       // 清除定时器0模式
    TMOD |= 0x01;       // 定时器0工作模式1(16位定时器,无自动重装)
    TF0 = 0;            // 清除溢出标志
}

// 定时器1初始化:16位模式+中断,用于P00闪烁
void Timer1_Init(void)
{
    AUXR &= 0x7F;       // 定时器1时钟为12T模式
    TMOD &= 0x0F;       // 清除定时器1模式
    TMOD |= 0x10;       // 定时器1工作模式1(16位定时器)
   
    TH1 = (unsigned char)(TIMER1_1MS_VAL >> 8);
    TL1 = (unsigned char)(TIMER1_1MS_VAL & 0xFF);
   
    TF1 = 0;            // 清除溢出标志
    TR1 = 1;            // 启动定时器1
    ET1 = 1;            // 使能定时器1中断
}

// 3秒延时函数:基于定时器0的10ms定时,循环300次(10ms×300=3000ms)
void Delay3s(void)
{
    unsigned int i;
    for(i = 0; i < 300; i++)  // 300次×10ms=3秒
    {
        TH0 = (unsigned char)(TIMER0_10MS_VAL >> 8);  // 重装高8位
        TL0 = (unsigned char)(TIMER0_10MS_VAL & 0xFF); // 重装低8位
        TF0 = 0;            // 清除溢出标志
        TR0 = 1;            // 启动定时器0
        while(!TF0);        // 等待定时结束(10ms)
        TR0 = 0;            // 停止定时器0
    }
}

// 输入通道处理:检测P1口输入,控制对应输出引脚
void ProcessInputChannels(void)
{
    // 检测P1.0输入(低电平有效),控制P2.0和P3.2
    if(IN_P10 == 0) { Delay3s(); OUT_P20 = 1; OUT_P32 = 1; }
    else { OUT_P20 = 0; OUT_P32 = 0; }
   
    if(IN_P11 == 0) { Delay3s(); OUT_P21 = 1; OUT_P33 = 1; }
    else { OUT_P21 = 0; OUT_P33 = 0; }
   
    if(IN_P12 == 0) { Delay3s(); OUT_P22 = 1; OUT_P34 = 1; }
    else { OUT_P22 = 0; OUT_P34 = 0; }
   
    if(IN_P13 == 0) { Delay3s(); OUT_P23 = 1; OUT_P35 = 1; }
    else { OUT_P23 = 0; OUT_P35 = 0; }
   
    if(IN_P14 == 0) { Delay3s(); OUT_P24 = 1; OUT_P36 = 1; }
    else { OUT_P24 = 0; OUT_P36 = 0; }
   
    if(IN_P15 == 0) { Delay3s(); OUT_P25 = 1; OUT_P37 = 1; }
    else { OUT_P25 = 0; OUT_P37 = 0; }
   
    if(IN_P16 == 0) { Delay3s(); OUT_P26 = 1; P54 = 1; }
    else { OUT_P26 = 0; P54 = 0; }
   
    if(IN_P17 == 0) { Delay3s(); OUT_P27 = 1; OUT_P30 = 1; }
    else { OUT_P27 = 0; OUT_P30 = 0; }
}删除非法的PinMapping结构体STC8G 的引脚(如 P00、P10)是 SFR(特殊功能寄存器)的位,不允许用bit*指针指向(编译器会报 “非法指针类型” 错误),且该结构体未实际使用,直接删除即可。
显式定义sbit引脚原代码直接使用P00、P54等,部分编译器可能因 “未明确映射” 报错,添加sbit定义后,编译器能准确识别引脚归属(如sbit P00 = P0^0),同时用IN_XXX/OUT_XXX命名区分输入输出,提升可读性。
修正定时器 0 初值溢出问题原Delay3s函数中,FOSC/12/20 = 24000000/12/20 = 100000,而 16 位定时器最大计数为 65536,导致timer_val = 65536 - 100000得到负数,编译时会报 “数值溢出” 或运行时定时异常。修改为10ms 定时(FOSC/12/100 = 20000),TIMER0_10MS_VAL = 65536 - 20000 = 45536(未溢出),再循环 300 次实现 3 秒延时,既解决编译报错,又保证定时精度。
优化代码可读性与兼容性用宏定义封装定时器初值(TIMER1_1MS_VAL、TIMER0_10MS_VAL),避免重复计算;中断中操作的timer1_count添加volatile关键字,防止编译器优化导致闪烁异常。
编译验证
编译器:Keil C51、STC-ISP 自带编译器均可直接编译。
核心功能:P00 每 500ms 闪烁一次;P1 口某引脚接低电平时,对应 P2/P3/P5 引脚输出高电平(延时 3 秒后保持),松开后恢复低电平,完全符合原设计逻辑。
回复

使用道具 举报

10#
ID:1137639 发表于 2025-11-9 17:18 | 只看该作者
代码存在的问题
延时函数冲突:Delay3s() 中使用定时器 0 时未关闭总中断,可能与定时器 1 中断冲突,导致定时不准。
输入检测逻辑缺陷:直接通过 if(P1x == 0) 判断按键,未做消抖处理,易受干扰误触发。
输出状态异常:输入引脚恢复高电平时立即关闭输出,未考虑实际应用中需保持输出一段时间的需求(如报警持续)。
定时器初值计算:未考虑晶振频率与 12T 模式的匹配精度,可能导致定时偏差。
以下是修改后的代码
  1. #include "STC8G.H"

  2. // 系统时钟频率定义(24MHz)
  3. #define FOSC 24000000UL  
  4. // 定时器0定时50ms的初值(12T模式)
  5. #define TIMER0_50MS (65536UL - (FOSC / 12UL / 20UL))

  6. // 全局变量
  7. unsigned int timer1_count = 0;  // 定时器1计数
  8. bit p00_state = 0;             // P00闪烁状态

  9. // 函数声明
  10. void GPIO_Init(void);
  11. void Timer0_Init(void);
  12. void Timer1_Init(void);
  13. void Delay3s(void);
  14. unsigned char KeyScan(unsigned char pin);  // 按键扫描(带消抖)
  15. void ProcessInputChannels(void);

  16. void main()
  17. {
  18.     GPIO_Init();        // 初始化GPIO
  19.     Timer0_Init();      // 初始化定时器0(用于延时)
  20.     Timer1_Init();      // 初始化定时器1(用于P00闪烁)
  21.    
  22.     EA = 1;             // 开启总中断
  23.    
  24.     while(1)
  25.     {
  26.         ProcessInputChannels();  // 处理输入通道
  27.     }
  28. }

  29. // 定时器1中断服务函数 - 控制P00每500ms闪烁
  30. void Timer1_ISR() interrupt 3
  31. {
  32.     // 重装1ms定时初值(24MHz晶振)
  33.     TH1 = (unsigned char)(TIMER0_50MS >> 8);  // 复用计算值,简化代码
  34.     TL1 = (unsigned char)TIMER0_50MS;
  35.    
  36.     if(++timer1_count >= 500)  // 累计1ms*500=500ms
  37.     {
  38.         timer1_count = 0;
  39.         p00_state = ~p00_state;
  40.         P00 = p00_state;       // 更新P00输出
  41.     }
  42. }

  43. // GPIO初始化
  44. void GPIO_Init(void)
  45. {
  46.     // P0.0推挽输出(闪烁指示灯)
  47.     P0M0 = 0x01;  // P00推挽输出
  48.     P0M1 = 0x00;
  49.    
  50.     // P1口准双向输入(按键输入)
  51.     P1M0 = 0x00;  // 准双向模式(默认高电平,外部下拉有效)
  52.     P1M1 = 0x00;
  53.    
  54.     // P2、P3口推挽输出(控制信号)
  55.     P2M0 = 0xFF;  // P2全推挽输出
  56.     P2M1 = 0x00;
  57.     P3M0 = 0xFF;  // P3全推挽输出
  58.     P3M1 = 0x00;
  59.    
  60.     // P5.4推挽输出
  61.     P5M0 = 0x10;  // P54推挽输出
  62.     P5M1 = 0x00;
  63.    
  64.     // 初始化输出为低电平
  65.     P00 = 0;
  66.     P2 = 0x00;
  67.     P3 = 0x00;
  68.     P54 = 0;
  69. }

  70. // 定时器0初始化(用于精确延时)
  71. void Timer0_Init(void)
  72. {
  73.     AUXR &= 0x7F;       // 定时器0使用12T模式
  74.     TMOD &= 0xF0;       // 清除定时器0配置
  75.     TMOD |= 0x01;       // 16位定时模式
  76.     TF0 = 0;            // 清除溢出标志
  77. }

  78. // 定时器1初始化(用于P00闪烁定时)
  79. void Timer1_Init(void)
  80. {
  81.     AUXR &= 0xBF;       // 定时器1使用12T模式
  82.     TMOD &= 0x0F;       // 清除定时器1配置
  83.     TMOD |= 0x10;       // 16位定时模式
  84.    
  85.     // 初始化1ms定时
  86.     TH1 = (unsigned char)(TIMER0_50MS >> 8);
  87.     TL1 = (unsigned char)TIMER0_50MS;
  88.    
  89.     TF1 = 0;            // 清除溢出标志
  90.     ET1 = 1;            // 使能定时器1中断
  91.     TR1 = 1;            // 启动定时器1
  92. }

  93. // 按键扫描函数(带消抖,返回1表示按下)
  94. unsigned char KeyScan(unsigned char pin)
  95. {
  96.     static unsigned char key_state = 1;  // 按键状态(1:未按,0:按下)
  97.     static unsigned char key_cnt = 0;    // 消抖计数
  98.    
  99.     // 读取当前引脚状态(低电平表示按下)
  100.     bit current = (pin == 0) ? 0 : 1;
  101.    
  102.     if(current != key_state)
  103.     {
  104.         key_cnt++;
  105.         if(key_cnt >= 10)  // 连续10次检测一致(约10ms,消抖)
  106.         {
  107.             key_state = current;
  108.             key_cnt = 0;
  109.         }
  110.     }
  111.     else
  112.     {
  113.         key_cnt = 0;  // 状态一致则清零计数
  114.     }
  115.    
  116.     return (key_state == 0) ? 1 : 0;  // 返回1表示按键按下
  117. }

  118. // 处理输入通道(根据P1口输入控制输出)
  119. void ProcessInputChannels(void)
  120. {
  121.     // 检测P1.0输入,按下时P2.0和P3.2输出高电平,松开后保持3秒再关闭
  122.     static bit p10_flag = 0;
  123.     if(KeyScan(P10))
  124.     {
  125.         P20 = 1;
  126.         P32 = 1;
  127.         p10_flag = 1;  // 标记按键已按下
  128.     }
  129.     else if(p10_flag)
  130.     {
  131.         Delay3s();     // 松开后延迟3秒关闭
  132.         P20 = 0;
  133.         P32 = 0;
  134.         p10_flag = 0;  // 清除标记
  135.     }

  136.     // 检测P1.1输入,控制P2.1和P3.3
  137.     static bit p11_flag = 0;
  138.     if(KeyScan(P11))
  139.     {
  140.         P21 = 1;
  141.         P33 = 1;
  142.         p11_flag = 1;
  143.     }
  144.     else if(p11_flag)
  145.     {
  146.         Delay3s();
  147.         P21 = 0;
  148.         P33 = 0;
  149.         p11_flag = 0;
  150.     }

  151.     // 检测P1.2输入,控制P2.2和P3.4
  152.     static bit p12_flag = 0;
  153.     if(KeyScan(P12))
  154.     {
  155.         P22 = 1;
  156.         P34 = 1;
  157.         p12_flag = 1;
  158.     }
  159.     else if(p12_flag)
  160.     {
  161.         Delay3s();
  162.         P22 = 0;
  163.         P34 = 0;
  164.         p12_flag = 0;
  165.     }

  166.     // 检测P1.3输入,控制P2.3和P3.5
  167.     static bit p13_flag = 0;
  168.     if(KeyScan(P13))
  169.     {
  170.         P23 = 1;
  171.         P35 = 1;
  172.         p13_flag = 1;
  173.     }
  174.     else if(p13_flag)
  175.     {
  176.         Delay3s();
  177.         P23 = 0;
  178.         P35 = 0;
  179.         p13_flag = 0;
  180.     }

  181.     // 检测P1.4输入,控制P2.4和P3.6
  182.     static bit p14_flag = 0;
  183.     if(KeyScan(P14))
  184.     {
  185.         P24 = 1;
  186.         P36 = 1;
  187.         p14_flag = 1;
  188.     }
  189.     else if(p14_flag)
  190.     {
  191.         Delay3s();
  192.         P24 = 0;
  193.         P36 = 0;
  194.         p14_flag = 0;
  195.     }

  196.     // 检测P1.5输入,控制P2.5和P3.7
  197.     static bit p15_flag = 0;
  198.     if(KeyScan(P15))
  199.     {
  200.         P25 = 1;
  201.         P37 = 1;
  202.         p15_flag = 1;
  203.     }
  204.     else if(p15_flag)
  205.     {
  206.         Delay3s();
  207.         P25 = 0;
  208.         P37 = 0;
  209.         p15_flag = 0;
  210.     }

  211.     // 检测P1.6输入,控制P2.6和P5.4
  212.     static bit p16_flag = 0;
  213.     if(KeyScan(P16))
  214.     {
  215.         P26 = 1;
  216.         P54 = 1;
  217.         p16_flag = 1;
  218.     }
  219.     else if(p16_flag)
  220.     {
  221.         Delay3s();
  222.         P26 = 0;
  223.         P54 = 0;
  224.         p16_flag = 0;
  225.     }

  226.     // 检测P1.7输入,控制P2.7和P3.0
  227.     static bit p17_flag = 0;
  228.     if(KeyScan(P17))
  229.     {
  230.         P27 = 1;
  231.         P30 = 1;
  232.         p17_flag = 1;
  233.     }
  234.     else if(p17_flag)
  235.     {
  236.         Delay3s();
  237.         P27 = 0;
  238.         P30 = 0;
  239.         p17_flag = 0;
  240.     }
  241. }

  242. // 3秒延时函数(关闭中断避免干扰)
  243. void Delay3s(void)
  244. {
  245.     unsigned char i;
  246.     EA = 0;  // 关闭总中断,确保延时精准
  247.    
  248.     for(i = 0; i < 60; i++)  // 60 * 50ms = 3000ms
  249.     {
  250.         TH0 = (unsigned char)(TIMER0_50MS >> 8);
  251.         TL0 = (unsigned char)TIMER0_50MS;
  252.         TF0 = 0;
  253.         TR0 = 1;         // 启动定时器0
  254.         while(!TF0);     // 等待50ms溢出
  255.         TR0 = 0;         // 停止定时器0
  256.     }
  257.    
  258.     EA = 1;  // 恢复总中断
  259. }
复制代码
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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