小学期实训-智慧电子时钟
摘 要
项目选题为智慧电子时钟,相对于传统时钟,该智慧时钟有实时时钟、实时日期、光照与温度显示、闹钟设置、闹钟关闭密码设置功能。同时,闹钟需要满足一定的条件才能开启,通过光照传感器来实现对闹钟的开启条件进行限制,需要光照条件到达一定值以上才会开启,防止夜间闹钟意外响铃,同时关闭闹钟时需要准确地输入设计好的八位密码,否则音乐会一直播放,以此更有效地实现闹钟的自动化、智能化。其次,电子时钟新增光照、温度显示的功能,帮助辨别冷暖,适当的增减衣物。
实现功能:
1)通过无源蜂鸣器实现闹钟响铃功能,并播放出一首音乐;
2)通过光照传感器限制闹钟开启功能;
3)通过输入密码实现闹钟关闭功能,其他方式无法关闭;
4)可以在数码管上显示实时时间、日期、温度、亮度、闹钟时间、密码设置、密码验证,通过K1、K2键进行显示切换;
5)通过导航键设置实时时间、日期、闹钟时间、密码、关闭闹钟时需要的密码。
关键词:电子时钟、智慧闹铃、密码控制
目录
一、 绪论... 1
(一) 主题和选题... 1
(二) 题目背景... 1
(三) 面临问题... 1
二、 课程设计... 2
(一) 总体方案设计... 2
1.设计目的... 2
2.设计思路图... 2
3.时间计划、内容... 3
(二) 各部分详细设计... 3
1. STC-BSP头文件选择... 3
2. 设置事件回调函数... 3
3. 基本原理... 4
4. 函数设计... 11
(三) 硬件测试结果... 14
1. 编译结果... 14
2. 下载结果... 14
3. 实操测试... 15
4. 实现功能... 16
三、 总结... 17
(一) 问题及解决... 17
(二) 完成进度... 17
四、 心得体会... 18
五、 参考文献... 18
1.如何将密码和其他信息同时存入非易失存储器,如何判断自己输入的密码是否与存储的密码正确匹配?
2.数码管如何正确显示多级界面以及如何根据当前状态进行按键判断?
- 各部分详细设计
- STC-BSP头文件选择
根据项目功能选择BSP包中所需的头文件:
#include "STC15F2K60S2.H" //必须
#include "sys.H" //必须
#include "displayer.H" //display(显示模块)
#include "key.h" //key(按键模块)
#include "beep.h" //beep(蜂鸣器模块)
#include "music.h" //music(音乐播放)
#include "adc.h" //adc(热敏、光敏、导航按键、扩展接口ADC功能)
#include "DS1302.h" //DS1302实时时钟
#include "M24C02.h" //24C02非易失性存储器
并加载需要用的模块(由各模块提供加载函数):
Key_Init(); //按键模块加载函数
DisplayerInit(); //加载显示模块工作
BeepInit(); //蜂鸣器初始化
MusicPlayerInit(); //驱动music模块
AdcInit(ADCexpEXT); //ADC模块初始化,不含对扩展接口EXT设置ADC功能
DS1302Init(t); //DS1302初始化
MySTC_Init(); //MySTC_OS初始化
- 设置事件回调函数
SetEventCallBack(enumEventKey, mykey_callback); //K1、K2按键
SetEventCallBack(enumEventSys100mS, my100mS_callback); //显示
SetEventCallBack(enumEventNav, myKN_callback); //导航按键
SetEventCallBack(enumEventSys1S, my1S_callback); //闹钟判断
在每一级数码管显示界面,都会检测按键和导航按键的使用,故需要K1、K2按键和导航按键的回调函数,而数码管本身显示需要一个系统100mS事件回调函数,闹钟判断需要一个系统1S事件回调函数。
P0口的8位输出分别连接了8个发光二极管L0~L7的阳极, P2.3经过一个反相器连接到8个发光二极管L0~L7的阴极(共阴极):
P0口的8位输出分别控制1个LED数码管的7段和一个小数点:
寻址信号由一个字节构成,高7位为地址位,最低位为方向位,用以表明主机与从器件的数据传送方向。方向位位0,表明主机接下来对从器件进行写操作;方向位位1,表明主机接下来对从器件进行读操作。
数据传输:SCL为高电平时,SDA线若保持稳定,那么SDA上是在传输数据bit;若SDA发生跳变,则用来表示一个会话的开始或结束
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据
若没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程。
当按键被按下的时候,电路导通接地,I/O口为低电平;当按键未被按下时,电路断开,I/O口保持高电平。
P0口的8位输出分别控制8个发光二极管L0~L7的阳极;而P2.3经反相器U4C控制8个发光管阴极E3;当阳极为高(对应P0口位为1)、阴极为低时,对应的二极管将会发光。
导航按键在上图的标注为MINI_KEY5,导航按键的每一个方向被按下,都会引起实际电压的改变,从而可以根据这个原理,与A/D转换器配合,可以判断哪个方位被按下,获取按下后A/D转换的结果。
将ADC0~7的模拟量送到比较器中,用DAC(数/模转换器)转换的模拟量与输入的模拟量通过比较器进行比较。
转换结束后,将比较结果放入转换结果寄存器(ADC_RES和ADC_RESL)。
注意硬件会自动将ADC_START清零,如果需要进行下一次转换,则需要将ADC_START置位。
(1)数码管所显示的ADC转换结果并不是电压值,而是电压进行转换后所得的一个值。如果需要实际的电压值可以参照STC15F2K60S2数据手册的760页上面的公式进行计算得出。
蜂鸣器分为有源蜂鸣器和无源蜂鸣器,这里的源特指振荡源;有源蜂鸣器直接加电就可以响起,无源蜂鸣器需要我们给提供振荡源。理想的振荡源为一定频率的方波。
- 函数设计
- 各状态结构体设计
unsigned char funcmode; //定义显示、按键功能模式
enum funcname
{
RTC_HMS = 1, //实时时钟:时分秒
RTC_YMD, //实时时钟:年月日
Rt_Rop, //热敏光敏测量
Alarm, //闹钟
Code, //设置密码
Code_test //密码测试
};
- K1、K2按键回调函数设计
void dealwithmykey() //k1、k2按键效果
{
if (GetKeyAct(enumKey2) == enumKeyPress) //按键2按下时切换显示和按键功能模式
{
if (funcmode == Code_test) //闹钟状态下,K2键按下不会改变状态
{
funcmode == Code_test;
}
else
{
SetBeep(1000, 10); //蜂鸣器鸣叫一声
tempadj = 0;
if (++funcmode > Code) //状态合理切换
funcmode = RTC_HMS;
LedPrint(funcmode);
M24C02_Write(0x00, funcmode);
}
}
if (GetKeyAct(enumKey1) == enumKeyPress) //K1按下时切换显示和按键功能模式
{
if (funcmode == Code_test) //闹钟状态下,K1键按下不会改变状态
{
funcmode == Code_test;
}
else
{
SetBeep(1000, 10); //蜂鸣器鸣叫一声
tempadj = 0;
if (--funcmode < RTC_HMS) //状态合理切换
funcmode = Code;
LedPrint(funcmode);
M24C02_Write(0x00, funcmode);
}
}
}
- 显示回调函数设计
void dealwithDisp()
{
unsigned char d0, d1, d2, d3, d4, d5, d6, d7; //8位数码管显示定义
static unsigned char ct100mS = 10;
if (--ct100mS == 0) //设置一个数码管闪烁的计时函数
ct100mS = 10;
switch (funcmode)
{
case RTC_YMD:
if (tempadj == 0)
t = RTC_Read(); //非调时钟时, 读RTC
.
.详见工程文件
case RTC_HMS:
.
.详见工程文件
case Rt_Rop:
ADCresult = GetADC();
ADCresult.Rt = tempdata[ADCresult.Rt - 330]; //根据转换表进行读取的温度与实际温度转换
d0 = ADCresult.Rop % 1000 / 100; //取出数据的百位
d1 = ADCresult.Rop % 100 / 10; //取出数据的十位
d2 = ADCresult.Rop % 10; //取出数据的个位
.
.详见工程文件
case Alarm:
if (tempadj == 0)
{
m.hour = NVM_Read(0x01); //将闹钟的小时数存入DS1302中的0x01地址中
m.minute = NVM_Read(0x02); //将闹钟的分钟数存入DS1302中的0x02地址中
m.second = NVM_Read(0x03); //将闹钟的秒钟数存入DS1302中的0x03地址中
}
d0 = m.hour >> 4; //取8 bit数据中的高四位
d1 = m.hour & 0xf; //取8 bit数据中的低四位
.
.详见工程文件
case Code:
if (tempadj == 0)
{
c.a1 = NVM_Read(0x04); //将8位闹钟密码分别存入DS1302中的0x04~0x11地址中
.
.详见工程文件
case Code_test:
.
.详见工程文件
}
if (funcmode == RTC_YMD || funcmode == RTC_HMS || funcmode == Alarm)
//时间、日期、闹钟显示界面时数码管如何闪烁
{
if (ct100mS >= 8)
switch (tempadj)
{
.
.详见工程文件
}
}
if (funcmode == Code || funcmode == Code_test)
//设置密码、密码输入界面时数码管如何闪烁
{
.
.详见工程文件
}
Seg7Print(d0, d1, d2, d3, d4, d5, d6, d7); //8位数码管显示
}
- 导航按键回调函数设计
在时间、日期、闹钟状态下导航中键选择开始更改或者确认更改,导航左右键更改选择时、分、秒 或 年、月、日,上下键数字加减一。在设置密码状态下,按下导航中键更改密码,导航左右键更改选择密码位数,上下键数字加减一。在闹钟响起后输入密码状态下,上下键数字加减一,右键按下判断密码是否正确,其余键无法改变闹钟状态。
- 闹钟回调函数
void dealwithAlarm() //闹钟回调函数
{
if (m.hour == t.hour && m.minute == t.minute && m.second == t.second)
//判断条件
{
ADCresult = GetADC();
if (ADCresult.Rop >= 20)
{
funcmode = Code_test;
SetMusic(Music_PM, Music_tone, &song, sizeof(song), 0xF0);
//初始化音乐
SetPlayerMode(enumModePlay); //播放音乐
}
}
}
- 硬件测试结果
- 编译结果:
- 下载结果:
实操测试:
时钟显示界面 日期显示界面
亮度、温度显示界面 闹钟显示界面
密码设置显示界面 闹钟响起显示界面、
- 实现功能:
a)通过无源蜂鸣器实现闹钟响铃功能,并播放出一首音乐;
b)通过光照传感器限制闹钟开启功能;
c)通过输入密码实现闹钟关闭功能,其他方式无法关闭;
d)可以在数码管上显示实时时间、日期、温度、亮度、闹钟时间、密码设置、密码验证,通过K1、K2键进行显示切换;
e)通过导航键设置实时时间、日期、闹钟时间、密码、关闭闹钟时需要的密码。
- 总结
- 问题及解决
Q1:如何将密码和信息同时存入非易失存储器24C02,如何判断自己输入的密码是否与存储的密码正确匹配?
A1:将输入密码与储存密码设为同一结构体类型,输入信息(8字节)与对应的密码(8字节,读出24C02中0x04~0x11地址处的密码)做比较,若8个数据均相同则密码正确,否则密码错误。
Q2:数码管如何现实以及多级界面如何分配并且根据当前状态进行按键判断?
A2:设置一个变量funcmode来表示界面的状态,1代表实时时钟、2代表实时日期、3代表敏光敏测量、4代表闹钟、5代表设置密码、6代表密码检测等等,将各个状态变成各个数值;将界面的改变放在按键回调函数中,当按下按键时根据当前状态来进入下一界面并完成界面初始化。
Q3:如何通过导航按键来修改密码以及信息(精确到数码管上每一位数字所代表的四位bite的自由修改而不是一个字节的修改)?
A3:如在具体实现中所提到的,定义两个变量分别表示修改字节的步长和被修改的字节,根据flag2标志来设置步长与字节,flag%2=0的话表明修改的是flag/2这一字节的高四位,因此步长为0x10,否则修改低四位步长为0x10。
Q4:因为要使用导航按键进行数值的变化,那么最好是使用Key3的P1.7口作为虚拟AD口,但是我还是需要Key3的按键功能,那么该如何解决?
A4:学习导航按键与数字按键综合控制数码管工程中的使用方法,为Key3单门设置一个btkey3flag,按下key3时虽然不能直接使用Key3=P1.7的按键消抖方法来实现,但同样可以在导航按键模块返回ADC等于0x00(也就是表示key3被按下)时将标志置1,这样就可以知道什么时候按下key3以及有没有按下key进而使用这个按键。
- 完成进度
至2021年9月16日,预期功能均已完成并通过测试。
整个项目设计历时两个星期,直到16号才终于画下句号,在此感慨良多。因为想法和工程函数是自己设计实现的,所以在编程与调试上的时间不短,也遇到过很多的bug,也解决了很多的难题。
这次小学期的实训我感觉非常有意义,不仅学到了很多的新知识并将之运用到了实践上,而且了解到了这些简单的硬件的工作方式,真是受益匪浅。
[1] STC-B学习板原理图
[2] STC15F2K60S2数据手册
[3] 工程训练学习板原理
[4] 基于STCBSP的应用程序设计
//******* 用户程序段1:用户程序包含文件 *************//
#include "main.H" //编写应用程序时,仅需改写 main.h 和 main.c文件
#include "song.c" //song.c中编写了音乐(同一首歌)编码
//******* 用户程序段2:用户自定义函数声明 *************////******* 用户程序段3:用户程序全局变量定义 *************//
struct_DS1302_RTC t = {0x30, 0, 9, 0x06, 9, 1, 0x21}; //实时时钟数据结构:秒、分、时、日、月、周、年。初值:2021年9月6日,周一,9:00:30
struct_RTA m = {0, 0x30, 0x12};
struct_Code c = {0, 0, 0, 0, 0, 0, 0, 0};
struct_Code s_code = {0, 0, 0, 0, 0, 0, 0, 0};
int code tempdata[]={239,197,175,160,150,142,135,129,124,120,116,113,109,107,104,101, 99, 97, 95, 93, 91, 90, 88, 86, 85, 84, 82, 81, 80, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, 63, 62, 61, 61, 60, 59, 58, 58, 57, 57, 56, 55, 55, 54, 54, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37, 36, 36, 36, 35, 35, 34, 34, 34, 33, 33, 32, 32, 32, 31, 31, 31, 30, 30, 29, 29, 29, 28, 28, 28, 27, 27, 27, 26, 26, 26, 25, 25,24, 24, 24, 23, 23, 23, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6,5, 5, 54,4, 3, 3,3, 2, 2, 1, 1, 1, 0, 0, -1, -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8, -8, -9, -9, -10, -10, -11, -11, -12, -13, -13, -14, -14, -15, -16, -16, -17, -18, -19, -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -30, -32, -33, -35, -36, -38, -40, -43, -46, -50, -55, -63, 361};
struct_SysPerF SysPer; //系统性能数据结构:每秒主循环次数4字节、每秒轮询丢失次数1字节
struct_ADC ADCresult; //热敏、光敏测量AD值
unsigned char Music_tone, Music_PM; //音乐播放音调、节凑(每分钟节拍数)unsigned char funcmode; //定义显示、按键功能模式
enum funcname
{RTC_HMS = 1, //实时时钟:时分秒RTC_YMD, //实时时钟:年月日Rt_Rop, //热敏光敏测量Alarm, //闹钟Code, //设置密码Code_test //密码检测
};
unsigned char tempadj; //程序变量。调整时钟时用:=1 调年或时;=2 调月或分 =3 调日 或秒//******* 用户程序段4:用户自定义函数原型 *************//
#include "function.c"
void my100mS_callback() //100mS事件回调函数
{dealwithDisp();
}
void myKN_callback() //导航按键事件回调函数
{dealwithmyKN();
}
void mykey_callback() // 按键(Key1、Key2)事件回调函数
{dealwithmykey();
}void my1S_callback() // 闹铃回调函数
{dealwithAlarm();
}
//******* main()函数 *************//
void main()
{ //主函数 main() 开始//******* 用户程序段5:用户main()函数内部局部变量定义 *************////******* 用户程序段6:用户main()函数(初始化类程序) *************////1,加载需要用的模块(由各模块提供加载函数)Key_Init(); //按键模块加载函数DisplayerInit(); //加载显示模块工作BeepInit(); //蜂鸣器初始化MusicPlayerInit(); //驱动music模块AdcInit(ADCexpEXT); //ADC模块初始化,不含对扩展接口EXT设置ADC功能DS1302Init(t); //DS1302初始化//2,设置事件回调函数(由sys提供设置函数SetEventCallBack())SetEventCallBack(enumEventKey, mykey_callback); //按键SetEventCallBack(enumEventSys100mS, my100mS_callback); //显示SetEventCallBack(enumEventNav, myKN_callback); //设置导航按键回调函数SetEventCallBack(enumEventSys1S, my1S_callback); //闹钟判断//3,用户程序状态初始化SetDisplayerArea(0, 7);//4,用户程序变量初始化funcmode = 1;Music_PM = 90;Music_tone = 0xFC;funcmode = M24C02_Read(0x00);LedPrint(funcmode);/***************** MySTC_OS 初始化与加载开始 ********************************/MySTC_Init(); // MySTC_OS 初始化while (1) // 系统主循环{MySTC_OS(); // MySTC_OS 加载/***************** MySTC_OS 初始化与加载结束 ********************************/} //主循环while(1)结束
} //主函数 main() 结束
/********************************** Ver3.3 说明 ********************************************************************(1) 系统工作时钟频率可以在main.c中修改 SysClock赋值(单位Hz)。如:code long SysClock=11059200; 定义系统工作时钟频率为11059200Hz(也即11.0592MHz) 系统工作频率必须与实际工作频率(下载时选择的)一致,以免与定时相关的所有功能出现误差或错误。(2) 使用方法:1,在工程中加载main.c文件和STC_BSP.lib库文件2,在main.c中选择包含以下头文件(如果要使用可选模块提供的函数和方法,就必须包含其头文件) :#include "STC15F2K60S2.H" //必须,"STC-B学习板"使用MCU指定的头文件#include "sys.H" //必须,sys(MySTC_OS调度程序)头文件#include "display.H" //可选,display(显示模块)头文件 #include "key.H" //可选,key(按键模块)头文件。#include "hall.H" //可选,hall(霍尔传感器模块)头文件。#include "Vib.h" //可选,Vib(振动传感器模块)头文件。 #include "beep.H" //可选,beep(蜂鸣器模块)头文件。 #include "music.h" //可选,music(音乐播放)头文件。 #include "adc.h" //可选,adc(热敏、光敏、导航按键、扩展接口ADC功能)头文件。 #include "uart1.h" //可选,uart1(串口1通信)头文件。#include "uart2.h" //可选,uart2(串口2通信)头文件。#include "stepmotor.h" //可选,步进电机 #include "DS1302.h" //可选,DS1302实时时钟#include "M24C02.h" //可选,24C02非易失性存储器#include "FM_Radio.h" //可选,FM收音机#include "EXT.h" //可选,EXT扩展接口(电子秤、超声波测距、旋转编码器、PWM输出控制电机快慢和正反转)#include "IR.h" //可选,38KHz红外通信3,MySTC_Init()是sys初始化函数,必须执行一次;MySTC_OS()是sys调度函数,应置于while(1)循环中;4,各可选模块如果选用,必须在使用模块其它函数和方法前执行一次模块所提供的驱动函数(设置相关硬件、并在sys中加载其功能调度):DisplayerInit(); //显示模块驱动 Key_Init(); //按键模块驱动BeepInit(); //蜂鸣器模块驱动MusicPlayerInit(); //蜂鸣器播放音乐驱动HallInit(); //霍尔传感器模块驱动 VibInit(); //振动传感器模块驱动 AdcInit(); //模数转换ADC模块驱动(含温度、光照、导航按键与按键Key3、EXT扩展接口上的ADC)StepMotorInit(); //步进电机模块驱动 DS1302Init(); //DS1302实时时钟驱动FMRadioInit(); //FM收音机驱动 EXTInit(); //扩展接口驱动(含电子秤、超声波测距、旋转编码器、PWM输出,但不含EXT上Uart2和与之相关应用)Uart1Init(); //Uart1(串口1)驱动:USB上(与计算机通信) Uart2Init(); //Uart2(串口2)驱动:485接口、或EXT扩展接口(多机通信、Uart方式模块如蓝牙模块) IrInit(); //38KHz红外通信模块驱动说明:有部分模块不需要驱动;驱动函数有些有参数。(具体见各模块头文件说明)5,sys和各模块共提供以下事件:numEventSys1mS: 1mS事件 ("1毫秒时间间隔到"事件)enumEventSys10mS: 10mS事件 ("10毫秒时间间隔到"事件)enumEventSys100mS: 100mS事件 ("100毫秒时间间隔到"事件)enumEventSys1S: 1S事件 ("1秒时间间隔到"事件)enumEventKey: 按键事件 (K1、K2、K3 三个按键有"按下"或"抬起"操作)enumEventHall: 霍尔传感器事件 (霍尔传感器有"磁场接近"或"磁场离开"事件)enumEventVib: 振动传感器事件 (振动感器检测到"振动"事件)enumEventNav: 导航按键事件 (导航按键5个方向、或按键K3 有"按下"或"抬起"操作)enumEventXADC: 扩展接口上完成一次ADC转换事件 (P1.0、P1.1采取到一组新数据)enumEventUart1Rxd: Uart1收到了一个符合指定要求(数据包头匹配、数据包大小一致)的数据包enumEventUart2Rxd: Uart2收到了一个符合指定要求(数据包头匹配、数据包大小一致)的数据包 enumEventIrRxd: 红外接收器Ir上收到一个数据包 对这些事件,应采用"回调函数"方法响应(即用sys提供的SetEventCallBack()设置用户回调函数),以提高系统性能。6,各可选模块提供的其它函数和具体使用方法请参见:各模块头文件中的说明;main.c提供的推荐程序框架和部分示例;其它可能技术文档或应用示例编写:徐成(电话18008400450) 2021年2月26日设计,2021年9月1日更新
**************************************************************************/
#include "STC15F2K60S2.H" //必须
#include "sys.H" //必须
#include "displayer.H" //display(显示模块)
#include "key.h" //key(按键模块)
#include "beep.h" //beep(蜂鸣器模块)
#include "music.h" //music(音乐播放)
#include "adc.h" //adc(热敏、光敏、导航按键、扩展接口ADC功能)
#include "DS1302.h" //DS1302实时时钟
#include "M24C02.h" //24C02非易失性存储器
typedef struct
{unsigned char second; //秒(BCD码,以下均为BCD码)unsigned char minute; //分unsigned char hour; //时
} struct_RTA;typedef struct
{unsigned char a1;unsigned char a2;unsigned char a3;unsigned char a4;unsigned char a5;unsigned char a6;unsigned char a7;unsigned char a8;
} struct_Code;code unsigned long SysClock = 11059200; //必须。定义系统工作时钟频率(Hz),用户必须修改成与实际工作频率(下载时选择的)一致
#ifdef _displayer_H_ //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等)
code char decode_table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x00, 0x08, 0x40, 0x01, 0x41, 0x48,/* 序号: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 *//* 显示: 0 1 2 3 4 5 6 7 8 9 (无) 下- 中- 上- 上中- 中下- */0x3f | 0x80, 0x06 | 0x80, 0x5b | 0x80, 0x4f | 0x80, 0x66 | 0x80, 0x6d | 0x80, 0x7d | 0x80, 0x07 | 0x80, 0x7f | 0x80, 0x6f | 0x80};
/* 带小数点 0 1 2 3 4 5 6 7 8 9 */#endif
/* 音乐编码规则: 1,常规音乐简谱发音编码(成对出现,不可分开,即中间不能插入其它编码和控制字) 音高(1字节),节拍数(1字节),音高,节拍,....... // 音高: 00 :休止符0x11 — 0x17 :对应低音 do、re、mi、fa、so、la、si0x21 — 0x27 :对应中音 do、re、mi、fa、so、la、si0x31 — 0x37 :对应高音 do、re、mi、fa、so、la、si节拍: 1-255(0x01-0xFF): 单位1/16拍或十六进制中,高4位表示整拍数,低4位表示分拍数如:发音2拍: 0x20发音半拍: 0x08发音1拍半:0x182,音乐编码中可以插入以下控制字,用于设定音乐播放参数等(前6个也可以通过函数,用程序设定和实现)Use_null : 不用LED和LightUse_LED : 启用LEDUse_Light : 启用LightUse_LEDandLight : 启用LED和LightSet_beatsPM : 设置节拍率, 后面再跟 节拍率(1字节)Set_tone : 设置音调, 后面再跟 音调(1字节):0xFA 或 0xFB 或 0xFC 或 0xFD 或 0xFE 或 0xFF 或 0xF9Repeat_begin : 设置音乐播放重复开始处。重复一次(暂不能多次),暂不能嵌套(嵌套无效或可能导致不可预期结果)Repeat_end : 设置音乐播放重复结束处
*/
code unsigned char song[]={ //《同一首歌》
0x00,0x10,
0x25,0x10,
0x31,0x10,
0x32,0x10,
0x33,0x30,
0x32,0x08,
0x31,0x08,
0x32,0x20,
0x31,0x10,
0x26,0x10,
0x31,0x40,
0x31,0x08,
0x26,0x08,
0x25,0x08,
0x23,0x08,
0x21,0x08,
0x16,0x08,
0x15,0x08,
0x13,0x08,
enumMscRepeatBegin,
0x15,0x20,
0x21,0x10,
0x22,0x10,
0x23,0x18,
0x24,0x08,
0x23,0x10,
0x21,0x10,
0x22,0x20,
0x21,0x10,
0x16,0x10,
0x21,0x40,
0x15,0x20,
0x21,0x10,
0x22,0x10,0x23,0x10,
0x23,0x08,
0x24,0x08,
0x25,0x10,
0x21,0x10,
0x24,0x18,
0x23,0x08,
0x25,0x10,
0x22,0x08,
0x23,0x08,
0x23,0x08,
0x22,0x08,
0x22,0x30,
0x23,0x20,
0x25,0x10,
0x31,0x10,0x27,0x18,
0x26,0x08,
0x26,0x20,
0x25,0x10,
0x25,0x08,
0x26,0x08,
0x27,0x10,
0x26,0x08,
0x25,0x08,
0x23,0x40,
0x24,0x18,
0x24,0x08,
0x25,0x10,
0x26,0x10,0x25,0x10,
0x24,0x08,
0x23,0x08,
0x22,0x20,
0x17,0x10,
0x17,0x08,
0x16,0x08,
0x15,0x10,
0x16,0x10,
0x21,0x80,// enumMscDrvSeg7, //改变显示
enumMscSetTone, 0xFF, //设置音调
enumMscSetBeatsPM,120, //设置节拍?
enumMscRepeatEnd //设置重复结束
};
void dealwithmykey() //k1、k2按键效果
{if (GetKeyAct(enumKey2) == enumKeyPress) //按键2按下时切换显示和按键功能模式{if (funcmode == Code_test) //闹钟状态下,K2键按下不会改变状态{funcmode == Code_test;}else{SetBeep(1000, 10); //蜂鸣器鸣叫一声tempadj = 0;if (++funcmode > Code) //状态合理切换funcmode = RTC_HMS;LedPrint(funcmode);M24C02_Write(0x00, funcmode);}}if (GetKeyAct(enumKey1) == enumKeyPress) //K1按下时切换显示和按键功能模式{if (funcmode == Code_test) //闹钟状态下,K1键按下不会改变状态{funcmode == Code_test;}else{SetBeep(1000, 10); //蜂鸣器鸣叫一声tempadj = 0;if (--funcmode < RTC_HMS) //状态合理切换funcmode = Code;LedPrint(funcmode);M24C02_Write(0x00, funcmode);}}
}
void dealwithDisp()
{unsigned char d0, d1, d2, d3, d4, d5, d6, d7; //8位数码管显示定义static unsigned char ct100mS = 10;if (--ct100mS == 0) //设置一个数码管闪烁的计时函数ct100mS = 10;switch (funcmode){case RTC_YMD:if (tempadj == 0) t = RTC_Read(); //非调时钟时, 读RTCd0 = t.year >> 4;d1 = t.year & 0x0f;d2 = 12;d3 = t.month >> 4;d4 = t.month & 0x0f;d5 = 12;d6 = t.day >> 4;d7 = t.day & 0x0f;break;case RTC_HMS:if (tempadj == 0)t = RTC_Read();d0 = t.hour >> 4;d1 = t.hour & 0x0f;d2 = 12;d3 = t.minute >> 4;d4 = t.minute & 0x0f;d5 = 12;d6 = t.second >> 4;d7 = t.second & 0x0f;break;case Rt_Rop:ADCresult = GetADC();ADCresult.Rt = tempdata[ADCresult.Rt - 330]; //根据转换表进行读取的温度与实际温度转换d0 = ADCresult.Rop % 1000 / 100; //取出数据的百位d1 = ADCresult.Rop % 100 / 10; //取出数据的十位d2 = ADCresult.Rop % 10; //取出数据的个位d3 = 10;d4 = 10;d5 = ADCresult.Rt % 1000 / 100; d6 = ADCresult.Rt % 100 / 10;d7 = ADCresult.Rt % 10;break;case Alarm:if (tempadj == 0){m.hour = NVM_Read(0x01); //将闹钟的小时数存入DS1302中的0x01地址中m.minute = NVM_Read(0x02); //将闹钟的分钟数存入DS1302中的0x02地址中m.second = NVM_Read(0x03); //将闹钟的秒钟数存入DS1302中的0x03地址中}d0 = m.hour >> 4; //取8 bit数据中的高四位d1 = m.hour & 0xf; //取8 bit数据中的低四位d2 = 12;d3 = m.minute >> 4;d4 = m.minute & 0xf;d5 = 12;d6 = m.second >> 4;d7 = m.second & 0xf;break;case Code:if (tempadj == 0){c.a1 = NVM_Read(0x04); //将8位闹钟密码分别存入DS1302中的0x04~0x11地址中c.a2 = NVM_Read(0x05);c.a3 = NVM_Read(0x06);c.a4 = NVM_Read(0x07);c.a5 = NVM_Read(0x08);c.a6 = NVM_Read(0x09);c.a7 = NVM_Read(0x10);c.a8 = NVM_Read(0x11);}d0 = c.a1;d1 = c.a2;d2 = c.a3;d3 = c.a4;d4 = c.a5;d5 = c.a6;d6 = c.a7;d7 = c.a8;break;case Code_test:if (tempadj == 0){tempadj = 1;}d0 = s_code.a1;d1 = s_code.a2;d2 = s_code.a3;d3 = s_code.a4;d4 = s_code.a5;d5 = s_code.a6;d6 = s_code.a7;d7 = s_code.a8;break;default:break;}if (funcmode == RTC_YMD || funcmode == RTC_HMS || funcmode == Alarm) //时间、日期、闹钟显示界面时数码管如何闪烁{if (ct100mS >= 8)switch (tempadj){case 1:d0 = 10;d1 = 10;break;case 2:d3 = 10;d4 = 10;break;case 3:d6 = 10;d7 = 10;break;default:break;}}if (funcmode == Code || funcmode == Code_test) //设置密码、密码输入界面时数码管如何闪烁{if (ct100mS >= 8)switch (tempadj){case 1:d0 = 12;break;case 2:d1 = 12;break;case 3:d2 = 12;break;case 4:d3 = 12;break;case 5:d4 = 12;break;case 6:d5 = 12;break;case 7:d6 = 12;break;case 8:d7 = 12;break;default:break;}}Seg7Print(d0, d1, d2, d3, d4, d5, d6, d7); //8位数码管显示
}
void dealwithmyKN() //导航按键效果
{unsigned char a;switch (funcmode){case RTC_HMS:if (GetAdcNavAct(enumAdcNavKeyRight) == enumKeyPress){if (tempadj)if (tempadj < 3){tempadj++;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyLeft) == enumKeyPress){if (tempadj)if (tempadj > 1){tempadj--;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyUp) == enumKeyPress){if (tempadj == 1){a = t.hour / 16 * 10 + t.hour % 16;if ((++a) >= 24)a = 0;t.hour = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 2){a = t.minute / 16 * 10 + t.minute % 16;if ((++a) >= 60)a = 0;t.minute = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 3){a = t.second / 16 * 10 + t.second % 16;if ((++a) >= 60)a = 0;t.second = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyDown) == enumKeyPress){if (tempadj == 1){a = t.hour / 16 * 10 + t.hour % 16;if ((a--) == 0)a = 23;t.hour = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 2){a = t.minute / 16 * 10 + t.minute % 16;if ((a--) == 0)a = 59;t.minute = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 3){a = t.second / 16 * 10 + t.second % 16;if ((a--) == 0)a = 59;t.second = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyCenter) == enumKeyPress){SetBeep(1000, 10); //蜂鸣器鸣叫一声if (tempadj == 0)tempadj = 3;else{tempadj = 0;RTC_Write(t);}}break;case RTC_YMD:if (GetAdcNavAct(enumAdcNavKeyRight) == enumKeyPress){if (tempadj)if (tempadj < 3){tempadj++;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyLeft) == enumKeyPress){if (tempadj)if (tempadj > 1){tempadj--;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyUp) == enumKeyPress){if (tempadj == 1){a = t.year / 16 * 10 + t.year % 16;if ((++a) >= 99)a = 0;t.year = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 2){a = t.month / 16 * 10 + t.month % 16;if ((++a) >= 12)a = 1;t.month = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 3){a = t.day / 16 * 10 + t.day % 16;if ((++a) >= 31)a = 1;t.day = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyDown) == enumKeyPress){if (tempadj == 1){a = t.year / 16 * 10 + t.year % 16;if ((a--) == 0)a = 99;t.year = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 2){a = t.month / 16 * 10 + t.month % 16;if ((a--) == 1)a = 12;t.month = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 3){a = t.day / 16 * 10 + t.day % 16;if ((a--) == 1)a = 31;t.day = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyCenter) == enumKeyPress){SetBeep(1000, 10); //蜂鸣器鸣叫一声if (tempadj == 0)tempadj = 3;else{tempadj = 0;RTC_Write(t);}}break;case Alarm:if (GetAdcNavAct(enumAdcNavKeyRight) == enumKeyPress){if (tempadj)if (tempadj < 3){tempadj++;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyLeft) == enumKeyPress){if (tempadj)if (tempadj > 1){tempadj--;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyUp) == enumKeyPress){if (tempadj == 1){a = m.hour / 16 * 10 + m.hour % 16;if ((++a) >= 24)a = 0;m.hour = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 2){a = m.minute / 16 * 10 + m.minute % 16;if ((++a) >= 60)a = 0;m.minute = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 3){a = m.second / 16 * 10 + m.second % 16;if ((++a) >= 60)a = 0;m.second = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyDown) == enumKeyPress){if (tempadj == 1){a = m.hour / 16 * 10 + m.hour % 16;if ((a--) == 0)a = 23;m.hour = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 2){a = m.minute / 16 * 10 + m.minute % 16;if ((a--) == 0)a = 59;m.minute = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}if (tempadj == 3){a = m.second / 16 * 10 + m.second % 16;if ((a--) == 0)a = 59;m.second = a / 10 * 16 + a % 10;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}if (GetAdcNavAct(enumAdcNavKeyCenter) == enumKeyPress){SetBeep(1000, 10); //蜂鸣器鸣叫一声if (tempadj == 0)tempadj = 3;else{tempadj = 0;NVM_Write(0x01, m.hour);NVM_Write(0x02, m.minute);NVM_Write(0x03, m.second);}}break;case Code:if (GetAdcNavAct(enumAdcNavKeyRight) == enumKeyPress){if (tempadj){if (tempadj == 1){NVM_Write(0x04, c.a1);}if (tempadj == 2){NVM_Write(0x05, c.a2);}if (tempadj == 3){NVM_Write(0x06, c.a3);}if (tempadj == 4){NVM_Write(0x07, c.a4);}if (tempadj == 5){NVM_Write(0x08, c.a5);}if (tempadj == 6){NVM_Write(0x09, c.a6);}if (tempadj == 7){NVM_Write(0x10, c.a7);}if (tempadj == 8){NVM_Write(0x11, c.a8);}if (tempadj < 8){tempadj++;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}}if (GetAdcNavAct(enumAdcNavKeyLeft) == enumKeyPress){if (tempadj){if (tempadj == 1){NVM_Write(0x04, c.a1);}if (tempadj == 2){NVM_Write(0x05, c.a2);}if (tempadj == 3){NVM_Write(0x06, c.a3);}if (tempadj == 4){NVM_Write(0x07, c.a4);}if (tempadj == 5){NVM_Write(0x08, c.a5);}if (tempadj == 6){NVM_Write(0x09, c.a6);}if (tempadj == 7){NVM_Write(0x10, c.a7);}if (tempadj == 8){NVM_Write(0x11, c.a8);}if (tempadj > 1){tempadj--;SetBeep(1000, 10); //蜂鸣器鸣叫一声}}}if (GetAdcNavAct(enumAdcNavKeyUp) == enumKeyPress){SetBeep(1000, 10); //蜂鸣器鸣叫一声if (tempadj == 1){c.a1++;if (c.a1 == 10)c.a1 = 0;}if (tempadj == 2){c.a2++;if (c.a2 == 10)c.a2 = 0;}if (tempadj == 3){c.a3++;if (c.a3 == 10)c.a3 = 0;}if (tempadj == 4){c.a4++;if (c.a4 == 10)c.a4 = 0;}if (tempadj == 5){c.a5++;if (c.a5 == 10)c.a5 = 0;}if (tempadj == 6){c.a6++;if (c.a6 == 10)c.a6 = 0;}if (tempadj == 7){c.a7++;if (c.a7 == 10)c.a7 = 0;}if (tempadj == 8){c.a8++;if (c.a8 == 10)c.a8 = 0;}}if (GetAdcNavAct(enumAdcNavKeyDown) == enumKeyPress){SetBeep(1000, 10); //蜂鸣器鸣叫一声if (tempadj == 1){c.a1--;if (c.a1 == -1)c.a1 = 9;}if (tempadj == 2){c.a2--;if (c.a2 == -1)c.a2 = 9;}if (tempadj == 3){c.a3--;if (c.a3 == -1)c.a3 = 9;}if (tempadj == 4){c.a4--;if (c.a4 == -1)c.a4 = 9;}if (tempadj == 5){c.a5--;if (c.a5 == -1)c.a5 = 9;}if (tempadj == 6){c.a6--;if (c.a6 == -1)c.a6 = 9;}if (tempadj == 7){c.a7--;if (c.a7 == -1)c.a7 = 9;}if (tempadj == 8){c.a8--;if (c.a8 == -1)c.a8 = 9;}}if (GetAdcNavAct(enumAdcNavKeyCenter) == enumKeyPress){SetBeep(1000, 10); //蜂鸣器鸣叫一声if (tempadj == 0)tempadj = 8;else{if (tempadj == 1){NVM_Write(0x04, c.a1);}if (tempadj == 2){NVM_Write(0x05, c.a2);}if (tempadj == 3){NVM_Write(0x06, c.a3);}if (tempadj == 4){NVM_Write(0x07, c.a4);}if (tempadj == 5){NVM_Write(0x08, c.a5);}if (tempadj == 6){NVM_Write(0x09, c.a6);}if (tempadj == 7){NVM_Write(0x10, c.a7);}if (tempadj == 8){NVM_Write(0x11, c.a8);}tempadj = 0;}}break;case Code_test:if (GetAdcNavAct(enumAdcNavKeyRight) == enumKeyPress){c.a1 = NVM_Read(0x04);c.a2 = NVM_Read(0x05);c.a3 = NVM_Read(0x06);c.a4 = NVM_Read(0x07);c.a5 = NVM_Read(0x08);c.a6 = NVM_Read(0x09);c.a7 = NVM_Read(0x10);c.a8 = NVM_Read(0x11);if (tempadj == 1){if (s_code.a1 == c.a1)tempadj++;else{s_code.a1 = 0;s_code.a2 = 0;s_code.a3 = 0;s_code.a4 = 0;s_code.a5 = 0;s_code.a6 = 0;s_code.a7 = 0;s_code.a8 = 0;tempadj = 1;}}else if (tempadj == 2){if (s_code.a2 == c.a2)tempadj++;else{s_code.a1 = 0;s_code.a2 = 0;s_code.a3 = 0;s_code.a4 = 0;s_code.a5 = 0;s_code.a6 = 0;s_code.a7 = 0;s_code.a8 = 0;tempadj = 1;}}else if (tempadj == 3){if (s_code.a3 == c.a3)tempadj++;else{s_code.a1 = 0;s_code.a2 = 0;s_code.a3 = 0;s_code.a4 = 0;s_code.a5 = 0;s_code.a6 = 0;s_code.a7 = 0;s_code.a8 = 0;tempadj = 1;}}else if (tempadj == 4){if (s_code.a4 == c.a4)tempadj++;else{s_code.a1 = 0;s_code.a2 = 0;s_code.a3 = 0;s_code.a4 = 0;s_code.a5 = 0;s_code.a6 = 0;s_code.a7 = 0;s_code.a8 = 0;tempadj = 1;}}else if (tempadj == 5){if (s_code.a5 == c.a5)tempadj++;else{s_code.a1 = 0;s_code.a2 = 0;s_code.a3 = 0;s_code.a4 = 0;s_code.a5 = 0;s_code.a6 = 0;s_code.a7 = 0;s_code.a8 = 0;tempadj = 1;}}else if (tempadj == 6){if (s_code.a6 == c.a6)tempadj++;else{s_code.a1 = 0;s_code.a2 = 0;s_code.a3 = 0;s_code.a4 = 0;s_code.a5 = 0;s_code.a6 = 0;s_code.a7 = 0;s_code.a8 = 0;tempadj = 1;}}else if (tempadj == 7){if (s_code.a7 == c.a7)tempadj++;else{s_code.a1 = 0;s_code.a2 = 0;s_code.a3 = 0;s_code.a4 = 0;s_code.a5 = 0;s_code.a6 = 0;s_code.a7 = 0;s_code.a8 = 0;tempadj = 1;}}else if (tempadj == 8){if (s_code.a8 == c.a8){SetPlayerMode(enumModeStop);tempadj = 0;funcmode = RTC_HMS;}else{s_code.a1 = 0;s_code.a2 = 0;s_code.a3 = 0;s_code.a4 = 0;s_code.a5 = 0;s_code.a6 = 0;s_code.a7 = 0;s_code.a8 = 0;tempadj = 1;}}}if (GetAdcNavAct(enumAdcNavKeyUp) == enumKeyPress){if (tempadj == 1){s_code.a1++;if (s_code.a1 == 10)s_code.a1 = 0;}if (tempadj == 2){s_code.a2++;if (s_code.a2 == 10)s_code.a2 = 0;}if (tempadj == 3){s_code.a3++;if (s_code.a3 == 10)s_code.a3 = 0;}if (tempadj == 4){s_code.a4++;if (s_code.a4 == 10)s_code.a4 = 0;}if (tempadj == 5){s_code.a5++;if (s_code.a5 == 10)s_code.a5 = 0;}if (tempadj == 6){s_code.a6++;if (s_code.a6 == 10)s_code.a6 = 0;}if (tempadj == 7){s_code.a7++;if (s_code.a7 == 10)s_code.a7 = 0;}if (tempadj == 8){s_code.a8++;if (s_code.a8 == 10)s_code.a8 = 0;}}if (GetAdcNavAct(enumAdcNavKeyDown) == enumKeyPress){if (tempadj == 1){s_code.a1--;if (s_code.a1 == -1)s_code.a1 = 9;}if (tempadj == 2){s_code.a2--;if (s_code.a2 == -1)s_code.a2 = 9;}if (tempadj == 3){s_code.a3--;if (s_code.a3 == -1)s_code.a3 = 9;}if (tempadj == 4){s_code.a4--;if (s_code.a4 == -1)s_code.a4 = 9;}if (tempadj == 5){s_code.a5--;if (s_code.a5 == -1)s_code.a5 = 9;}if (tempadj == 6){s_code.a6--;if (s_code.a6 == -1)s_code.a6 = 9;}if (tempadj == 7){s_code.a7--;if (s_code.a7 == -1)s_code.a7 = 9;}if (tempadj == 8){s_code.a8--;if (s_code.a8 == -1)s_code.a8 = 9;}}break;default:break;}
}
void dealwithAlarm()
{if (m.hour == t.hour && m.minute == t.minute && m.second == t.second){ADCresult = GetADC();if (ADCresult.Rop >= 20){funcmode = Code_test;SetMusic(Music_PM, Music_tone, &song, sizeof(song), 0xF0); //初始化音乐SetPlayerMode(enumModePlay); //播放音乐}}
}
小学期实训-智慧电子时钟相关推荐
- HNU小学期实训课设
1,设计概述 由于社会的发展和科技的进步,人们对生活品质要求越来越高,而计算机时代的来临和物联网技术的发展也会给我们的生活带来巨大的变化,所以我希望通过物联网传感技术实现对闹钟的创意设计,从而改进人们 ...
- java web 小学期实训小节
这次实训学习了Java spring,mybaits,ssm框架的搭建和整合,详细的了解了 spring框架的流程:1.用户发出请求到前端控制器2.前端控制器请求handlermaping查到hand ...
- hnu小学期实训之数圈
文章目录 题目 思路 代码 收获 题目 思路 其实看到的第一眼我是想利用递归来求解的,但是它这个数圈很奇怪,不是很好利用第n-1个数圈推出第n个数圈.所以就模拟一个一个的暴力打出来.两点在于定义了一个 ...
- 北京电子科技学院c语言实验报告,最新单片机 实训报告电子万年历实训报告.doc...
最新单片机 实训报告电子万年历实训报告 河南工程学院 单片机 实训报告 学 院 电气信息工程学院 专 业 电气工程及其自动化 组员及学号 李 东 盼 201250712138 高 辉 20125071 ...
- 综合专题学期实训IV综合报告
综合专题学期实训IV综合报告 题目 基于Java的聊天系统设计与实现 所在院系 计算机与信息工程学院 学科专业名称 计算机科学与技术 导师及职称 夏端峰(副高).黄烜(讲师) 撰写时间 2023年6月 ...
- java小游戏实训报告心得_Java实训报告-扫雷.doc
Java实训报告-扫雷 实训报告书 实训名称: JAVA程序设计实训 系 (部): 信息工程系 专业班级: 计算机科学与技术08-1 学生姓名: 学 号: 指导教师: 完成日期: 山东科技大学泰山科技 ...
- 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二十四节:小项目实训《绝命沙滩》
<使用Cocos2d-x 开发3D游戏>系列在线课程 第二十四节:小项目实训<绝命沙滩> 视频地址:http://edu.csdn.net/course/detail/1330 ...
- SSM框架体会和小结(短学期实训)
短短两周的小学期的实训,我对ssm框架有了初步的认识.所谓ssm就是指spring+springMVC+mybatis .spring用于实现业务的对象,springMVC负责转发请求和视图,而myb ...
- 物联网工程实训——智慧家居开发
物联网工程实训 目标:用嵌入式开发板采集信息,用WiFi传输到云平台. 开发手机App或者微信小程序,实现云平台数据和信息的读取.可以开发Web页面,对采集的数据进行显示. 本组目标:设计并制造一个物 ...
最新文章
- python opencv图片编码为h264文件
- 如何用java创建超链接_Java如何在PPT中的幻灯片上创建超链接?
- PHP 接口开发注意事项
- java jxl之Excel的创建
- http协议报文体_HTTP报文基本概念学习
- class传参 python_Python类的概念、定义、属性、继承
- Spring-Boot (四) 集成Spring Security
- python获取app信息的库_Python学习教程:另辟蹊径,appium抓取app应用数据了解一下...
- 前端学习笔记--百度2010校园招聘题目
- MYSQL 表左连接 ON AND 和ON WHERE 的区别
- 联想笔记本键盘排线,联想笔记本原装键盘价格表 联想笔记本键盘如何更换
- 品达物流项目重点技术 微服务高性能实战
- 移动设备上“精灵图”的制作
- 百度地图、高德地图和腾讯地图定位不准确的解决方案
- 一种可以使身体吸收天道法则的电脑
- 数字设计(二)之FPGA到底属于硬件还是软件设计
- 小米盒子4用u盘导入html文件格式,小米盒子4好用吗?通过U盘安装沙发管家教程...
- 计算机应用基础课是干嘛的,《计算机应用基础》课程简介
- Leetcode594(力扣594):最长和谐子序列
- 优秀期刊《儿童绘本》CN刊物征稿