【STM32单片机】数学自动出题器设计

文章目录

  • 一、功能简介
  • 二、软件设计
  • 三、实验现象
  • 联系作者


一、功能简介

本项目使用STM32F103C8T6单片机控制器,使用按键、IIC OLED模块等。
主要功能:
系统运行后,OLED液晶显示出题器开机界面,默认结果范围为100,可按下S13键进入范围值设置,S1-S10键输入0-9数字,最大输入3位数;若输入有误可按下S11键撤回,若输入完成,可按下S12键进入答题界面;如果无需设置,则按下S16键进入答题界面;出题的计算结果范围则为前面设置的范围内。
此时显示屏会显示答题时间、得分、计算题(程序内设置了加减乘除,默认仅开启加减运算功能)和计算结果输入窗口,可按下S1-S10键输入答案,如果结果正确,
得分+5,否则显示错误提示,且需重新输入结果。答案正确则自动进入下一题,如此循环。当得分为100,则完成测试。


二、软件设计

/*
作者:嗨小易(QQ:3443792007)

*/


//系统生成题目
void sys_generate_subject(void)
{
	u8 key=0;
	u8 buf[3];
	u16 result=0;
	
	OLED_Clear();
	OLED_ShowString(0,0, "00:00:00   Socre:   ",12);
	OLED_ShowString((X_WIDTH-6*12)/2,16,"  +  =",24);
	OLED_DrawRectanglex(0,45,X_WIDTH,18,1);
	OLED_ShowString(2,46,"-->   ",16);
	
	TIM_Cmd(TIM3,ENABLE); //打开定时器	
	
	while(1)
	{
		//显示时间
		OLED_ShowxNum(0,0,sys_ctrl.hour,2,12,0x80,1);
		OLED_ShowxNum(6*3,0,sys_ctrl.min,2,12,0x80,1);
		OLED_ShowxNum(6*6,0,sys_ctrl.sec,2,12,0x80,1);
		//显示得分
		OLED_ShowxNum(17*6,0,sys_ctrl.score,3,12,0x80,1);
		
		//开始生成题目
		if(sys_ctrl.start==1)
		{
			sys_ctrl.start=0;
			srand(sys_ctrl.sec);//播种
			//生成随机符号值,加和减
			sys_ctrl.sign=rand()%2;
			//显示符号
			switch(sys_ctrl.sign)
			{
				case 0://加
					OLED_ShowString((X_WIDTH-6*12)/2+2*12,16,"+",24);
					//生成有效的两个计算数,在指定范围数内
					//rand() % (b-a+1)+ a ; 就表示 a~b 之间的一个随机整数
					sys_ctrl.num[0]=rand()%((sys_ctrl.range-1)-1+1)+1;
					sys_ctrl.num[1]=rand()%(sys_ctrl.range-sys_ctrl.num[0])+1;
					break;
				case 1://减
					OLED_ShowString((X_WIDTH-6*12)/2+2*12,16,"-",24);
					//生成的第一个数必须大于第二个数
					while(1)
					{
						sys_ctrl.num[0]=rand()%((sys_ctrl.range-1)-1+1)+1;
						sys_ctrl.num[1]=rand()%(sys_ctrl.range-sys_ctrl.num[0])+1;
						if(sys_ctrl.num[0]>=sys_ctrl.num[1])break;
					}
					break;
				case 2://乘
					OLED_ShowString((X_WIDTH-6*12)/2+2*12,16,"*",24);
					sys_ctrl.num[0]=rand()%((sys_ctrl.range-1)-1+1)+1;
					sys_ctrl.num[1]=rand()%(sys_ctrl.range-sys_ctrl.num[0])+1;
					break;
				case 3://除
					OLED_ShowString((X_WIDTH-6*12)/2+2*12,16,"/",24);
					//生成的第一个数必须大于第二个数
					while(1)
					{
						sys_ctrl.num[0]=rand()%((sys_ctrl.range-1)-1+1)+1;
						sys_ctrl.num[1]=rand()%(sys_ctrl.range-sys_ctrl.num[0])+1;
						if(sys_ctrl.num[0]>=sys_ctrl.num[1])break;
					}
					break;
			}
			//显示生成的两个计算数
			OLED_ShowxNum((X_WIDTH-6*12)/2,16,sys_ctrl.num[0],2,24,0,1);
			OLED_ShowxNum((X_WIDTH-6*12)/2+3*12,16,sys_ctrl.num[1],2,24,0,1);
		}
		//开始答题
		else
		{
			key=KEY_Matrix_Scan();
			if(key!=0)BEEP_Alarm(50,100);//提示音
			//输入数值键范围0-9
			if(key>0 && key<=10)
			{
				//最多输入3位数
				if(sys_ctrl.cnt<3)
				{
					//第一位输入0,后面都是0
					if(sys_ctrl.cnt==0 && key==1)
					{
						buf[sys_ctrl.cnt]=key-1;
						OLED_ShowNum(2+8*3+(sys_ctrl.cnt)*8,46,buf[sys_ctrl.cnt-1],1,16);
					}	
					else
					{
						buf[sys_ctrl.cnt]=key-1;
						sys_ctrl.cnt++;//输入位数+1
						OLED_ShowNum(2+8*3+(sys_ctrl.cnt-1)*8,46,buf[sys_ctrl.cnt-1],1,16);
					}	
				}
			}
			//按下删除键
			else if(key==11)
			{
				sys_ctrl.cnt--;
				if(sys_ctrl.cnt<0)sys_ctrl.cnt=0;
				OLED_ShowString(2+8*3+(sys_ctrl.cnt)*8,46," ",16);
			}	
			//按下确定键
			else if(key==12)
			{
				//获取范围值
				switch(sys_ctrl.cnt)
				{
					case 1://1位
						sys_ctrl.result=buf[0];
						break;
					case 2://2位
						sys_ctrl.result=buf[0]*10+buf[1];
						break;
					case 3://3位
						sys_ctrl.result=buf[0]*100+buf[1]*10+buf[2];
						break;
				}
				
				//根据符号计算生成题目的数值
				switch(sys_ctrl.sign)
				{
					case 0://加
						result=sys_ctrl.num[0]+sys_ctrl.num[1];
						break;
					case 1://减
						result=sys_ctrl.num[0]-sys_ctrl.num[1];
						break;
					case 2://乘
						result=sys_ctrl.num[0]*sys_ctrl.num[1];
						break;
					case 3://除
						result=sys_ctrl.num[0]/sys_ctrl.num[1];
						break;
				}
				//如果答题正确
				if(result==sys_ctrl.result)
				{
					sys_ctrl.start=1;
					sys_ctrl.cnt=0;
					sys_ctrl.score+=5;
					if(sys_ctrl.score>=100)
					{
						TIM_Cmd(TIM3,DISABLE); //关闭定时器
						sys_parm_init();//系统参数初始化
						break;
					}	
					OLED_ShowString(2+8*3,46,"   ",16);
				}
				//如果答题错误
				else
				{
					sys_ctrl.cnt=0;
					OLED_ShowString(2+8*3,46,"Error!",16);
					OLED_Refresh_Gram();//刷新显示缓存
					delay_ms(500);
					OLED_ShowString(2+8*3,46,"      ",16);
				}
			}		
		}
		
		OLED_Refresh_Gram();//刷新显示缓存
	}
}


//应用控制系统
void app_sys_ctrl_demo(void)
{
	LED_Init();
	USART1_Init(115200);
	OLED_Init();
	KEY_Matrix_Init();
	BEEP_Init();
	TIM3_Init(1000,36000-1);  //定时500ms
	sys_parm_init();//系统参数初始化
	
	while(1)
	{
		sys_open_show();//系统开机界面显示
		sys_generate_subject();//系统生成题目
	}
}





三、实验现象

B站演示视频:https://space.bilibili.com/444388619

【STM32单片机】数学自动出题器设计_第1张图片
【STM32单片机】数学自动出题器设计_第2张图片
【STM32单片机】数学自动出题器设计_第3张图片


联系作者

专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。

你可能感兴趣的:(单片机,stm32,mongodb,游戏,proteus,嵌入式硬件)