嵌入式实验报告Word格式.docx
《嵌入式实验报告Word格式.docx》由会员分享,可在线阅读,更多相关《嵌入式实验报告Word格式.docx(40页珍藏版)》请在冰豆网上搜索。
2、修改源代码,使得四个灯依次循环点亮,或两个一组循环点亮(使用两种方式控制LED灯,一种通过对寄存器赋值方式,另一种通过固件函数调用方式)
3、解释主函数中TimingDelay_Decrement的作用,delay()函数是一个死循环,程序通过什么方式从这个死循环中跳出来。
4、在自己的U盘上新建工程添加各类文件,使得自己新建的工程文件能够正常编译(若不能正常编译找出原因),下载后验证实验现象与原始工程是否相同。
实
验
设
计
思
路
步
骤
与
结
果
分
析
(1)硬件电路设计
在EduKit-M3实验平台上,LED1、LED2、LED3、LED4分别与PC6、PC7、PC8、PC9相连,按键Key与PB9相连。
硬件电路结构如图所示:
(2)软件程序设计
根据任务要求,程序内容主要包括:
(1)配置PB口第9个引脚作为外部中断,下降延触发;
(2)读取端口数据输出寄存器GPIOC_ODR[15:
0]的值,因为C口[9:
6]位和四个LED灯连通。
(3)初始化时,LED依次点亮,当按下Key键时产生中断;
(4)中断服务子程序内容:
灯全部熄灭,2秒钟后发光二极管全部点亮,再过1秒钟后中断返回。
1、源文件及其函数
(1)整个工程包含3个源文件:
STM32F10x.s、stm32f10x_it.c和main.c,其中STM32F10x.s为启动代码,所有中断服务子程序均在stm32f10x_it.c
中,其它函数则在main.c中。
(2)GPIO_Configuration函数负责配置GPIO端口,其中GPIO_InitStructure数据结构包含所有GPIO端口配置所需各项,函数GPIO_Init则实现某个端口的配置。
(3)NVIC_Configuration函数用于配置嵌入式中断控制器,相关内容将在后面章节介绍,此处需要将PB9引脚配置为外部中断。
2、函数简介
(1)EXTI9_5_IRQHandler函数是PB9的中断服务子程序,当按下Key按钮之后触发EXTI9_5中断,在中断服务子程序中先将灯全部熄灭,延迟2秒后全部点亮,再延迟1秒之后退出中断服务子程序。
(2)SysTick_Configuration函数用于配置和允许系统时钟中断,系统时钟中断服务子程序SysTickHandler函数则用于产生1毫秒的延时,这样Delay函数就可以通过开关系统时钟计数器来实现精确延时了。
3、运行过程
(1)使用KeiluVision3通过ULINK2仿真器连接EduKit-M3实验平台,打开实验例程目录GPIO_TEST子目录下的
GPIO.Uv2例程,编译链接工程;
(2)选择软件调试模式,点击MDK的Debug菜单,选择Start/StopDebugSession项或Ctrl+F5键,
在逻辑分析仪中添加GPIOC_ODR.6、GPIOC_ODR.7、GPIOC_ODR.8、GPIOC_ODR.9,点击Run按钮即可在
逻辑分析仪中看到如图7-11;
(3)选择硬件调试模式,选择Start/StopDebugSession项或Ctrl+F5键,下载程序并运行,观察LED
灯的变化情况;
当程序运行在while循环体内时,按Key键,程序进入中断服务子程序EXTI9_5_IRQHandler(),
单步运行,观察LED的变化情况。
(4)退出Debug模式,打开Flash菜单>
Download,将程序下载到EduKit-M3实验平台的Flash中,按RESET键复位,
观察LED灯的情况,正常情况应如表所列。
LED灯状态说明
LED1LED2LED3LED4
亮灭灭灭程序正常运行,发光二极管依次点亮
灭亮灭灭
灭灭亮灭
灭灭灭亮
灭灭灭灭外部信号输入,发生中断,执行中断处理程序
亮亮亮亮
去掉DELAY,运行程序观察结果,灯全部亮了,而且一直亮着,如果
不用Delay,人眼将分辨不出来灯依次亮的过程。
端口配置寄存器(低位)(GPIOA_CRL-GPIOG_CRL)
(1)低位配置寄存器用来设置端口低8位的工作模式。
(2)该寄存器的地址偏移量为00h(所有GPIO控制寄存器的地址都从0x40010800处开始)。
端口配置寄存器(低位)的定义
端口配置寄存器(高位)(GPIOA_CRH-GPIOG_CRH)
(1)高位配置寄存器用来设置端口高8位的工作模式。
(2)寄存器的地址偏移量为04h,复位值为44444444h。
端口配置寄存器(高位)的定义
主
要
程
序
代
码
4、主要程序代码及分析
初始化主要代码:
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&
GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
GPIO_Init(GPIOF,&
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_Init(GPIOA,&
GPIO_SetBits(GPIOB,GPIO_Pin_8);
GPIO_SetBits(GPIOB,GPIO_Pin_9);
GPIO_SetBits(GPIOF,GPIO_Pin_6);
GPIO_SetBits(GPIOF,GPIO_Pin_7);
方法一,直接通过寄存器控制管脚的高低电平
(1)改变while循环语句:
GPIOB->
ODR=0xfffff0ff;
ODR=0xffffff0f;
ODR=0xfffffeff;
//灯LED1会亮
Delay(80);
ODR=0xfffffdff;
//灯LED2会亮
GPIOF->
ODR=0xffffffbf;
//灯LED3会亮
ODR=0xffffff7f;
//灯LED4会亮
可以看到灯亮顺序为:
LED1亮----LED2亮(LED1灭)-----LED3亮(LED2灭)------LED4亮(LED3灭)即每次只有一个灯循环亮
方法二,直接通过寄存器控制管脚的高低电平
(2)改变while循环语句
GPIO_SetBits(GPIOB,GPIO_Pin_8);
//灯LED1亮
GPIO_SetBits(GPIOB,GPIO_Pin_9);
//灯LED2亮
Delay(80);
GPIO_ResetBits(GPIOB,GPIO_Pin_8);
//灯LED1灭
GPIO_SetBits(GPIOF,GPIO_Pin_6);
//灯LED3亮
GPIO_ResetBits(GPIOB,GPIO_Pin_9);
//灯LED2灭
GPIO_SetBits(GPIOF,GPIO_Pin_7);
//灯LED4亮
GPIO_ResetBits(GPIOF,GPIO_Pin_6);
//灯LED3灭
GPIO_ResetBits(GPIOF,GPIO_Pin_7);
//灯LED4灭
可以看到两个灯同时亮并循环移动
2011级
实验二、TIMERx定时器实验(软件仿真)
1、设计要求:
对TIM2定时器进行控制,使得TIM2通道1产生频率为900Hz
2、配置TIM2各通道均为输出比较模式(预分频系数设为2),设置各通道的参数(TIM2CC1=0x8000、TIM2CC2=0x4000、TIM2CC3=0x2000、TIM2CC4=0x1000);
3、测量定时器程序中各指定输出引脚的频率及占空比(分别采用逻辑分析仪软件仿真和示波器测量),查看程序,判断是否与程序相符
TIM2定时器的通道1到4分别对应PA.00、PA.01、PA.02和PA.03引脚,这些处理器引脚已经以插针形式引出。
(1)配置TIM2各通道均为输出比较模式(预设分频系数为2)设置各通道的参数(TIM2_CC1=0x8000、TIM2_CC2=0x4000、TIM2_CC3=0x2000、TIM2_CC4=0x1000);
(2)在相应的TIM2定时器中断服务处理程序中根据定时器的值翻转输出电平,以输出方波。
1、实验步骤:
(1)使用KeiluVision3通过ULINK2仿真器连接EduKit-M3实验平台,打开实验例程目录TIMx_test子目录下的TIMx.Uv2例程,编译链接工程;
(2)点击MDK的Debug菜单,选择软件仿真模式,点击Start/StopDebugSession,将PORTA.0、PORTA.1、PORTA.2和PORTA.3加入到逻辑分析仪中,点击Run按钮运行程序,在逻辑分析仪中可以看到各通道波形。
(3)进行硬件调试,将EduKit-M3实验平台上的PA.00、PA.01、PA.02和PA.03引脚接入示波器。
选择项或Ctrl+F5键,远程连接EduKit-M3实验平台并下载调试代码到目标系统的RAM中,点击Run按钮或按F5开始运行例程,在示波器上可以看到各通道的波形。
(4)改变通道一的占空比及频率输出为1000HZ
2、实验结果:
在main.c里面设置:
vu16CCR1_Val=0x8000;
vu16CCR2_Val=0x4000;
vu16CCR3_Val=0x2000;
vu16CCR4_Val=0x1000;
可以看到TIM2通道1产生频率为900Hz的方波,通道2产生频率为366.2Hz的方波,通道3产生频率为732.4Hz的方波,通道4产生频率为1464.8Hz的方波。
运行结果如下:
改变通道1的vu16CCR1_Val=0x1B4E;
通道1变为900HZ,结果如下:
3、主要程序代码及分析
1、初始化四个通道的参数
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
ErrorStatusHSEStartUpStatus;
TIM2Configuration:
OutputCompareToggleMode:
TIM2CLK=36MHz,Prescaler=0x2,(分频数为2)
TIM2counterclock=12MHz
CC1updaterate=TIM2counterclock/CCR1_Val=366.2Hz
CC2updaterate=TIM2counterclock/CCR2_Val=732.4Hz
CC3updaterate=TIM2counterclock/CCR3_Val=1464.8Hz
CC4updaterate=TIM2counterclock/CCR4_Val=2929.6Hz
//updaterate通过公式算出来的是更新频率,即TIM2counterclock/CCR1_Val,而在通道上面实际测出来的频率需要乘以2,一个周期更新了两次。
2、以下为TIM2的中断处理程序
voidTIM2_IRQHandler(void)
{
/*TIM2_CH1togglingwithfrequency=183.1Hz*/
if(TIM_GetITStatus(TIM2,TIM_IT_CC1)!
=RESET)
{
TIM_ClearITPendingBit(TIM2,TIM_IT_CC1);
capture1=TIM_GetCapture1(TIM2);
//capture1=TIMx->
CCR1;
//TIM_GetCapture1获得输入捕获的值
//TIMx->
CCR1
TIM_SetCompare1(TIM2,capture1);
CCR1=TIMx->
//TIM_SetCompare1设置比较捕获寄存器值
CCR1=Compare1
}
/*TIM2_CH2togglingwithfrequency=366.2Hz*/
if(TIM_GetITStatus(TIM2,TIM_IT_CC2)!
TIM_ClearITPendingBit(TIM2,TIM_IT_CC2);
capture2=TIM_GetCapture2(TIM2);
TIM_SetCompare2(TIM2,capture2);
}
/*TIM2_CH3togglingwithfrequency=732.4Hz*/
if(TIM_GetITStatus(TIM2,TIM_IT_CC3)!
TIM_ClearITPendingBit(TIM2,TIM_IT_CC3);
capture3=TIM_GetCapture3(TIM2);
TIM_SetCompare3(TIM2,capture3);
/*TIM2_CH4togglingwithfrequency=1464.8Hz*/
if(TIM_GetITStatus(TIM2,TIM_IT_CC4)!
=RESET)
TIM_ClearITPendingBit(TIM2,TIM_IT_CC4);
capture4=TIM_GetCapture4(TIM2);
TIM_SetCompare4(TIM2,capture4);
}
}
实验三、LCD显示实验
1、在液晶显示屏上显示每个组成员各自的学号和姓名
2、改变原显示函数,用点阵来重新显示学号和姓名
由于系统自带的flash容量有限,故使用SPIFlash来存储16×
16的汉字字库或者图片。
因此,程序使用两个步骤来实现:
首先使用一个工程将字库以及图片烧写到SPIFLASH中去;
再使用两外一个工程显示任何16×
16的汉字和显示8×
16的ASCII码;
两副图片分别位于picture.h与picture1.h中;
汉字库位于hzk16.c中;
WAV音乐位于music.h中。
1、首先双击工程文件(在LCD显示(实验三)目下),编译下载程序,观察实验现象,分析原因
2、在自己的U盘上新建工程添加各类文件,看到与步骤一相同的实验现象
3、修改代码,使得LCD屏幕上显示的内容发生变化(如显示自己的学号与姓名)
4、通过取模软件将字体设置为二号字体,生成字模点阵编码,修改程序使得屏幕上显示二号字体的姓名。
(1)在液晶显示屏上显示每个组成员各自的学号和姓名:
核心代码如下:
lcd_display_string("
11061043"
BLACK,GREEN,0,1);
lcd_display(0,BLACK,GREEN,0,2);
lcd_display(1,BLACK,GREEN,1,2);
lcd_display_string("
11061147"
BLACK,GREEN,0,6);
lcd_display(2,BLACK,GREEN,0,4);
lcd_display(3,BLACK,GREEN,1,4);
lcd_display(4,BLACK,GREEN,2,4);
1106xxxx"
BLACK,GREEN,0,10);
lcd_display(5,BLACK,GREEN,0,6);
lcd_display(6,BLACK,GREEN,1,6);
lcd_display(7,BLACK,GREEN,2,6);
(2)改变原显示函数,用点阵来重新显示学号和姓名:
这个步骤必须先用相应的字符转换软件来将字符转换为相应的点阵,其实也就是一个十六进制数组,每个元素相当于一个点的坐标。
这个步骤三个组员的学号和姓名的显示其实是一个道理,所以为了简便,只用了一个组员的信息:
利用自模提取软件得到相应文字的点阵如下图所示
//简体汉字点阵
//字体:
宋体
//点阵:
16×
16
//叶
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,
0x00,0x00,0x03,0xC0,0x1F,0xFF,0xFF,0xE0,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
0x00,0x07,0x00,0x00,0x00,0x07,0x03,0x00,0x00,0x07,0x07,0x80,0x0F,0xFF,0xFD,0x80,
0x00,0x07,0x00,0xE0,0x7F,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
//繁
0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x0C,0x00,0xF0,0x00,0x07,0x00,0xE0,0x00,
0x07,0x80,0xE0,0xC0,0x03,0x80,0xE1,0xE0,0x03,0x7F,0xFF,0x70,0x00,0xC1,0xC0,0x00,
0x00,0xC1,0xC3,0x80,0x79,0xFF,0xFF,0x80,0x3D,0x81,0xC0,0xC0,0x1F,0x83,0x80,0x00,
0x0F,0x83,0x81,0xE0,0x03,0xFF,0xFF,0xF0,0x03,0x07,0x06,0x30,0x07,0x07,0x07,