实现三个不同用户发送评论——以duan***.cn为例

本文介绍使用JMeter进行性能测试的基本配置步骤,包括线程组数量设置、循环次数定义及计数器应用等内容。

D:\jmeter\workspace2020\duan***.cn+计数器.jmx

1.线程组还是选择1

2.循环控制器循环次数为3

3.设置用户参数和循环次数一致

4.计数器和固定定时器可不要?有待验证

我们将在 **金沙滩 STC89C52 51单片机** 上实现一个完整的 **排队叫号机系统**,功能包括: - 使用 **数码管(4位或8位)动态扫描显示当前叫号** - 加入 **串口通信(UART)**,将取号、叫号信息发送到上位机(如PC) - 支持按键取号和叫号 - 利用定时器实现数码管刷新与串口波特率生成 --- ## ✅ 系统功能概览 | 模块 | 功能 | |------|------| | 数码管显示 | 显示当前被叫号码(如 A001) | | Key1(P3.2) | 取号按键 —— 发放新号码 | | Key2(P3.3) | 叫号按键 —— 呼叫下一位 | | UART 串口 | 向 PC 发送日志:`GET:A005`, `CALL:A003` | | 定时器T0 | 提供数码管动态扫描时序(约 4ms 中断一次) | | 波特率 | 设为 9600bps(常用标准) | --- ## 🔧 硬件连接说明(金沙滩典型配置) ### 数码管部分(共阴/共阳,以共阴为) 假设使用 **4位数码管(带锁存器)** | 锁存器控制 | 单片机引脚 | |------------|-----------| | ADDR0~ADDR3(选择数码管位) | P1^0 ~ P1^3(通过74HC138或直接控制) | | DUAN(段选锁存端) | P2^6(控制段码输出) | | WEI(位选锁存端) | P2^7 | | 段码输入(a~dp) | P0 | | 位选输入(1~4) | P0(通过锁存后)| > 实际中常通过两个锁存器分离“段码”和“位码”。 ### 串口部分(STC89C52 内置 UART) | 引脚 | 连接 | |------|------| | P3.0(RXD) | 连 USB转TTL 的 TXD | | P3.1(TXD) | 连 USB转TTL 的 RXD | | GND | 共地 | > 使用 MAX232 或 CH340G 转 RS232/USB 下载和通信。 --- ## ✅ 软件设计思路 - 使用 **定时器0中断** 实现数码管动态刷新(每4ms刷新一位) - 主循环检测按键状态(带消抖) - 按键触发后更新号码,并通过串口发送消息 - 数码管显示格式:`Axxx` → 高位补空格或0,如 `A 1`, `A023` --- ## ✅ 完整 C 代码(Keil C51 格式) ```c #include <reg52.h> // 数码管段码表(0~9, A, B, C, D, E, F, 空格) unsigned char code seg_code[] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, // 0~7 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, // 8~F 0x00 // 空格 }; sbit KEY_GET = P3^2; // 取号键 sbit KEY_CALL = P3^3; // 叫号键 // 全局变量 unsigned int current_ticket = 1; // 已发最大号 unsigned int called_ticket = 0; // 当前叫到的号 unsigned char display_buf[4] = {16, 16, 16, 16}; // 显示缓冲区:空格填充 // 函数声明 void timer0_init(); void uart_init(); void send_string(char *str); void update_display_buffer(unsigned int num); void delay_ms(unsigned int ms); // 初始化定时器0(用于数码管动态扫描) void timer0_init() { TMOD |= 0x01; // 定时器模式1(16位) TH0 = (65536 - 4000) / 256; // 约4ms中断一次(12MHz晶振) TL0 = (65536 - 4000) % 256; ET0 = 1; // 开启T0中断 TR0 = 1; // 启动定时器0 EA = 1; // 开总中断 } // 初始化串口(方式1,8位UART,波特率9600) void uart_init() { SCON = 0x50; // 方式1,允许接收 TMOD |= 0x20; // 定时器1工作于模式2(8位自动重载) TH1 = TL1 = 0xFD; // 9600bps @12MHz TR1 = 1; // 启动定时器1 ES = 1; // 开串口中断(可选) EA = 1; } // 发送一个字节 void uart_send_byte(unsigned char byte) { SBUF = byte; while (!TI); // 等待发送完成 TI = 0; // 清标志 } // 发送字符串 void send_string(char *str) { while (*str) { uart_send_byte(*str++); } } // 将数字写入显示缓冲区(格式化为 Axxx) void update_display_buffer(unsigned int num) { unsigned char d[3]; d[0] = num / 100; d[1] = (num % 100) / 10; d[2] = num % 10; display_buf[0] = 10; // 'A' display_buf[1] = d[0] ? d[0] : 16; // 百位(非零显示,否则空格) display_buf[2] = d[0] || d[1] ? d[1] : 16; // 十位(前面有数才显示) display_buf[3] = d[2]; // 个位总是显示 } // 数码管动态扫描中断服务程序 void timer0_isr() interrupt 1 { static unsigned char pos = 0; // 关闭所有位选(防止重影) P0 = 0xFF; P2 |= 0xC0; // WEI=1, DUAN=1 → 锁存无效 P2 &= ~0xC0; // 输出当前位的数据 P0 = seg_code[display_buf[pos]]; // 段码 P2 |= 0x80; // DUAN = 1 → 锁存段码 P2 &= ~0x80; P0 = ~(1 << pos); // 位选:共阴极,低电平有效 P2 |= 0x40; // WEI = 1 → 锁存位码 P2 &= ~0x40; // 移动到位 pos++; if (pos >= 4) pos = 0; // 重新加载定时器 TH0 = (65536 - 4000) / 256; TL0 = (65536 - 4000) % 256; } // 按键消抖 unsigned char key_scan(sbit key) { if (key == 0) { delay_ms(10); if (key == 0) { while (key == 0); return 1; } } return 0; } // 延时函数 void delay_ms(unsigned int ms) { unsigned int i, j; for (i = ms; i > 0; i--) for (j = 110; j > 0; j--); } // 主函数 void main() { // 初始化 timer0_init(); uart_init(); delay_ms(100); // 初始化显示 update_display_buffer(called_ticket); // 初始显示 A000 send_string("System Ready: Queuing Machine\r\n"); while (1) { // 检测取号键 if (key_scan(KEY_GET)) { current_ticket++; if (current_ticket > 999) current_ticket = 1; update_display_buffer(current_ticket); // 串口通知 send_string("GET:A"); if (current_ticket < 10) send_string("00"); else if (current_ticket < 100) send_string("0"); uart_send_byte('0' + current_ticket / 100); uart_send_byte('0' + (current_ticket % 100) / 10); uart_send_byte('0' + current_ticket % 10); send_string("\r\n"); delay_ms(50); } // 检测叫号键 if (key_scan(KEY_CALL)) { if (called_ticket < current_ticket) { called_ticket++; if (called_ticket > 999) called_ticket = 1; update_display_buffer(called_ticket); // 串口通知 send_string("CALL:A"); if (called_ticket < 10) send_string("00"); else if (called_ticket < 100) send_string("0"); uart_send_byte('0' + called_ticket / 100); uart_send_byte('0' + (called_ticket % 100) / 10); uart_send_byte('0' + called_ticket % 10); send_string("\r\n"); } delay_ms(50); } } } ``` --- ## 📌 代码解释 ### 1. **定时器0:数码管动态扫描** - 每 4ms 触发一次中断。 - 在中断中轮流点亮 4 位数码管中的每一位。 - 使用 `display_buf[]` 存储要显示的内容(索引对应 `seg_code`)。 - 使用锁存器控制段码和位码。 ### 2. **数码管显示逻辑** - `update_display_buffer(num)` 将数字格式化为 `Axxx` 形式。 - 自动去除前导零,如: - `5` → `A 5` - `23` → `A 23` - `123` → `A123` > 注:由于数码管不能直接显示字母'A'和前缀,我们用第一个位置显示 `'A'` 字符(`seg_code[10]`),其余三位显示数字。 ### 3. **串口通信** - 使用 UART 方式1,波特率9600。 - 每次取号/叫号都通过串口向上位机发送一行文本: ``` GET:A005 CALL:A003 ``` > 可用串口助手(如XCOM、SSCOM)查看输出。 ### 4. **按键处理** - 使用软件延时消抖。 - 按下后等待释放,避免重复触发。 --- ## 🖥️ 上位机示(Python 读取串口日志) ```python import serial import datetime ser = serial.Serial('COM3', 9600, timeout=1) print("正在监听叫号机...") try: while True: if ser.in_waiting: line = ser.readline().decode().strip() timestamp = datetime.datetime.now().strftime("%H:%M:%S") print(f"[{timestamp}] {line}") except: print("串口断开") finally: ser.close() ``` --- ## ✅ 注意事项 1. **晶振频率必须是12MHz**,否则定时器和波特率不准确。 2. 若使用11.0592MHz晶振,修改TH1=0xFD仍适用9600bps。 3. 数码管亮度可通过调整定时器周期或加限流电阻调节。 4. 如需更多功能(如多窗口、语音播报),可扩展外部芯片。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值