当前位置: 首页 > article >正文

proteus+51单片机+实验(LCD1620、定时器)

目录

1.LCD1602液晶显示屏

1.1基本概念

1.1.1LCD的简介

1.1.2LCD的显示原理

​​​1.1.3LCD的硬件电路

1.1.4LCD的常见指令

1.1.5LCD的时序

​​​​​​​1.2代码

1.2.1写命令和写数据操作

 1.2.2初始化和测试代码

1. 3.3功能函数

1.3proteus代码

1.3.1器件代码

1.3.2总体Proteus

​编辑​ 2.定时器

2.1基本概念

2.1.1定时器的简介

2.1.2定时器的计数模式

 2.1.3寄存器

​编辑 2.1.4中断系统

​编辑  ​编辑

2.2代码

2.2.1定时器初始化代码

2.2.2定时器中断代码

2.2.3计数器函数

2.3proteus仿真

2.3.1定时器总体仿真

2.3.2计数器总体框图


1.LCD1602液晶显示屏

1.1基本概念

1.1.1LCD的简介

  • LCD1602(Liquid Crystal Display)液晶显示屏是一种专门用来显示字母、数字、符号和字符型等的点阵型液晶模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符。

  • 它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。该显示屏的优点是耗电量低、体积小、辐射低。

  • 显示容量:16×2个字符,每个字符为5*7点阵,、

1.1.2LCD的显示原理

我们所用的LCD屏的命名,基本都是按照其分辨率来进行命名的比如lcd1602就是分辨率为16×2,lcd12864就是分辨率为128×64

  • LCD1602主要用来显示数字、字母、图形以及少量自定义字符。可以显示2行16个字符,拥有16个引脚,其中8位数据总线D0-D7,和RS、R/W、EN三个控制端口,工作电压为5V,并且带有字符对比度调节V0和背光源AK。

  • LCD需要背光源才能亮

  • 80个字节的显示缓冲区DDRAM,分两行,地址分别为00H27H,40H67H
  • LCD1602,总共显示为16行2列,对应着32个RAM地址,在使用的时候,需要在哪个位置显示,就写入对应的RAM地址,然后再写入需要的字符,对应就会显示该字符。

  • 转义字符(\)

​​​1.1.3LCD的硬件电路

引脚功能
VSS
VDD电源正极(4.5~5.5V)
VO对比度调节电压,即调节LCD的显示
RS数据/指令选择,1为数据,0为指令
RW读(read)/写(write)信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或显示地址;当RS为低电平,R/W为高电平时,可以读忙信号;当RS为高电平,R/W为低电平时,可以写入数据
E使能,1为数据有效,下降沿执行命令
D0~D78位并行数据口数据输入/输出
A背光灯电源正极
K背光灯电源负极

1.1.4LCD的常见指令

ASCll码表

  • 清屏指令(0x01)

(1)清除液晶显示器,即将DDRAM的内容全部填入“空白”的ASCII码20H;

(2)光标归位,将光标撤回液晶显示屏的左上方;

(3)将地址计数器(AC)的值设置为0;

  • 光标复位,光标返回到地址00H

(1) 光标复位到地址00H位置

(2)LCD显示DDRAM的内容不变

  • 进入模式设置指令

(1) 功能:设定每次定入1位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。参数设定的情况如下所示:

(2)0=写入新数据后光标左移 ; 1=写入新数据后光标右移;

(3)S—0=写入新数据后显示屏不移动 ;1=写入新数据后显示屏整体右移1个字符

  • 显示开关指令

(1)功能 : 控制显示器开/关、光标显示/关闭以及光标是否闪烁。

(2)D(Dispaly):控制整体的显示开与关,高电平表示开显示屏,低电平表示关显示屏

(3)C(Cursor):控制光标的开与关,高电平表示有光标,低电平表示无光标

(4)B(Blink):控制光标是否闪烁,高电平闪烁,低电平不闪烁

  • 功能设定指令

(1) 功能 : 设定数据总线位数、显示的行数及字型

(2)DL —— 0=数据总线为4位 ; 1=数据总线为8位;

(3)N —— 0=显示1行 ; 1=显示2行;

(4)F —— 0=5×7点阵/每字符 ; 1=5×10点阵/每字符;

  • 光标和显示移位

(1) SC=0,RL=0 :光标左移

(2)SC=0,RL=1 : 光标右移

(3)SC=1,RL=0时,字符和光标都左移

(4)SC=1,RL=1时字符和光标都右移

1.1.5LCD的时序

  • 写指令/数据

  • ​​​​​​​​​​读指令/数据

​​​​​​​​​​​​​​1.2代码

1.2.1写命令和写数据操作

sbit RS=P3^0;
sbit RW=P3^1;
sbit E=P3^2;

void writecommand(unsigned char command)
{
    RS=0;  //RS为低电平时此时为读数据
    RW=0;  //RW为低表示数据写入
    E=0;   //E=0表示在前半部分,此时数据没有传送无需置高
    P2=command; //command为命令
    Delay_ms(5);
    E=1;   //E此时表示传送数据有效
    E=0;   //E此时表示数据传送完成此时为空闲状态
}

void writedata(unsigned char dat)
{
    RS=1;  //RS为低电平时此时为读数据
    RW=0;  //RW为低表示数据写入
    E=0;   //E=0表示在前半部分,此时数据没有传送无需置高
    P2=dat; //command为命令
    Delay_ms(5);
    E=1;   //E此时表示传送数据有效
    E=0;   //E此时表示数据传送完成此时为空闲状态
}

 1.2.2初始化和测试代码

void lcd_init()
{
    writecommand(0x38);//设置16×2显示、5×7点阵和8位数据接口
    writecommand(0x0C);//设置开启显示,不显示光标
    writecommand(0x06);//显示地址地址加1,即写一个数据后,显示位置右移一位 
    writecommand(0x01);//显示清零,数据指针清零
}

void lcd_test()
{
    writecommand(0x80); //LCD的第一行起始地址
    Delay_ms(5);
    writedata('A');
    Delay_ms(5);
    writecommand(0x80+0x40); //LCD的第二行起始地址
    Delay_ms(5);
    writedata('X');
    Delay_ms(5);
}

1. 3.3功能函数

/**
 * @brief 在LCD中显示一个字符
 * @param Line:表示在第几行显示
 * @param Column:表示在第几列显示
 * @param Char:显示字符
 * @retval
 */
void LCD_Showchar(unsigned char Line,unsigned char Column,unsigned char Char)
{   
    if(Line==1)
    { 
        writecommand(0x80|(Column-1));      //此时在第一行显示
    }
    else
    {
        writecommand (0x80|(Column-1)+0x40);//此时在第二行显示,
        writedata(Char);
    }
}


/**
 * @brief 在LCD中显示一个字符串
 * @param Line:表示在第几行显示
 * @param Column:表示在第几列显示
 * @param Char:显示字符串
 * @retval
 */
void LCD_Showstring(unsigned char Line,unsigned char Column,unsigned char *String)
{
    unsigned char i;
    if(Line==1)
    { 
        writecommand(0x80|(Column-1));      //此时在第一行显示
    }
    else
    {
        writecommand (0x80|(Column-1)+0x40);//此时在第二行显示,
        
    } 
    for(i=0;String[i]!='\0';i++)
    {
        writedata(String[i]);
    }  
}


/**
 * @brief 立方函数
 * @param x为分子
 * @param y为立方根
 */
int LCD_POW(int x,int y)
{
    unsigned char i;
    int result=1;
    for(i=0;i<y;i++)
    {
        result*=x;
    }
    return result;
}

/**
 * @brief 设置字符位置
 * @param x为行
 * @param y为列
 */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
    unsigned char i;
    if(Line==1)
    { 
        writecommand(0x80|(Column-1));      //此时在第一行显示
    }
    else
    {
        writecommand (0x80|(Column-1)+0x40);//此时在第二行显示,
    } 
}

/**
 * @brief 设置数字
 */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned char Num,unsigned char Length)
{
    unsigned char i;
    LCD_SetCursor(Line,Column);
    for(i=Length;i>0;i--)
    {
       writedata(Num/LCD_POW(10,i-1)%10+0x30);//得到数字的高位);     
    }
}


1.3proteus代码

1.3.1器件代码

1.3.2总体Proteus

​ 2.定时器

2.1基本概念

2.1.1定时器的简介

  (1)STC89C52系列单片机内部设置的两个16位定时器/计数器T0和T1都具有计数方式和定时方式两种工作方式。对每个定时器/计数器(T0和T1),在特殊功能寄存器TM0D中都有一控制位一C/T来选择T0或T1为定时器还是计数器。

(2)定时器/计数器的核心部件是一个加法(也有减法)的计数器,其本质是对脉冲进行计数。只是计数脉冲来源不同:如果计数脉冲来自系统时钟,则为定时方式,此时定时器/计数器每12个时钟或者每6个时钟得到一个计数脉冲,计数值加1;如果计数脉冲来自单片机外部引脚(T0为P3.4,T1为P3.5),则为计数方式,每来一个脉冲加1。

(3)SYSclk:系统时钟,即晶振周期,晶振为12MHz 

(4)当定时器/计数器工作在定时模式时,可在烧录用户程序时在STC-ISP编程器中设置(如下
图所示)是系统时钟÷12还是系统时钟÷6后让T0和T1进行计数。当定时器/计数器工作在计数模式时,对外部脉冲计数不分频。

(5)GATE:门控位,用于控制定时/计数器的启动是否受外部中断请求信号的影响。

2.1.2定时器的计数模式

  • 模式1(16位定时器/计数器)及其测试程序

  • 模式2(8位计数器模式)

  • 16位定时器工作方式 

(1)​​​​​​​计数值为N和初值X关系:X=65536-N(12/fosc),N的单位为us即定义的时间

(2)上次计数完,计数器值为0,要重复计数需重置初值。

fosc为晶振频率,51单片机一般为12MHz或者11.0592MHz

  • 16位计数器工作方式

​​​​​​​(1)16位定时/计数器方式计数值为N和初值X关系:X=65536-N
(2)上次计数完,计数器值为0,要重复计数需重置初值。

 2.1.3寄存器

  • 定时器/计数器控制寄存器TCON 

  •  定时器/计数器工作模式寄存器TMOD

 2.1.4中断系统

  

2.2代码

2.2.1定时器初始化代码

void timerinit()
{
    TMOD=0x01;              //定时器0工作在16位定时器模式下,TH0、TL0全用
    TF0=0;                  //防止开始定时器溢出产生中断,因此将TF0定时器清零
    TH0=(65536-50000)/256;  //计时50000us,并且除以2^8相当于右移8位,取出了高八位
    TH0=(65536-50000)%256;  //取出低八位,
    ET0=1;                  //开启定时器0的中断
    EA=1;                   //开启总中断
    TR0=1;                  //启动定时器0 
    PT0=0;                  //配置低优先级    
}

2.2.2定时器中断代码

void timer_isr()  interrupt 1   //0表示外部中断0:1表示定时器中断0:2表示外部中断1;3表示定时器中断1;4表示串口中断
{
    TH0=(65536-50000)/256;  
    TH0=(65536-50000)%256;  
    count++;
    if(count==10)count=0;
    P2=s[count];
   // Delay_ms(200);
}

2.2.3计数器函数

void timerinit()
{
    TMOD=0x06;              //定时器0工作在8位自动重载计数器模式下,TH0、TL0全用
    TF0=0;                  //防止开始计数器溢出产生中断,因此将TF0计数器清零
    TH0=256-3;              //计数值为3,由于是8位所以不需要将数据取出
    TH0=256-3;              //计数器3
    ET0=1;                  //开启定时器0的中断
    EA=1;                   //开启总中断
    TR0=1;                  //启动定时器0 
    PT0=0;                  //配置低优先级    
}

void count_isr()  interrupt 1   //0表示外部中断0:1表示定时器中断0:2表示外部中断1;3表示定时器中断1;4表示串口中断
{
    num++;     //每隔3次,进入计数器的中断函数使得Num的值加1
}

2.3proteus仿真

2.3.1定时器总体仿真

2.3.2计数器总体框图


http://www.kler.cn/a/302079.html

相关文章:

  • 【因果分析方法】MATLAB计算Liang-Kleeman信息流
  • 图像处理技术椒盐噪声
  • Go语言的零值可用性:优势与限制
  • 《动手学深度学习》中d2l库的安装以及问题解决
  • 【Three.js基础学习】22.New project structure
  • 基于GPU器件行为的创新分布式功能安全机制为智能驾驶保驾护航
  • 【JavaScript】LeetCode:31-35
  • 软件工程知识点总结(7):软件项目管理
  • 【STM32项目】基于STM32+RTOS音频光通信设计与实现(完整工程资料源码)
  • 网络安全产品认证证书大全(持续更新...)
  • 【复杂系统系列(中级)】Kolmogorov复杂度——信息的无序度量【通俗理解】
  • Python设计模式实战:开启软件设计的精进之旅
  • Log4j 1.x如何升级到Log4j 2.x
  • NVIDIA Blackwell 架构
  • HivisionIDPhotos
  • 【小沐学OpenGL】Ubuntu环境下glew的安装和使用
  • HTML高级技术解析与实践指南
  • 非线性规划及其MATLAB实现
  • 第十八节:学习统一异常处理(自学Spring boot 3.x的第五天)
  • 线程---实践与技巧(C语言)
  • 项目实战 ---- 商用落地视频搜索系统(9)---UI与上层service的交互优化
  • ubuntu2204安装kvm
  • 华为 HCIP-Datacom H12-821 题库 (20)
  • ArmSoM-Sige5 的 RK3576 SoC 主线内核支持进展
  • React 嵌套类名样式不生效
  • CSS 布局技巧实现元素左右排列