文章导航
大三下电子线路设计下中期报告
一、开始的准备
(一)软件准备
在上学期电子线路设计实验一中我们主要用到了Proteus和keil两个软件的联调仿真,但是这学期的实验板使用的C8051F020单片机在Proteus当中找不到。在查阅相关资料和网上求证后得知,该单片机系统比较复杂,无法用软件仿真,只能在实物上面调试。在当前条件下只能先自己完成代码部分。
关于查看使用单片机型号的问题,我经过学习了解到,应该Project-> Select Device for Target即可查看单片机型号。在例程中查看发现该单片机在Silicon Laboratories.Inc.下面。选择C8051F020单片机芯片即可完成工程的初始创建。
(二)硬件准备
经过前期和老师的交流,我得知学校的实验板上面是没有对应的SD卡读卡模块的,而我的工程中包含相应的读卡器,所以需要自己外接。我在网上查看了对应的单片机读卡模块,加上手头有一张2GB micro SD卡,我选中了下面两款读卡模块:
而我们的单片机对应参数为:
供电电压3.3V,比较而言,选择第二个模块比较合适,可以直接挂接在实验板上,不用另外加其他电源。型号为120801。
这个模块的外形如下,支持大小两张卡,使用SPI方式读写即可,而C8051F020支持SPI读写方式。
二、上学期的遗留问题
上学期仿真软件中的mmc文件(SD卡映像文件)是当时找到的例程中已经写好的,我没有弄清楚它里面的机制。非常感谢刘老师,她给我推荐了软件winimage,可以把文件另存为一个软盘映像文件,但是在具体操作中读入失败,原因可能是我封装的文件格式不对。尝试了各种类型的文件,包括二进制文件,文本文件等等都显示为乱码,于是我直接把转码后的二进制文件后缀改为.mmc发现可以显示图片。
转码文件 存为二进制改为mmc
但是显示明显有问题,我认为这是因为原始显示图片时文件的扫描方式不对导致了这一的结果。更改扫描方式以后虽然有了大致的图像,但是仍然是错位的两幅图:
预期显示的图片 实际显示的图片
研究具体扫描方式时,由于之前例程中有显示模块,故我把它拿来查看,发现扫描方式应该是水平,但是字节是垂直的,只保留一半的显示函数时很明显能说明问题:
扫描方式 修改函数后的显示
所以在转码时采取这种方式,转为二进制bin文件并改后缀名为mmc即可。
造成左边图像的原因是字节内的像素反了,也就是每八行的图像颠倒了,修改为字节内像素反序即可,如右图所示。
显示效果如下:
字节未反 字节反序
另外,用ultraedit软件打开原来的SD.mmc文件,里面其实也是二进制文件,将其中的一幅图单独显示即可看出里面的像素确实是这样安排的,其中自己的图片存为img1.mmc,抽取的一帧存为img2.mmc。
那么,把这些像素帧放到一起不断地读取就可以形成动画效果了,但是工具所限,UltraEdit编辑功能有限,我用记事本将转码后的20帧的二进制文件合并,发现漏了几个字节,这就导致动画播放产生了位移,并且其中还有好多横线影响观感。其中gf.mmc是合成的第一个文件,gf2.mmc是6个原文件合并,位移效果更明显。
直接合并播放效果 改进后播放效果
在网上找到了一个可以合并bin文件的软件(附在作业中),直接运行即可:
指定输入文件夹和输出文件夹就能得到合并后的bin文件,将后缀名改成mmc即可。在工程文件中gf3.mmc是用软件合成的完整文件,gf4.mmc是4个gf3合成的结果,播放时间更长。 而对于新的单片机,需要采用新的读卡方式,但是最终仍然要落在读取字节信息上面,合成对应的二进制文件仍然是必不可少的。 之前例程中也是采用SPI总线方式读取SD卡,我也在网上找到了相应的C8051F020单片机读写SD卡的例程,以此在后续编写新的程序。
三、工程建立遇到的问题与解决
(一)模块化编程
之前C51编程没有逻辑,不讲规则,但是在看了几个例程之后发现可以使用以下几步使得工程变得有条理。
通过设置头文件指定文件夹、选择object、list文件夹等方法将不同类比的文件分别存储便于管理,在工程中也可以新建group管理不同模块的代码。
(二)关于初始化
之前各种模块的初始化都是直接放在主函数里面,这样安排没有条理,代码可读性差,和例程学习将所有的初始化函数放到一起命名为Init_Device,如图所示:
(三)禁止看门狗
用户的应用软件应周期性地向WDTCN写入0xA5,以防止看门狗定时器溢出。每次系统复位都将使能并启动WDT。向WDTCN寄存器写入0XDE后再写入0XAD将禁止WDT。所以,在前面的时钟初始化程序中,{WDTCN=0xde;;//禁止看门狗定时器WDTCN=0xad;}禁止WDT。 看门狗的禁止用以下代码实现: EA=0;/最好将中断关闭 WDTCN=0xde;WDTCN=0xad;EA=1;/恢复中断 注意:写0xDE和0xAD必须在4个机器周期内完成,否则禁止操作不生效。中断的关闭就是为了保证此两条操作代码能在4个周期内完成。
(四)中断的设定
51单片机中可以设置四种中断,其中的按键功能可以用中断实现,之前我是放在循环里面去轮询,这样功耗大且费时间,下面计划改为中断方式,这是代码改进中很重要的一步。 关于interrupt函数用法: void+函数名+interrupt+数字0~4 0表示外部中断0 1表示定时器/计数器(TO) 2外部中断1 3:定时器/计数器(T1) 4:串行口
这个就是按键的中断服务子程序
(五)防止头文件重复包含
在先设定好工程基本结构,导入对应子函数框架尝试编译时,编译器报错说重复定义了东西,再次查看例程发现在头文件中都加了这样两句程序: #ifndef C8051F020_H #define C8051F020_H
这样做的目的是防止两次包含同一头文件产生冲突,这样就可以避免。
(六)下一步的工作
这是目前程序的结构,其中led,lcd的部分很快就可以改好,其中有点问题的是将按键从轮询改为中断,在上学期嵌入式实验中曾经使用过中断,这次有例程的帮助相信也可以解决。而SD卡的读写将会是一个挑战,我将结合查到的例程继续学习,争取可以在开学以前实现。
C8051F020 SPI特殊功能寄存器和I/O引脚的配置:
C8051F020的SPI引脚分配为
P0.0——CLK
P0.1——MISO
P0.2——MOSI
P0.3——NSS(一主多从模式,接高电平+Vdd)
P0.4~P0.7——Slaves 片选信号
C8051F020SPI特殊功能寄存器的配置:
①SPI控制寄存器SPI0CN的配置:
选择MSTEN=1,使能主方式;SPIEN=1,使能SPI。
SPIF WCOL MODF RXOVRN TXBSY SLVSEL MSTEN SPIEN
0 0 0 0 0 0 1 1
所以,PI0CN=03H。
②SPI配置寄存器SPI0CFG的配置:
CKPHA CKPOL BC2 BC1 BC0 SPIFRS2 SPIFRS1 SPIFRS0
1 1 0 0 0 1 1 1
选择CKPHA=1,在SCK周期的第二个边沿采样数据;CKPOL=1,SCK在空闲状态处于高电平;BC2BC0=000,表示数据从最高位一直发送到最低位;SPIFRS2 SPIFRS0=111,表示发送8位数据。
所以,SPI0CFG=16H。
③内部振荡器控制寄存器OSCICN的配置
MSCLKE —— —— IFRDY CLKSL IOSCEN IFCN1 IFCN0
0 0 0 1 0 1 1 1
选择IFRDY=1,内部振荡器频率按照IFCN位确定的频率运行;IOSCEN=1使能内部振荡器;IFCN1~IFCN0=11,内部振荡器频率为16MHz。
所以,OSCICN=17H。
④SPI时钟速率寄存器SPI0CKR配置:
SCR7 SCR6 SCR5 SCR4 SCR3 SCR2 SCR1 SCR0
0 1 0 0 0 0 0 1
设定SPI的时钟为fSCK=100KHz,
则SPI0CKR =[(SYSCLK/2)/ fSCK]—1=79=41H。
所以,SPI0CKR=41H。
⑤端口I/O交叉开关寄存器0(XBR0)的配置:
CP0E ECI0E PCA0ME UART0EN SPI0EN SMB0EN
0 0 0 0 0 0 1 0
选择SPI0EN=1,SPI总线使能,SPI的SCK、MISO、MOSI、NSS分别连到P0.0、P0.1、P0.2和P0.3四个端口引脚。
所以,XBR0=02H。
⑥端口I/O交叉开关寄存器1(XBR1)的配置:
WEAKPUD XBARE — T4EXE T4E UART1E EMIFLE CNVSTE
0 1 0 0 0 0 0 0
选择WEAKPUD=0,全局弱上拉;XBARE=1,交叉开关使能。
所以,XBR1=40H。
⑦端口0输出方式寄存器P0MDOUT的配置:
D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 1 1 1 1
选择SCK、MISO、MOSI、NSS为推挽输出方式。
所以,P0MDOUT=0DH。
其中最后第七条,MISO应该为开漏输出,相应的位为0。P0MDOUT值需要再算,
http://bbs.eeworld.com.cn/thread-114758-1-1.html