单片机实验报告-史昊卿杨 - 图文

更新时间:2024-02-02 03:05:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

单片机实验报告

学院:交通运输工程学院 班级: 交 设1403 姓名: 史昊卿杨 学号: 109140331

指导老师: 傅勤毅

2017年5月20日

目录

第一章 单片机简介 .................................................... 2 第二章 实验要求 .......................................................... 4 第三章 实验设备 .......................................................... 4 第四章 实验安排 .......................................................... 5 第五章 实验内容 .......................................................... 5

实验一:LED流水灯实验 ................................... 5 实验二 步进电机 .................................................. 9 实验三 独立按键 ................................................ 12 实验四 矩阵键盘 ................................................ 17 实验五 静态数码管显示 .................................... 25 实验六 动态数码管显示 .................................... 28 实验七NE555脉冲发生器 ................................. 32 实验八 RS232串口实验 .................................... 37

六、心得体会 .............................................................. 39

1

第一章 单片机简介

单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。从上世纪80年代,由当时的4位、8位单片机,发展到现在的300M的高速单片机。

单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。相当于一个微型的计算机,和计算机相比,单片机只缺少了I/O设备。概括的讲:一块芯片就成了一台计算机。它的体积小、质量轻、价格便宜、为学习、应用和开发提供了便利条件。同时,学习使用单片机是了解计算机原理与结构的最佳选择。

单片机的使用领域已十分广泛,如智能仪表、实时工控、通讯设备、导航系统、家用电器等。各种产品一旦用上了单片机,就能起到使产品升级换代的功效,常在产品名称前冠以形容词——“智能型”,如智能型洗衣机等。

单片机(Microcontrollers)诞生于1971年,经历了SCM、MCU、SoC三大阶段,早期的SCM单片机都是8位或4位的。其中最成功的是INTEL的8051,此后在8051上发展出了MCS51系列MCU系统。基于这一系统的单片机系统直到

2

现在还在广泛使用。随着工业控制领域要求的提高,开始出现了16位单片机,但因为性价比不理想并未得到很广泛的应用。90年代后随着消费电子产品大发展,单片机技术得到了巨大提高。随着INTEL i960系列特别是后来的ARM系列的广泛应用,32位单片机迅速取代16位单片机的高端地位,并且进入主流市场。

而传统的8位单片机的性能也得到了飞速提高,处理能力比起80年代提高了数百倍。高端的32位Soc单片机主频已经超过300MHz,性能直追90年代中期的专用处理器,而普通的型号出厂价格跌落至1美元,最高端的型号也只有10美元。

当代单片机系统已经不再只在裸机环境下开发和使用,大量专用的嵌入式操作系统被广泛应用在全系列的单片机上。而在作为掌上电脑和手机核心处理的高端单片机甚至可以直接使用专用的Windows和Linux操作系统。

3

第二章 实验要求

1.学习Keil C51集成开发工具的操作及调试程序的方法,包括:仿真调试与

脱机运行间的切换方法

2.熟悉TD-51单片机系统板及实验系统的结构及使用 3.进行MCS51单片机指令系统软件编程设计与硬件接口功能设

4. 学习并掌握Keil C51软件联机进行单片机接口电路的设计与编程调试 5.完成指定MCS51单片机综合设计题

第三章 实验设备

1. HC600S-51单片机开发板 2. Keil C51 3. 普中自动下载软件

4

第四章 实验安排

1.LED灯实验 2.步进马达试验

3.独立按键控制LED实验 4.矩阵键盘实验 5.静态数码管实验 6.动态数码管实验

7.NE555脉冲发生器实验(定时/计数器) 8.RS232串口通信实验(接收与发送)

第五章 实验内容

实验一:LED流水灯实验

一、实验目的:

1.掌握Keil软件的使用方法。 2.掌握普中下载软件的使用方法。 3.加深理解单片机I/O引脚以及内存结构。 4.重新熟悉C语言编程法则。

二、实验要求

编写一段程序,使8个发光二极管D1、D2、D3、D4、D5、D6、D7、D8顺序(正序)点亮:先点亮D1,再点亮D2、D3??D8、D1??,循环点亮。每点亮一个LED,采用软件延时一段时间。

5

三、实验内容

1、实验程序设计

如图1-1为发光二极管的内部连接图,本次设计使用P1口进行连接。

发光二极管内部连接图

用KEIL软件设计程序如下:

#include #include #define unit unsigned int #define uchar unsigned char uchar temp;

sbit beep=P2^3;//定义蜂鸣

void delay(unit z);//参数类型一定要写,参数名可以不写 void main() {

beep=0; temp=0xfe;

6

}

while(1) //死循环 { }

P1=temp;

temp=_crol_(temp,1);//循环左移一位 delay(200); P1=temp;

void delay(unit z) { }

编译程序后生成.hex文件。 2、实验连线

如图,将P1口与锁存器74C53相连。再利用普中科技软件将编译好.hex文件下载到单片机中。可观察到流水灯连续闪烁的现象。

unit x,y; //局部变量 for(x=200;x>0;x--) {

for(y=200;y>0;y--){};

};//延时程序

7

流水灯实验

8

实验二 步进电机

一、实验目的

1.熟悉步进机的工作原理。

2.通过编写指令控制步进机工作,进一步熟悉单片机I/O引脚功能。 3.熟悉实验板及相关软件操作。

二、实验要求

P1口作为输出口控制步进电动机的四相绕组,编写程序,控制步进电动机每1s正向转动一步。晶振频率12MHz。

解:步距角:θb=360/mZ (°) 电机转速:n =60f/mZ (r/min) 上式中:f 为脉冲频率,单位:Hz或步/s。

m 为拍数,本例中m=4。 Z 为转子齿数,本例中Z=5。 则步距角θb=18°。题目要求步进电动机每1s正向转动一步,即T=1s, f =1 Hz,电机转速n =3r/min。

三、实验内容

1、步进电机工作原理

步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。 2、程序设计

根据步进电机的工作原理,设计步进电动机的控制状态与P1口的控制码的对应关系如下表2-1所示。

表2-1

控制状态 P1口 控制码 P1.7 P1.6 P1.5 P1.4 P1.3 D相 0 P1.2 C相 0 P1.1 B相 1 P1.0 A相 1 A相、B相03H 0 0 0 9

0

绕组通电 B相、C相绕组通电 C相、D相绕组通电 D相、A相绕组通电 3、程序:

#include #define uint unsigned int void Delayms (uint x); main ( ) {

while(1) //死循环

{ P1=0x03; Delayms(1000); //A相、B相绕组通电 P1=0x06; Delayms(1000); //B相、C相绕组通电 P1=0x0c; Delayms(1000); //C相、D相绕组通电 P1=0x09; Delayms(1000); //D相、A相绕组通电 } }

void Delayms (uint x) //延时函数 { uint n; for( ;x > 0; x--) { for(n=0;n<123;n++) { ; } } }

10

06H 0 0 0 0 0 1 1 0 0CH 0 0 0 0 1 1 0 0 09H 0 0 0 0 1 0 0 1 4、实验连线

将程序下载到单片机中,可以看到步进电机转动。实现现象如图2-1所示:

步进电机实验

11

实验三 独立按键

一、实验目的

1.熟悉C51包含的头文件。 2.掌握独立按键的工作原理。 3.学习按键去抖动问题。

二、实验要求

通过开发板上的8个独立按键控制8个LED灯,实现按下按键对应的LED灯亮,其他灯灭的效果。

三、实验内容

3.1独立式按键问题

1、独立式按键:其特点是每个按键单独占用一根I/O口线。每个按键工作不会 影响其他I/O口线的状态,多用于所需按键不多的场合。

2、按键去抖问题:

按键的抖动时间约为5~10ms,抖动会引起CPU对一次键操作进行多次处理,从而错误的键响应。

软件去抖动:检测到按键按下/释放后,延时10ms后再确认该键是否确实按下/释放,消除抖动影响。 3、实验程序设计

12

#include //此文件中定义了51的一些特殊功能寄存器 #include //--定义要使用的IO口--//

#define GPIO_KEY P1 //独立键盘用P1口 #define GPIO_LED P0 //led使用P0口 //--声明全局函数--//

void Delay10ms(unsigned int c); //延时10ms unsigned char Key_Scan(); void main(void) {

unsigned char ledValue, keyNum; ledValue = 0x01; while (1) {

keyNum = Key_Scan(); //扫描键盘 switch (keyNum) {

case(0xFE) : //返回按键K1的数据

ledValue = 0x01; break;

case(0xFD) : //返回按键K2的数据

ledValue = 0x02; break;

case(0xFB) : //返回按键K3的数据

ledValue = 0x04; break;

case(0xF7) : //返回按键K4的数据

ledValue = 0x08;

13

}

}

}

break;

case(0xEF) : //返回按键K5的数据

ledValue = 0x10; break;

case(0xDF) : //返回按键K6的数据

ledValue = 0x20; break;

case(0xBF) : //返回按键K7的数据

ledValue = 0x40; break;

case(0x7F) : //返回按键K8的数据

ledValue = 0x80; break;

default:

break;

GPIO_LED = ledValue;//点亮LED灯

unsigned char Key_Scan() {

unsigned char keyValue = 0 , i; //保存键值 //--检测按键1--// if (GPIO_KEY != 0xFF) {

Delay10ms(1); //消除抖动

if (GPIO_KEY != 0xFF) //再次检测按键是否按下 {

14

//检测按键K1是否按下

}

}

}

keyValue = GPIO_KEY; i = 0;

while ((i<50) && (GPIO_KEY != 0xFF)) //检测按键是否松开 { }

Delay10ms(1); i++;

return keyValue; //将读取到键值的值返回

void Delay10ms(unsigned int c) //误差 0us {

unsigned char a, b;

//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值

了--//

for (;c>0;c--) }

3.3实验现连线

将程序下载到单片机中,可以看到不同按键下相应的led灯点亮。实现现象如图所示:

{

for (b=38;b>0;b--) { }

for (a=130;a>0;a--);

}

15

独立按键实验

16

实验四 矩阵键盘

一、实验目的

1.充分理解4x4矩阵键盘内部接线图,并根据其结构进行程序设计。 2.试比较独立按键与矩阵键盘的区别。 3.进一步掌握单片机程序设计办法。

二、实验要求

按下矩阵键盘按键,1602显示其键值。

三、实验内容

1、矩阵键盘

矩阵键盘是进行逐行扫描的。每一个按键的两端,都分别接在某一个列线和行线上,即:“行线和列线是通过某个按键的按下和抬起实现联通和断开的”,和“导线两端上的信号是经过“与”的关系再体现到导线上的。”

17

图4-1 矩阵键盘

2、程序设计

根据表4-1 K0~K15键码表以及独立按键的程序用KEIL软件设计如下程序:

表4-1 K0~K15键码表

K0:0xee K1:0xde K2:0xbe K3:0x7e 1110 1110 1101 1110 1011 1110 0111 1110 K4:0xed K5:0xdd K6:0xbd K7:0x7d 1110 1101 1101 1101 1011 1101 0111 1101 K8:0xeb K9:0xdb K10:0xbb K11:0x7b 1110 1011 1101 1011 1011 1011 0111 1011 K12:0xe7 K13:0xd7 K14:0xb7 K15:0x77 1110 0111 #include

18

1101 0111 1011 0111 #include\

0111 0111 //--定义使用的IO口--// #define GPIO_KEY P1 //--定义全局变量--//

unsigned char PuZh[17]=\is:\

unsigned char KeyValue; //用来存放读取到的键值

void KeyScan(void); //--声明全局函数--//

void Delay10ms(unsigned int c); //误差 0us void main(void) {

unsigned char i; LcdInit(); for(i=0; i<17; i++) {

LcdWriteCom(0x80 + 0x44); if(KeyValue < 10) {

LcdWriteData('0'

+

KeyValue);

} else {

LcdWriteData('7'

+

KeyValue); //A的ASCII码的前10位是7,所以用7做基数 }

void KeyScan(void) {

char a = 0; GPIO_KEY=0x0f;

if(GPIO_KEY!=0x0f)//读取按键是 }

}

if(i == 14) {

LcdWriteCom(0x80

+

0x40);

否按下

}

LcdWriteData(PuZh[i]);

{

Delay10ms(1);//延时10ms进

}

行消抖

if(GPIO_KEY!=0x0f)//再次检

while(1) {

KeyScan();

19

测键盘是否按下

{

//测试列

GPIO_KEY=0X0F; switch(GPIO_KEY) {

case(0X07):

检测 }

void Delay10ms(unsigned int c) //误差 0us {

unsigned char a, b;

//--c已经在传递过来的时候已经 }

}

{ }

Delay10ms(1); a++;

KeyValue=0;break;

case(0X0b):

KeyValue=4;break;

case(0X0d):

KeyValue=8;break;

case(0X0e):

KeyValue=12;break;

} //测试行

GPIO_KEY=0XF0; switch(GPIO_KEY) {

case(0X70):

赋值了,所以在for语句第一句就不用赋值了--// for (;c>0;c--) }

附1:lcd.c(包含main函数中lcdinit

&&

函数) #include\

20

{

for (b=38;b>0;b--) {

for (a=130;a>0;a--);

KeyValue=KeyValue+3;break;

case(0Xb0):

KeyValue=KeyValue+2;break;

case(0Xd0):

}

KeyValue=KeyValue+1;break;

case(0Xe0):

}

KeyValue=KeyValue;break;

}

while((a<50)

(GPIO_KEY!=0xf0)) //检测按键松手

void Lcd1602_Delay1ms(uint c) //误差 0us {

uchar a,b; }

#ifndef LCD1602_4PINS

//当没有

for (; c>0; c--) { }

for (b=199;b>0;b--) {

for(a=1;a>0;a--); }

LCD1602_E = 1; //写入

时序

Lcd1602_Delay1ms(5); //保持

时间 } #else

void LcdWriteCom(uchar com) 写入命令 {

LCD1602_E = 0; //使能清零 LCD1602_RS = 0; //选择写入

//

LCD1602_E = 0;

命令

LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = com;

定义这个LCD1602_4PINS时 void LcdWriteCom(uchar com) 写入命令 {

LCD1602_E = 0; //使能 LCD1602_RS = 0; //选择发

//

//由于4位的接线是接到P0口的高四位,所以传送高四位不用改

LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; Lcd1602_Delay1ms(1);

LCD1602_DATAPINS = com << 4; Lcd1602_Delay1ms(1);

送命令 入

LCD1602_DATAPINS

=

LCD1602_RW = 0; //选择写

com;

//放入命令

Lcd1602_Delay1ms(1);

//等

//发送低四位

21

Lcd1602_Delay1ms(1);

待数据稳定

LCD1602_E = 1; //写入时序

}

Lcd1602_Delay1ms(5); LCD1602_E = 0;

数据

//

LCD1602_DATAPINS = dat; //因4LCD1602_RW = 0; //选择写入

#endif

#ifndef LCD1602_4PINS

位的接线是接到P0口的高四位,传送高四位不用改

Lcd1602_Delay1ms(1);

void LcdWriteData(uchar dat) 写入数据 { 据

LCD1602_E = 0; //使能清零

LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0;

LCD1602_RS = 1; //选择输入数

LCD1602_RW = 0; //选择写入

LCD1602_DATAPINS = dat << 4;

LCD1602_DATAPINS = dat; //写入//写入低四位

LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; Lcd1602_Delay1ms(1);

数据 间 } #else

void LcdWriteData(uchar dat) 写入数据 {

Lcd1602_Delay1ms(1);

LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); //保持时

}

LCD1602_E = 0; #endif #ifndef

LCD1602_4PINS

void LcdInit()

//

//LCD初始化子程序 {

LcdWriteCom(0x38); //开显示 LcdWriteCom(0x0c); //开显示不

LCD1602_E = 0; //使能清零 LCD1602_RS = 1; //选择写入

22

显示光标

LcdWriteCom(0x06); //写一个指/**当使用的是4位数据传输的时候定义,使用8位取消这个定义**/ #define LCD1602_4PINS /**包含头文件**/ #include //---重定义关键词---// #ifndef uchar

针加1

LcdWriteCom(0x01); //清屏 LcdWriteCom(0x80); //设置数据

指针起点 } #else void LcdInit()

#define uchar unsigned char #endif

//LCD初始化子程序 {

LcdWriteCom(0x32); //将8位总线

#ifndef uint

#define uint unsigned int #endif

#define LCD1602_DATAPINS P0 sbit LCD1602_E=P2^7; sbit LCD1602_RW=P2^5; sbit LCD1602_RS=P2^6;

void Lcd1602_Delay1ms(uint c); //误差 0us

/*LCD1602写入8位命令子函数*/ void LcdWriteCom(uchar com); /*LCD1602写入8位数据子函数*/ void LcdWriteData(uchar dat) ; /*LCD1602初始化子程序*/ void LcdInit(); #endif

转为4位总线

LcdWriteCom(0x28); //在四位线

下的初始化

LcdWriteCom(0x0c); //开显示不

显示光标

LcdWriteCom(0x06); //写一个指

针加1

LcdWriteCom(0x01); //清屏 LcdWriteCom(0x80); //设置数据

指针起点 } #endif

附2:lcd.h(上述两个程序引用的头文件)

#ifndef __LCD_H_ #define __LCD_H_

23

3、 实验连线

将程序下载到单片机中,连接液晶显示器,可以看到按下不同键,1602显示出不同的键值,实验完成。

矩阵键盘实验

实验五 静态数码管显示

一、实验目的

1.充分理解数码管显示原理。

2.能够利用延迟循环函数使数码管值连续变化。

二、实验要求

下载程序后,静态数码管流动显示数字0~9

三、实验内容

1、静态显示接口

一个并行I/O口接一个数码管。特点:编程较简单,但占用I/O口线多,一般用于显示位数较少的场合。

图5-1静态数码管显示结构

2、实验程序设计

通过KEIL软件进行程序设计如下:

显示段与段码位对应表

段码位 D7 D6 D5 D4 D3 D2 D1 D0 25

显示段 h g f

e d c b a #include #define GPIO_DIG P0

void Delay10ms(unsigned int c); //误差 0us

unsigned char code DIG_CODE[16]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71}; void main(void) { }

void Delay10ms(unsigned int c) //误差 0us {

unsigned char a, b;

for (;c>0;c--) {

for (b=38;b>0;b--)

26

unsigned char i = 0; while(1) { }

GPIO_DIG = ~DIG_CODE[i]; i++; if(i == 16) { }

Delay10ms(50);

i = 0;

}

{

for (a=130;a>0;a--);

}

}

3.3实验现象

将程序下载到单片机中,可以看到静态数码管从0~F连续循环变化,实验正确。

静态数码管

27

实验六 动态数码管显示

一、实验目的

1.充分理解多位数码管应用于某一系统时的“位选”与“段选”。 2.通过程序加深对数码管的动态扫描显示的理解。

二、实验要求

设计编写程序出现以下现象:第一个数码管显示0,间隔一段时间关闭它,立即让第二个数码管显示1……一直到最后一个数码管显示8,再间隔一段时间后关闭它,立即让第一个数码管显示,一直这样循环下去。

三、实验内容

1、动态显示方式

1) 所有数码管的a~h段同名端连在一起,每一个数码管的公共极COM各自独

立地受I/O线控制。

2) 任一时刻只有一位显示,依次循环扫描,轮流显示。由于人眼的视觉滞留效

应,看起来与静态的效果基本一样。

3) 特点:占用I/O端口线少,电路较简单,但扫描过程不能停, 占用CPU的时

间长,适合显示位数较多的场合。 2、实验程序设计

显示原理:设待显的6个数放在内部RAM的mDS[0:5]中。从左至右一位一位地显示。P1.x=0 :x段亮。P2.y=1: y位选通。通过P22、P23、P24控制3-8译码器来对数码管进行位选,通过P0口经过573的驱动控制数码管的段选,通过P13控制573的使能端,为低电平时573才会有输出。 3、程序: #include #define GPIO_DIG P0 sbit LSA=P2^2; sbit LSB=P2^3;

28

sbit LSC=P2^4;

unsigned char code DIG_CODE[17]={

//--定义全局变量--//

0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码 unsigned char DisplayData[8]; void DigDisplay(); //动态显示函数 void main(void) { }

void DigDisplay() {

unsigned char i; for(i=0;i<8;i++) { } while(1) { }

DigDisplay();

DisplayData[i]=DIG_CODE[i];

unsigned char i; unsigned int j; for(i=0;i<8;i++) {

switch(i) {

case(0):

LSA=0;LSB=0;LSC=0; break;//显示第0位

29

//位选,选择点亮的数码管,

}

}

}

case(1):

LSA=1;LSB=0;LSC=0; break;//显示第1位

case(2):

LSA=0;LSB=1;LSC=0; break;//显示第2位

case(3):

LSA=1;LSB=1;LSC=0; break;//显示第3位

case(4):

LSA=0;LSB=0;LSC=1; break;//显示第4位

case(5):

LSA=1;LSB=0;LSC=1; break;//显示第5位

case(6):

LSA=0;LSB=1;LSC=1; break;//显示第6位

case(7):

LSA=1;LSB=1;LSC=1; break;//显示第7位

GPIO_DIG=DisplayData[i];//发送段码 j=10;

//扫描间隔时间设定

while(j--);

GPIO_DIG=0x00;//消隐

4、实验连线

将程序下载到单片机中,可以看到各数码管按照顺序从0~F依次显示,实验完成。

30

动态数码管实验

31

实验七NE555脉冲发生器

一、实验目的

1.学习了解ne555用作定时器构成的时基电路。

2.通过学习ne555内部结构以及单片机定时/计数器功能编写相关程序。 4.再次熟悉使用1602液晶显示器。

二、实验要求

编写相关程序,使得在1602显示脉冲频率,调节电位器可改变频率。

三、实验内容

1、 ne555定时器

ne555的内部结构可等效成23个晶体三极管.17个电阻。两个二极管组成了比较器、RS触发器。等多组单元电路。特别是由三只精度较高5k电阻构成了一个电阻分压器。为上、下比较器提供基准电压.所以称之为555。 ne555属于cmos工艺制造。

由555定时器和外接元件R1、R2、C构成多谐振荡器,脚2与脚6直接相连。电路没有稳态,仅存在两个暂稳态,电路亦不需要外接触发信号,利用电源通过R1、R2向C充电,以及C通过R2向放电端Dc放电,使电路产生振荡。电容C在2/3Vcc和1/3Vcc之间充电和放电,从而在输出端得到一系列的矩形波,对应的波形如图7-1所示。

图7-1 ne555定时器的电路结构与震荡波形图

32

2、程序设计

1) NE555:out →P3.5 —— T1的输入端 作为计数器输入

定时器T1做计数器,工作方式1(16位定时器),由TR1打开计数器

2) 每1秒内,输入脉冲的个数 —— 由T0提供时间基准

定时器T0做定时器,工作方式1(16位定时器),由TR0打开定时器 ——TMOD=0x51;

3) //--设置定时器T0的初值:例如晶振为12MHZ时定时50ms,需要20倍频

输出--//

TH0=0x3C; TL0=0xB0;

4) //开放中断、定时器T0、计数器T1 5) 中断函数void Timer0() interrupt 1 {}

——提供倍频、1秒时间到的信息。如果1秒时间到,则提供主函数的计算/显示频率的标识:例如用TR0=0信号//停止定时器

6) 中断函数void Timer1() interrupt 3 {}

——计数到65536,未到计算频率的时机,脉冲数+65536

7) 主函数扫描标识TR0:计算/显示频率。 3、程序代码 #include #include\

#define uchar unsigned char #define uint unsigned int #define ulong

unsigned long

HZ\

//--声明全局函数--//

void TIMER_Configuration(); //初始化定时器

//--定义全局变量--//

ulong Freq; //用来存放要显示

//--定义LCD显示的文字--// uchar

code

EN_CHAR1[16]={\ 的频率值

ulong TimeCount; //用于计算1S钟的

CYMOMETER \

uchar code EN_CHAR2[16]={\ void main()

33

{

//--显示要写的字母--// for(i=0;i<16;i++) { }

LcdWriteData(EN_CHAR1[i]);

uchar i, freqValue[6]; LcdInit();

TIMER_Configuration();

freqValue[0]='0'+Freq00000/10

0000;

freqValue[1]='0'+Freq0000/100

00;

freqValue[2]='0'+Freq000/1000;

freqValue[3]='0'+Freq00/100;

freqValue[4]='0'+Freq0/10;

//--显示求得的数值--// for(i=0;i<5;i++)//从最高位

freqValue[5]='0'+Freq;

LcdWriteCom(0xc0);//第二行显示 for(i=0;i<16;i++) { } while(1) {

if(TR0==0) //当计数LcdWriteData(EN_CHAR2[i]);

开始查找不为0的数开始显示(最低位为0显示0)

{

if(freqValue[i]==0x30) {

freqValue[i]=0x20;

器停下的时候,表明计数完毕

{

Freq = Freq + TL1;

34

//读取TL的值

Freq = Freq + (TH1 * 256);

//若为0则赋值空格键

} else {

break;

//读取TH的值

LcdWriteCom(0xc8); //--求频率的个十百千万

十万位--//

}

}

//--设置定时器晶振为12MHZ时

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

定时50ms--//

//--打开定时器*/ TR0=1; TR1=1; TH0=0x3C; TL0=0xB0; //--打开中断-// ET0=1; ET1=1; EA=1;

LcdWriteData(freqValue[i]);

}

//--显示完,重新计算下一

次频率。--// 零 零 }

void TIMER_Configuration() {

//--定时器T1做计数器,工作方式 }

}

TL1=0;

TR0=1; //开启定时器 TR1=1; //开启计数器

TH1=0; //将计数器的值清

Freq=0;//将计算的频率清

}

void Timer0() { --//

35

interrupt 1

TimeCount++;

if(TimeCount==20)//计时到1S { }

TR0=0; TR1=0; TimeCount=0;

1(16位定时器),只由TRx打开计数器--//

//--定时器T0做定时器,工作方式

//--12MHZ设置定时50ms的初值

1(16位定时器),只由TRx打开定时器--//

TH0=0x3C; TL0=0xB0;

TMOD=0x51;

}

void Timer1() {

//--进入一次中断,表明计数到了

interrupt 3

65536--// }

Freq=Freq+65536;

4、实验连线

下载程序到单片机,调节电位器可改变频率,实验正确。

NE555脉冲发生器实验

36

实验八 RS232串口实验

一、实验目的

1.通过实验了解串口的基本原理及使用,理解并掌握对串口进行初始化; 2.熟悉全双工串口通信方式。 3.理解串口助手的使用方法。

二、实验要求

通过串口助手发送数据到单片机,同时单片机将接收到的数据发送到串口助手。使用串口调试助手(Baud 9600、数据位8、停止位1、效验位无)做为上位机来做收发试验;利用串口调试助手中字符串输入进行数据发送,接受窗口显示收到的数据。

三、实验内容

1、 RS232C的特性

RS-232C接口总线的传送距离一般不超过15m。

RS-232C使用负逻辑:其逻辑“0”在+3~+15V之间,逻辑“1”在-3~-15V之间。因此,RS-232C不能和TTL电平直接相连,必须加适当的接口(转换)电路,否则将使TTL电路烧毁。 2、 程序设计

37

实验板内部结构图

根据接线图,用keil编写程序如下: #include void UsartConfiguration(); void main() { }

void UsartConfiguration() {

UsartConfiguration(); while(1) { }

SCON=0X50;

//设置为工作方式1 //设置计数器工作方式2 //波特率加倍

TMOD=0X20; PCON=0X80; TH1=0XF3; TL1=0XF3; ES=1; EA=1;

//计数器初始值设置,注意波特率是4800的

//打开接收中断 //打开总中断

38

}

TR1=1; //打开计数器

void Usart() interrupt 4 { }

receiveData=SBUF; //出去接收到的数据 RI = 0; //清除接收中断标志位

SBUF=receiveData; //将接收到的数据放入到发送寄存器 while(!TI); TI=0;

//等待发送数据完成 //清除发送完成标志位

unsigned char receiveData;

六、心得体会

单片机实验把我们在课堂上掌握的理论知识运用到了实际中来,锻炼我们的实践能力。通过这次单片机设计,我不仅加深了对单片机理论的理解,同时也使我认识到自身存在的不足之处。无论是理论上还是遇到问题的处理能力上都还有待提高而且这也激发了我今后努力学习的兴趣。

细节决定成败,这句话在这次课题中不仅一次得到了印证,特别是在软件的编程过程中,一点点的错误就会使你整个程序不能运行。因此我们不仅仅要有整体意识,也要注意细节,不要因一个关键地方的一个细节而导致满盘皆输。

在学习初期看别人的代码,学习别人的思路这个很有用。通过看别人的代码特别是有多年编程经验的人的程序,可以迅速提高自己的编程水平。也可以结合着别人的手法,与自己的想法结合在一起写出更好的程序。

在单片机的学习开始时感觉很吃力,在不断的学习过程中慢慢的对单片机产生了些好感,而且在编写程序过程中吃力的感觉慢慢的淡了。在这其中基础知识

39

掌握牢固是非常重要的,然后在学习过程中要学会提问题和自己解决问题,慢慢的对于学习单片机你也会产兴趣。虽然在开始学习单片机时感觉很晦涩难懂,但只要坚定自己的学习信心,在付出持之以恒的努力,我相信自己能进一步加深对单片机的了解,在单片机的学习道路上走得更远。

总之,亲自动手是课堂学习的延续,电子领域随时随地都在发生着翻天覆地的变化,现有的知识储备总是落后于科技的发展脚步,我们只有不断学习新知识,才能做到面对新课题时游刃有余。

通过这次单片机实习,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。创新可以是在原有的基础上进行改进,使之功能不断完善,成为真己的东西。

最后,谢谢李老师和傅老师老师的指导。

40

掌握牢固是非常重要的,然后在学习过程中要学会提问题和自己解决问题,慢慢的对于学习单片机你也会产兴趣。虽然在开始学习单片机时感觉很晦涩难懂,但只要坚定自己的学习信心,在付出持之以恒的努力,我相信自己能进一步加深对单片机的了解,在单片机的学习道路上走得更远。

总之,亲自动手是课堂学习的延续,电子领域随时随地都在发生着翻天覆地的变化,现有的知识储备总是落后于科技的发展脚步,我们只有不断学习新知识,才能做到面对新课题时游刃有余。

通过这次单片机实习,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。创新可以是在原有的基础上进行改进,使之功能不断完善,成为真己的东西。

最后,谢谢李老师和傅老师老师的指导。

40

本文来源:https://www.bwwdw.com/article/b7fw.html

Top