飞思卡尔单片机应用实验指导书Word文件下载.docx
《飞思卡尔单片机应用实验指导书Word文件下载.docx》由会员分享,可在线阅读,更多相关《飞思卡尔单片机应用实验指导书Word文件下载.docx(43页珍藏版)》请在冰点文库上搜索。
![飞思卡尔单片机应用实验指导书Word文件下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/7/6414a6c0-fb11-4474-a4ce-bc39e2faeb34/6414a6c0-fb11-4474-a4ce-bc39e2faeb341.gif)
3.串行通信线一根
4.万用表一只
四.实验内容
1.理解串行通信(SCI)原理。
2.运行与理解各子程序。
3.主程序运行课本的样例程序。
4.编制一个查询方式通信程序。
将字符通过SCI一个一个地发送,发送完一个字符后,控制接在PTB0~PTB7的8个LED灯显示被发送字符的ASCII码。
5.编制一个中断方式通信程序。
编程要求同上一条。
五.编程提示
1.按照结构要求写好编程代码和注释。
2.计算波特率,SCInInit(SCI初始化子程序)设置SCI比特率寄存器(SCInBDH,SCInBDL),设置允许SCI、正常码输出、8位数据、无校验,即设置SCI控制寄存器1(SCIxC1)相应位,设置是否允许发送与接收、是中断接收还是查询接收,即设置SCI控制寄存器2(SCIxC2)相应位。
3.查询方式通信程序的主程序主体是一个死循环,循环体中是不断检测SCI是否发送完毕,即检测SCI状态寄存器1(SCIxS1)第七位是否为1,为1则将字符的ASCII码输出到接在PTB口的LED上,并延时一会。
4.中断方式通信程序的主程序也主体是一个死循环,但该循环体是一个空循环体,所有接收和发送数据程序代码放在中断程序中,这里没有检测代码,数据开始发送和接收的条件就是中断的条件。
六.实验报告要求
1.小结AW60串行通信(SCI)的原理及编程,并画出其流程图和程序代码与硬件接线图。
2.小结中断方式和查询方式的编程方法,并画出其流程图和程序代码与硬件接线图。
3.回答下列问题
(1)串行SCI通信有哪些中断?
各在什么情况下发生,作用是什么?
(2)如何知道串行口TX发送了信号?
提示:
方法一,利用万用表在TX端发送0或者255持续0.5秒钟时的电压值。
方法二,在TX端发送0或255持续0.5秒钟的波形时的小灯变化。
七.参考例程:
voidmain(void){
unsignedcharSerialBuff[]="
Hello!
World!
"
;
//初始化存放接收数据的数组
//1关总中断
DisableInterrupts;
//禁止总中断
//2芯片初始化
MCUInit();
//3模块初始化
SCIInit();
//串行口初始化
//4开放中断
EnableInterrupts;
//开放总中断
SCISendN(13,SerialBuff);
//串口发送“HelloWorld!
”
//5主循环
while
(1)
{
if
((SCI1S1&
SCI1S1_RDRF_MASK)!
=0){
PTBD=SCI1D;
if((SCI1S1&
SCI1S1_TDRE_MASK)!
=0)
SCI1D=PTBD;
}
else
PTBD=0x00;
}
voidMCUInit(void)
{
SOPT=0b01100000;
//$70SystemOptionsRegister(writeonce)
ICGC2=0b00110000;
//$30internalclockgeneration2
ICGC1=0b01111000;
//$78internalclockgeneration1
//等待FLL稳定
while(!
ICGS1_LOCK);
PTBDD=0xff;
PTBD=0xff;
voidSCIInit()
unsignedintubgs,baud=9600;
unsignedcharsysclk=20;
//1.计算波特率并设置:
ubgs=fsys/(波特率*16)(其中fsys=sysclk*1000000)
ubgs=sysclk*(10000/(baud/100))/16;
//理解参考上一行,此处便于CPU运算
SCI1BDH=(unsignedchar)((ubgs&
0xFF00)>
>
8);
SCI1BDL=(unsignedchar)(ubgs&
0x00FF);
//无校验,正常模式(开始信号+8位数据(先发最低位)+停止信号)
SCI1C1=0;
//允许发送,允许接收,查询方式收发
SCI1C2=(0
|SCI1C2_TE_MASK
|SCI1C2_RE_MASK);
voidSCISend1(unsignedcharch)
(SCI1S1&
SCI1S1_TDRE_MASK));
//判断发送缓冲区是否为空
SCI1D=ch;
voidSCISendN(unsignedcharn,unsignedcharch[])
unsignedi;
for(i=0;
i<
n;
i++)
SCISend1(ch[i]);
unsignedcharSCIRe1(unsignedchar*p)
unsignedintk;
unsignedchari;
for(k=0;
k<
0x0b;
k++)//有时间限制
if((SCI1S1&
SCI1S1_RDRF_MASK)!
=0)//判断接收缓冲区是否满
{
i=SCI1D;
*p=0x00;
break;
}
if(k>
=0x0b)//接收失败
i=0xff;
*p=0x01;
returni;
unsignedcharSCIReN(unsignedn,unsignedcharch[])
unsignedcharm;
unsignedcharfp;
//接收标志
m=0;
while(m<
n)
{
ch[m]=SCIRe1(&
fp);
if(fp==1)
{
return1;
//接收失败
}
m++;
return0;
//接收成功
}
实验三键盘中断及LED数码块实验
1.熟练运用嵌入式开发系统环境、C语言及调试方式。
2.复习串行通信接口(SCI)的内容。
3.加强键盘中断基本原理及编程原理的理解。
4.理解“行扫描”法的原理并能进行键值识别和键值编码。
5.理解键盘接线原理图(如图3-1)。
6.理解LED数码块的显示原理,初步掌握LED数码块显示编程方法。
实验箱提供一个16键键盘,用于键盘中断信号的输入。
系统提供两种接线方式:
①当将键盘接入上一排插孔时为固定接线,键盘接线原理图如图3-1所示。
②当将键盘接入下一排插孔时为手动接线,连线的位置在键盘的左边。
实验箱提供四个LED数码块,PB0~PB7为段码接口,PTD0、PTD1、PTD4、PTD5为位码控制接口。
列线n1n2n3n4
MCU内部上拉电阻
1
2
3
4
5
6
7
8
行线m1
m2
m3
m4
+5V
PTG1
PTG0
PTG2
PTG3
PTG4
PTD2
PTD3
PTD7
a
g
d
f
e
c
b
h
CS0
CS1
CS2
CS3
9
10
11
12
PTB6
PTB2
PTB7
PTB3
PTB4
1K
PTB1
PTD1
PTB5
PTB0
PTD0
键盘及LED数码块原理图
2.复习有关的键盘中断和串行通信接口(SCI)的章节。
3.熟悉AW60键盘模块的工作方法及编程。
1.理解并运行按键扫描及键值键码发送样例程序(将按键的键值及键码从串行口发送到PC机端的串口工具软件);
2.编制一个中断方式的16键键盘程序,使用“行扫描”法识别按键;
采用键盘中断方式。
PTD7,3,2及PTG4接键盘4根列线,PTG3-0接键盘4根行线。
要求按下的一个键的键值和键面定义值(键的ASCII码值)通过串口在PC方软件界面显示,同时用小灯显示按键的键面定义值(键的ASCII码值),PTB7-PTB0口与小灯相连;
3.理解并运行LED数码块样例程序(在LED数码块上显示“2011”);
4.参考按键及LED数码块样例程序,设计一个按键显示程序。
将按键的键码在LED数码块上显示。
7段LED显示字型码
显示字符
字型码
共阴极
共阳极
3F
C0
06
F9
5B
A4
4F
B0
66
99
6D
92
7D
82
07
F8
7F
80
6F
90
A
77
88
B
7C
83
C
39
C6
D
5E
A1
E
79
86
F
71
8E
1.利用构件式方法编程,可以使程序结构清晰,可移植性好;
2.矩阵式键盘采用扫描法来确定哪一个键被按下,键盘的接口硬件确定后,每个键的键值就确定了,但每个键的键码可以根据需要定义;
3.PTD7,3,2及PTG4-PTG0与键盘中断输入引脚复用,设置键盘中断允许寄存器,当键盘有键被按下时,立即产生中断,中断程序处理按键事件,比如确定哪个键被按下,然后转换为该键的定义值。
4.键盘的键面标示码(键码)键盘扫描的键值对应关系通过列表对应起来,即键盘定义表对应表示。
当通过“行扫描”法获得某个键的键值时,通过查表法就可以得到它的定义值。
1.按实验报告格式认真完成实验报告,要求画出工程的总体流程图;
2.本实验中用的是键盘中断编程方式,也可以使用查询编程方式,请尽量少修改代码改用查询编程方式重新编写相应的子程序和主程序。
注意重键问题。
2.识别是否有键按下以及哪个键被按下有哪些方法?
3.有哪些方法可以用来消除键盘抖动?
4.AW60的键盘中断模块用行扫描方式最多能够实现几列的键盘?
voidmain(void)
//3.1SCI初始化
SCI1Init(SYSTEM_CLOCK,9600);
//用SCI1,系统时钟为时钟源,波特率为9600
//3.2键盘初始化
KBInit();
//4开中断
//4.1开键盘中断
KBI1SC|=(1<
<
1);
//4.2开总中断
键盘模块初始化
voidKBInit(void)
PTDD&
=0b01110011;
//键盘口复位
PTGD&
=0b11100000;
PTDDD&
//定义列线(7-4位)为输入
PTGDD&
=0b11101111;
PTDPE|=0b10001100;
//输入引脚(列线)有内部上拉电阻
PTGPE|=0b00010000;
PTGDD|=0b00001111;
//行线(3-0位)为输出
KBI1SC&
=~(1<
//屏蔽键盘中断(KBIE=0)
KBI1PE=(0
|KBI1PE_KBIPE7_MASK
|KBI1PE_KBIPE6_MASK
|KBI1PE_KBIPE5_MASK
|KBI1PE_KBIPE4_MASK);
//允许输入引脚(列线)的中断可进入
KBI1SC=(0
|KBI1SC_KBACK_MASK);
//清除键盘中断请求(KBACK=1)
键盘一次扫描
uint8KBScan1(void)
uint8line,i,tmp,tmp1,tmp2;
line=0b11111110;
//使第一根行线为0(低电平)
for(i=1;
=4;
i++)//最多将扫描4根行线
//当前扫描的一行,输出低电平
PTGD=line;
//输出开始扫描
asm("
NOP"
);
//读取键盘口数据寄存器
tmp1=PTDD;
//输入扫描结果
tmp2=PTGD;
//整合扫描结果,即键盘输入引脚的4位
tmp=(tmp1&
0x80);
tmp1&
=0x0C;
tmp1=(tmp1<
3);
tmp|=tmp1;
tmp|=(tmp2&
0x1f);
//通过观察4根列线中是否出现低电平来判断当前行有无按键
if((tmp&
0xF0)!
=0xF0)//当前行有键按下
//退出循环不再扫描
else//当前行无按键,准备扫描下一行
line=(line<
1)|0x01;
if(i==5)//无按键,以后将返回0xFF
tmp=0xFF;
return(tmp);
键盘进行N次扫描(去抖)
uint8KBScanN(uint8KB_count)
uint8i,KB_value_last,KB_value_now;
//先扫描一次得到的键值,便于下面比较
if(0==KB_count||1==KB_count)
returnKBScan1();
KB_value_now=KB_value_last=KBScan1();
//以下多次扫描消除误差
for(i=0;
i<
KB_count-1;
i++)
{
KB_value_now=KBScan1();
if(KB_value_now==KB_value_last)
returnKB_value_now;
//返回扫描的键值
else
KB_value_last=KB_value_now;
//返回出错标志
return0xFF;
键码表:
constuint8KBtable[]=
//自已添入键值键码表
0x00//键码表结束标志
};
键码转换
uint8KBDef(uint8valve)
uint8KeyPress;
//键定义值
uint8i;
i=0;
KeyPress=0xff;
while(KBtable[i]!
=0x00)//在键盘定义表中搜索欲转换的键值,直至表尾
if(KBtable[i]==valve)//在表中找到相应的键值
KeyPress=KBtable[i+1];
//取出对应的键定义值
i+=2;
//指向下一个键值,继续判断
returnKeyPress;
键盘中断程序(自行设计)
interrupt22voidisrKeyBoard(void)
uint8value;
uint16i;
for(i=0;
1000;
i++);
//关总中断
//屏蔽键盘中断
value=KBScanN(10);
//扫描键值,存于value中
SCI1Send1(value);
//发送键值
SCI1Send1(KBDef(value));
//键值转化为定义值并发送
//键盘初始化键盘中断
//开放键盘中断
EnableInterrupts;
//开总中断
LED显示:
LEDBUF[0]='
2'
LEDBUF[1]='
0'
LEDBUF[2]='
1'
LEDBUF[3]='
LEDinit();
while
(1){
LEDshow(LEDBUF);
LED.C中包含三个函数及段码表和位码表:
voidLEDinit(void)
PTBDD=0xFF;
//数据口为输出
PTDDD|=0x33;
//位选口为输出
voidLEDshow(uint8*Buf)
uint8i,c;
//uint16j;
i<
=3;
i++)
c=Buf[i]-'
LEDshow1(3-i,c);
//延时
Delay(10);
voidLEDshow1(uint8i,uint8c)
PTDD=CStable[i];
PTBD=Dtable[c];
//显示码表(共阴极)
constuint8Dtable[10]=
//0123456789
{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//片选表(电平为低片选)
constuint8CStable[4]=
//0123
{0xDF,0xEF,0xFD,0xFE};
公共函数中包含一个延时程序:
voidDelay(uint16count)
{uint8i;
uint16j;
for(j=0;
j<
count;
j++)
200;
;
实验五定时器输入捕捉与输出比较功能实验
1.熟练运用嵌入式开发系统环境、C语言及调试方式;
2.理解定时器工作原理;
3.初步掌握定时器输入捕捉与输出比较功能及程序设计方法;
4.进一步熟悉LED数码块显示编程原理及方法。
2.复习有关的定时器章节。
3.熟悉定时器模块的原理及定时器模块输入捕捉及输出比较功能及及编程方法。