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

【Proteus仿真】【51单片机】基于51单片机自动售货机12864屏幕

目录

一、主要功能

二、使用步骤

三、硬件资源

四、软件设计

五、实验现象

一、主要功能

1、LCD12864液晶显示
2、5种商品
3、选择商品后,在规定时间内投入货币能实现累加并根据选择的商品进行结算
4、选择商品后,投入货币小于商品金额,在规定时间后,投入货币全部退还

二、使用步骤

  • 接通电源后LCD1602显示货物界面
  • 系统自动加载五种货物数据到内存中‌
  • 通过矩阵键盘选择商品类型:
    • 数字键对应不同商品分类‌
    • 投币键对应不同硬币价格
    • 当前选择会实时显示在LCD屏幕
    • 通过投币口投硬币:
      • 支持5元、1元、0.5元三种面额‌
      • 投币金额实时显示在找零区域

三、硬件资源

1、51单片机核心模块
2、按键模块
3、蜂鸣器模块
4、继电器模块
5、LCD12864显示模块

四、软件设计

#ifndef _LCD12864BU_H_
#define _LCD12864BU_H_

#define LCDLCDDisp_Off 0x3e
#define Page_Add 0xb8//页地址
#define Start_Line 0xC0//行地址
#define LCDCol_Add 0x40//列地址
#define LCDLCDDisp_On 0x3f

/*****液晶显示器的端口定义*****/
#define data_ora P0 /*液晶数据总线*/
sbit LCDDi=P2^0 ;     /*数据/指令 选择*/
sbit LCDRW=P2^1 ;     /*读/写 选择*/
sbit LCDEnable=P2^2 ;     /*读/写 使能*/
sbit cs1=P2^3 ;    /*片选1*/
sbit cs2=P2^4 ;    /*片选2*/  // 实物片选要互换
sbit RESET=P2^5 ;  /*复位信号*/
#include "value.h"
/****************************************************************************
函数功能:LCD延时程序
入口参数:t
出口参数:
****************************************************************************/
void LCDdelay(unsigned int t)
{
 unsigned int i,j;
 for(i=0;i<t;i++);
 for(j=0;j<10;j++);
}
/********************************************************************
* 名称 : LCEdelay_1ms()
* 功能 : 延时1ms函数
* 输入 : q
* 输出 : 无
***********************************************************************/
void LCEdelay_1ms(uint q)
{    
 uint i,j;
 for(i=0;i<q;i++)
 for(j=0;j<115;j++);
}

/****************************************************************************
状态检查,LCD是否忙
*****************************************************************************/
void CheckState()        
{
 unsigned char dat,DATA;//状态信息(判断是否忙)
 LCDDi=0; // 数据\指令选择,D/I(RS)="L" ,表示 DB7∽DB0 为显示指令数据 
 LCDRW=1; //R/W="H" ,E="H"数据被读到DB7∽DB0 
 do
 {
  DATA=0x00;
  LCDEnable=1;    //EN下降源
  LCDdelay(2);//延时
  dat=DATA;
  LCDEnable=0;
  dat=0x80&dat; //仅当第7位为0时才可操作(判别busy信号)
 }
 while(!(dat==0x00));
}
/*****************************************************************************
函数功能:写命令到LCD程序,RS(DI)=L,RW=L,EN=H,即来一个脉冲写一次
入口参数:cmdcode
出口参数:
*****************************************************************************/
void write_com(unsigned char cmdcode)
{
 CheckState();//检测LCD是否忙
 LCDDi=0;
 LCDRW=0;
 P0=cmdcode;        
 LCDdelay(2);
 LCDEnable=1;
 LCDdelay(2);
 LCDEnable=0;
}
/*****************************************************************************
函数功能:LCD初始化程序
入口参数:
出口参数:
*****************************************************************************/
void init_lcd()
{
 LCDdelay(100);    
 cs1=0;//仿真要打开  实物要关闭两屏
 cs2=0;
 LCDdelay(100);
 write_com(LCDLCDDisp_Off);     //写初始化命令
 write_com(Page_Add+0);
 write_com(Start_Line+0);
 write_com(LCDCol_Add+0);
 write_com(LCDLCDDisp_On);
}
/*****************************************************************************
函数功能:写数据到LCD程序,RS(DI)=H,RW=L,EN=H,即来一个脉冲写一次
入口参数:LCDDispdata
出口参数:
*****************************************************************************/
void write_data(unsigned char LCDDispdata)
{
 CheckState();//检测LCD是否忙
 LCDDi=1;
 LCDRW=0;
 P0=LCDDispdata;
 LCDdelay(2);
 LCDEnable=1;
 LCDdelay(2);
 LCDEnable=0;
}

/***********************写汉字函数**********************/
void write_yhanzi(uchar n,uchar x,uchar y,uchar  * p)
{
 uchar i,j,nm,m; 
 m=0xb8+x;
 for(j=0;j<n;j++)
 {       
  if((16*j+y)<64)
  {
   cs1=1;cs2=0;nm=0x40+y+16*j;  
  }
  else
  {
   cs1=0;cs2=1;nm=0x40+y+16*(j-4);  
  }
  write_com(m);
  write_com(nm);
  for(i=0;i<16;i++)
  { 
   write_data(*p);p++; 
  }
  write_com(m+1);
  write_com(nm);
  for(i=16;i<32;i++)
  { 
   write_data(*p);p++;
  }
 }
}

void write_yhanzi_fanbai(uchar n,uchar x,uchar y,uchar  * p,uchar fanbai)
{
 uchar i,j,nm,m; 
 m=0xb8+x;
 for(j=0;j<n;j++)
 { 
  if((16*j+y)<64)
  {
   cs1=1;cs2=0;nm=0x40+y+16*j;  
  }
  else
  {
   cs1=0;cs2=1;nm=0x40+y+16*(j-4);  
  }
  write_com(m);
  write_com(nm);
  for(i=0;i<16;i++)
  { 
   if(fanbai==0)
   write_data(*p);
   else     
   write_data(~(*p));
   p++; 
  }
  write_com(m+1);
  write_com(nm);
  for(i=16;i<32;i++)
  { 
   if(fanbai==0)
   write_data(*p);
   else     
   write_data(~(*p));
   p++; 
  }
 }
}

/***********************写数字函数**********************/
void write_shuzi(uchar n,uchar x,uchar y,uchar  * p,uchar fanbai)
{
 uchar i,j,nm,m; 
 m=0xb8+x;
 for(j=0;j<n;j++)
 {   
  if((8*j+y)<64)
  {
   cs1=1;cs2=0;nm=0x40+y+8*j;  
  }
  else
  {
   cs1=0;cs2=1;nm=0x40+y+8*(j-8);  
  }
  write_com(m);
  write_com(nm);
  for(i=0;i<8;i++)
  { 
   if(fanbai==0)
   write_data((*p));
   else 
   write_data(~(*p));
   p++; 
  }
  write_com(m+1);
  write_com(nm);
  for(i=8;i<16;i++)
  { 
   if(fanbai==0)
   write_data((*p));
   else 
   write_data(~(*p));
   p++; 
  }
 }
}

/**********************************************************
*函数名: write_shu16
*功能:在12864上显示16进制数据
*说明:
*输入:无
*返回:无
**********************************************************/
void write_shu16(uchar x,uchar y,uchar dat,uchar fanbai)
{     
 if(dat>=100)
 {
     write_shuzi(1,x,y-8,shuzi[dat/100],fanbai);
     write_shuzi(1,x,y,shuzi[dat%100/10],fanbai);
     write_shuzi(1,x,y+8,dian[0],fanbai);//.
     write_shuzi(1,x,y+16,shuzi[dat%10],fanbai);
 }
 else
 {
     write_shuzi(1,x,y,shuzi[dat/10],fanbai);
     write_shuzi(1,x,y+8,dian[0],fanbai);//.
     write_shuzi(1,x,y+16,shuzi[dat%10],fanbai);
 }
}

void write_time(uchar x,uchar y,uchar dat,uchar fanbai)
{


     write_shuzi(1,x,y,shuzi[dat/10],fanbai);
     write_shuzi(1,x,y+8,shuzi[dat%10],fanbai);

}
/*****************************************************************************
函数功能:清除LCD内存程序
入口参数:pag,col,hzk
出口参数:
*****************************************************************************/
void Clr_Scr()
{
 unsigned char j,k;
 cs1=1; //左、右屏均开显示
 cs2=1;
 write_com(Page_Add+0);
 write_com(LCDCol_Add+0);
 for(k=0;k<8;k++)//控制页数0-7,共8页
 {
  write_com(Page_Add+k); //每页每页进行写
  for(j=0;j<64;j++)  //每页最多可写32个中文文字或64个ASCII字符
  {
   write_com(LCDCol_Add+j);
   write_data(0x00);//控制列数0-63,共64列,写点内容,列地址自动加1
  }
 }
}
/*****************************************************************************
函数功能:左屏位置显示
入口参数:page,column,hzk
出口参数:
*****************************************************************************/
void Bmp_Left_Disp(unsigned char page,unsigned char column, unsigned char code *Bmp)
{
 unsigned char j=0,i=0;
 for(j=0;j<2;j++)
 {
  write_com(Page_Add+page+j);
  write_com(LCDCol_Add+column);
  for(i=0;i<16;i++) 
  {
   write_data(Bmp[128*j+i]);
   LCEdelay_1ms(50);
  }
 }
}
void Bmp_Left_Disp_hanzi(unsigned char page,unsigned char hang, unsigned char code *Bmp)
{
 unsigned char j=0,i=0;
 for(j=0;j<2;j++)
 {
  write_com(Page_Add+page+j);
  write_com(LCDCol_Add+hang);
  for(i=0;i<16;i++) 
  write_data(Bmp[0x00]);
 }
}
void clear_12864()
{         
 uchar x,y;
 cs1=1;
 cs2=0;
 for(x=0;x<8;x++)
 {
  write_com(0xb8+x);
  for(y=0;y<64;y++)
  {         
   write_data(0X00);
  }
 }        
}
/*****************************************************************************
函数功能:右屏位置显示
入口参数:page,column,hzk
出口参数:
*****************************************************************************/
void Bmp_Right_Disp(unsigned char page,unsigned char column, unsigned char code *Bmp)
{
 unsigned char j=0,i=0;
 for(j=0;j<2;j++)
 {
  write_com(Page_Add+page+j);
  write_com(LCDCol_Add+column);
  for(i=64;i<128;i++) 
  {
   write_data(Bmp[128*j+i]);
   LCEdelay_1ms(50);
  }
 }
}
void qingling()
{
 uchar x,y ;
 cs1=0;
 cs2=0;
 write_com(0x3f);
 write_com(0xc0);
 for(x=0;x<8;x++)
 {  
  write_com(0xb8+x);
  write_com(0xc0);
  for(y=0;y<64;y++)
  {
   write_data(0x00);
  }
  write_com(0xb8+x+1);
  write_com(0xc0);
  for(y=0;y<64;y++)
  {
   write_data(0x00);
  }
 }
}
#endif

五、实验现象

演示视频:

【51单片机-B005】【protues仿真】基于51单片机自动售货机12864屏幕1仿真

http://www.lryc.cn/news/625780.html

相关文章:

  • ICCV 2025 | 首个3D动作游戏专用VLA模型,打黑神话只狼超越人类玩家
  • 如何免费给视频加字幕
  • AndroidR车机系统Settings数据库增加非持久化存储键值方案-续
  • 国产!全志T113-i 双核Cortex-A7@1.2GHz 工业开发板—ARM + FPGA通信案例
  • 深入解析Spring MVC运行流程:从请求到响应的完整旅程
  • React学习(六)
  • Spring Cache 整合 Redis 实现高效缓存
  • Android音频学习(十三)——音量配置文件分析
  • proDAD VitaScene:专业视频转场特效滤镜软件
  • spring声明式事务,finally 中return对事务回滚的影响
  • 第12章 React生态工具链
  • 第14章 现代React特性
  • 在VSCode中进行Vue前端开发推荐的插件
  • Web3.0 时代的电商系统:区块链如何解决信任与溯源问题?
  • [Git] 如何拉取 GitHub 仓库的特定子目录
  • 神经网络训练过程详解
  • 20.2 QLoRA微调全局参数实战:高点击率配置模板+显存节省50%技巧
  • (一)八股(数据库/MQ/缓存)
  • 【赎金信】
  • 环境变量不生效?
  • C#三大核心特性
  • 实现自己的AI视频监控系统-第一章-视频拉流与解码1
  • Laya的适配模式选择
  • 代码随想录算法训练营四十六天|图论part04
  • BROADCHIP广芯电子在各类电子产品的方案与应用
  • 企业如何让内部视频仅限指定域名播放,确保视频不被泄露?
  • 2025年8月16日(星期六):雨骑古莲村游记
  • 机器人控制基础:运动控制中的串级pid原理以及实现方案(包含代码示例)
  • 学习笔记分享——基于STM32的平衡车项目
  • 8.19打卡 DAY 46 通道注意力(SE注意力)