单片机基础4文档格式.docx

上传人:b****1 文档编号:5200671 上传时间:2023-05-04 格式:DOCX 页数:20 大小:23.08KB
下载 相关 举报
单片机基础4文档格式.docx_第1页
第1页 / 共20页
单片机基础4文档格式.docx_第2页
第2页 / 共20页
单片机基础4文档格式.docx_第3页
第3页 / 共20页
单片机基础4文档格式.docx_第4页
第4页 / 共20页
单片机基础4文档格式.docx_第5页
第5页 / 共20页
单片机基础4文档格式.docx_第6页
第6页 / 共20页
单片机基础4文档格式.docx_第7页
第7页 / 共20页
单片机基础4文档格式.docx_第8页
第8页 / 共20页
单片机基础4文档格式.docx_第9页
第9页 / 共20页
单片机基础4文档格式.docx_第10页
第10页 / 共20页
单片机基础4文档格式.docx_第11页
第11页 / 共20页
单片机基础4文档格式.docx_第12页
第12页 / 共20页
单片机基础4文档格式.docx_第13页
第13页 / 共20页
单片机基础4文档格式.docx_第14页
第14页 / 共20页
单片机基础4文档格式.docx_第15页
第15页 / 共20页
单片机基础4文档格式.docx_第16页
第16页 / 共20页
单片机基础4文档格式.docx_第17页
第17页 / 共20页
单片机基础4文档格式.docx_第18页
第18页 / 共20页
单片机基础4文档格式.docx_第19页
第19页 / 共20页
单片机基础4文档格式.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

单片机基础4文档格式.docx

《单片机基础4文档格式.docx》由会员分享,可在线阅读,更多相关《单片机基础4文档格式.docx(20页珍藏版)》请在冰点文库上搜索。

单片机基础4文档格式.docx

//P3作为输入,初始化输出高

While

(1)

{

if(KEY_0==0)i=0;

if(KEY_1==0)i=1;

if(KEY_2==0)i=2;

if(KEY_3==0)i=3;

if(KEY_4==0)i=4;

if(KEY_5==0)i=5;

if(KEY_6==0)i=6;

if(KEY_7==0)i=7;

if(KEY_8==0)i=8;

if(KEY_9==0)i=9;

if(KEY_A==0)i=0xA;

if(KEY_B==0)i=0xB;

if(KEY_C==0)i=0xC;

if(KEY_D==0)i=0xD;

if(KEY_E==0)i=0xE;

if(KEY_F==0)i=0xF;

SLED=Seg7Code[i];

//开始时显示0,根据i取应七段编码

}

第二节:

双数码管可调秒表

解:

只要满足题目要求,方法越简单越好。

由于单片机I/O资源足够,所以双数码管可接成静态显示方式,两个共阴数码管分别接在P1(秒十位)和P2(秒个位)口,它们的共阴极都接地,安排两个按键接在P3.2(十位数调整)和P3.3(个位数调整)上,为了方便计时,选用12MHz的晶体。

为了达到精确计时,选用定时器方式2,每计数250重载一次,即250us,定义一整数变量计数重载次数,这样计数4000次即为一秒。

定义两个字节变量S10和S1分别计算秒十位和秒个位。

编得如下程序:

unsignedintus250=0;

unsignedchars10=0;

unsignedchars1=0;

unsignedcharkey10=0;

//记忆按键状态,为1按下

unsignedcharkey1=0;

//记忆按键状态,为1按下

//初始化定时器Timer0

TMOD=(TMOD&

0xF0)|0x02;

TH1=-250;

//对于8位二进数来说,-250=6,也就是加250次1时为256,即为0

TR1=1;

while

(1){//----------循环1

P1=Seg7Code[s10];

//显示秒十位

P2=Seg7Code[s1];

//显示秒个位

while

(1){//----------循环2

//计时处理

if(TF0==1){

TF0=0;

if(++us250>

=4000){

us250=0;

if(++s1>

=10){

s1=0;

if(++s10>

=6)s10=0;

}

break;

//结束“循环2”,修改显示

}

}

//按十位键处理

P3.2=1;

//P3.2作为输入,先要输出高电平

if(key10==1){//等松键

if(P3.2==1)key10=0;

else{//未按键

if(P3.2==0){

key10=1;

if(++s10>

//按个位键处理

P3.3=1;

//P3.3作为输入,先要输出高电平

if(key1==1)//等松键

{if(P3.3==1)key1=0;

}

else{//未按键

if(P3.3==0){key1=1;

if(++s1>

=10)s1=0;

}//循环2’end

}//循环1’end

}//main’end

用P1端口的6个引脚控制交通灯,高电平灯亮,低电平灯灭。

//sbit用来定义一个符号位地址,方便编程,提高可读性,和可移植性

sbitSNRed=P1^0;

//南北方向红灯

sbitSNYellow=P1^1;

//南北方向黄灯

sbitSNGreen=P1^2;

//南北方向绿灯

sbitEWRed=P1^3;

//东西方向红灯

sbitEWYellow=P1^4;

//东西方向黄灯

sbitEWGreen=P1^5;

//东西方向绿灯

/*用软件产生延时一个单位时间*/

voidDelay1Unit(void)

unsignedinti,j;

for(i=0;

i<

1000;

i++)

for(j<

0;

j<

j++);

//通过实测,调整j循环次数,产生1ms延时

//还可以通过生成汇编程序来计算指令周期数,结合晶体频率来调整j循环次数,接近1ms

/*延时n个单位时间*/

voidDelay(unsignedintn){for(;

n!

=0;

n--)Delay1Unit();

while

(1)

{

SNRed=0;

SNYellow=0;

SNGreen=1;

EWRed=1;

EWYellow=0;

EWGreen=0;

Delay(60);

SNYellow=1;

SNGreen=0;

Delay(10);

SNRed=1;

EWRed=0;

EWGreen=1;

EWYellow=1;

显示“12345678”

P1端口接8联共阴数码管SLED8的段极:

P1.7接段h,…,P1.0接段a

P2端口接8联共阴数码管SLED8的段极:

P2.7接左边的共阴极,…,P2.0接右边的共阴极

方案说明:

晶振频率fosc=12MHz,数码管采用动态刷新方式显示,在1ms定时断服务程序中实现

at89x92.h>

unsignedcharDisBuf[8];

//全局显示缓冲区,DisBuf[0]对应右SLED,DisBuf[7]对应左SLED,

voidDisplayBrush(void)

{codeunsignedcharcathode[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

//阴极控制码

{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

staticunsignedchari=0;

//(0≤i≤7)循环刷新显示,由于是静态变量,此赋值只做一次

//显示消隐,以免下一段码值显示在前一支SLED

P1=Seg7Code[DisBuf[i]];

//从显示缓冲区取出原始数据,查表变为七段码后送出显示

P2=cathode[i];

//将对应阴极置低,显示

if(++i>

=8)i=0;

//指向下一个数码管和相应数据

voidTimer0IntRoute(void)interrupt1

TL0=-1000;

//由于TL0只有8bits,所以将(-1000)低8位赋给TL0

TH0=(-1000)>

>

8;

//取(-1000)的高8位赋给TH0,重新定时1ms

DisplayBrush();

voidTimer0Init(void)

{TMOD=(TMOD&

0xf0)|0x01;

//初始化,定时器T0,工作方式1

TL0=-1000;

//定时1ms

TR0=1;

//允许T0开始计数

ET0=1;

//允许T0计数溢出时产生中断请求

voidDisplay(unsignedcharindex,unsignedchardataValue){DisBuf[index]=dataValue;

unsignedchari;

for(i=0;

i++){Display(i,8-i);

区qhkode[DisBuf[i]];

//;

f7,0xfd,0xfb,0xfe};

}//DisBuf[0]为右,DisBuf[7]为左

Timer0Init();

EA=1;

//允许CPU响应中断请求

While

(1);

指提供一些函数给任务调用,获取按键信息,或读取按键值。

定义一个头文档<

KEY.H>

,描述可用函数,如下:

#ifndef_KEY_H_//防止重复引用该文档,如果没有定义过符号_KEY_H_,则编译下面语句

#define_KEY_H_//只要引用过一次,即#include<

key.h>

,则定义符号_KEY_H_

unsignedcharkeyHit(void);

//如果按键,则返回非0,否则返回0

unsignedcharkeyGet(void);

//读取按键值,如果没有按键则等待到按键为止

voidkeyPut(unsignedcharucKeyVal);

//保存按键值ucKeyVal到按键缓冲队列末

voidkeyBack(unsignedcharucKeyVal);

//退回键值ucKeyVal到按键缓冲队列首

#endif

定义函数体文档KEY.C,如下:

#include“key.h”

#defineKeyBufSize16//定义按键缓冲队列字节数

unsignedcharKeyBuf[KeyBufSize];

//定义一个无符号字符数组作为按键缓冲队列。

该队列为先进

//先出,循环存取,下标从0到KeyBufSize-1

unsignedcharKeyBufWp=0;

//作为数组下标变量,记录存入位置

unsignedcharKeyBufRp=0;

//作为数组下标变量,记录读出位置

//如果存入位置与读出位置相同,则表明队列中无按键数据

unsignedcharkeyHit(void)

{if(KeyBufWp==KeyBufRp)return(0);

elsereturn

(1);

unsignedcharkeyGet(void)

{unsignedcharretVal;

//暂存读出键值

while(keyHit()==0);

//等待按键,因为函数keyHit()的返回值为0表示无按键

retVal=KeyBuf[KeyBufRp];

//从数组中读出键值

if(++KeyBufRp>

=KeyBufSize)KeyBufRp=0;

//读位置加1,超出队列则循环回初始位置

return(retVal);

voidkeyPut(unsignedcharucKeyVal)

{KeyBuf[KeyBufWp]=ucKeyVal;

//键值存入数组

if(++KeyBufWp>

=KeyBufSize)KeyBufWp=0;

//存入位置加1,超出队列则循环回初始位置

/*****************************************************************************************

由于某种原因,读出的按键,没有用,但其它任务要用该按键,但传送又不方便。

此时可以退回按键队列。

就如取错了信件,有必要退回一样

******************************************************************************************/

voidkeyBack(unsignedcharucKeyVal)

/*

如果KeyBufRp=0;

减1后则为FFH,大于KeyBufSize,即从数组头退回到数组尾。

或者由于干扰使得KeyBufRp超出队列位置,也要调整回到正常位置,

*/

if(--KeyBufRp>

=KeyBufSize)KeyBufRp=KeyBufSize-1;

KeyBuf[KeyBufRp]=ucKeyVal;

//回存键值

下面渐进讲解键盘物理层的驱动。

电路共同点:

P2端口接一共阴数码管,共阴极接GND,P2.0接a段、P2.1接b段、…、P2.7接h段。

软件共同点:

codeunsignedcharSeg7Code[10]是七段数码管共阴编码表。

CodeunsignedcharSeg7Code[16]=

例一:

P1.0接一按键到GND,键编号为‘6’,显示按键。

#include“KEY.H”

{P1_0=1;

//作为输入引脚,必须先输出高电平

while

(1)//永远为真,即死循环

{if(P1_0==0)//如果按键,则为低电平

{keyPut(6);

//保存按键编号值为按键队列

while(P1_0==0);

//如果一直按着键,则不停地执行该循环,实际是等待松键

}

if(keyHit()!

=0)//如果队列中有按键

P2=Seg7Code[keyGet()];

//从队列中取出按键值,并显示在数码管上

例二:

在例一中考虑按键20ms抖动问题。

{delay20ms();

//延时20ms,跳过接下抖动

keyPut(6);

while(P1_0==0);

delay20ms();

//延时20ms,跳过松开抖动

例三:

在例二中考虑干扰问题。

即小于20ms的负脉冲干扰。

if(P1_0==1)continue;

//假按键

例四:

状态图编程法。

通过20ms周期中断,扫描按键。

/****************************************************************************************

采用晶体为12KHz时,指令周期为1ms(即主频为1KHz),这样T0工作在定时器方式2,8位自动重载。

计数值为20,即可产生20ms的周期性中断,在中断服务程序中实现按键扫描

*****************************************************************************************/

{

TMOD=(TMOD&

0xf0)|0x02;

//不改变T1的工作方式,T0为定时器方式2

TH0=-20;

//计数周期为20个主频脉,即20ms

TL0=TH0;

//先软加载一次计数值

TR0=1;

//允许T0开始计数

ET0=1;

//允许T0计数溢出时产生中断请求

EA=1;

//允许CPU响应中断请求

voidtimer0int(void)interrupt1//20ms;

T0的中断号为1

{staticunsignedcharsts=0;

P1_0=1;

switch(sts)

case0:

if(P1_0==0)sts=1;

break;

//按键则转入状态1

case1:

if(P1_0==1)sts=0;

//假按错,或干扰,回状态0

else{sts=2;

keyPut(6);

}//确实按键,键值入队列,并转状态2

break;

case2:

if(P1_0==1)sts=3;

//如果松键,则转状态3

case3:

if(P1_0==0)sts=2;

//假松键,回状态2

elsests=0;

//真松键,回状态0,等待下一次按键过程

}

例五:

如果采用晶体为12MHz时,指令周期为1us(即主频为1MHz),要产生20ms左右的计时,则计数值达到20000,T0工作必须为定时器方式1,16位非自动重载,即可产生20ms的周期性中断,在中断服务程序中实现按键扫描

voidmain(voi

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

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2