可设置初值的正倒计时秒表Word格式.docx

上传人:b****5 文档编号:19106055 上传时间:2023-01-03 格式:DOCX 页数:34 大小:1.24MB
下载 相关 举报
可设置初值的正倒计时秒表Word格式.docx_第1页
第1页 / 共34页
可设置初值的正倒计时秒表Word格式.docx_第2页
第2页 / 共34页
可设置初值的正倒计时秒表Word格式.docx_第3页
第3页 / 共34页
可设置初值的正倒计时秒表Word格式.docx_第4页
第4页 / 共34页
可设置初值的正倒计时秒表Word格式.docx_第5页
第5页 / 共34页
点击查看更多>>
下载资源
资源描述

可设置初值的正倒计时秒表Word格式.docx

《可设置初值的正倒计时秒表Word格式.docx》由会员分享,可在线阅读,更多相关《可设置初值的正倒计时秒表Word格式.docx(34页珍藏版)》请在冰豆网上搜索。

可设置初值的正倒计时秒表Word格式.docx

(4)秒表具有清除当前显示值,显示初值的功能。

(5)秒表的显示全部在LED灯上实现。

(6)秒表的显示全部在LCD灯上实现。

第二章IIC通信协议

1、IIC总线的特点

I2C串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。

所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。

为了避免总线信号的混乱,要求各设备连接到总线的输出端时必须是漏极开路(OD)输出或集电极开路(OC)输出。

设备上的串行数据线SDA接口电路应该是双向的,输出电路用于向总线上发送数据,输入电路用于接收总线上的数据。

而串行时钟线也应是双向的,作为控制总线数据传送的主机,一方面要通过SCL输出电路发送时钟信号,另一方面还要检测总线上的SCL电平,以决定什么时候发送下一个时钟脉冲电平;

作为接受主机命令的从机,要按总线上的SCL信号发出或接收SDA上的信号,也可以向SCL线发出低电平信号以延长总线时钟信号周期。

总线空闲时,因各设备都是开漏输出,上拉电阻Rp使SDA和SCL线都保持高电平。

任一设备输出的低电平都将使相应的总线信号线变低,也就是说:

各设备的SDA是“与”关系,SCL也是“与”关系。

总线对设备接口电路的制造工艺和电平都没有特殊的要求(NMOS、CMOS都可以兼容)。

在I2C总线上的数据传送率可高达每秒十万位,高速方式时在每秒四十万位以上。

另外,总线上允许连接的设备数以其电容量不超过400pF为限。

总线的运行(数据传输)由主机控制。

所谓主机是指启动数据的传送(发出启动信号)、发出时钟信号以及传送结束时发出停止信号的设备,通常主机都是微处理器。

被主机寻访的设备称为从机。

为了进行通讯,每个接到I2C总线的设备都有一个唯一的地址,以便于主机寻访。

主机和从机的数据传送,可以由主机发送数据到从机,也可以由从机发到主机。

凡是发送数据到总线的设备称为发送器,从总线上接收数据的设备被称为接受器。

2、开始和停止条件

当IIC总线接口是不活动,其通常是在从设备模式。

换言之,接口在检测到SDA线上的开始条件之间一直处于从设备模式(开始条件可以被初始化,当SCL时钟信号是高电平是SDA线下跳变)。

当接口状态变为主设备模式,在SDA线上的数据传输被初始化且SCL信号生成。

开始条件可以通过SDA线传输一个字节串行数据,一个停止条件可以终止一个数据传输。

停止条件是当SCL是高电平时,SDA线从低电平到高电平的跳变。

开始和停止条件都是由主设备生成。

当开始条件生成,IIC总线忙。

停止条件将使IIC总线空闲。

当一个主设备初始化开始条件,它应该发送一个从地址来停止从设备。

一个字节的地址域包含7位地址和一位传输方向指示(说明读写)。

如果位8是0,说明是写操作。

如果位8是1说明是数据读请求。

主设备通过发送停止条件来完成一个传输操作。

如果主设备想继续到总线的数据传输,他应该生成另一个开始条件和从地址。

用这个方法,读写操作可以在不同形式下执行。

下图为起始和停止条件。

3、数据传输格式

每个放到SDA线上的字节应该是8位长度。

该字节应该被无限制的传输。

紧接着开始条件的第一个字节应该有一个地址区域。

当IIC在主设备模式下操作,地址区域应该由主设备发送。

每个字节后面应该紧跟一个应答位(ACK)。

串行数据的MSB位和地址总是先发。

4、ACK信号传输

为了完成一个字节的传输操作,接收器应该发送一个ACK位给发送器。

ACK脉冲应该出现在SCL线的第九个时钟。

一个字节数据传输需要8个时钟。

主设备生成传输ACK位所需的时钟脉冲。

发送器应该在接收到ACK时钟脉冲以后通过拉高SDA线释放SDA线。

接收器也应该在ACK时钟脉冲期间拉低SDA线,以至于在第九个SCL脉冲为高电平期间SDA保持低电平。

ACK位发送功能可以通过软件(IICSTAT)使能或使无效。

但是在SCL第九个时钟的ACK脉冲是用于完成一个字节数据传输。

5、读写操作

在发送模式下,如果数据传输后,IIC总线接口会等待直到IIC总线数据移位寄存器(IICDS)收到一个新数据。

在新数据写入寄存器之前,SCL线将保持低电平,然后在数据写入后释放。

S3C2410A应该保持中断来识别当前数据发送是否完成。

在CPU收到中断请求以后,它应该再写一个新数据到IICDS寄存器。

在接收模式下,当数据收到后,IIC总线几口应该等待直到IICDS寄存器被读取。

在一个新数据被读出之前,SCL线应该保持低电平,在数据被读出后再释放。

S3C2410A应该保持中断来识别当前数据接收是否完成。

在CPU收到中断请求以后,它应从IICDS寄存器读取数据。

第三章关键代码分析

3.1设置初值

运行程序中,初值可以由操作者自行设置,由于此处采用的是时——分——秒计时,所以在编写程序的时候注意,部分显示数字的最大值问题,比如说因为秒位最大值只有60,所以对于秒的十位来说,其最大值就应该是6,7、8、9不可取。

同理,对于分钟来说,也是一样的,但是对于时来说,个位和十位同样是需要注意的。

因为时的最大值就是24,所以在设置按键的时候,如果超过相应的最大位。

此时应该全部置0。

这块是容易出现错误的难点,此时应该注意。

其中,设置变量flag,用于多种程序之间的互相访问。

这是非常重要的一点。

关键代码如下:

//如果时的十位大于2,置0

if(s[0]==0xf2||s[0]==0x66||s[0]==0xb6||s[0]=

=0xbe||s[0]==0xe0||s[0]==0xfe||s[0]==0xf6)

{

s[0]=0xfc;

}

//如果分的十位大于6,置0

if(s[2]==0xe0||s[2]==0xfe||s[2]==0xf6)

s[2]=0xfc;

//如果秒的十位大于6,置0

if(s[4]==0xe0||s[4]==0xfe||s[4]==0xf6)

{

s[4]=0xfc;

}

//如果时的个位大于4,置0

if((s[0]==0xda&

&

s[1]==0x66)||(s[0]==0xda&

s[1]==0xb6)||

(s[0]==0xda&

s[1]==0xbe)||(s[0]==0xda&

s[1]==0xe0)||

s[1]==0xfe)||(s[0]==0xda&

s[1]==0xf6))

s[1]=0xfc;

3.2正计时启动

当按下按键‘+’的时候,秒表进行加运算。

//加计时

if(bkey==0xce)

flag=2;

}

if(flag==2)

second++;

if(second>

=60){second=0;

minut++;

if(minut>

=60){minut=0;

hour++;

if(hour>

=24){hour=0;

Show_Time();

LCD_printf("

%2d-%2d-%2d"

hour,minut,second);

3.3倒计时启动

当按下按键‘—’的时候,秒表进行减运算。

//减计时

if(bkey==0x3e)

flag=3;

if(flag==3)

second--;

if(second<

=0){second=59;

minut--;

if(minut<

=0){minut=59;

hour--;

if(hour<

=0){hour=0;

}

3.4暂停计时

本实验中,通过按Enter键控制暂停计时。

关键代码分析如下:

if(tempmcukey==31)

flag=1;

up=0;

count=0;

3.5清除数据,显示初值

本实验中,通过按*键控制清除数据。

for(i=0;

i<

6;

i++)

s1[i]=s[i];

if(bkey==0x6e)

hour=change(s1[0])*10+change(s1[1]);

minut=change(s1[2])*10+change(s1[3]);

second=change(s1[4])*10+change(s1[5]);

3.6LED显示

Show_Time();

voidShow_Time()

sechigh=Seg7Val_Map[second/10];

seclow=Seg7Val_Map[second%10];

minuhigh=Seg7Val_Map[minut/10];

minulow=Seg7Val_Map[minut%10];

hourhigh=Seg7Val_Map[hour/10];

hourlow=Seg7Val_Map[hour%10];

IIC_Write(0x70,0x10,seclow);

IIC_Write(0x70,0x11,sechigh);

IIC_Write(0x70,0x12,0x02);

IIC_Write(0x70,0x13,minulow);

IIC_Write(0x70,0x14,minuhigh);

IIC_Write(0x70,0x15,0x02);

IIC_Write(0x70,0x16,hourlow);

IIC_Write(0x70,0x17,hourhigh);

3.7LCD显示

3.8本章小结

程序在不断的调试过程中已经成功,并且可以成功的编译运行。

第四章系统测试分析

4.1系统整体布局

4.2实验步骤

1、在MetrowerksCodeWarriorforARMDeveloper开发平台上进行编程与调试,并生成可执行文件;

2、通过超级终端将可执行文件烧入实验箱;

3、在实验箱上进行操作,演示时钟的计时与修改时间。

4.3程序代码截图

主程序:

Timer1程序:

键盘程序:

4.4超级终端截图

4.5实验箱截图:

实验箱刚开始界面:

(LED空,LCD正在初始化)

设置初值,进行按键的响应,分别按键六次,其中如果超出相应的最大值,该位全部置0。

本次按键为11-11-11。

按“+”键,加计时启动,由于拍照的原因,LED和LCD显示不同步。

按“—”键,再按Enter键,减计时启动后暂停,此时,LED和LCD显示同步。

按“Enter”键,计时暂停,LED和LCD显示同步。

按“*”键,显示初值,LED和LCD显示同步。

4.6本章小结

经过耐心调试后,程序运行畅通。

第五章结论

通过本次实验,使我熟悉了IIC通信协议的原理以及熟悉了定时器的使用,掌握了一些编程的技巧。

通过对程序的不断修改和调试,我知道了要实现一个功能远不止仅仅搭出框架实现功能,通过对时钟的设计,需要保证多方面的判断条件,其中包含了很多的逻辑关系,所以要写出一个好的程序,必须把逻辑梳理清楚再进行编程。

在以后的编程路上,我会吸取本次实验的经验,更加注重逻辑关系以及编程语言中的一些细节问题,而且要耐心的不断调试程序。

在整个调试的过程中,我遇到了一些问题,在不断的尝试和同学们的帮助下,我都顺利的解决了,现在就我遇到的问题做下汇总:

问题1:

在开始设计按键的时候,对实验箱上的按键对应的十六进制数不清楚,导致不知道对应的参数分别是多少,在自己的耐心查看下,得出对应的值分别是多少。

解决方法:

unsignedcharGetKey()

unsignedcharscankey;

unsignedcharKeyBoard_Map[]={0,0,0x9e,0,0,0xe0,0x66,0x60,0,0,0x8e

14,0,0xfe,0xb6,0xda,0xfc,0x1c,0x6e,0,0

0xf6,0xbe,0xf2,0x3e,0,0,0,0,0xce,0

0x7c,0,1,0,0,17,2,0,0,0

4,0,6,0,5,0,0,0,7,0

9,15,8,0,0,0,0,0,0,0

0,0,0

};

//64,键值映射表while

(1){

if((up==1)&

(count==1)){

scankey=KeyBoard_Map[tempmcukey];

break;

elsecontinue;

returnscankey;

问题2:

本次实验没有两次使用Enter键,在之前的编程过程中,由于本次实验的设计,按键次数比较多,所以为避免冲突按键,设置不同的按键。

1、2、3、4、5、6、7、8、9、+、-、*、\、Enter键都使用。

问题3:

最开始没有想到时分秒,后来在编写的过程中,需要设置超过最大值归0。

//如果时的十位大于2,置0

另外,本次设计还有不足:

界面不是特别漂亮,优化界面还有待提高;

参考文献

ARM2410-SforUCOS实验指导书07.02.28

附录部分程序源代码

//*******************************main函数********************************//

voidsettime(void)//设置时间格式

for(a=0x15;

a>

=0x10;

a--)

key=GetKey();

s[b]=key;

if(s[0]==0xf2||s[0]==0x66||s[0]==0xb6||s[0]==0xbe||

s[0]==0xe0||s[0]==0xfe||s[0]==0xf6){s[0]=0xfc;

if(s[2]==0xe0||s[2]==0xfe||s[2]==0xf6){s[2]=0xfc;

if(s[4]==0xe0||s[4]==0xfe||s[4]==0xf6){s[4]=0xfc;

b=b+1;

if(a==0x15){IIC_Write(0x70,0x17,s[0]);

if(a==0x14)

{if((s[0]==0xda&

s[1]==0x66)||(s[0]==

0xda&

s[1]==0xb6)||(s[0]==0xda&

s[1]==0xbe)

||(s[0]==0xda&

s[1]==0xe0)||(s[0]==0xda&

s[1]

==0xfe)||(s[0]==0xda&

s[1]==0xf6)){s[1]=0xfc;

IIC_Write(0x70,0x16,s[1]);

}

if(a==0x13){IIC_Write(0x70,0x14,s[2]);

if(a==0x12){IIC_Write(0x70,0x13,key);

if(a==0x11){IIC_Write(0x70,0x11,s[4]);

if(a==0x10){IIC_Write(0x70,0x10,key);

IIC_Write(0x70,0x15,0x02);

hour=change(s[0])*10+change(s[1]);

minut=change(s[2])*10+change(s[3]);

second=change(s[4])*10+change(s[5]);

b=0;

i++){s1[i]=s[i];

intmain(void)

{

ARMTargetInit();

Timer1_init();

Key_init();

Led_IIC_init();

LCD_Init();

LCD_Cls();

settime();

while

(1)

if(flag==1)

bkey=GetKey();

if(bkey==0xce){flag=2;

}//加计时

if(bkey==0x3e){flag=3;

}//减计时

}

}

return0;

//*******************************Timer1函数********************************//

intchange(chartime)//找到seg7val-map中与输入时间相同的元素下标

intj;

for(j=0;

j<

=9;

j++)

if(Seg7Val_Map[j]==time)

returnj;

staticvoidTimer1_ISR(intvector,void*data)//时钟开始计时

if(flag==3)

voidTimer1_init(void)

rTCFG0=119;

//prescaler=119,也可取0-255,对应的rTCFG1=0x10;

rTCFG1=0x30;

//clockdivider=16

rTCNTB1=26406;

//pclk=50.7Mhz,rTCNTB1=50700000/(119+1)/16

rTCMPB1=0x0;

rTCON=(1<

<

11)|(1<

9)|(0<

8);

//手动设置相应定时器的手动更新位:

8:

start/stop9:

manualupdate11:

autoreloadon/off

11)|(0<

9)|(1<

INTS_OFF();

SetISR_Interrupt(IRQ_TIMER1,Timer1_ISR,NULL);

INTS_ON();

voidShow_Time()

IIC_Write(0x70,0x

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

当前位置:首页 > PPT模板 > 其它模板

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

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