统一区域内变量重名

本文通过一个简单的C++程序示例介绍了宏定义的使用方法以及局部与全局变量的作用域区别。示例中定义了几个宏来简化常量的声明,并展示了如何在一个函数内部声明局部变量并修改其值。
#define TRUE 1
#define FALSE 0
#define PI 3.1455
void fun()
{
    int a = 0;
    bool b = true;
    if(b)
    {
        int a = 100;
        a = a + 1;
    }
    cout << a << endl;
}
int main()
{
    int a[4] = {1,2,3,4};
    fun();
    return 0;
}

#include <reg51.h> // 引脚定义(清晰分类,可直接对接硬件) sbit ENA = P1^0; // 直流电机使能端 sbit IN1 = P1^1; // 直流电机正转控制 sbit IN2 = P1^2; // 直流电机反转控制 sbit BUZZER = P1^3; // 蜂鸣器(报警用,新增明确定义) // LCD相关引脚 sbit RS = P2^0; sbit RW = P2^1; sbit EN_LCD = P2^2; // 避免与全局变量重名,修改LCD使能引脚名 #define LCD_DATA P0 // LCD数据端口 // 全局变量声明(保留原有逻辑,补充注释) unsigned int count = 0; // 当前药片计数 bit count_flag = 0; // 计数防抖标志位 unsigned char pwm_val = 100; // PWM占空比(0-200),控制电机转速 bit motor_run = 0; // 直流电机运行标志 unsigned char step_seq[8] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09}; // 步进电机八拍序列 unsigned char step_cnt = 0; // 步进电机节拍计数 unsigned int set_num = 50; // 预设药片数量 bit fault_flag = 0; // 故障标志位(0=无故障,1=故障) // 函数声明(关键修改:移除bit*指针,适配方案2返回值传递) void Init_System(void); void LCD_Display(void); bit Key_Scan(bit auto_mode, unsigned int *set_num); // 修改:返回bit类型更新auto_mode void Motor_Start(void); void Motor_Stop(void); void Step_Motor_Run(unsigned int steps, bit dir); void Alarm_Control(void); void Manual_Control(void); void LCD_Init(void); void LCD_Write_Command(unsigned char cmd); void LCD_Write_Data(unsigned char dat); void LCD_Write_Num(unsigned int num); void LCD_Write_String(char *str); void Delay_ms(unsigned int ms); // 延时函数(12MHz晶振,精准毫秒延时,适配51单片机) void Delay_ms(unsigned int ms) { unsigned int i, j; for(i = 0; i < ms; i++) for(j = 114; j > 0; j--); } // 系统初始化函数(保留原有逻辑,稳定可靠) void Init_System(void) { // I/O口初始化:全部置高,默认关闭外设 P1 = 0xFF; P2 = 0xFF; P3 = 0xFF; P0 = 0xFF; // 定时器初始化:定时器0用于PWM,定时器1用于通用延时 TMOD = 0x11; // 定时器0、1均为16位自动重装模式 TH0 = (65536 - 100)/256; TL0 = (65536 - 100)%256; // 定时100µs,用于PWM生成 TH1 = (65536 - 1000)/256; TL1 = (65536 - 1000)%256; // 定时1ms,用于系统扫描/防抖 ET0 = 1; // 使能定时器0中断 ET1 = 1; // 使能定时器1中断 IT0 = 1; // 外部中断0下降沿触发(药片计数传感器) IT1 = 1; // 外部中断1下降沿触发(故障/药瓶检测传感器) EX0 = 1; // 使能外部中断0 EX1 = 1; // 使能外部中断1 EA = 1; // 开启总中断 TR1 = 1; // 启动定时器1 LCD_Init(); // LCD初始化 } // LCD初始化函数(8位模式,适配P0口,初始化稳定) void LCD_Init(void) { Delay_ms(15); // 上电延时,确保LCD稳定 LCD_Write_Command(0x38); // 8位数据,2行显示,5*7点阵 LCD_Write_Command(0x0C); // 开显示,关闭光标 LCD_Write_Command(0x06); // 光标自动右移,不移动屏幕 LCD_Write_Command(0x01); // 清屏 Delay_ms(2); // 清屏延时 } // LCD写命令函数(适配修改后的EN_LCD引脚) void LCD_Write_Command(unsigned char cmd) { RS = 0; RW = 0; LCD_DATA = cmd; EN_LCD = 1; Delay_ms(1); EN_LCD = 0; Delay_ms(2); } // LCD写数据函数(适配修改后的EN_LCD引脚) void LCD_Write_Data(unsigned char dat) { RS = 1; RW = 0; LCD_DATA = dat; EN_LCD = 1; Delay_ms(1); EN_LCD = 0; Delay_ms(2); } // LCD写数字函数(3位显示,适配set_num/count(1-999)范围) void LCD_Write_Num(unsigned int num) { LCD_Write_Data((num / 100) % 10 + '0'); // 百位 LCD_Write_Data((num / 10) % 10 + '0'); // 十位 LCD_Write_Data(num % 10 + '0'); // 个位 } // LCD写字符串函数(逐字符写入,兼容ASCII码) void LCD_Write_String(char *str) { while(*str != '\0') { LCD_Write_Data(*str); str++; } } // LCD显示函数(保留原有逻辑,信息直观清晰) void LCD_Display(void) { LCD_Write_Command(0x80); // 第一行起始地址(0x80) LCD_Write_Data('S'); LCD_Write_Data('E'); LCD_Write_Data('T'); LCD_Write_Data(':'); LCD_Write_Num(set_num); // 显示预设药片数量 LCD_Write_Command(0xC0); // 第二行起始地址(0xC0) LCD_Write_Data('C'); LCD_Write_Data('U'); LCD_Write_Data('R'); LCD_Write_Data(':'); LCD_Write_Num(count); // 显示当前药片计数 // 显示电机运行状态 if(motor_run == 1) { LCD_Write_String(" RUN "); } else { LCD_Write_String(" STOP"); } } // 外部中断0服务函数(药片计数,防抖优化,防止误触发) void Int0_ISR(void) interrupt 0 { static unsigned int time = 0; if(count_flag == 0) { time++; if(time >= 5) // 防抖:累计5次触发才计数,过滤干扰 { count++; if(count > 999) count = 999; // 计数溢出保护,避免超出显示范围 time = 0; count_flag = 1; // 置位标志,防止重复计数 } } else { time--; if(time <= 0) { count_flag = 0; // 清零标志,允许下次计数 time = 0; } } } // 定时器0中断服务函数(PWM生成,控制直流电机转速) void Timer0_ISR(void) interrupt 1 { static unsigned char pwm_cnt = 0; // 重装定时器初值,保证PWM周期稳定 TH0 = (65536 - 100)/256; TL0 = (65536 - 100)%256; pwm_cnt++; if(pwm_cnt >= 200) pwm_cnt = 0; // PWM周期20ms(200*100µs) // PWM调速逻辑:根据pwm_val控制电机转速 if(motor_run == 1) { if(pwm_cnt < pwm_val) ENA = 1; else ENA = 0; } else ENA = 0; // 电机停止时,关闭使能端,降低功耗 } // 直流电机启动函数(正转,驱动出药装置,启动PWM) void Motor_Start(void) { IN1 = 1; IN2 = 0; motor_run = 1; TR0 = 1; // 启动定时器0,生成PWM波形 } // 直流电机停止函数(停止出药,关闭PWM) void Motor_Stop(void) { IN1 = 0; IN2 = 0; motor_run = 0; TR0 = 0; // 停止定时器0,关闭PWM输出 } // 步进电机运行函数(送瓶/移瓶,dir=1正转,dir=0反转,修复负数报错) void Step_Motor_Run(unsigned int steps, bit dir) { unsigned int i; for(i=0; i<steps; i++) { if(dir == 1) // 正转:节拍递增 { step_cnt++; if(step_cnt >= 8) step_cnt = 0; } else // 反转:避免unsigned char负数,先判断再递减 { if(step_cnt == 0) step_cnt = 7; else step_cnt--; } // P1口高4位控制步进电机,低4位保留(不影响直流电机/蜂鸣器) P1 = (P1 & 0x0F) | (step_seq[step_cnt] << 4); Delay_ms(2); // 步进延时,控制电机转速 } } // 按键扫描函数(核心修改:返回bit类型更新auto_mode,移除bit*指针,解决C165报错) bit Key_Scan(bit auto_mode, unsigned int *set_num) { // 预设数量增加按键(P3^3,防抖处理) if(P3^3 == 0) { Delay_ms(10); // 软件防抖,过滤抖动干扰 if(P3^3 == 0) { (*set_num)++; if(*set_num > 999) *set_num = 1; // 数量上限保护 while(P3^3 == 0); // 等待按键释放,防止连加 } } // 预设数量减少按键(P3^4,防抖处理) if(P3^4 == 0) { Delay_ms(10); if(P3^4 == 0) { if(*set_num > 1) (*set_num)--; else *set_num = 999; // 数量下限保护 while(P3^4 == 0); // 等待按键释放,防止连减 } } // 自动/手动模式切换按键(P3^5,防抖处理) if(P3^5 == 0) { Delay_ms(10); if(P3^5 == 0) { auto_mode = !auto_mode; // 切换模式状态 while(P3^5 == 0); // 等待按键释放 } } return auto_mode; // 返回更新后的模式状态,解决状态无法同步问题 } // 手动控制函数(占位完善,支持手动出药测试) void Manual_Control(void) { // 手动启动出药电机(P3^6,防抖处理) if(P3^6 == 0) { Delay_ms(10); if(P3^6 == 0) { Motor_Start(); Delay_ms(1000); // 手动出药1秒 Motor_Stop(); while(P3^6 == 0); // 等待按键释放 } } } // 报警控制函数(完善蜂鸣器逻辑,故障时闪烁报警) void Alarm_Control(void) { if(fault_flag == 1) { static unsigned int alarm_cnt = 0; alarm_cnt++; if(alarm_cnt % 500 == 0) { BUZZER = !BUZZER; // 蜂鸣器翻转,实现闪烁报警 } } else { BUZZER = 1; // 无故障时,关闭蜂鸣器 } } // 主函数(核心修改:接收Key_Scan返回值,更新auto_mode状态,流程更严谨) void main(void) { bit auto_mode = 1; // 1=自动模式,0=手动模式,初始化默认自动 bit bottle_ok = 0; // 药瓶到位标志(0=未到位,1=到位) Init_System(); // 系统初始化 LCD_Display(); // 初始化LCD显示 while(1) // 主循环,持续运行 { // 关键修改:接收Key_Scan返回值,更新auto_mode状态 auto_mode = Key_Scan(auto_mode, &set_num); if(auto_mode == 1) // 自动模式 { if(bottle_ok == 1) // 药瓶到位,启动自动装瓶流程 { Motor_Start(); // 启动出药电机 // 计数未达预设值且无故障,持续计数 while(count < set_num) { LCD_Display(); // 实时更新显示 if(fault_flag == 1) break; // 故障时立即退出循环 } Motor_Stop(); // 停止出药电机 Step_Motor_Run(200, 1); // 步进电机运行,送走满瓶 count = 0; // 清零当前计数 bottle_ok = 0; // 清除药瓶到位标志 } } else // 手动模式 { Manual_Control(); // 执行手动控制逻辑 } Alarm_Control(); // 故障报警检测 LCD_Display(); // 实时更新LCD显示 Delay_ms(10); // 降低主循环频率,减少CPU占用 } } 检查该程序能否运行
最新发布
12-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值