STC89C52R控制抢答器+数码管+后台显示+LCD1602x显示
- STC89C52R控制抢答器+数码管+后台显示+LCD1602x显示
- [1 概述](#1 概述)
-
- [1.1 项目概述](#1.1 项目概述)
- [1.2 项目组成部分](#1.2 项目组成部分)
- [1.3 功能描述](#1.3 功能描述)
- [2 开发环境](#2 开发环境)
-
- [2.1 支持设备](#2.1 支持设备)
- [2.2 硬件电路](#2.2 硬件电路)
- [3 软件代码工程](#3 软件代码工程)
- [4 演示Proteus仿真](#4 演示Proteus仿真)
- [5 总结](#5 总结)
STC89C52R控制抢答器+数码管+后台显示+LCD1602x显示
1 概述
1.1 项目概述
该项目旨在利用STC89C52R单片机构建一个多功能抢答器显示系统,涵盖LCD1602x显示屏、数码管和后台数码显示器。通过串口通信,单片机能够与后台数码显示器进行数据交换和控制,实现更加灵活和多样化的显示功能。
1.2 项目组成部分
(1)STC89C52R单片机:
(2)LCD1602显示:
(3)数码管:
(4)后台数码显示器(通过串口通信):
(5)按键:
(6)Proteus:
1.3 功能描述
(1)LCD1602:
LCD1602显示屏用于展示文字信息,能够显示实时数据如日期、时间、温度等。
(2)数码管:
数码管用于呈现数字信息,例如计数器数值、计时器时间等。
后台数码显示器(通过串口通信):
借助串口通信,单片机与后台数码显示器相连,实现双向数据传输和控制,扩展显示功能。
(3)按键:
通过4个按键实现抢答器按钮功能。
(4)Proteus:
使用实物演示和Proteus仿真方式展示系统功能。
2 开发环境
2.1 支持设备
我们采用华晴51开发板、Keil开发工具和PROTEUS仿真软件。结合这三者,开发人员得以进行完整的嵌入式系统开发流程。他们可以利用Keil开发工具编写、编译和调试8051单片机程序,接着通过PROTEUS仿真软件验证程序正确性和系统功能。一旦验证通过,程序可下载至华晴51开发板进行实际硬件调试和测试,完成嵌入式系统的开发。这些工具的综合运用使得开发人员能够全面开发和验证嵌入式系统,提升开发效率、降低成本,并确保系统的稳定性和可靠性。
(1)华晴51开发板:
华晴51开发板是一款基于8051系列单片机的专用开发板,主要用于嵌入式系统的学习、开发和测试。该开发板拥有多样的外设接口,包括LED、按键、数码管、LCD显示屏、通信接口等,使用户能够轻松进行各种实验和项目开发。此外,华晴51开发板支持多种编程方式,如汇编语言、C语言等,适用于各类用户,无论是初学者还是专业开发人员。
(2)Keil开发工具:
Keil开发工具是一套专业的嵌入式系统开发工具,主要针对ARM和8051等处理器的嵌入式软件开发。其中,Keil C51是专为8051系列单片机设计的C语言集成开发环境,提供编译、调试、仿真等功能,使开发人员能够高效进行嵌入式软件开发。该工具配备了强大的调试功能,可帮助开发人员快速定位和解决程序中的问题,提升开发效率。
(3)PROTEUS仿真软件:
PROTEUS是一款被广泛应用于电子电路设计和仿真的软件。在嵌入式系统开发领域,PROTEUS通常用于对电路设计和单片机程序进行仿真,以验证系统功能、调试程序并检测潜在问题。该软件提供了丰富的元件库和仿真功能,使用户能够轻松搭建电路原理图、加载单片机程序,并进行实时仿真。
2.2 硬件电路
(1)STC89C52R单片机:
晶振使用11.0592Mhz
(2)LCD1602码表:
(3)数码管:
(4)后台数码显示器(通过串口通信):
(5)按键:
按键使用独立按键形式,P34 P35 P36 P37引脚
(6)实物与Proteus:
3 软件代码工程
c
#include "includes.h"
/******************************************************************/
/* 微秒延时函数 //10us */
/******************************************************************/
void delay_us(unsigned int us)//delay us
{
while(us--)
{
}
}
/******************************************************************/
/* 微秒延时函数 */
/******************************************************************/
void delay_ms(unsigned int Ms)//delay us
{
while(Ms--)
{
delay_us(100);
}
}
/*------------------------------------------------
主函数
------------------------------------------------*/
unsigned char pro_key_data = 0;
void main (void)
{
char Test2[] = " ";
unsigned char databuf[4] = {0};
//串口外设初始化
sys_uart_init();
//LCD1602显示屏初始化
LCD_init();
sprintf(Test2,"Nunber:");
LCD_write_strl(0,0,Test2,16);
P1 = 0xFF;
while (1)
{
//获取按键值
pro_key_data = sys_key_single();
if(pro_key_data)
{
//指示灯显示
P1 &= ~(1<<(pro_key_data-1));
//数码管显示
sys_keynum_ledon(pro_key_data,0);
//LCD1602显示
LCD_write_com(0x80+7);
lcd_number(pro_key_data);
}
}
}
c
#ifndef __INCLUDES_H__
#define __INCLUDES_H__
//#include<reg52.h>
#include<intrins.h> //汇编指令_nop_
#include<stdio.h> //标准输入输出
//_nop_(); 产生一条NOP指令
//作用:对于延时很短的,要求在us级的,采用"_nop_"函数,这个函数相当汇编NOP指令,延时几微秒。
//NOP指令为单周期指令,可由晶振频率算出延时时间。
//8051 为每个机器周期 12 时钟
//对于12M晶振,延时1uS。
//11.0592M晶振,延时1.0851uS。
//对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。
//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "STC89C5xRC_RDP.h"
//应用层头文件
//#include "c51_gpio.h"
#include "c51_ledtube.h"
#include "c51_key.h"
//#include "c51_timer.h"
//#include "c51_exit.h"
#include "c51_lcd1602.h"
//#include "c51_iic.h"
//#include "c51_tx1838.h"
#include "c51_uart.h"
//#include "c51_28byj48.h"
//#include "c51_ds1302.h"
extern unsigned char pro_key_data;
extern void delay_us(unsigned int us);//delay us;
extern void delay_ms(unsigned int Ms);//delay Ms;
#endif
//c51_ledtube.c文件
c
#include "includes.h"
显示段码值01234567,可对应原理图查看显示不同图形对应的引脚高点电平配置状态
//unsigned char const EL[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
code unsigned char ledmap[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x40,0x80};
///********************************************************
//函数名称:sys_ledtube_on1
//函数功能:点亮一个数码管全为亮起来
//入口参数:
//出口参数:
//修 改:
//内 容:
//********************************************************/
//void sys_ledtube_on1(void)
//{
// //根据原理图,将P0口全部输出高电平,P2选择0号数码管
// P0=0xFF;//取显示数据,段码
// P2=0; //取位码
//}
///********************************************************
//函数名称:sys_ledtube_on2
//函数功能:显示一组数据
//入口参数:
//出口参数:
//修 改:
//内 容:
//********************************************************/
//static unsigned char ledtube_cnt = 0;
//void sys_ledtube_on2(void)
//{
// ledtube_cnt++;
// if(ledtube_cnt>7)
// {
// ledtube_cnt = 0;
// }
// P0 = 0x00; //防止切换数码管瞬间有虚影出现
// P2 = 0x00;
// P0 = ledmap[ledtube_cnt]; //取显示数据,段码
// P2 = ledtube_cnt; //取位码
//
// //根据人眼适应虚影缓冲时间为50ms左右
// //我们调整delay在500以下可以看到明显的看起来是一串数据一起显示
// delay(100);
//}
///********************************************************
//函数名称:sys_keynum_ledon
//函数功能:显示按键数值
//入口参数:按键数值
//出口参数:
//修 改:
//内 容:
//********************************************************/
void sys_keynum_ledon(unsigned char num,unsigned char pn)
{
//根据原理图,将P0口全部输出高电平,P2选择0号数码管
P0 = 0x00; //防止切换数码管瞬间有虚影出现
P2 = pn; //取位码
P0 = ledmap[num]; //取显示数据,段码
delay_ms(1);
P2 = 7; //取位码
}
//c51_ledtube.h文件
c
#ifndef __C51_LEDTUBE_H__
#define __C51_LEDTUBE_H__
//extern unsigned char const EL[];
//extern void sys_ledtube_on1(void);
//extern void sys_ledtube_on2(void);
extern void sys_keynum_ledon(unsigned char num,unsigned char pn);
#endif
//c51_uart.c文件
c
#include "includes.h"
/*-----------------------------------------------
名称:串口通信
内容:连接好串口或者usb转串口至电脑,下载该程序,打开电源
打开串口调试程序,将波特率设置为9600,无奇偶校验
晶振11.0592MHz,发送和接收使用的格式相同,如都使用
字符型格式,在发送框输入 hello,I Love MCU ,在接
收框中同样可以看到相同字符,说明设置和通信正确
------------------------------------------------*/
/******************************************************************/
void sys_uart_init(void)
{
SCON = 0x50; /* SCON: 模式 1, 8-bit UART, 使能接收 */
TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 0xFD; /* TH1: reload value for 9600 baud @ 11.0592MHz */
TR1 = 1; /* TR1: timer 1 run */
EA = 1; /*打开总中断*/
//ES = 1; /*打开串口中断*///当使用串口协议通讯时可以使用此型号中断
}
void Uart_SendChar(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
char putchar(char c)//重定向
{
Uart_SendChar(c);
return c;
}
/******************************************************************/
/* 串口中断程序 */
/******************************************************************/
static unsigned char uart_temp = 0; //定义临时变量
static unsigned char uart_cnt = 0; //定义临时变量
void UART_isr(void) interrupt 4 //串行中断服务程序
{
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
uart_temp=SBUF; //读入缓冲区的值
if(uart_cnt==0)
{
if(0x02 == uart_temp)
{
uart_cnt = 1;
}
else
{
uart_cnt = 0;
}
}
else if(uart_cnt==1)
{
if(0x05 == uart_temp)
{
uart_cnt = 2;
}
else
{
uart_cnt = 0;
}
}
else if(uart_cnt==2)
{
uart_cnt = 0;
//P1=uart_temp; //把值输出到P1口,用于观察
SBUF=uart_temp; //把接收到的值再发回电脑端
}
else
{
uart_cnt = 0;
}
}
if(TI) //如果是发送标志位,清零
{
TI=0;
}
}
//c51_uart.h文件
c
#ifndef __C51_UART_H__
#define __C51_UART_H__
extern void Uart_SendChar(unsigned char dat);
extern char putchar(char c);//重定向
extern void sys_uart_init(void);
extern void UART_isr(void);
#endif
//c51_lcd1602.c文件
c
#include "includes.h"
#include <string.h>
/******************************************************************/
/* 写入命令函数 */
/******************************************************************/
void LCD_write_com(unsigned char com)
{
RS_CLR;
RW_CLR;
EN_SET;
P0 = com;
delay_us(5);
EN_CLR;
}
/******************************************************************/
/* 写入数据函数 */
/******************************************************************/
void LCD_write_Data(unsigned char Data)
{
RS_SET;
RW_CLR;
EN_SET;
P0 = Data;
delay_us(5);
EN_CLR;
}
/****************************************
函数功能:LCD显示数字0-9
*****************************************/
void lcd_number(unsigned int number)
{
int num[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
switch(number)
{
case 0:LCD_write_Data(num[0]);
break;
case 1:LCD_write_Data(num[1]);
break;
case 2:LCD_write_Data(num[2]);
break;
case 3:LCD_write_Data(num[3]);
break;
case 4:LCD_write_Data(num[4]);
break;
case 5:LCD_write_Data(num[5]);
break;
case 6:LCD_write_Data(num[6]);
break;
case 7:LCD_write_Data(num[7]);
break;
case 8:LCD_write_Data(num[8]);
break;
case 9:LCD_write_Data(num[9]);
break;
}
}
/******************************************************************/
/* 初始化函数 */
/******************************************************************/
void LCD_init(void)
{
LCD_write_com(0x38); /*显示模式设置*/
delay_ms(5);
LCD_write_com(0x38);
delay_ms(5);
LCD_write_com(0x38);
delay_ms(5);
LCD_write_com(0x38);
LCD_write_com(0x08); /*显示关闭*/
LCD_write_com(0x01); /*显示清屏*/
LCD_write_com(0x06); /*显示光标移动设置*/
delay_ms(5);
LCD_write_com(0x0C); /*显示开及光标设置*/
}
/******************************************************************/
/* 写入字符串函数 */
/* X:第几列 Y:第几行 *s字符串为空时跳出 */
/******************************************************************/
void LCD_write_strl(unsigned char x,unsigned char y,unsigned char *s,unsigned length)
{
unsigned char cnt = 0;
//LCD_write_com(0x01); /*显示清屏*/
if (y == 0)
{
LCD_write_com(0x80 + x);
}
else
{
LCD_write_com(0xC0 + x);
}
while(length--)
{
LCD_write_Data( *s);
s ++;
cnt++;
}
}
//c51_lcd1602.h文件
c
#ifndef __C51_LCD1602_H__
#define __C51_LCD1602_H__
#include "STC89C5xRC_RDP.h"
//定义宏定义
sbit RS = P2^4; //定义端口
sbit RW = P2^5;
sbit EN = P2^6;
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
extern void LCD_write_com(unsigned char com) ;
extern void LCD_write_Data(unsigned char Data) ;
extern void lcd_number(unsigned int number);
extern void LCD_init(void) ;
extern void LCD_write_strl(unsigned char x,unsigned char y,unsigned char *s,unsigned length) ;
#endif
//c51_key.c文件
c
#include "includes.h"
sbit key1=P3^7;//定义按键位置 需要切换到独立按键模式
sbit key2=P3^6;
sbit key3=P3^5;
sbit key4=P3^4;
bit Flag = 0;
unsigned char key_num = 0;
/******************************************************************/
/* 主函数 */
/******************************************************************/
unsigned char sys_key_single(void)
{
if(!Flag) //执行一次就停止了 先检测到的相应 复位后有效
{
if(!key1) {P1=0xFE;Flag=1;key_num=1;printf("The key_num :Number 1;\r\n");}//
else if(!key2){P1=0xFD;Flag=1;key_num=2;printf("The key_num :Number 2;\r\n");}//
else if(!key3){P1=0xFB;Flag=1;key_num=3;printf("The key_num :Number 3;\r\n");}//
else if(!key4){P1=0xF7;Flag=1;key_num=4;printf("The key_num :Number 4;\r\n");}//
else
{
key_num=0;
}
//串口后台打印数字
}
return key_num;
}
//如果有干扰请加去抖程序
//红外接收头部分用黑色物质遮光,防止干扰按键
//c51_key.h文件
c
#ifndef __C51_KEY_H__
#define __C51_KEY_H__
extern unsigned char sys_key_single(void); //键盘扫描函数,使用行列反转扫描法
#endif
4 演示Proteus仿真
5 总结
STC89C52R控制抢答器+数码管+后台显示+LCD1602x显示具有以下价值和优势:
功能丰富性:整合抢答器、数码管、后台显示和LCD1602x显示功能,实现多样化的信息展示和控制功能。
-
灵活性:通过STC89C52R控制,系统具有灵活的数据交换和控制能力,可根据需求定制显示内容和功能。
-
用户体验:提供直观的数码显示和LCD1602x显示,增强用户交互体验,使信息更加清晰和易读。
-
系统稳定性:采用STC89C52R作为控制核心,系统稳定可靠,保证长时间稳定运行。
-
开发效率:整合多种显示功能和控制模块,简化开发流程,提高开发效率和系统集成度。
-
教育和培训:适用于教育和培训领域,帮助学习者理解嵌入式系统开发和控制原理。
-
应用广泛:可用于各类竞赛、培训、演示等活动中,扩展了系统应用领域和功能范围。
这些优势使得STC89C52R控制的抢答器与数码管、后台显示和LCD1602x显示系统成为一款具有实用性和创新性的嵌入式系统,能够满足多样化的需求并提升用户体验。