实验报告课程名称嵌入式系统编程实践实验仪器清华同方辰源嵌入式系统实验箱实验名称实验二:利用中断实现OLED动态显示实验系别__计算机学院_专业___ __班级/学号_学生姓名___ __ ___ _ _实验日期_ 2013年9月22日成绩___________________指导教师_ _ 朱敏玲 ___实验二:利用中断实现OLED动态显示实验一、实验问题回答(1)ISR是什么?简述一下中断的作用和使用方法答:ISR是中断服务程序。
作用是通过处理器执行事先编好的某个特定的程序。
使用方法就是在main中写一个中断程序,然后在startup.s中进行注册。
(2)嵌入式系统中有哪些应用有定时性循环处理的要求?举几个例子答:在各种网络的应用中,设计的一些部件,如计数器,时钟等。
(3)定时时间间隔如何修改?答:通过改变SysTickPeriodSet(SysCtlClockGet()/100)后面的100这个参数。
(4)选作内容5-8的编程思路是什么?若做的话应该怎样实现?答:编程思路:先画直线和竖线,组成一个正方形,将各个参数填写到函数RIT128x96x4ImageDraw(buf,,,,);第6个选作:判断画的原点x,原点y,和画原点x+的长,画原点y+画宽的值要在0-128和0-96。
第7个选作:把RIT128x96x4StringDraw("hello",,,);就是把画的灰度定义为一个变量x。
最后就会出现由不同的亮度而形成的波浪。
第8个就是利用随机函数产生画的原点,随机的在屏幕上进行显示。
(5)拖影现象如何解决?计数值显示为什么没有拖影?答:在程序结束后执行清屏语句:计数显示是每次重新赋值,所以不会出现拖影。
二、实验目的和效果(效果即是否达到实验目的,达到的程度如何)(1)深入学习、理解、掌握OLED字符显示方法(2)深入学习、理解、掌握OLED图形显示方法(3)学习、理解、掌握中断使用方法实验效果图:三、实验内容和步骤(重点阐述自己的思路及遇到的问题)(一)Keil开发环境中对项目Project配置(1)建立项目1、新建一个project;2、选择CPU中的Luminary LM3S 8962;3、加载库文件;4、项目相关配置项修改。
(二)嵌入式C程序开发(1)加载必要程序本次实验提供了几个源程序rit128x96x4.h,rit128x96x4.c,startup.s。
(2)新建主函数程序,并加载到项目中新建一个文件,保存为main.c,把main.c也加载到项目中。
(3)开发主函数,完成基本显示功能头文件有以下三个#include <stdio.h>#include <LM3Sxxxx.H>#include "rit128x96x4.h"在主函数中,首先要进行CPU初始化,函数为/* Set the clocking to run from PLL at 50 MHz */SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);需要对显示屏进行初始化,初始化方法如下RIT128x96x4Init(1000000);一般在显示前,先对OLED显示屏进行清屏处理使用函数RIT128x96x4Clear,具体如何使用,自己查rit128x96x4.h和rit128x96x4.c代码。
以下为示例RIT128x96x4Clear();显示字符串方法使用函数RIT128x96x4StringDraw,具体如何使用,自己查rit128x96x4.h和rit128x96x4.c代码。
以下为示例While(1){ RIT128x96x4StringDraw(" hello ", 0, 6, 15);}显示图形方法使用函数RIT128x96x4ImageDraw,具体如何使用,自己查rit128x96x4.h和rit128x96x4.c代码。
以下为示例unsigned char buf[81];buf[0]=0xff;buf[80]=0xff;for(i=1; i<80; i++)buf[i] = 0x00;RIT128x96x4ImageDraw(buf, 18, 84, 162, 1);在OLED屏幕上显示学号、姓名、个性化字符、直线。
(三)利用中断,实现“0—阈值”循环显示(本例中以阈值100为例)(3—1)基本原理因为是无限循环显示,因此主函数中有个无限循环while(1),在该循环中不断进行计数值显示;为了能控制一定时间显示一次,设定一个全局变量Event,每次显示完成后置为0,每次中断发生时置为1。
在无限循环中,先判断该值是否为1,若为1,表示发生中断了,进行显示,显示完成后清为0,下次循环因为该值为0,故而不再显示,一直等到下次中断发生。
这样就可以用中断的频率控制显示的频率。
(3—2)实现步骤首先,写一个中断处理程序SysTick_Handler(你也可以自己起名字),响应系统SysTick 中断,其处理功能就是设置全局变量Event为1。
示例如下:在main.c中/* SysTick interrupt happens every XX ms */void SysTick_Handler (void) {Event = 1;}其次,注册该中断处理程序,在Startup.s中,找到中断向量表部分,如下所示:;******************************************************************** **********;; The vector table.;;******************************************************************** **********EXPORT __Vectors__VectorsDCD StackMem + Stack ; Top of StackDCD Reset_Handler ; Reset HandlerDCD NmiSR ; NMI HandlerDCD FaultISR ; Hard Fault HandlerDCD IntDefaultHandler ; MPU Fault HandlerDCD IntDefaultHandler ; SVCall HandlerDCD IntDefaultHandler ; Debug Monitor HandlerDCD 0 ; ReservedDCD IntDefaultHandler ; PendSV HandlerDCD IntDefaultHandler ; SysTick HandlerDCD IntDefaultHandler ; GPIO Port A将其中的SysTick Handler(阴影部分)默认的中断处理程序IntDefaultHandler 进行修改,改为SysTick_Handler(刚刚自己编写的中断处理程序名称)因为该中断处理函数在main.c中实现,所以在startup.s中在EXPORT __Vectors(阴影部分)前用extern声明,以表示函数的定义在别的文件中,提示编译器遇到此函数时在其他文件中寻找其定义。
修改后示例如下:(阴影部分);******************************************************************** **********;; The vector table.;;******************************************************************** **********EXTERN SysTick_HandlerEXPORT __Vectors__VectorsDCD StackMem + Stack ; Top of StackDCD Reset_Handler ; Reset HandlerDCD NmiSR ; NMI HandlerDCD FaultISR ; Hard Fault HandlerDCD IntDefaultHandler ; MPU Fault HandlerDCD IntDefaultHandler ; SVCall HandlerDCD IntDefaultHandler ; Debug Monitor HandlerDCD 0 ; ReservedDCD IntDefaultHandler ; PendSV HandlerDCD SysTick_Handler ; SysTick HandlerDCD IntDefaultHandler ; GPIO Port A然后,在主函数中开启该中断,示例如下:/* Setup and enable SysTick with interrupt (100Hz) */SysTickPeriodSet(SysCtlClockGet() / 100); //控制每次中断时间间隔,自己修改一下参数,看看有什么效果SysTickEnable();SysTickIntEnable();最后,主函数的无限循环中利用该全局变量控制计数值的循环显示unsigned char buf[10];while(1){if(Event){Event = 0;if(count>99) count = 0;else count ++;sprintf(buf, "%i", count);RIT128x96x4StringDraw(buf, 48, 40, 15);}}(四)亮线长度周期变化在OLED屏幕上显示一根亮线,根据计数值的不同显示不同长度,最终效果是一根亮线不断变长,变到最长,再从最短继续变长,周而复始……首先显示一根亮线的原理是定义一个数组,将里面每个元素设置值为0xff,表示最亮,然后进行画线操作,可以根据计数值的变化,不断对数组元素进行重新赋值,如下所示:for(i=0;i<count;i++)buf[i]=0xff;for(i=count;i<MAX;i++)buf[i]=0x00;需要注意的是:计数阈值和数组每个元素的映射关系;显示横线时不要超出屏幕。
(五)编译、连接,生成可执行程序文件(编译)(链接)(六)反复(3)--(6)步骤,直到完成如果中间出现错误,修改代码,一直到无错,生成最后程序。