《嵌入式技术基础与实践》实验报告.docx
- 文档编号:12672130
- 上传时间:2023-04-21
- 格式:DOCX
- 页数:21
- 大小:195.91KB
《嵌入式技术基础与实践》实验报告.docx
《《嵌入式技术基础与实践》实验报告.docx》由会员分享,可在线阅读,更多相关《《嵌入式技术基础与实践》实验报告.docx(21页珍藏版)》请在冰豆网上搜索。
《嵌入式技术基础与实践》实验报告
(此文档为word格式,下载后您可任意编辑修改!
)
2009级计算机科学与技术学院
《嵌入式技术基础与实践》实验报告
飞思卡尔S08系列单片机实验系统
综合实验的开发
学号:
姓名:
袁杰
2012年6月10日
目录
第1章需求分析1
第2章系统构成2
2.1硬件原理图2
2.2软件结构图2
2.2.1MCU端软件结构3
2.2.2PC端软件结构4
第3章MCU方的程序设计5
3.1串口数据接收与发送5
3.2时钟控制5
3.3主程序9
第4章PC方程序控制13
4.1串口数据接收与发送14
第5章总结与体会18
第6章使用说明19
第1章需求分析
HC08和HCS08单片机是Freescale公司于2000年前后推出的新一代单片机。
S08是HCS08的简写,表示增强型HC08。
从1993年起,Freescale公司为全球提供的8位微控制器已超过50亿片,然而我国国内大多数“熟悉”单片机的人却不知晓这一底细,国内的微控制器市场从20世纪80年代开始,一直由Intel公司推出的MCS-51占据着绝对的统治地位。
人们又逐渐发现,从进口的电子信息类产品,特别是各类通信产品中,其中有MCU的,多数使用了Freescale的产品,而不是MCS-51。
因此学习FreescaleS08是非常重要,本报告描述一个FreescaleS08单片机实验系统软件实例(Light.mcp),通过各个不同模块,验证单片机各模块工作是否正常。
可以独立工作观察MCU工作是否正常,也可以通过串口与PC机连接,实现与PC机的相互控制。
设计时首先设计MCU与PC机间的标志符号位,用于确定双方通讯数据的含义。
MCU端程序编写完成后,使用串口调试器观察输出数据,输入控制数据观察MCU工作状态。
使用串口调试器调试成功后,再使用C#编写与其匹配的可视化程序。
实现非联机验证最小系统、普通IO口输入输出、驱动LCD显示模块功能。
联机验证串口数据接收与发送、小灯测试、LCD及LED、时钟计时、PWM、键盘输入、AD转换、FLASH读写模块功能。
第2章系统构成
2.1硬件原理图
图2.1AW60硬件原理图(最小系统)
系统使用MC9S08AW60型MCU为核心,AW60芯片的硬件最小系统包括:
电源及其滤波电路、复位电路、晶振电路及PLL电路滤波电路、写入器接口电路。
其引脚包括:
电源信号引脚、复位信号引脚、主要功能模块引脚和其它引脚。
2.2软件结构图
软件包括MCU端与PC端2部分组成,下面分别介绍2部分软件的结构。
2.2.1MCU端软件结构
图2.2MCU端软件结构图
根据需求分析,对需要测试的功能进行编程,MCU端包含LED小灯、LCD显示、开关量输入、键盘输入、AD转换、PWM、FLASH读写、串口数据发送与接受等模块。
MCU端软件结构图,如图2.2所示。
在脱离PC端控制的情况下LED小灯、LCD显示可以得到验证,如果需要验证键盘输入、AD转换与串口数据发送与接收必须与PC端联机操作。
2.2.2PC端软件结构
图2.3PC端软件结构图
PC端使用C#编程,以串口通讯为核心,使用串口与MCU进行通讯实现,对MCU的控制和对MCU反馈信息进行处理,并反映在用户界面上。
根据MCU提供的功能,编写程序匹配其工作。
PC端程序包括串口数据输入输出、开关状态反馈、小灯控制、AD转换数据显示、时钟、PWM控制、FLASH读写、键盘数据显示模块。
软件结构图如图2.3所示。
第3章MCU方的程序设计
本章节将详细介绍MCU端的各个功能模块,其中包括串口数据输入输出、LCD显示、键盘、AD转换、PWM、时钟计时、FLASH读写。
程序基于C语言编写,使用面向硬件对象模块封装的思想。
面向硬件对象模块的封装是对系统中的每个硬件对象建立相对应的头文件和硬件驱动程序文件。
头文件中主要包含该硬件的接口和相应的寄存器设置参数,硬件驱动程序文件主要是对该硬件的驱动,同时标注出各个功能模块的功能,入口,出口和堆栈深度。
这样做剩下的编程工作就只是面向变量和PC的编程,屏蔽的具体硬件对象的差异性,提高了程序的移植性和复用性。
3.1串行通信数据接收与发送
MCU端使用串口中断,实现对串口数据的接收与发送。
串口是MCU与PC通讯的唯一通道,在串口中断处理子程序中,将处理由PC端发送的控制指令与数据。
标志位确定PC端发送指令的类型,并加以处理,使用MCU内部标志位确定所需要做的工作,在中断结束后使用主程序完成相应操作。
串口中断处理程序:
isrSCIre:
接收中断处理函数----*
功能:
接收1个字节数据,发送接到的数据*
总中断关闭,但是接收标志还是有,则直接识别缓冲区,就取走就行。
*
参数:
无*
返回:
无*
内部调用函数:
SCIreN,SCIsendN*
---*
interruptvoidisrSCIre(void)
{
uint8f,i,flag;标志是否接受到数据
DisableInterrupt();禁止总中断
接收32个字节的数据
f=SCIReN(1,1,SerialBuff);
若收到数据,则发送接到的数据
if(f==0)
{
if(SerialBuff[0]>=130&&SerialBuff[0]<=137)
{
flag=SerialBuff[0];
}
if(flag==130)
{
light模块
LightBuff=SCIRe1(1,&i);
}
elseif(flag==131)LCD标志
{连续接收可以,代码如下
LCDLen=SCIRe1(1,&i);LCD显示字符长度
SCIReN(1,LCDLen,ShowBuff);LCD显示的内容
}
elseif(flag==132)时钟标志
{
接收3个字节的数据
SCIReN(1,3,time);
}
elseif(flag==133)LED标志
{
pwm处理模块
pwmDutyPC=SCIRe1(1,&i);
}
elseif(flag==135)LED标志
{
接收4个字节的数据
i=SCIReN(1,4,LEDBuff);
if(i==0)
{
SCISend1(1,135);
SCISendN(1,4,LEDBuff);
for(i=0;i<4;i++)
LEDBuff[i]+='0';
}
}
elseif(flag==137)
{
AD模块
chanelNum=SCIRe1(1,&i);
}
else
{
SCISendN(1,1,SerialBuff);
}
}
EnableInterrupt();开放总中断
}
3.2时钟控制
MCU端实现精度为1秒的时钟计时功能,可以通过PC端发送指令设定当前时间,每秒通过串口发送时钟数据。
使用MCU内部定时器0实现计时,定时器0同时作为PWM使用,所以内部需要解决冲突问题。
中断服务中尽量减少其工作量,所以只对秒信号进行处理,其他计时工作使用主程序完成。
isrT1OV:
定时器溢出中断处理函数:
isrT1OV:
定时器1溢出中断处理函数------*
功能:
以秒为最小单位计时,并清定时器1溢出标志位*
内部调用:
*
SecAdd1:
以秒为最小单位递增时,分,秒缓冲区的值*
-*
interruptvoidisrT1OV(void)
{
uint8temp;
DisableInterrupt();禁止总中断
SecAdd1(time);1s到,递增时,分,秒缓冲区的值
SCISend1(1,132);
SCISendN(1,3,time);
temp=AW60_TPM_CSTR
(2);1.读取定时器1状态和控制寄存器T1SC
AW60_TPM_CSTR
(2)&=~AW60_TPM_CSTR_TOF;2.向定时器溢出标志TOF写0
EnableInterrupt();开放总中断
}
键盘中断处理函数:
isrKeyBoard:
键盘中断处理函数*
功能:
识别按键并发送键值,把键值转换成对应的定义值,再从串口发送出去*
调用函数:
*
(1)扫描法读取键值函数(KBscanN)*
(2)键值转为定义值函数(KBdef)*
(3)串行发送一个字节数据(SCIsend1)*
(4)键盘初试化(KBInit)*
-*
interruptvoidisrKeyBoard(void)
{
uint8value;
uint16i;
for(i=0;i<1000;i++);
DisableInterrupt();关总中断
DisableKBint();屏蔽键盘中断
value=KBScanN(10);扫描键值,存于value中
if(value!
=0xFF)
{
SCISend1(1,134);
SCISend1(1,KBDef(value));键值转化为定义值并发送
}
KBInit();键盘初始化键盘中断
EnableKBint();开放键盘中断
EnableInterrupt();开总中断
}
3.3主程序
主程序作用是将系统初始化,并且根据标志处理各工作
-*
工程名:
Light*
程序描述:
MCU综合实验,控制系统各个模块工作*
目的:
FreescaleAW系列MCUC语言综合程序*
说明:
包含串口数据输入输出、LCD显示、键盘、AD转换、PWM、时钟计时、FLASH读写等模块*
---苏州大学飞思卡尔嵌入式系统实验室2012年*
voidmain()
{
仅在本函数中用
uint8i;
uint8ma;
uint8LCDi=0;
定义初始显示缓存并赋初值
constuint8DisPalyInit[]
="WaitReceiving..Soochow2010.09";
LCDLen=0;
chanelNum=30;为30,说明没有收到AD转换的客户端信息
pwmDutyPC=101;
1关总中断
DisableInterrupt();禁止总中断
1.1芯片初始化
MCUInit();
2.模块初始化
SCIInit(1,SYSTEM_CLOCK,9600);
(1)串口初始化
Light_Init(Light_Run_PORT,Light_Run,Light_OFF);
(2)灯和蜂鸣器的引脚初始化
KBInit();(3)按键初始化
TPMinit
(2);(4)定时器2初始化
LEDinit();
PWM(1,0,0x800,0);定时器2通道0初始输出占空比为0周期为1s的PWM波
ADCInit();AD初始化
3.LCD显示初始化
LCDshow((uint8*)DisPalyInit);
4.内存初始化
(1)"时分秒"缓存初始化(00:
00:
00)
time[0]=0;
time[1]=0;
time[2]=0;
(2)小灯状态初始化3,表示没有命令发送过来
LightBuff=3;
(3)数码管状态初始化
LEDBuff[0]='8';
LEDBuff[1]='8';
LEDBuff[2]='8';
LEDBuff[3]='8';
5.开放各模块中断
EnableSCIReInt();
(1)开放SCI接收中断
EnableTimer
(2);
(2)开放定时器1溢出中断
EnableKBint();
6.开放总中断
EnableInterrupt();
主循环
while
(1)
{
if(LightBuff!
=3)
{
不等于3表明PC机有命令发送过来,然后进行处理
Light_Change(Light_Run_PORT,Light_Run);
SCISend1(1,130);发送串口的标志
SCISend1(1,LightBuff);
LightBuff=3;
}
if(LCDLen!
=0)接收在中断中进行
{
for(i=LCDLen;i<32;i++)为了满足32个字符
ShowBuff[i]='*';
LCD显示MCU从串口接收到的32个数据
LCDshow((uint8*)ShowBuff);
SCISend1(1,131);发送LCD的标志
SCISendN(1,32,ShowBuff);发回给PC机
LCDLen=0;
}
if(pwmDutyPC<101)
{
PWM(1,0,0x800,pwmDutyPC);
Delay(10);
pwmDutyPC=101;
}
if(chanelNum<30)
{
ma=(uint8)ADCAve(chanelNum,50);
SCISend1(1,137);
SCISend1(1,ma);
chanelNum=30;
}
LEDshow(LEDBuff);
}
}
第4章PC方程序控制
PC端程序以串口为核心,用户界面上划分多个区域,实现不同控制功能。
PC端用户界面如图4.1,4.2所示(因为界面太大,分为2幅图片截取)。
图4.1PC端程序界面
图4.2PC端程序界面
4.1串口数据接收与发送
串口接收数据子程序实现对于标志位的识别与处理,将MCU发送的数据进行分类,并且显示在用户界面上。
-----*
对象:
SCIPort*
事件:
DataReceived*
功能:
串口接收数据*
函数调用:
(1)SCIReceiveData,串口接收函数*
(2)SCIUpdateRevtxtbox,更新文本框中的内容*
-----*
privatevoidSCIPort_DataReceived(objectsender,
System.IO.Ports.SerialDataReceivedEventArgse)
{
if(!
SCIPort.IsOpen)
{
this.TSSLState.Text="串口没打开!
";
return;
}
Stringstr=String.Empty;
boolFlag;标记串口接收数据是否成功
intlen;标记接收的数据的长度
调用串口接收函数,并返回结果
Flag=sci.SCIReceiveData(SCIPort,refPublicVar.g_ReceiveByteArray);
if(Flag==true)
{
显示MCU端发来的数据,以便于调试
len=PublicVar.g_ReceiveByteArray.Length;
对于字符串形式,考虑到可能有汉字,
直接调用系统定义的函数,处理整个字符串
str=Encoding.Default.GetString(PublicVar.g_ReceiveByteArray);
if((this.TbShowString.Text).Length>100)
{
this.TbShowString.Text=string.Empty;
this.TbShowDec.Text=string.Empty;
this.TbShowHex.Text=string.Empty;
}
else
SCIUpdateRevtxtbox(TbShowString,str);
十进制和十六进制形式按字节进行处理
for(inti=0;i { data=PublicVar.g_ReceiveByteArray[i];获取命令类型 SCIUpdateRevtxtbox(TbShowString,((char)data).ToString());串口字符显示 十进制都是按照三位来显示,字节之间有空格表示区分 SCIUpdateRevtxtbox(TbShowDec,data.ToString("D3")+""); 十六进制都是按照两位来显示,字节之间有空格表示区分 SCIUpdateRevtxtbox(TbShowHex,data.ToString("X2")+""); if(data>=130&&data<=150) { commandType=data; 准备使长度值=0 if(commandType==131)this.tbLCDOutput.Text=string.Empty; if(commandType==132)this.tbMCUTime.Text=string.Empty; if(commandType==137)this.tbADValue.Text=string.Empty; continue; } if(commandType==130) { byteswKey=data;获取开关状态数据 小灯和开关模块 if(swKey==1)注意: 这是硬件开关的状态不一定对应软件开关的状态。 =1,则亮,否则暗 { this.btnSwKey.Image=Image.FromFile(Application.StartupPath+"\\..\\..\\Pictures\\buttonOn.BMP"); this.btnLight.Image=Image.FromFile(Application.StartupPath+"\\..\\..\\Pictures\\LightOn.BMP"); } else { this.btnSwKey.Image=Image.FromFile(Application.StartupPath+"\\..\\..\\Pictures\\buttonOff.BMP"); this.btnLight.Image=Image.FromFile(Application.StartupPath+"\\..\\..\\Pictures\\LightOff.BMP"); } } elseif(commandType==131) { LCD测试模块 SCIUpdateRevtxtbox(tbLCDOutput,((char)data).ToString()); } elseif(commandType==132) { timer模块 bytetmr=data; tmrCount++; tmrStr+=(tmrCount>1? ": ": "")+(tmr<10? ("0"+tmr.ToString()): tmr.ToString()); if(tmrCount>=3) { SCIUpdateRevtxtbox(tbMCUTime,tmrStr); tmrCount=0; tmrStr=string.Empty; commandType=0; } } elseif(commandType==133) { PWM测试模块 高端不作处理仅留一接口在此 } elseif(commandType==134) { 键盘测试模块 bytekbKey=data; for(bytej=0;j<16;j++) if(KBBoard[j]==(char)kbKey) { kb[j].Image=Image.FromFile(Application.StartupPath+"\\..\\..\\Pictures\\KeyDown.BMP"); KBi=j; SCIUpdateRevtxtbox(tbKBShow,KBBoard[j].ToString()); break; } } elseif(commandType==135) { LED测试模块 bytedtLED=data; for(bytej=0;j<8;j++) { 复原 LEDOpr(ledCount,j,"Off"); 再根据条件使相应的条型变换 if(GetBit(ledTBL[dtLED],j)) { LEDOpr(ledCount,j,"On"); } } ledCount++; if(ledCount>=4) { ledCount=0; } } elseif(commandType==137) { AD转换模块 intADValue=data; SCIUpdateRevtxtbox(tbADValue,ADValue.ToString()); } } } } 第5章总结与体会 通过本程序的编写与调试,了解了单片机设计的基础知识,熟悉了单片机的开发与调试过程,在实践中体会编程要领。 特别是将多个功能组合在一起时需要综合考虑MCU的资源利用问题,必须合理分配资源。 程序设计时解决了PWM与时钟共同使用定时器0的问题,解决了LCD显示与AD转换同时使用引脚PTB0的问题等。 设计过程中学会了一些设计思想和技巧,先将各个模块独立设计并验证其功能,最后将这些模块综合起来,有步骤地实现系统由小到大的过程。 设计与实现过程让自己学到许多知识,特别是遇到问题的时候学会的查找资料,网络上大量的资源都可以使用,只需要认真检索一定可以找到需要的内容。 设计系统需要信心也需要耐心,只有坚持不懈的努力才能完成任务。 第6章使用说明 本说明介绍一个FreescaleHC08单片机实验系统软件实例的使用步骤。 1.LCD显示验证,保持步骤1连线,将LCD显示器连接在实验箱默认接口上,写入字符,如正常显示说明LCD工作正常,如不显示请更换另一块LCD,如显示说明上一块LCD坏,如还不显示请检查MCU引脚是否正常。 2.与PC联机测试,请使用串口数据线将MCU与PC连接,打开PC端程序。 首先观察串口状态显示,是否已经为已连
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式技术基础与实践 嵌入式 技术 基础 实践 实验 报告