实验题目:并行接口输出型API函数运用
实验时间:2022.2.21(第1周周一)~2022.3.4(第2周周五)
实验地点:在规定时间中自主寻找合适实验地点并在规定时间内完成
实验条件:
1.STC-B学习板(2021暑假小学期每个学生自己做的) 2.个人电脑:自备 3.Keil、ISP、CH340驱动软件:自备 4.STC-BSP及Demo 程序:教师提供 5.“STC_B学习板”软件支持包使用说明:教师提供 6.C51语言语法:课程提供参考电子书籍,或自找自学
实验目的:
1.回顾与掌握集成开发环境Keil、“STC-B学习板”的主要功能和使用; 2.认识C51语言和语法,了解和学习基于支撑环境的结构化应用软件编写; 3.学习和熟悉STC-BSP(“STC-B学习板”板级软件开发支撑包)功能和使用方法,具体学习其中: sys STC-BSP内核系统 displayer 显示模块 beep 蜂鸣器模块 music 音乐播放 FM_Radio FM收音机 4.认识“阻塞型”和“非阻塞型”函数;
实验内容:
1.安装Keil与STC-ISP软件(包括必要的驱动文件或库文件以满足以下实验要求)。配置Keil环境,能正确打开和编译Demo工程,生成所需要的hex格式输出文件。安装CH340驱动,可识别USB-Serial CH340和STC-ISP可正常下载Hex文件到“STC-B学习板”; 2.阅读《“STC_B学习板”软件支持包使用说明》中sys、displayer、beep、music、FM_Radio五个模块说明,并阅读STC_Demo中的源程序,认识和学习C51语言、STC-BSP所提供函数和方法,并编写程序测试STC-BSP所提供的各个函数,报告测试方法、程序、过成和结果; 3.尝试利用所学模块API函数,设计与编写有一定功能、目的的应用程序,并调式和在“STC-B学习板”上实现; 4.选做:用所学的API函数,继续包装其它功能API函数(如:Music模块中的API函数是由Beep模块中的API函数包装而成的) 实验过程、步骤、现象、结果: ?安装Keil与STC-ISP软件: 下载Keil4后,打开“keil4”文件夹,鼠标右击“MDK412”,选择“以管理员身份运行”,以默认的安装选项安装。 安装完成后下载KEIL_LIC(keil注册机)打开刚安装的KEIL软件。然后选择File–License Management,在License Management对话框中复制CID编号 打开KEIL_LIC.EXE文件,在target内选择arm, 把刚从MDK复制的CID编号粘贴到CID里面,点击Generate. 则在最下方出现一串编号,把它复制到Keil的License Management对话框的New License ID Code内,点击上AddLIC即可完成破解 破解完成后会显示相应的CID码:如图表示破解完成
下在STC-ISP软件,下载完成后打开STC -ISP软件,检测串口号。若单片机与电脑未连接,串口号没有显示USB-SERAL CH340,否则显示USB-SERAL CH340和对应串口号;
其中在芯片类型处选择IAP15F2K61S2 如要烧录hex文件到STC-B板子中,先选择相应的hex文件,然后点击下载/编程按钮,然后按下板子上的复位键即可完成文件的烧录
阅读模块说明和demo程序并编写程序测试STC-BSP所提供的各个函数:
模块说明概述: Sys.H系统模块主要功能为设置回调事件和记录系统运行性能情况 display.h显示模块用于控制数码管和8个LED灯的显示情况 beep.h控制蜂鸣器的发声基本操作 Music.h 集成了beep和display模块,对beep模块集成实现了播放音调的方法,从而实现播放音乐,对display模块的集成实现了播放音乐时显示音乐信息和打拍 FM_Radio 用于控制收音机频率 Demo程序说明: 8个Led 指示灯上显示0x55,即:01010101 ( LedPrint(0x55);) 8个七段数码管上显示:1 2 3 4 5 6 7 8(Seg7Print(1,2,3,4,5,6,7,8);) 插入耳机后,FM收音机接收长沙市"精英955"电台,音量:5,三个指示灯状态:亮、暗、亮(FMRadioInit(FM);struct_FMRadio FM={955,5,0,1,0};) 同时蜂鸣器会播放"歌唱祖国"(SetMusic(90, 0xFA, &song, sizeof(song), enumMscNull); SetPlayerMode(enumModePlay);) 第一遍时数码管显示1~8的数字,第二遍时显示音乐播放的信息 注意:这里音乐能够播放两次且在第2次改变数码管和LED灯是由于在歌曲内部嵌套了控制字符,和设置歌曲播放模式没有关系 "歌唱祖国"结束后,蜂鸣器循环播放C调中音1-7,每个音发声500mS 1.测试sys.H模块: sys系统模块含有MySTC_Init(),系统初始化函数和MySTC_OS系统调度函数前者需要在程序开始时运行后者需要在死循环中无限执行否者系统无法正常执行 不使用MySTC_Init()时,demo程序运行如下,系统基本无法正常运行,不使用MySTC_OS或都不使用时情况一样
sys中还包括回调函数和系统性能测试函数,我们可以通过设置相应的回调事件和回调处理函数来使用 这里我设置了一个按键回调:
系统一旦检测到按键按下就会执行相应的回调函数,这里我按下Key1后demo样例中LED灯就会全灭
按下前: 按下后:
如图说明sys中回调函数运行成功 接下来测试sys中的系统性能测试函数 根据sys说明文档中的描述,GetSysPerformance()函数提供的结构体提供系统主循环数和丢失数,这两者一个是unsigned long类型和unsigned char类型,但这里因为数码管能够显示的位数有限,对于主循环数只能有5位的显示空间,所以这里只显示主循环数的后5位,如果不止5位数就显示99999测试代码如下:
测试结果如图:主循环数在1000,丢失数在70上下浮动:
但通过请教老师,这里的主循环数偏低而且存在丢失情况说明while每次循环时间过长了,其原因是在while(1)主循环中每次对long 4个字节类型的变量做了多次的除法导致,导致主循环数下降,产生丢失,这里想到系统GetSysPerformance()每一秒更新一次数据,所以我们不需要实时更新我们只需要每1s更新一次即可,所以这里使用1s的回调函数来显示主循环数和丢失数,效果很明显,主循环数大大提升且消除了丢失情况:
这里老师还提供了一种方法,既然只能显示后面5位,那么可以直接使用int(这里是2字节的)类型变量获取低16位然后在来做除法操作,修改代码为:
运行结果如图所示:消除了丢失情况且提升了3倍的主循环数
这里将两种方法合并测试一下不过由于改良的主要原因是执行的次数大大减少了,所以主循环数没有发生明显变化:
2.测试displayer.h模块: displayer内包含3个函数,其中SetDisplayerArea()用于设置数码管的有效位,经测试多次使用该函数,函数效果会覆盖上一次的效果而不是和上一次合并 例如:SetDisplayerArea(0,1);SetDisplayerArea(2,3)并不会显示01和23的数码管而只会显示2~3的数码管,LedPrint()参数表示的二进制数对应从左到右的每一位,为1的位会亮:
所以想要做到不连续的数码管显示只能在Seg7print对应位置数码管使用序号10(10对应的显示情况为不显示) 3.测试beep.h 模块: beep.h中包含2个函数,SetBeep(unsigned int Beep_freq, unsigned int Beep_time)和GetBeepStatus()前者是用于发出指定频率和时间的声音,当然这里有限制(来源于其参数的数据类型) 测试代码:在主循环中进行判断如果蜂鸣器正在发声显示2,否者显示1 Demo代码中会播放音乐,这里使用按键回调函数通过Key1键可以暂停音乐播放
回调代码:
实现效果: 播放音乐时: 暂停时:
4.测试music.h模块:
只执行一次该函数,会发出指定的音调和节拍,类似于SetBeep,不过功能更多样化 SetMusic函数用于设置音乐播放的信息,需要设置节拍,音调以及导入音乐数据等信息,SetPlayerMode用于改变播放状态,GetPlayerMode用于返回播放状态 测试代码:这里一开始就会启动数码管和LED灯进行显示音乐信息
同时设置按键回调函数使用Key1可以控制音乐播放状态
在音乐处于停止或暂停时按下key1,可以播放音乐,处于播放状态时可以暂停音乐,这里可以同时测试这些函数 效果如下:一开始就会显示音乐信息,按下key1可以成功暂停继续,但音乐结束后必须再次设定播放音乐和播放参数,才能重新播放。直接改变播放状态无效
5.测试FM_Radio模块: FM_Radio模块中含有SetFMRadio和GetFMRadio两个函数,前者设置收音机的属性如频率,音量和指示灯信息,后者可以返回这些消息 测试函数:这里使用数码管将收音机的属性频率和音量显示出来
运行效果:显示与我们设置的一致,插入耳机后可以顺利收听到广播(不过5的音量比较大,1比较合适)这里如果没有安装CH340串口驱动是无法收听的。
尝试利用所学模块API函数,设计与编写有一定功能、目的的应用程序,并调式和在“STC-B学习板”上实现
这里为了模式切换更加清晰,多使用了Key模块用于输入,实现的功能为开机后key1控制音乐的播放和暂停(初始为停止状态),数码管显示目前的主循环数和丢失数,LED灯在左边第3个亮起表示音乐处于停止状态,刚开始的界面如下:
按下Key1后音乐开始播放,可以看到此时主循环数减少,LED灯在左边第一个亮起表示此时为播放状态:
再次按下key1后音乐暂停,主循环数再次超限,LED灯左边第2个亮起
按下key3后切换到收音机设置模式:右边第一个LED灯亮起表示现在为收音机模式(没有亮表示音乐播放模式) 此模式下按下Key1和Key2可以增加/减少收音机的音量,数码管上显示收音机的频率和音量
具体烧录的代码:使用了3个回调函数
按键回调用于控制音乐播放和收音机音量以及模式切换,1s和10ms回调函数用于显示调试信息和收音机信息 按键回调函数: 如果按键1,按下后,根据目前的模式选择不同的处理方案,对于音乐播放模式key1按下后暂停或播放音乐并更改LED的显示情况,对于收音机模式这增加音量。Key2,Key3效果同理。
1s回调函数: 效果为在音乐播放模式下,显示主循环数和丢失数
1ms回调函数: 效果同理用于显示和更新收音机频率和音量
用所学的API函数,继续包装其它功能API函数
这里是对music模块的函数进行了一次集成,集成后可以方便的对多首音乐进行操作 下面是根据music模块新定义的结构体:
第一个结构体只是将PlayTone的元素整合了一下。 下面的Song结构体用于对歌曲属性的一个整合,而Songs结构体则是用于管理多首歌曲的变脸,其中cour表示目前的歌曲,count表示现在表中有多少歌曲(最大为8首)
接下来是歌曲的载入 和删除部分,AddSong用于歌曲的载入,在歌曲属性定义好后,可以将歌曲载入到歌曲列表变量中(Psongs)是从末尾插入,DeleteSong()则可以删除末尾的歌曲。
接下来是对歌曲的播放,下面的方法支持播放当前cour指向的歌曲或者跳转到上一首或下一首然后进行播放
使用新整合的API进行测试:
在主函数中定义了两个歌曲,然后添加到歌曲列表中,然后进行播放(此时播放的是第一首歌曲)
在按键回调中添加,播放上一首和下一首歌曲的函数。
最终效果:刚开机时,音乐播放《歌唱祖国》按下key3后播放《同一首歌》,按下key2后播放《歌唱祖国》(跳转回来)说明新API函数运行正确。现在集成后的函数,可以更加方便的导入多首个然后,然后进行切换播放。
实验遇到的问题和难点
1,打开keil后编译报错:
有些keil安装后没有自带C51文件。 解决办法:在网上下载C51文件,并在TOOLS.INI文件中添加C51的配置信息和C51文件的路径和keil的版本号,添加内容如下:
2,在测试sys模块中,主循环数不能正常显示(一直为0) 解决办法:老师重新提供一个静态库后,成功正常显示 3,测试收音机时,耳机插入后没有声音 解决办法:CH340驱动没有安装或者误删了,重新安装CH340串口驱动后可以正常收听收音机 4,编译keil4时报错:数据大小超限 解决方法:keil4的RAM中最多只能给128字节的数据让我们定义变量,所以我们遇到这种情况只能删除一些不重要的变量,或者在一些常量前添加code字段,这样此变量会存到ROM中不占用RAM的大小。
实验结果分析、结论、待续的工作
虽然我们暑假进行过相关BSP的运用,但在这次实验当中还是遇到了不少的问题,通过上网查资料和请教老师,最终顺利的完成了本次实验,最终实验结果符合预期。 实验收获、体会、改进意见 改进意见:因为keil烧录中对全局变量定义的大小有限制(128字节以内),所以在老师demo中tone数组前可以添加code字段,因为tone在demo中并未被改变过,可以看作常量,这样可以节省14字节的空间用于定义其他变量 最后还有因为这次的实验内容只有输出部分的模块,想只用输出模块编写一个具有一定功能的代码,感觉还是十分的困难(因为很少有应用程序没有输入信息而只输出信息,这样就与外界没有交互,这样就只能编写时钟或者类型的功能了),所以这次还是多使用了按键模块作为输入来编写的具有一定目的的应用程序。
|