1.按下复位键,数码管从左到右显示自己的学号后三位
2.按下一个独立按键,数码管间隔一位显示1357。
3.按下一个独立按键,数码管显示最右边数字加一,且蜂鸣器响起。若该到9则清零。
基于Monster 组和GPT的调写:
#include <reg52.h>
sbit btn_reset = P1^0; // 复位按键
sbit btn_display = P1^1; // 显示按键
sbit btn_increment = P1^2; // 数字增加按键
sbit buzzer = P2^3; // 蜂鸣器
unsigned char seg_code[10] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
void delay(unsigned int time) {
while(time--);
}
void display(unsigned char digit) {
P0 = seg_code[digit];
delay(100);
P0 = 0x00;
}
void main() {
unsigned char num = 0;
while(1) {
if (btn_reset == 0) { // 复位按键按下
display(2); // 显示学号后三位
display(1);
display(5);
delay(1000);
P0 = 0x00;
}
else if (btn_display == 0) { // 显示按键按下
display(1); // 显示 1 3 5 7
delay(100);
P0 = 0x00;
delay(100);
display(3);
delay(100);
P0 = 0x00;
delay(100);
display(5);
delay(100);
P0 = 0x00;
delay(100);
display(7);
delay(100);
P0 = 0x00;
}
else if (btn_increment == 0) { // 数字增加按键按下
num++;
if (num == 10) { // 如果数字到达 10,则清零
num = 0;
}
display(num);
buzzer = 1; // 蜂鸣器响起
delay(100);
buzzer = 0;
delay(1000);
P0 = 0x00;
}
}
}
用 P0 口控制数码管的显示,使用 P1 口控制按键的输入,使用 P2 口控制蜂鸣器的输出。
在主函数中,使用一个无限循环来不断检测按键的状态。如果复位按键按下,则显示学号后三位;如果显示按键按下,则显示 1 3 5 7;如果数字增加按键按下,则数字加一并显示,同时蜂鸣器响起,如果数字到达 10,则清零。
该回答引用ChatGPT
如果运行报错,可以回复我
#include <reg52.h>
#include <intrins.h>
// 延时函数
void delay(unsigned int x)
{
while(x--);
}
// 数码管位选函数
void display(unsigned char num)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
P0 = i;
P2 = num % 10;
num /= 10;
delay(100);
P2 = 0x0f; // 关闭数码管
}
}
void main()
{
unsigned char num = 123; // 学号后三位
unsigned char flag1 = 0; // 第一个按键标志
unsigned char flag2 = 0; // 第二个按键标志
unsigned char count = 0; // 计数器
P1 = 0xff; // 设置P1口为输入口
P2 = 0x0f; // 关闭数码管
while(1)
{
if(P1 != 0xff) // 检测按键是否按下
{
delay(10); // 延时去抖
if(P1 != 0xff) // 确认按键按下
{
if(P1 == 0xfe) // 第一个按键
{
flag1 = ~flag1;
flag2 = 0;
if(flag1 == 1) // 间隔一位显示1357
{
display(1357);
}
else
{
P2 = 0x0f; // 关闭数码管
}
}
else if(P1 == 0xfd) // 第二个按键
{
flag1 = 0;
flag2 = ~flag2;
if(flag2 == 1) // 最右边数字加一
{
count++;
if(count > 9)
{
count = 0; // 清零
}
P2 = count;
// 蜂鸣器响一声
P3 |= 0x10;
delay(1000);
P3 &= ~0x10;
}
else
{
P2 = 0x0f; // 关闭数码管
}
}
}
}
if(flag1 == 0 && flag2 == 0) // 复位键
{
display(num);
}
}
}
程序一直处于死循环中,不断检测按键是否按下。如果按下,就根据不同的按键标志位执行不同的操作。复位键执行显示学号后三位的操作,第一个按键执行显示1357的操作,第二个按键执行最右边数字加一并响蜂鸣器的操作。
下面是一个可以实现你所描述的功能的 C 语言代码。该代码使用了单片机的外部中断和定时器中断,以实现动态数码管显示和独立按键的检测:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit beep = P1^5; // 蜂鸣器接口
sbit k1 = P3^2; // 独立按键1
sbit k2 = P3^3; // 独立按键2
sbit rst = P3^4; // 复位按键
sbit dula = P2^6; // 数码管段选1
sbit wela = P2^7; // 数码管位选
uchar code duanma[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 共阳极数码管段码表
uchar num1[4] = {0}; // 显示学号后三位
uchar num2[4] = {1, 3, 5, 7}; // 显示 1357
uchar num3[4] = {0}; // 显示计数值
uint cnt = 0; // 计数器
// 定时器中断服务函数,每隔 10ms 执行一次
void timer0() interrupt 1 {
TH0 = 0xFC; // 重置定时器初值
TL0 = 0x67;
cnt++; // 增加计数器
if(cnt >= 100) { // 计数器达到 100 时清零
cnt = 0;
num3[3]++; // 右数第一位加一
if(num3[3] > 9) { // 判断是否需要进位
num3[3] = 0;
}
beep = 1; // 蜂鸣器响
}
if(cnt % 2 == 0) { // 数码管动态扫描,每隔 20ms 扫描一次
dula = 1; // 显示数码管左边一位
P0 = duanma[num1[3]];
wela = 0;
wela = 1;
dula = 0; // 显示数码管右边一位
P0 = duanma[num2[3]];
wela = 0;
wela = 1;
dula = 1; // 显示数码管左边二位
P0 = duanma[num3[2]];
wela = 0;
wela = 1;
dula = 0; // 显示数码管右边二位
P0 = duanma[num3[3]];
wela = 0;
wela = 1;
}
}
参考GPT和自己的思路,以下是基于STC89C52单片机的C语言示例代码,实现上述动态数码管与独立按键的功能。代码中使用了中断服务函数,需要设置相应的中断向量和优先级。
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit beep=P1^5; // 定义蜂鸣器输出引脚
sbit KEY1=P3^2; // 定义按键1输入引脚
sbit KEY2=P3^3; // 定义按键2输入引脚
uchar code table[]={
// 数码管显示码表,分别对应数字0~9
0x3f, 0x06, 0x5b, 0x4f, 0x66,
0x6d, 0x7d, 0x07, 0x7f, 0x6f
};
uchar num[4]={0, 0, 0, 0}; // 存放数码管的数字
void delay(uint x) // 延时函数
{
uint i, j;
for(i=x; i>0; i--)
for(j=110; j>0; j--);
}
void display() // 数码管显示函数
{
uchar i;
for(i=0; i<4; i++)
{
P0=table[num[i]]; // 数码管赋值
P2=0x0f^(1<<i); // 选择数码管位
delay(1); // 稍作延时
P2=0x0f; // 关闭数码管
}
}
void init_timer() // 定时器初始化函数
{
TMOD=0x01; // 定时器0工作在模式1
TH0=0x3c; // 定时器初值高8位
TL0=0xb0; // 定时器初值低8位
ET0=1; // 开启定时器0中断
EA=1; // 开启总中断
TR0=1; // 启动定时器0
}
void timer0() interrupt 1 // 定时器0中断服务函数
{
static uchar cnt=0; // 计数器,用于控制定时周期
cnt++;
if(cnt==20) // 定时周期为20ms
{
cnt=0;
display(); // 数码管显示函数
}
}
void main()
{
KEY1=1; // 初始化按键1输入状态
KEY2=1; // 初始化按键2输入状态
init_timer(); // 定时器初始化
while(1)
{
if(KEY1==0) // 按键1被按下
{
num[0]=6; // 显示自己的学号后三位,示例为"006"
num[1]=0;
num[2]=0;
num[3]=6;
delay(1000); // 稍作延时,防止按键抖动
如果对您有帮助,请给与采纳,谢谢。