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

8088单板机接口扩展实验(二)LCD1602

1.硬件

2.程序

#define IO1 0x0600 #define IO2 0x0400 #define IO3 0x0600 #define ADR_244 IO3 //LCD Registers addresses #define LCD_CMD_WR (IO1+0x00) #define LCD_DATA_WR (IO1+0x02) #define LCD_BUSY_RD (IO1+0x04) #define LCD_DATA_RD (IO1+0x06) /* 可编程定时/计数器接口8253A */ #define ADR_TIMER_CONTROL (IO2 + 0x06) #define ADR_TIMER_DATA0 (IO2 + 0x00) #define ADR_TIMER_DATA1 (IO2 + 0x02) #define ADR_TIMER_DATA2 (IO2 + 0x04) #define TIMER_COUNTER0 0x00 #define TIMER_COUNTER1 0x40 #define TIMER_COUNTER2 0x80 #define TIMER_LATCH 0x00 #define TIMER_LSB 0x10 #define TIMER_MSB 0x20 #define TIMER_LSB_MSB 0x30 #define TIMER_MODE0 0x00 #define TIMER_MODE1 0x02 #define TIMER_MODE2 0x04 #define TIMER_MODE3 0x06 #define TIMER_MODE4 0x08 #define TIMER_MODE5 0x09 #define TIMER_BCD 0x01 unsigned char Str1[]=" Current Time"; unsigned char Str2[]="Set "; unsigned char HMS_String[]=" 12:30:00 "; unsigned char Hour=12,Minute=30,Second=0; unsigned char Settime; unsigned char Change_H_or_M=1; void outp(unsigned int addr, char data) // 输出一字节到I/O端口 { __asm { mov dx, addr mov al, data out dx, al } } char inp(unsigned int addr) // 从I/O端口输入一字节 { char result; __asm { mov dx, addr in al, dx mov result, al } return result; } //设置中断失量表 void set_int(unsigned char int_no, void * service_proc) { _asm { push es xor ax, ax mov es, ax mov al, int_no xor ah, ah shl ax, 1 shl ax, 1 mov si, ax mov ax, service_proc mov es:[si], ax inc si inc si mov bx, cs mov es:[si], bx pop es } } //中断处理函数 /* void _interrupt _far nmi_handler(void) { if(++Second==60) { Second=0; if(++Minute==60) { Minute=0; if(++Hour==24) { Hour=0;Minute=0;Second=0; } } } } void setup_nmi(void) // 在中断失量表添加2号中断失量 { set_int(0x02, (void *)&nmi_handler); // 设置8253A定时/计数器 outp(ADR_TIMER_CONTROL, TIMER_COUNTER0 | TIMER_MODE3 | TIMER_LSB_MSB|TIMER_BCD); outp(ADR_TIMER_DATA0, 0x00); outp(ADR_TIMER_DATA0, 0x01); outp(ADR_TIMER_CONTROL, TIMER_COUNTER2 | TIMER_MODE2 | TIMER_LSB_MSB|TIMER_BCD); outp(ADR_TIMER_DATA2, 0x00); outp(ADR_TIMER_DATA2, 0x10); } */ //LCD忙等待 void WaitForEnable( void ) { unsigned char result; do{ result=inp(LCD_BUSY_RD); }while(result&0x80); } //LCD写命令 void LcdWriteCommand( unsigned char cmd) { WaitForEnable(); outp(LCD_CMD_WR,cmd); } //LCD写数据 void LcdWriteData( char data ) { WaitForEnable(); outp(LCD_DATA_WR,data); } void LcdReset( void ) { LcdWriteCommand( 0x38); LcdWriteCommand( 0x0c); LcdWriteCommand( 0x06); LcdWriteCommand( 0x01); } void lcd_pos(unsigned char pos) { LcdWriteCommand( pos|0x80); } void lcd_out(unsigned char *row) { unsigned char *p; p=row; while(*p!='\0') { LcdWriteData(*p); p++; } } void delay(unsigned int x) {unsigned char i; while(x--) {for(i=0; i<120;i++){}} } //时分秒转换为字符串 void hms_str(unsigned char h,unsigned char m,unsigned char s) { HMS_String[4]=h/10+'0'; HMS_String[5]=h%10+'0'; HMS_String[7]=m/10+'0'; HMS_String[8]=m%10+'0'; HMS_String[10]=s/10+'0'; HMS_String[11]=s%10+'0'; } //调整时间 void Change_Time() { Settime=0; if(inp(ADR_244)!=0x0f) { lcd_pos(0x00); lcd_out(Str2); Settime=1; } while(Settime) { if(!(inp(ADR_244)&0x01)) { while(!(inp(ADR_244)&0x01)){} Change_H_or_M=!Change_H_or_M; if(!Change_H_or_M) {Str2[4]=' ';Str2[5]=' ';Str2[7]='<';Str2[8]='>';} else {Str2[4]='<';Str2[5]='>';Str2[7]=' ';Str2[8]=' ';} lcd_pos(0x00);lcd_out(Str2); } if(!(inp(ADR_244)&0x02)) { while(!(inp(ADR_244)&0x02)){} if(Change_H_or_M==1) {if(++Hour==24)Hour=0;} else {if(++Minute==60)Minute=0;} } if(!(inp(ADR_244)&0x04)) { while(!(inp(ADR_244)&0x04)){} if(Change_H_or_M==1) {if(--Hour==0xff)Hour=23;} else {if(--Minute==0xff)Minute=59;} } if(!(inp(ADR_244)&0x08)) { while(!(inp(ADR_244)&0x08)){} lcd_pos(0x00); lcd_out(Str1); Settime=0; } hms_str(Hour,Minute,Second); lcd_pos(0x40); lcd_out(HMS_String); } } void main(void) { // setup_nmi(); LcdReset(); lcd_pos(0x00); lcd_out(Str1); lcd_pos(0x40); lcd_out(HMS_String); while(1) { //hms_str(Hour,Minute,Second); lcd_pos(0x40); lcd_out(HMS_String); outp(0x800,0xff); delay(100); // LcdReset(); lcd_pos(0x00); lcd_out(Str1); outp(0x800,0x00); delay(100); outp(0x600,0xff); delay(100); //Change_Time(); } } char end_flag[5]={0x55,0x55,0x55,0x55,0x55};

3.测试

http://www.gsyq.cn/news/1338856.html

相关文章:

  • 从Spy++到Python脚本:手把手教你用pywin32.win32gui逆向分析桌面应用界面结构
  • eTs UI布局实战:从Flex容器到响应式设计,构建自适应界面
  • 【限时解禁】Midjourney官方未文档化的--sepia--与--chroma-shift--双引擎分离协议,实测提升色彩独立性达63.8%
  • GB35114客户端开发实战:手把手教你用eXosip2搞定SIP注册与SM2国密认证
  • Python核心基础
  • 发现FinalBurn Neo:解锁经典街机游戏的终极模拟方案
  • 零成本!用AI打造你的第一款游戏Demo(2026保姆级教程)
  • 终极无线协议分析指南:用URH快速成为无线安全专家
  • Arm SME指令集:SMOP4S与SMOPS矩阵运算优化指南
  • STM32F103工程跨型号移植实战:从‘小钢炮’C8T6到‘大坦克’ZET6,资源升级全记录
  • 对抗性深度强化学习:自动驾驶碰撞避免算法的极限压力测试框架
  • ElevenLabs支持海南话吗?2024最新实测结果曝光:仅3.2%开发者知道的方言微调密钥
  • LVGL多语言界面实战:一个工程如何优雅管理中英文两套字体(含动态切换代码)
  • Python websocket-client事件回调全解析:从连接到关闭,一个不漏的保姆级指南
  • 基于i.MX8M Mini核心板的工业压力位移智能分析仪方案详解
  • 用FPGA和串口玩点不一样的:手把手教你实现PC传图到TFT屏实时显示(Vivado 2023.1)
  • 这种只有ISSN号没有CN号的期刊是否靠谱,能投吗?
  • 企业用车公司在线预约品牌该怎么选看这几点 - 资讯速览
  • 做网安的这几年,挖漏洞接私活赚的是我工资的3倍,这些门道没几人知道
  • 别再让治具压坏你的板子!手把手教你用TSK-64应力测试仪搞定ICT/FCT应力管控
  • 【全开源】跑腿小程序系统源码_智能派单_系统派单_同城配送_校园跑腿_预约取件_用户端
  • 【全开源】多功能完美运营版商城 虚拟商品全功能商城 全能商城小程序 智慧商城系统 全品类百货商城
  • 免费网盘直链解析神器:5分钟告别下载限速
  • 从一次EMC测试失败说起:RK3588产品设计中那些容易被忽略的PCB细节
  • 别光看手册了!手把手教你用STM32CubeMX + HAL库快速点亮STM32F429的第一盏灯
  • 避坑指南:在Ubuntu 20.04上从零配置华为昇腾MindX SDK与CANN 5.0.2的完整流程
  • 避坑!STM32CubeIDE偏好设置改了回不去?这份备份与恢复攻略请收好
  • 北京朱雀智能获客重磅升级:三大系统 + 百城基地,重构企业增长新范式 - 品牌企业推荐师(官方)
  • 2026年北京大数据精准获客服务商选型指南|SDK+DPI双技术驱动的B端增长破局 - 企业名录优选推荐
  • 外部表(EXTERNAL_TABLE)Hive 借用数据,删表不删数据