while(1) {
for(i=0;i<60;i++) {
t=(((i/10)<<4)|(i));// 将i转换为BCD码 P1=~t; delay1s(); } } }
(3)可控霓虹灯设计。系统包括8个发光二极管,连接在P3.2引脚的一个按键,通过按键改变霓虹灯的显示方式。要求正常情况下8个霓虹灯依次顺序点亮,循环显示,时间间隔为1 s。按键按下后8个霓虹灯同时亮灭一次,时间间隔为0.5 s。(按键动作采用外部中断0实现)。 答:
参考程序如下:
//功能:可控信号灯程序
#include
//函数功能:用T0的方式1编制0.5秒延时程序,假定系统采用12MHz晶振,定 // 时器1、工作方式1定时50ms,再循环10次即可定时到0.5秒 //形式参数:无 //返回值:无 void delay0_5s() {
unsigned char i; for(i=0;i<0x0a;i++) { TH0=0x3c; TL0=0xb0;
TR0=1; TF0=0; } }
//函数名:delay_t
//函数功能:实现0.5秒~128秒延时 //形式参数:unsigned char t; // 延时时间为0.5秒×t //返回值:无
void delay_t(unsigned char t) {
unsigned char i;
for(i=0;i // 启动T0 while(!TF0); // 查询计数是否溢出,即定时50ms时间到,TF0=0 // 50ms定时时间到,将定时器溢出标志位TF0清零 // 设置定时器初值 // 设置10次循环次数 // 计数值取反后送P1口显示 // 调用1秒延时函数 //函数名:int_0 //函数功能:外部中断0中断函数,当CPU响应外部中断0的中断请求时,自动执行该 // 函数,实现八个信号灯闪烁 //形式参数:无 //返回值:无 void int_0() interrupt 0 //外部中断0的中断号为0 { P1=0x00; P1=0xff; delay0_5s(); } void main() { unsigned char i,w; EA=1; EX0=1; IT0=1; while(1){ w=0x01; // 显示码初值为01H for(i=0;i<8;i++){ P1=~w; // w取反后送P1口,点亮相应LED灯 w<<=1; // 点亮灯的位置移动 delay_t(2); // 调用延时函数delay_t(),实际参数为2,延时1秒 } } } // 打开中断总允许位 // 打开外部中断0允许位 // 设置外部中断为边沿(下降沿)触发方式 //主函数 //熄灭八个信号灯 //调用0.5秒延时函数 //点亮八个信号灯 delay0_5s(); //调用0.5秒延时函数 TMOD=0x01; // 设置T0为工作方式1 习 题 6 6.1 单项选择题 (1)A (2)B (3)D (4)C (5)B (6)C (7)B (8)C (9)C (10)A (11)C (12)D (13)A 6.2 问答题 (1)什么是串行异步通信?有哪几种帧格式? 答: 在异步通信中,数据通常是以字符为单位组成字符帧传送的。字符帧由发送端一帧一帧地发送,每一帧数据是低位在前,高位在后,通过传输线由接收端一帧一帧地接收。发送端和接收端分别使用各自独立的时钟来控制数据的发送和接收,这两个时钟彼此独立,互不同步。 在串行通信中,两相邻字符帧之间可以没有空闲位,也可以有若干空闲位,这由用户来决定。 (2)定时器T1做串行口波特率发生器时,为什么采用工作方式2? 答: 实际上,当定时器T1做波特率发生器使用时,通常是工作在定时器的模式2下,即作为一个自动重装载的8位定时器,TL1做计数用,自动重装载的值在TH1内。 7.3 编程题 (1)利用串行口设计4位静态LED显示,画出电路图并编写程序,要求4位LED每隔1 s交替显示“1234”和“5678”。 参考电路在教材第207页图6.16的基础之上再添加两片74LS164和两个数码管即可。 参考程序如下: #include \包含头文件reg51.h,定义51单片机的专用寄存器 unsigned char da[]={0xF9,0xA4,0xB0,0x99}; //定义1~4的共阳极字型显示码 unsigned char da1[]={0x92,0x82,0x0F8,0x80}; //定义5~8的共阳极字型 void delay1s() { unsigned char i; for(i=0;i<0x20;i++) { TH0=0x3c; TL0=0xb0; TR0=1; TF0=0; } } main() { unsigned char i; P1=0xff; SCON=0x00; while(1){ for (i=0;i<4;i++) { SBUF=da[i]; TI=0; while(!TI); } //送显示数据5678 //等待发送完毕 //等待发送完毕 //送显示数据1234 //P1.0置1,允许串行移位 //设串行口方式0 // 设置T0为工作方式1 // 启动T0 while(!TF0); // 查询计数是否溢出,即定时50ms时间到,TF0=0 // 50ms定时时间到,将定时器溢出标志位TF0清零 // 设置定时器初值 // 设置20次循环次数 TMOD=0x01; delay1s(); for (i=0;i<4;i++) { SBUF=da1[i]; TI=0; while(!TI); } } } (2)编程实现甲乙两个单片机进行点对点通信,甲机每隔1 s发送一次“A”字符,乙机接收到以后,在LCD上能够显示出来。 参考电路图略。 参考程序如下: 甲机发送程序: //功能:甲机发送数据程序,采用查询方式实现 #include unsigned char i; TMOD=0x20; //定时器T1工作于方式2 TL1=0xf4; //波特率为2400bps TH1=0xf4; TR1=1; //主函数 while(1) { } 乙机接收程序略。 (3)编写一个实用的串行通信测试软件,其功能为:将PC机键盘的输入数据发送给单片机,单片机收到PC机发来的数据后,回送同一数据给PC机,并在屏幕上显示出来。只要屏幕上显示的字符与所键入的字符相同,说明二者之间的通信正常。 通信协议: 第1字节,最高位(MSB)为1,为第1字节标志;第2字节,MSB为0,为非第1字节标志,依次类推,最后1字节为前几字节后7位的异或校验和。 单片机串行口工作在方式1,晶振为11.0592 MHz,波特率为4800 bps。 通信程序略。 SCON=0x40; //定义串行口工作于方式1 while(TI==0); // 查询等待发送是否完成 TI=0; } // 发送完成,TI由软件清0 SBUF=0x41; // 发送A delay1s(); //1秒延时函数参见7.3(1)题 习 题 7 7.1 单项选择题 (1)D (2)A (3)C (4)D (5)A 7.2 填空题 (1)模拟,数字,数字,模拟 (2)分辨率、建立时间 7.3 问答题 (1)判断A/D转换是否结束,一般可采用几种方式?每种方式有何特点? 答: 查询方式,CPU通过查询转换结束标志位确认转换结束后,再执行后面的操作,占用CPU时间; 中断方式,转换结束后向CPU申请中断,CPU在中断服务函数中读取转换值,不占用CPU时间; 延时方式,如果知道A/D转换时间,可以在转换开始后直接延时超过该时间的时间,占用CPU时间。 7.4 应用题 (1)设计一个锯齿波发生器系统。 提示:程序ex7_3.c中修改数组sin据即可。 (2)EEPROM芯片AT24C02采用的也是I2C总线接口,请设计51单片机扩展EEPROM的软硬件系统。 提示:请查阅AT24C02资料,参考电路(AT24C01) //功能:EEPROM读写程序,从AT24C01的4个连续存储单元中读出4个字节的数据,然后将4 // 个新的数值写入AT24C01的对应4个存储单元中,再重新读出。 //_nop_()函数所在的头文件 //器件地址选择及写数据地址0xa0 //器件地址选择及读数据地址0xa1 #include #include /******************************位定义及预定义*******************************/ //串行数据输入/输出位定义 //串行时钟位定义 //应答标志 //延时函数声明 //开始函数 //停止函数 /******************************函数声明************************************/ void mDelay(unsigned char ms); void Start(void); void Stop(void);