for(j=0;j<110;j++);
}
voidaa()interrupt0
{
unsignedchartmp=0xfe;
unsignedinti=0;
P1=tmp;
delay(100);
i=7;
while(i--)
{
tmp=_crol_(tmp,1);
P1=tmp;
delay(100);
}
//delay(500);
i=7;
while(i--)
{
tmp=_cror_(tmp,1);
P1=tmp;
delay(100);
}
//delay(500);
}
voidbb()interrupt2
{
P1=0xf0;
delay(500);
P1=0x0f;
delay(500);
}
四、实验思考题:
根据指导书中提供的原理图,自行设计一个外部中断实验,要求:
1.两个外部中断全部用上;
2.实验能体现不同中断优先级的中断源的相应情况;
3.不同中断处理程序能输出不同的响应效果
第二部分:
定时器中断实验
一、实验目的:
通过使用定时器T0的中断来控制P2.0引脚的的LED的灯闪烁,要求闪烁时间2S,既亮1S,灭1S。
二、实验原理图
实验参考电路图如下(注释,下图只有D1等闪烁,既亮1S,灭1S):
三、参考实验程序
//用定时器T0的中断实现长时间定时,单片机晶体振荡器周期为12MHZ,机器//周期为1us
#include//包含51单片机寄存器定义的头文件
sbitD1=P2^0;//将D1位定义为P2.0引脚
unsignedcharCountor;//设置全局变量,储存定时器T0中断次数
/**************************************************************
函数功能:
主函数
**************************************************************/
voidmain(void)
{
EA=1;//开总中断
ET0=1;//定时器T0中断允许
TMOD=0x01;//使用定时器T0的模式2
TH0=(65536-15536)/256;//定时器T0的高8位赋初值
TL0=(65536-15536)%256;//定时器T0的高8位赋初值
TR0=1;//启动定时器T0
Countor=0;//从0开始累计中断次数
while
(1)//无限循环等待中断
;
}
/**************************************************************
函数功能:
定时器T0的中断服务程序
**************************************************************/
voidTime0(void)interrupt1using0//“interrupt”声明函数为中断服务函数
//其后的1为定时器T0的中断编号;0表示使用第0组工作寄存器
{
Countor++;//中断次数自加1
if(Countor==20)//若累计满20次,即计时满1s
{
D1=~D1;//按位取反操作,将P2.0引脚输出电平取反
Countor=0;//将Countor清0,重新从0开始计数
}
TH0=(65536-15536)/256;//定时器T0的高8位重新赋初值
TL0=(65536-15536)%256;//定时器T0的高8位重新赋初值
}
}
四、实验思考题:
修改程序使用定时器T1的中断方式来控制P2.0、P2.1引脚的LED灯分别以200mshe800ms的周期闪烁
调试后的程序代码:
实验三:
串行口实验
一、实验目的:
本实验要求单片机U1通过其串行口TXD向计算机发送一个数据“oxab”。
利用集成电路MAX232将单片机的输出信号转化成计算机能够识别的信号。
针对发送的实例,再设计一个单片机接受计算机送出数据的过程
二、实验原理图
单片机发送数据实验参考电路图如图
(1):
图
(1)
单片机接受数据实验参考电路图如下:
图
(2)
三、参考实验程序
//单片机向PC发送数据
#include//包含单片机寄存器的头文件
unsignedcharcodeTab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
//流水灯控制码,该数组被定义为全局变量
/*****************************************************
函数功能:
向PC发送一个字节数据
***************************************************/
voidSend(unsignedchardat)
{
SBUF=dat;
while(TI==0)
;
TI=0;
}
/**************************************************************
函数功能:
延时约150ms
**************************************************************/
voiddelay(void)
{
unsignedcharm,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/*****************************************************
函数功能:
主函数
***************************************************/
voidmain(void)
{
unsignedchari;
TMOD=0x20;//TMOD=00100000B,定时器T1工作于方式2
SCON=0x40;//SCON=01000000B,串口工作方式1
PCON=0x00;//PCON=00000000B,波特率9600
TH1=0xfd;//根据规定给定时器T1赋初值
TL1=0xfd;//根据规定给定时器T1赋初值
TR1=1;//启动定时器T1
while
(1)
{
for(i=0;i<8;i++)//模拟检测数据
{
Send(Tab[i]);//发送数据i
delay();//150ms发送一次数据
}
}
}
四、实验思考题:
根据参考原理图图
(2)设计一个单片机接受计算机送出数据的过程。
调试后的程序代码:
实验四:
矩阵式键盘输入识别
一、实验目的:
设计一个4X4的矩阵键盘,键盘的号码0~15,要求编写出一个键盘输入扫描程序,要求单片机能根据键盘排列顺序,能将按下去键盘号正确识别出来,并采用两个数码管分别键盘号码的个位和十位。
二、实验原理图
实验参考电路图如下:
三、参考实验程序
#include//包含51单片机寄存器定义的头文件
sbitP14=P1^4;
sbitP15=P1^5;
sbitP16=P1^6;
sbitP17=P1^7;
unsignedcharcodeTab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数字0~9的段码
unsignedcharkeyval;
/**************************************************************
函数功能:
数码管动态扫描延时
**************************************************************/
voidled_delay(void)
{
unsignedcharj;
for(j=0;j<200;j++)
;
}
/**************************************************************
函数功能:
按键值的数码管显示子程序
**************************************************************/
voiddisplay(unsignedchark)
{
P2=0xbf;
P0=Tab[k/10];
led_delay();
P2=0x7f;
P0=Tab[k%10];
led_delay();
}
/**************************************************************
函数功能:
软件延时子程序
**************************************************************/
voiddelay20ms(void)
{
unsignedchari,j;
for(i=0;i<100;i++)
for(j=0;j<60;j++)
;
}
/**************************************************************
函数功能:
主函数
**************************************************************/
voidmain(void)
{
EA=1;
ET0=1;
TMOD=0x01;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
TR0=1;
keyval=0x00;
while
(1)
{
display(keyval);
}
}
/**************************************************************
函数功能:
定时器0的中断服务子程序,进行键盘扫描,判断键位
**************************************************************/
voidtime0_interserve(void)interrupt1using1
{
TR0=0;
P1=0xf0;
if((P1&0xf0)!
=0xf0)
delay20ms();
if((P1&0xf0)!
=0xf0)
{
P1=0xfe;
if(P14==0)
keyval=1;
if(P15==0)
keyval=2;
if(P16==0)
keyval=3;
if(P17==0)
keyval=4;
P1=0xfd;
if(P14==0)
keyval=5;
if(P15==0)
keyval=6;
if(P16==0)
keyval=7;
if(P17==0)
keyval=8;
P1=0xfb;
if(P14==0)
keyval=9;
if(P15==0)
keyval=10;
if(P16==0)
keyval=11;
if(P17==0)
keyval=12;
P1=0xf7;
if(P14==0)
keyval=13;
if(P15==0)
keyval=14;
if(P16==0)
keyval=15;
if(P17==0)
keyval=16;
}
TR0=1;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
}
四、实验思考题:
修改实验电路图和实验程序和设计电路,改成静态显示
调试后的程序代码:
实验五:
LCD循环显示设计
一、实验目的:
采用1602型LCD循环显示字符串“WelcometoHeifeiNormalUniversity”。
其中LCD显示模式为:
16*2显示、5*7点阵、8位数据口;
显示开、有光标开且光标闪烁;
光标右移,字符不移。
二、实验原理图
实验参考电路图如下:
三、参考实验程序
//用LCD循环右移显示"WelcometoHeifeiNormalUniversity"
#include//包含单片机寄存器的头文件
#include//包含_nop_()函数定义的头文件
sbitRS=P2^0;//寄存器选择位,将RS位定义为P2.0引脚
sbitRW=P2^1;//读写选择位,将RW位定义为P2.1引脚
sbitE=P2^2;//使能信号位,将E位定义为P2.2引脚
sbitBF=P0^7;//忙碌标志位,,将BF位定义为P0.7引脚
unsignedcharcodestring[]={"WelcometoHeifeiNormalUniversity"};
/*****************************************************
函数功能:
延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
voiddelay1ms()
{
unsignedchari,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
/*****************************************************
函数功能:
延时若干毫秒
入口参数:
n
***************************************************/
voiddelay(unsignedcharn)
{
unsignedchari;
for(i=0;idelay1ms();
}
/*****************************************************
函数功能:
判断液晶模块的忙碌状态
返回值:
result。
result=1,忙碌;result=0,不忙
***************************************************/
unsignedcharBusyTest(void)
{
bitresult;
RS=0;//根据规定,RS为低电平,RW为高电平时,可以读状态
RW=1;
E=1;//E=1,才允许读写
_nop_();//空操作
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
result=BF;//将忙碌标志电平赋给result
E=0;
returnresult;
}
/*****************************************************
函数功能:
将模式设置指令或显示地址写入液晶模块
入口参数:
dictate
***************************************************/
voidWriteInstruction(unsignedchardictate)
{
while(BusyTest()==1);//如果忙就等待
RS=0;//根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲,
//就是让E从0到1发生正跳变,所以应先置"0"
_nop_();
_nop_();//空操作两个机器周期,给硬件反应时间
P0=dictate;//将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=1;//E置高电平
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:
指定字符显示的实际地址
入口参数:
x
***************************************************/
voidWriteAddress(unsignedcharx)
{
WriteInstruction(x|0x80);//显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:
将数据(字符的标准ASCII码)写入液晶模块
入口参数:
y(为字符常量)
***************************************************/
voidWriteData(unsignedchary)
{
while(BusyTest()==1);
RS=1;//RS为高电平,RW为低电平时,可以写入数据
RW=0;
E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲,
//就是让E从0到1发生正跳变,所以应先置"0"
P0=y;//将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=1;//E置高电平
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:
对LCD的显示模式进行初始化设置
****************