嵌入式系统编程实践数字钟.docx

上传人:b****7 文档编号:11304659 上传时间:2023-02-26 格式:DOCX 页数:21 大小:139.89KB
下载 相关 举报
嵌入式系统编程实践数字钟.docx_第1页
第1页 / 共21页
嵌入式系统编程实践数字钟.docx_第2页
第2页 / 共21页
嵌入式系统编程实践数字钟.docx_第3页
第3页 / 共21页
嵌入式系统编程实践数字钟.docx_第4页
第4页 / 共21页
嵌入式系统编程实践数字钟.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

嵌入式系统编程实践数字钟.docx

《嵌入式系统编程实践数字钟.docx》由会员分享,可在线阅读,更多相关《嵌入式系统编程实践数字钟.docx(21页珍藏版)》请在冰豆网上搜索。

嵌入式系统编程实践数字钟.docx

嵌入式系统编程实践数字钟

实验报告

 

课程名称嵌入式系统编程实践

实验仪器清华同方辰源嵌入式系统实验箱

实验名称实验五:

数字钟实验

 

系别__计算机学院_

专业______

班级/学号__

学生姓名

实验日期

成绩___________________

指导教师_____

 

实验五:

数字钟实验

一、实验问题回答

(1)画出数字时钟的有限状态自动机,列出全部状态、状态转换规则,以及对应状态下的动作。

按A键

 

按A键

按B键设置结束按C键

 

按C键按B键

 

(2)倒计时和正计时怎么设置?

答:

先添加一个功能键,令其完成的功能是实现倒计时和正计时。

正计时实现利用

if(ms>=99){

ms=0;

if(s>=59){

s=0;

if(m>=59){

m=0;

}

else{

m++;

}

}

else{

s++;

}

}

else{

ms++;

}

在毫秒计数满100令其置零,并向秒进1,秒计数满60令其置零,并向分钟进1。

在其后面加上代码段

else{

if(ms<=0){

ms=99;

if(s<=0){

s=59;

if(m<=0){

m=59;

}

else{

m--;

}

}

else{

s--;

}

}

else{

ms--;

}

}

若毫秒小于等于0责令其变为0,秒计数-1,若秒小于等于0责令其变为0,分钟计数-1,即可实现倒计时功能。

二、实验目的和效果

(1)学习、理解、掌握利用状态机模型实现数字钟系统

实验结果及检查

(1)6个数码管上显示样式改为“分钟+秒+百分之一秒”,其中各占两个数码管。

(2)OLED屏幕上显示和数码管一样效果,“分钟:

秒:

百分之一秒”各占两个字符。

(3)屏幕上显示功能选单,通过键盘A-F键选择不同功能,选择后屏幕显示相关功能提示,并在数码管和OLED屏幕上显示相应功能。

如:

开始显示:

“pleasechoosethefunction:

”“A:

…”“B:

…”“C:

…”“D:

…”

按下“A”键后,显示”nowyouchoosefunctionA”

(4)按下“A”键,暂停,再按“A”键,继续。

(5)按下“B”键,表示设置时钟时间,从前往后或从后往前逐次设置时钟值。

(6)按下“C”键,OLED和数码管回归“00:

00:

00”。

(7)扩展:

按下“D”键,倒计时,再按“D”键,正计时。

三、实验内容和步骤(重点阐述自己的思路及遇到的问题)

(一)Keil开发环境中对项目Project配置

(1)建立项目

1、新建一个project;

2、选择CPU中的LuminaryLM3S8962;

3、加载库文件;

4、项目相关配置项修改。

(二)新建主函数程序,并加载到项目中

(1)加载必要程序

本次实验提供了几个源程序rit128x96x4.h,rit128x96x4.c,startup.s,utility.c,utility.h,definition.h都压在work2.zip中,与实验一

(二)

(1)步骤类似。

其中,definition.h文件中定义了一些宏定义,用于将整个工程中的宏定义放在一起,目的是为了程序的可读性更好。

本例中定义了五个不同的功能模式,可以根据自己习惯进行修改。

Utility.c和utility.h中包含了数码管显示处理函数。

其函数声明如下:

voiddisp(charx,intlocation);使用方法:

第一个参数表示要显示的字符,在本例中,就是键盘中断服务程序执行完后保存在oledkey[0]里的字符,第二个参数表示显示的位置,其中1表示数码管的最右端,6表示数码管的最左端,2-4依次表示中间4个数码管。

新建一个文件,保存为main.c,把main.c也加载到项目中,与实验一

(二)

(2)步骤类似。

本次实验需要增加以下头文件

#include

#include

#include

#include

#include

#include

#include

#include

#include"rit128x96x4.h"

#include"utility.h"

#include"definition.h"

(2)系统初始化

SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN|SYSCTL_XTAL_8MHZ);

/*使能外设GPIO*/

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

/*配置GPIO端口为输出*/

//7segd1(PB6);7segd2(PB4);7segd3(PB5)

GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);

//bitcode0(PC5);bitcode1(PC6);bitcode2(PC7)

GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE,GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);

//7segd0(PD4);7segdot(PD5);rst(PD6)

GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);

/*设置GPIO为输入*/

GPIOPinTypeGPIOInput(GPIO_PORTD_BASE,GPIO_PIN_7);

GPIOPinTypeGPIOInput(GPIO_PORTC_BASE,GPIO_PIN_4);

/*使能中断*/

IntEnable(INT_GPIOD);

IntMasterEnable();

GPIOPinIntEnable(GPIO_PORTD_BASE,GPIO_PIN_7);

GPIOIntTypeSet(GPIO_PORTD_BASE,GPIO_PIN_7,GPIO_RISING_EDGE);

(3)利用键盘GPIOPortD中断,接收键盘输入

本步骤与实验

(二)对应部分一样,不再重复。

(4)利用系统Time0中断,来控制控制时钟速度

/*使能中断*/

IntEnable(INT_GPIOD);

IntMasterEnable();

GPIOPinIntEnable(GPIO_PORTD_BASE,GPIO_PIN_7);

GPIOIntTypeSet(GPIO_PORTD_BASE,GPIO_PIN_7,GPIO_RISING_EDGE);

/*计时器初始化*/

timerset();

初始化的具体函数实现

voidtimerset()

{

SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

TimerConfigure(TIMER0_BASE,TIMER_CFG_32_BIT_PER);

TimerLoadSet(TIMER0_BASE,TIMER_A,SysCtlClockGet()/100);//不除以100则1秒中断一次

IntEnable(INT_TIMER0A);

TimerIntEnable(TIMER0_BASE,TIMER_TIMA_TIMEOUT);

}

 

通过对Timer0中断进行使能和屏蔽来实现秒表的暂停和恢复

TimerEnable(TIMER0_BASE,TIMER_A);

TimerDisable(TIMER0_BASE,TIMER_A);

中断处理函数实例

voidTimer0IntHandler(void)

{

unsignedlongulStatus;

ulStatus=TimerIntStatus(TIMER0_BASE,true);//获取当前中断状态

TimerIntClear(TIMER0_BASE,TIMER_TIMA_TIMEOUT);//清除全部中断状态

if(ulStatus&TIMER_TIMA_TIMEOUT)//如果是超时中断

{

//补充该部分代码

//每次计时中断,相应计数值进行变化

}

}

(5)修改主函数,实现本次实验要求的功能

选好A、B、F功能后,按键后在数码管上按照不同的功能显示秒表显示效果。

自己设计程序逻辑并实现。

注意:

数码管上所有位置的数字同时显示,可以使用for循环赋值并进行显示:

for(j=1;j<7;j++)

{

disp(digits[j],j);

for(k=0;k

}

计数值如m,s,ms分别表示分钟,秒,百分之一秒的具体数值,是个整数,方便计数,但在OLED上显示需要转换成字符格式。

charbuf[2];

sprintf(buf,“%d”,m);

再显示buf[0]和buf[1]的字符

暂停的功能实现:

关掉中断即可、

(6)编译、连接,生成可执行程序文件

(编译)

(链接)

(7)反复(3)--(7)步骤,直到完成

如果中间出现错误,修改代码,一直到无错,生成最后程序。

(三)硬件连接

(1)接上电源线,先关闭开关

(2)用蓝色USB线接上仿真器,仿真器另一JTAG端接LM3S8962CPU板(左下较大子板),USB线接电脑

(3)确认连接无误后,打开电源开关

(四)联调

(1)在KeiluVision4中执行下载,(Flash菜单---Download),即可通过仿真器将

(一)步编译链接好的执行程序下载到LM3S8962芯片内的Flash中。

(2)按下实验箱上LM3S8962子板屏幕上方的白色按钮Reset键,即可查看程序执行效果。

若有问题,返回第一步继续修改程序,编译、链接、下载,一直到显示出满意的效果。

实验代码:

main.c

#include

#include

#include

#include

#include

#include

#include

#include

#include"rit128x96x4.h"

#include"utility.h"

#include"definition.h"

intEvent_key=0;

intb_press_count=0;

intc_press_count=0;

intcountdown_flag=0;//倒计时标记,1表示倒计时;0表示正常计时

intkey_i=0;//i定义为全局变量,因为只有1根线GPIO_PIN_4与CPU相联,所以一个按键(16种,4bit表示)需要四次中断才能传给CPU。

unsignedcharucValue=0x00;//ucValue定义为全局变量,该值存储输入的按键值的中间结果。

charoledkey[2];//设置全局变量oledkey用于保存键盘输入的按键

charkeychar[1];

intkey_press_flag=0;//有没有按键,0表示没有,1表示有

intA_flag,B_flag,C_flag,D_flag,E_flag,F_flag;//按键ABCDEF状态,0表示未选中,1表示选中

intled_postion;//led位置

chardigits[7];//6个位置的数字字符

intinputnext=0;//检测有无下一个输入数字,0表示没有,1表示有。

charcm[3];//cm[2]=cs[0]

charcs[3];

charcms[3];

intm=0,s=0,ms=0;

intE_clr=0;

//时钟中断处理函数实例

voidTimer0IntHandler(void)

{

unsignedlongulStatus;

ulStatus=TimerIntStatus(TIMER0_BASE,true);//获取当前中断状态

TimerIntClear(TIMER0_BASE,TIMER_TIMA_TIMEOUT);//清除全部中断状态

if(ulStatus&TIMER_TIMA_TIMEOUT)//如果是超时中断

{if(countdown_flag==0){

if(ms>=99){

ms=0;

if(s>=59){

s=0;

if(m>=59){

m=0;

}

else{

m++;

}}

else{

s++;

}}

else{

ms++;

}}

else{

if(ms<=0){

ms=99;

if(s<=0){

s=59;

if(m<=0){

m=59;

}

else{

m--;

}}

else{

s--;

}}

else{

ms--;

}}

//补充该部分代码

//每次计时中断,相应计数值进行变化

}}

//键盘中断服务函数

voidGPIO_PORT_D_ISR(void)

{

unsignedcharucKey;

unsignedlongulStatus;

ulStatus=GPIOPinIntStatus(GPIO_PORTD_BASE,true);

GPIOPinIntClear(GPIO_PORTD_BASE,ulStatus);

if(ulStatus&GPIO_PIN_7)

{

ucKey=GPIOPinRead(GPIO_PORTC_BASE,GPIO_PIN_4);

ucKey=ucKey>>1;

ucValue=ucValue+ucKey;

ucValue=ucValue<<1;

key_i++;

if(key_i==4)

{

key_i=0;

Event_key=1;

oledkey[1]='\0';

if((ucValue>>4)<10)

oledkey[0]=(ucValue>>4)+48;

else

oledkey[0]=(ucValue>>4)-10+'A';

}}}

//计时器初始化函数

voidtimerset()

{

SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

TimerConfigure(TIMER0_BASE,TIMER_CFG_32_BIT_PER);

TimerLoadSet(TIMER0_BASE,TIMER_A,SysCtlClockGet()/100);//不除以100则1秒中断一次

IntEnable(INT_TIMER0A);

TimerIntEnable(TIMER0_BASE,TIMER_TIMA_TIMEOUT);

}

//更新led

//暂停或者继续

voidgoOn_pause(inti)

{

//如果是奇数次(第一次)按B就是暂停,偶数次(第二次)就是恢复

if((i%2)==1)

TimerEnable(TIMER0_BASE,TIMER_A);//恢复

else

TimerDisable(TIMER0_BASE,TIMER_A);//暂停

}

//倒计时

voidcountdown(inti)

{

if((i%2)==1)

countdown_flag=1;

else

countdown_flag=0;

}

voiddispled(){

inti,k;

for(i=1;i<=6;i++){

disp(digits[i],i);

for(k=0;k<200;k++);

}}

voidclear(){

inti;

for(i=1;i<=6;i++)

digits[i]='0';

}

//主函数

intmain()

{charbuf[5];

SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN|SYSCTL_XTAL_8MHZ);

RIT128x96x4Init(1000000);

RIT128x96x4Clear();

/*使能外设GPIO*/

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

/*配置GPIO端口为输出*/

//7segd1(PB6);7segd2(PB4);7segd3(PB5)

GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);

//bitcode0(PC5);bitcode1(PC6);bitcode2(PC7)

GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE,GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);

//7segd0(PD4);7segdot(PD5);rst(PD6)

GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);

/*设置GPIO为输入*/

GPIOPinTypeGPIOInput(GPIO_PORTD_BASE,GPIO_PIN_7);

GPIOPinTypeGPIOInput(GPIO_PORTC_BASE,GPIO_PIN_4);

/*使能中断*/

IntEnable(INT_GPIOD);

IntMasterEnable();

GPIOPinIntEnable(GPIO_PORTD_BASE,GPIO_PIN_7);

GPIOIntTypeSet(GPIO_PORTD_BASE,GPIO_PIN_7,GPIO_RISING_EDGE);

/*计时器初始化*/

timerset();

//默认

RIT128x96x4StringDraw("2011011374",0,0,15);

RIT128x96x4StringDraw("pengxin",0,10,15);

RIT128x96x4StringDraw("Work5",0,20,15);

RIT128x96x4StringDraw("pleasechoose",0,30,15);

RIT128x96x4StringDraw("A:

start",5,40,15);

RIT128x96x4StringDraw("B:

inputchar",5,50,15);

//RIT128x96x4StringDraw("B:

pause",5,50,15);

RIT128x96x4StringDraw("C:

clear",5,60,15);

RIT128x96x4StringDraw("D:

countdown",5,70,15);

//RIT128x96x4StringDraw("B:

inputchar",5,70,15);

while

(1)

{

if(Event_key)

{

Event_key=0;

if('A'<=oledkey[0]&&oledkey[0]<='F')

{

//显示按下的字母

keychar[0]=oledkey[0];

RIT128x96x4StringDraw(keychar,90,30,15);

//只要按ABCDEF中任意一个都必须先把A_flag,B_flag,D_flag,F_flag置0,避免混乱。

A_flag=B_flag=D_flag=E_flag=F_flag=0;

switch(oledkey[0]){

case'A':

A_flag=1;//开始

TimerEnable(TIMER0_BASE,TIMER_A);

b_press_count=b_press_count+1;

TimerDisable(TIMER0_BASE,TIMER_A);

goOn_pause(b_press_count);

break;

case'B':

E_flag=1;//input

E_clr=1;

m=s=ms=0;

TimerDisable(TIMER0_BASE,TIMER_A);

clear();

led_postion=6;

break;

case'C':

D_flag=1;//qing0

TimerDisable(TIMER0_BASE,TIMER_A);

m=s=m

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 历史学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1