单片机原理流水灯实验报告

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机原理流水灯实验报告相关的知识,希望对你有一定的参考价值。

参考技术A

单片机原理流水灯实验报告: 一、实验目的:进一步熟习keil仿真软件、proteus仿真软件的使用。认识并熟习单片机I/O口和LED灯的电路构造,学会建立简单的流水灯电路。掌握C51中单片机I/O口的编程方法和使用I/O口进行输入输出的注意事项。

二、实验原理:MCS-51系列单片机有四组8位并行I/O口,记作P0、P1、P2和P3。每组I/O口内部都有8位数据输入缓冲器、8位数据输出锁存器及数据输出驱动等电路。四组并行I/O端口即能够按字节操作,又能够按位操作。当系统没有扩展外面器件时,I/O端口用作双向输入输出口;当系统作外面扩展时,使用P0、P2口作系统地点和数据总线、P3口有第二功能,与MCS-51的内部功能器件配合使用。

《蓝桥杯CT107D单片机竞赛板》:定时器模块

定时器模块

实验简介

定时器配置实现LED亮灭,流水灯效果,蜂鸣器是否发声,继电器是否吸附,数码管示值,数字秒表。

实验原理图

实验原理

声明:实验原理部分来自普中51单片机攻略和《“蓝桥杯”全国软件和信息技术专业人才大赛(电子类)实训指导书》

  • 定时器介绍:定时计数器可以用于精确事件定时。IAP15F2K61S2 单片机内部集成了 3 个 16 位的定时/计数器 T0、 T1 和 T2,其核心部件是一个加法计数器( TH 和 TL),对输入脉冲进行计数。若计数脉冲来自系统时钟,则为定时器方式;若计数脉冲来自 T0( P34)、 T1( P35)或 T2( P31)引脚,则为计数器方式。

  • 知识补充:学习定时器需要了解CPU 时序的有关知识。 振荡周期: 为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期) 。机器周期:即CPU周期,完成一个基本操作所需要的时间。机器周期=1/单片机的内部时钟频率。内部时钟频率外部时钟的 12 分频,也就是说当外部晶振的频率输入到单片机里面的时候要进行 12分频。1 个机器周期含12 个振荡周期。指令周期:完成 1 条指令所占用的全部时间,它以机器周期为单位。外接晶振为 12MHz 时,振荡周期=1/12us;机器周期=1us;指令周期=1~4us;可知工作在定时模式时最高单次定时时间约为65535*1us=65ms < 100ms,也就是说单次定时无法达到0.1s,这点在后面的综合模块中会用到

  • 特殊功能寄存器介绍:TMOD是定时/计数器的工作方式寄存器, 确定工作方式和功能; TCON控制寄存器, 控制 T0、 T1 的启动和停止及设置溢出标志。

  1. 工作方式寄存器 TMOD。

    工作方式寄存器 TMOD 用于设置定时/计数器的工作方式,低四位用于 T0高四位用于 T1GATE 是门控位,GATE = ,软件使 TR0 或 TR1 为 1,能启动定时/计数器工作。GATE = 1,软件使 TR0 或 TR1 为 1,再使外部中断引脚 INT0/1 也为高电平时, 才能启动定时/计数器工作。C/T :定时/计数模式选择位。 C/T =0 为定时模式;C/T =1 为计数模式。M1M0:定时/计数器 T0 和 T1 具有四种工作方式,由特殊功能寄存器 TMOD 中的 M1 和 M0 位决定,具体工作方式设置,下图示。


其中我们特别解释一下,方式 1 的计数位数是 16 位, 由 TL0 作为低 8 位, TH0 作为高 8 位, 组成了16 位加 1 计数器。 门控位 GATE = 0,经过非门反相,再经过或门输出为1,此时仅由 TR0 控制与门的开启, 与门输出 1 时, 控制开关接通, 计数开始;而门控位 GATE = 1,我们类比可以分析出,此时与门的开启由外中断引脚信号和 TR0 共同控制,由此解释了上述工作方式寄存器 TMOD中门控位GATE的相关赋值方式。方式1其结构图如下所示:

  1. 控制寄存器 TCON


TCON 的低 4 位用于控制外部中断,可以去《蓝桥杯CT107D单片机竞赛板》:中断模块查看。TCON 的高 4 位用于控制定时/计数器的启动和中断申请。TF1:T1 溢出中断请求标志位。 T1 计数溢出时由硬件自动置 TF1为 1。CPU 响应中断后 TF1 由硬件自动清 0。 T1 工作时, CPU 可随时查询 TF1 的状态。 所以, TF1 可用作查询测试的标志。这点我们会在后面的综合应用中使用到,TF1 也可以用软件置 1 或清 0, 同硬件置 1 或清 0 的效果一样。TR1:T1 运行控制位。TR1 = 1,定时器1工作,TR1 = 0,定时器停止工作。TR1 由软件置 1 或清 0。TF0,和TR0用法类似于定时器1。

  • 定时器配置:①TMOD设置定时器模式,确定 T0 和 T1 的工作方式。②根据所要定时的时间计算初值,并将其写入THx,TLx中,例如外部晶振12MHZ,定时1ms,每次获取输入脉冲,即经历了一个机器周期1us时间,1ms/1us=1000。计数 1000 个,对于方式1为16位的定时/计数器,由于计数器到65535 再加 1 才会溢出,故初值=65535-1000+1=64536=FC18H,所以初值即为 THx=0XFC,TLx=0X18。③使用中断,则对 EA 赋值,开放定时器中断④启动定时器的运行控制位TRx

实验程序

定时器0控制LED隔 1 秒闪烁

//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器

//typedef unsigned char uchar;
#define uchar unsigned char
#define uint unsigned int

#endif
//main.c--通过定时器 0中断控制 D1 指示灯间隔 1 秒闪烁。 
#include "config.h"

uchar uled = 0;

void close_peripheral()

	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;
	
	P2 = (P2 & 0x1f) | 0xa0;
	P0 = 0xaf;
	P2 &= 0x1f;


void Timer0Init()		//1000微秒@12.000MHz

	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;			//打开定时器 0 中断允许
	EA=1;			//打开总中断



void main()		

	close_peripheral();
	Timer0Init();
	while(1);


							 	
void timer0() interrupt 1

	static uint i;//静态变量存储器内部会自动赋初值为0
	TL0 = 0x18;		//设置定时初值,定时1ms
	TH0 = 0xFC;
	i++;
	if (1000 == i)
	
		i = 0;
		uled ^= 1;
		P2 = (P2 & 0x1f) | 0x80;
		P0 = ~uled;
		P2 &= 0x1f;
	


定时器0控制蜂鸣器和继电器

main.c代码主要改变部分

void timer0() interrupt 1

	static uint i;//静态变量存储器内部会自动赋初值为0
	TL0 = 0x18;		//设置定时初值,定时1ms
	TH0 = 0xFC;
	i++;
	if (1000 == i)
	
		i = 0;
		uled ^= 0x50;
		P2 = (P2 & 0x1f) | 0xa0;
		P0 = ~uled;
		P2 &= 0x1f;
	



定时器1实现流水灯效果

//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器
#include<intrins.h>
//typedef unsigned char uchar;
#define uchar unsigned char
#define uint unsigned int


#endif
//main.c--通过定时器 1中断控制 LED 模块实现每隔0.5s移位 
#include "config.h"

uchar time = 0;

void Timer1Init(void)		//50毫秒@12.000MHz

	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x10;		//设置定时器模式
	TL1 = 0xB0;		//设置定时初值
	TH1 = 0x3C;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	ET1 = 1;//打开定时器1的中断允许
	EA = 1;//打开总中断


void main()

	uchar data1 = 0xfe;
	Timer1Init();
	while(1)
	
		P2 = (P2 & 0x1f) | 0x80;
		P0 = data1;
		P2 &= 0x1f;
		if (time >= 10)
		
			time = 0;
			data1 = (data1 << 1) | 0x01;
			if(0xff == data1) 
				data1 = 0xfe;
		
	


void timer1() interrupt 3

	time++;
	TL1 = 0xB0;		//设置定时初值
	TH1 = 0x3C;		//设置定时初值	

定时器0每2ms对S7进行扫描,按下则n值加1,数码管显示

//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器
#include<intrins.h>
//typedef unsigned char uchar;
#define uchar unsigned char
#define uint unsigned int
void Delay20ms();		//@12.000MHz


#endif
//main.c--2ms对S7进行扫描,按下n值加1,数码管显示

#include "config.h"

sbit S7 = P3^0;
uchar dspcom = 0;
uchar dspbuf[8];
uchar n = 0;
//共阴数码管段选表
uchar tab[] =                        //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46;    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

void close_peripheral()

	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;
	
	P2 = (P2 & 0x1f) | 0xa0;
	P0 = 0xaf;
	
	P2 &= 0x1f;



void Timer0Init(void)		//2毫秒@12.000MHz

	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x30;		//设置定时初值
	TH0 = 0xF8;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;//打开定时器0中断允许
	EA = 1;//打开总中断


void display()

	//消隐
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = 0xff;
	
	//位选
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 1 << dspcom;
	
	//段选
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = ~tab[dspbuf[dspcom]];
	
	P2 &= 0x1f;
	if (++dspcom == 8)
	
		dspcom = 0;
	


void main()

	close_peripheral();
	Timer0Init();

	while(1)
	
		if (0 == S7)
		
			Delay20ms();//消抖
			if (0 == S7)
			
				n++;
				dspbuf[0] = n / 10;
				dspbuf[1] = n % 10;
				if (n >= 100)
					n = 0;
			
			while(!S7);
		
	
	



void timer0() interrupt 1

	//重新赋初值
	TL0 = 0x30;		//设置定时初值,2毫秒
	TH0 = 0xF8;		
	display();//每隔2ms扫描一次


void Delay20ms()		//@12.000MHz

	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 234;
	k = 113;
	do
	
		do
		
			while (--k);
		 while (--j);
	 while (--i);



定时器1实现数字秒表–使用定时器1查询

注意:该实验与下一个实验区别可以观察Timer1Init()函数,以及TF1的使用

//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器
#include<intrins.h>
//typedef unsigned char uchar;
#define uchar unsigned char
#define uint unsigned int
void Delay20ms();		//@12.000MHz


#endif
//main.c--定时器1实现数字秒表
#include "config.h"

uchar dspcom = 0;
uchar dspbuf[8];
uint cnt;
uchar sec, min;//秒,分
//共阴数码管段选表
uchar tab[] =                        //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46;    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

void close_peripheral()

	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;
	
	P2 = (P2 & 0x1f) | 0xa0;
	P0 = 0xaf;
	
	P2 &= 0x1f;



void Timer1Init(void)		//2毫秒@12.000MHz

	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x10;		//设置定时器模式
	TL1 = 0x30;		//设置定时初值
	TH1 = 0xF8;		//设置定时初值
	TR1 = 1;		//定时器1开始计时


void data_proc()

	dspbuf[0] = 16;//tab[16] = 数码管灭
	dspbuf[1] = 16;
	dspbuf[2] = 16;
	dspbuf[3] = 16;
  	dspbuf[4] = min / 10;
	dspbuf[5] = min % 10;
	dspbuf[6] = sec / 10;
	dspbuf[7] = sec % 10;



void display()

	//消隐
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = 0xff;
	
	//位选
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 1 << dspcom;
	
	//段选
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = ~tab[dspbuf[dspcom]];
	
	P2 &= 0x1f;
	if (++dspcom == 8)
	
		dspcom = 0;
	


void main()

	close_peripheral();
	Timer1Init();
	
	while(1)
	
		if (TF1)//定时器T1溢出标志
		
			data_proc();
			display();//每隔2ms扫描一次
			cnt++;
			TF1 = 0;
			//重新赋初值,每隔2ms
			TL1 = 0x30;		//设置定时初值
			TH1 = 0xF8;		//设置定时初值
			if (cnt >= 500)
			
			 cnt = 0;
			 sec++;
			 if (sec >= 60)
			 
				sec = 0;
				min++;
				if (min >=60)
					min = 0;
			 
			

		
	
	




定时器1实现数字秒表

//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器
#include<intrins.h>
//typedef unsigned char uchar;
#define uchar unsigned char
#define uint unsigned int

#endif
以上是关于单片机原理流水灯实验报告的主要内容,如果未能解决你的问题,请参考以下文章

《蓝桥杯CT107D单片机竞赛板》:LED模块

数据库原理实验(openGauss)实验报告

ROS/51单片机/机器人控制器实验报告册

ROS/51单片机/机器人控制器实验报告册

hbuilder网页设计实验报告原理

实验报告怎么写?