Prj08--8088单板机C语言8255读取按键码
1.验证结果
2.代码片
key_code=inp(PORT_8255_C)&0x0f;tiny_sprintf(buffer,"Key_code= 0X%x \r\n",key_code);uart_str_send(buffer);
3.完整代码
#include "tiny_stdarg.h" // 使用自定义可变参数实现#define ADR_273 0x0200
#define ADR_244 0x0400
#define LED_PORT 0x800
#define PC16550_THR 0x1f0
#define PC16550_LSR 0x1f5
/
//基本的IO操作函数
/
char str[]="Hello World! 20250531 Very Ok!!!\r\n";
//char buff[60]
char cx='A';
unsigned int cs_adr=0,ds_adr=0,ss_adr=0;/// @brief
/// @param addr
/// @param data
void outp(unsigned int addr, char data)
// 输出一字节到I/O端口{ __asm{ mov dx, addrmov al, dataout dx, al}}
char inp(unsigned int addr)
// 从I/O端口输入一字节{ char result;__asm{ mov dx, addrin al, dxmov result, al}return result;}void register_read(void){__asm{mov ax,CSmov cs_adr,axmov ax,DSmov ds_adr,axmov ax,SSmov ss_adr,ax}}//串口发送函数void uart_send(char x)
{int temp;while(1){temp=inp(PC16550_LSR);if((temp&0x20)==0x20){break;}}outp(PC16550_THR,x);}void uart_str_send(char *p)
{//int i=0;//char str1[20]="Hello World!\r\n";//char *p;//p=str1;while(*p!='\0'){uart_send(*p);p++;}/*for(i=0;i<14;i++){uart_send(str1[i]);}
*/}
///
/* sprintf()函数实现 */
/* tiny_sprintf.c */
#include "tiny_stdarg.h"static void itoa(unsigned num, int base, char *out) {char buf[6]; // 16位整数最大5位数字 + 结束符char *p = buf;int i = 0;if (num == 0) {*out++ = '0';*out = '\0';return;}while (num > 0) {int r = num % base;*p++ = (r < 10) ? (r + '0') : (r - 10 + 'a');num /= base;i++;}while (i-- > 0) {*out++ = *--p;}*out = '\0';
}int tiny_sprintf(char *buf, const char *fmt, ...) {va_list args;char *p = buf;const char *s = fmt;va_start(args, fmt);while (*s) {if (*s != '%') {*p++ = *s++;continue;}s++;switch (*s) {case 'd': {int num = va_arg(args, int);if (num < 0) {*p++ = '-';num = -num;}itoa(num, 10, p);while (*p) p++;s++;break;}case 'x': {unsigned num = va_arg(args, unsigned);itoa(num, 16, p);while (*p) p++;s++;break;}case 's': {char *str = va_arg(args, char *);while (*str) *p++ = *str++;s++;break;}case 'c': {char c = (char)va_arg(args, int);*p++ = c;s++;break;}case '%': {*p++ = '%';s++;break;}default: {*p++ = '%';*p++ = *s++;break;}}}*p = '\0';va_end(args);return p - buf;
}
///
//NMI 中断
//
/* NMI 计数器 */
volatile unsigned char nmi_count =10;
//设置中断失量表
void set_int(unsigned char int_no, void * service_proc){ _asm{ push esxor ax, axmov es, axmov al, int_noxor ah, ahshl ax, 1shl ax, 1mov si, axmov ax, service_procmov es:[si], axinc siinc simov bx, csmov es:[si], bxpop es}}
//中断处理函数
/*
void _interrupt near nmi_handler(void){nmi_count++;}*/
//
//8255
//
// 定义8255端口地址 (根据原理图译码确定)
#define PORT_8255_A 0x200 // PA端口地址
#define PORT_8255_B 0x201 // PB端口地址
#define PORT_8255_C 0x202 // PC端口地址
#define PORT_8255_CTRL 0x203 // 控制寄存器地址// 数码管段码表 (共阴极)
unsigned char seg_codes[] = {0x3F, // 00x06, // 10x5B, // 20x4F, // 30x66, // 40x6D, // 50x7D, // 60x07, // 70x7F, // 80x6F // 9
};// 延时函数
void delay(unsigned int ms) {for (unsigned int i = 0; i < ms; i++) {for (unsigned int j = 0; j < 100; j++) {// 空循环延时}}
}// 初始化8255
void init_8255() {// 控制字: 10000001 (0x81)// A口输出, B口输出, C口输出outp(PORT_8255_CTRL, 0x81);
}// 显示8位数字
void display_numbers() {unsigned char digits[] = {1, 2, 3, 4, 5, 6, 7, 8}; // 要显示的数字while (1) { // 按任意键退出for (int i = 0; i < 8; i++) {// 设置位选 (选中当前位)outp(PORT_8255_B, ~(1 << i));// 设置段码outp(PORT_8255_A, ~seg_codes[digits[i]]);// 延时保持显示delay(1);// 关闭当前位显示 (消除鬼影)outp(PORT_8255_A, 0x00);}}
}////char end_flag[5]={0x55,0x55,0x55,0x55,0x55};
extern void nmi_handler(void);
void main(void)
/*检测按键状态并由LED发光二极管显示,若按键闭合对应LED发光二极管点亮,若按键断开对应LED发光二极管灭.*/{ int i=0;char buffer[80];unsigned char key_code=0xff; // 使用安全格式化//tiny_sprintf(buffer, "Hex: %x\n",255);// 使用安全格式化tiny_sprintf(buffer, "Decimal: %d \n""Hex: %x \n""String: %s \r\n", -123, 0xABCD, "Hello");register_read(); //set_nmi_handler(); set_int(0x02, (void *)&nmi_handler);init_8255();while (1){//char button_state;//button_state=inp(ADR_244);//int i=0;//uart_str_send(str);uart_str_send(buffer);tiny_sprintf(buffer,"******************************************\r\n");uart_str_send(buffer);tiny_sprintf(buffer,"CS_ADR= 0X%x \r\n",cs_adr);uart_str_send(buffer);tiny_sprintf(buffer,"DS_ADR= 0X%x \r\n",ds_adr);uart_str_send(buffer);tiny_sprintf(buffer,"SS_ADR= 0X%x \r\n",ss_adr);uart_str_send(buffer);tiny_sprintf(buffer,"NMI Interrupt count=%x \r\n",nmi_count);uart_str_send(buffer);tiny_sprintf(buffer,"******************************************\r\n");uart_str_send(buffer);key_code=inp(PORT_8255_C)&0x0f;tiny_sprintf(buffer,"Key_code= 0X%x \r\n",key_code);uart_str_send(buffer);//uart_send(cx);for(i=0;i<5000;i++);for(i=0;i<5000;i++);outp(LED_PORT, 0xff);for(i=0;i<5000;i++);for(i=0;i<5000;i++);outp(LED_PORT, 0x00);//display_numbers();}}
char end_flag[5]={0x55,0x55,0x55,0x55,0x55};
4.项目进度
相关文章:

Prj08--8088单板机C语言8255读取按键码
1.验证结果 2.代码片 key_codeinp(PORT_8255_C)&0x0f;tiny_sprintf(buffer,"Key_code 0X%x \r\n",key_code);uart_str_send(buffer); 3.完整代码 #include "tiny_stdarg.h" // 使用自定义可变参数实现#define ADR_273 0x0200 #define ADR_244 0x…...

蜜獾算法(HBA,Honey Badger Algorithm)
2021年由Hashim等人提出(论文:Honey Badger Algorithm: A New Metaheuristic Algorithm for Solving Optimization Problems)。模拟蜜獾在自然界中的智能捕食行为,属于群体智能优化算法(与粒子群PSO、遗传算法GA同属一…...

Modbus转Ethernet IP网关助力罗克韦尔PLC数据交互
在工业自动化领域,Modbus协议是一种广泛应用的串行通信协议,它定义了主站和从站之间的通信规则和数据格式。罗克韦尔PLC是一种可编程的逻辑控制器,通过Modbus协议实现与其他设备之间的数据交互。然而,随着以太网技术的普及和发展&…...

飞算JavaAI 炫技赛重磅回归!用智能编码攻克老项目重构难题
深夜还在排查十年前Hibernate框架埋下的N1查询隐患?跨语言迁移时发现SpringMVC控制器里的业务逻辑像一团乱麻?当企业数字化进入深水区,百万行代码的老系统就像一座随时可能崩塌的"技术债冰山"。近日,飞算科技发布JavaAI…...
青少年编程与数学 02-020 C#程序设计基础 15课题、异常处理
青少年编程与数学 02-020 C#程序设计基础 15课题、异常处理 一、异常1. 异常的分类2. 异常的作用小结 二、异常处理1. 异常处理的定义2. 异常处理的主要组成部分3. 异常处理的作用小结 三、C#异常处理1. 异常的基本概念2. 异常处理的关键字3. 异常处理的流程4. 自定义异常5. 异…...
Electron打包前端和后端为exe
文章目录 什么是Electron? 安装electron过程 其他git项目地址比较好的文章electron的替代品安装报错 npm ERR! request to https://registry.npm.taobao.org/electron failed, reason: certificate has expired安装提示 npm WARN deprecated boolean3.2.0: Package …...
unix/linux,sudo,一个强大且灵活的工具,允许一个被授权的用户以另一个用户(通常是root,即超级用户)的身份来执行命令
sudo:不仅仅是“用管理员权限运行” sudo 这个词,来源于 SuperUser DO (或者 Substitute User DO,后者的含义更为广阔和准确)。它是一个强大且灵活的工具,允许一个被授权的用户以另一个用户(通常是root,即超级用户)的身份来执行命令。 1. Unix/Linux 的权限哲学:最小…...
JavaScript 二维数组初始化:为什么 fill([]) 是个大坑?
JavaScript 二维数组初始化:为什么 fill([]) 是个大坑? 今天刷leetcode的时候,遇到一个神奇的bug。 当我修改数组中的一个元素,却意外影响了其他所有元素???。 问题重现:诡异的数组…...
项目任务,修改svip用户的存储空间。
修改存储空间 3GB->5GB,这是项目任务,首先有人任务就要去思考实现思路,首先存储空间,也就是说不只是前端样式3GB改一下就可以了,那用户实际还是3GB,所以我们去网站看后端谁返回给我们了3GB,我…...
TypeScript 全面学习指南 (2025最新版)
TypeScript 全面学习指南 目录 TypeScript 简介环境搭建与工具基础类型变量声明接口(Interfaces)类(Classes)函数(Functions)泛型(Generics)枚举(Enums)类型…...
【redis】过期策略 懒惰删除
过期删除: redis会将所有设置过期时间的key以及过期时间存储在字典里。 redis采取两个策略实现删除过期key: 1、定时删除:定期扫描字典,采用贪心的策略,从字典随机抽20个key,删除其中已经过期的key&#x…...
Docker或Docker-Compose时间时区配置
Docker或Docker-Compose配置时区,主要是为了使用容器内的时间和物理机操作系统的时间保持一致。以下是集中配置Docker或Docker-Compose环境时间时区的方式。 Dockerfile(Docker)中配置时区 在Dockerfile中,可以通过如下方式添加…...
如何在IDE中通过Spark操作Hive
在IDE中通过Spark操作Hive是一项常见的任务,特别是在大数据处理和分析的场景中。本文将详细介绍如何在集成开发环境(IDE)中使用Apache Spark与Hive进行交互,包括必要的设置、代码示例以及详细解释。 环境准备 在开始之前&#x…...

ToolsSet之:XML工具
ToolsSet是微软商店中的一款包含数十种实用工具数百种细分功能的工具集合应用,应用基本功能介绍可以查看以下文章: Windows应用ToolsSet介绍https://blog.csdn.net/BinField/article/details/145898264 ToolsSet中Text菜单下的XML Tool工具是一个Xml工…...

keepalived定制日志bug
keepalived定制日志bug 源码安装apt安装endl 源码安装 在/etc/rsyslog.d/目录下创建 keepalived的日志配置文件keepalived.conf [rootubuntu24-13:~]# vim /etc/rsyslog.d/keepalived.conf [rootubuntu24-13:~]# cat /etc/rsyslog.d/keepalived.conf local6.* /var/log/keepa…...
ElasticSearch+Gin+Gorm简单示例
更多个人笔记见: (注意点击“继续”,而不是“发现新项目”) github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note gitee 个人笔记仓库 https://gitee.com/harryhack/it_note 个人学习,学习过程中还会不断补充&…...

数据库系统概论(十三)详细讲解SQL中数据更新(插入,修改与更新)
数据库系统概论(十三)详细讲解SQL中数据更新 前言一、数据插入1. 插入数据是什么?2.插入单条数据(插入元组)场景 1:指定部分列插入场景 2:不指定列名(插入所有列)场景 3&…...
JVMTI 在安卓逆向工程中的应用
JVMTI 在安卓逆向工程中的应用 JVMTI 在安卓逆向工程中扮演着重要角色,尤其是在分析和修改 Java 层应用行为时。以下是其核心应用场景、实现方式及典型工具: 一、核心应用场景 1. 动态代码注入与 hook 通过 JVMTI 可以在运行时修改或拦截 Java 方法&…...

极客时间-《搞定音频技术》-学习笔记
极客时间-《搞定音频技术》-学习笔记 语音基础知识 https://www.zhangzhenhu.com/audio/feature.html 序章-0 作者说这个语音技术啊,未来肯定前景大好啊,大家都来学习,然后给出了课程的脑图 音频基础 什么是声音 声音的三要素是指响度、…...

网络攻防技术十三:网络防火墙
文章目录 一、网络防火墙概述1、网络型防火墙(网络防火墙)2、Web应用防火墙3、数据库防火墙4、主机防火墙(个人防火墙)5、网络防火墙的功能 二、防火墙工作原理1、无状态包过滤防火墙2、有状态包过滤防火墙(状态检测/动…...

Express 集成Sequelize+Sqlite3 默认开启WAL 进程间通信 Conf 打包成可执行 exe 文件
代码:express-exe: 将Express开发的js打包成exe服务丢给客户端使用 实现目标 Express 集成 Sequelize 操作 Sqlite3 数据库; 启动 Sqlite3 时默认开启 WAL 模式,避免读写互锁,支持并发读; 利用 Conf 实现主进程与 Ex…...
CppCon 2015 学习:A C++14 Approach to Dates and Times
Big Picture — 日期库简介 扩展 标准库 这个库是对 C 标准库中 <chrono> 的自然延伸,专注于处理“日历”相关的功能(比如年月日、闰年、节假日等),而不仅仅是时间点和时长。极简设计 它是**单头文件(header-on…...
基于CNN的OFDM-IM信号检测系统设计与实现
基于CNN的OFDM-IM信号检测系统设计与实现 摘要 本文详细研究了基于卷积神经网络(CNN)的正交频分复用索引调制(OFDM-IM)信号检测方法。通过在不同信噪比(SNR)和信道条件下进行系统仿真,对比分析了CNN检测器与传统最大似然(ML)检测器的误码率(BER)性能和计算复杂度。实验结果表…...
macos常见且应该避免被覆盖的系统环境变量(避免用 USERNAME 作为你的自定义变量名)
文章目录 macos避免用 USERNAME 作为你的自定义变量名macos常见且应该避免被覆盖的系统环境变量 macos避免用 USERNAME 作为你的自定义变量名 问题: 你执行了:export USERNAME“admin” 然后执行:echo ${USERNAME} 输出却是:xxx …...

2024年认证杯SPSSPRO杯数学建模D题(第二阶段)AI绘画带来的挑战解题全过程文档及程序
2024年认证杯SPSSPRO杯数学建模 D题 AI绘画带来的挑战 原题再现: 2023 年开年,ChatGPT 作为一款聊天型AI工具,成为了超越疫情的热门词条;而在AI的另一个分支——绘图领域,一款名为Midjourney(MJÿ…...
深入理解CSS常规流布局
引言 在网页设计中,理解元素如何排列和相互作用至关重要。CSS提供了三种主要的布局方式:常规流、浮动和定位。本文将重点探讨最基础也是最常用的常规流布局(Normal Flow),帮助开发者掌握页面布局的核心机制。 什么是…...

DOCKER使用记录
1、拉取镜像 直接使用docker pull <image>,大概率会出现下面的报错信息: (base) jetsonyahboom:~$ docker pull ubuntu:18.04 Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while …...
MYSQL中常见的函数和使用
字符串函数 CONCAT(str1,str2,...,strN) :用于将多个字符串连接成一个字符串。例如,SELECT CONCAT(SQL, , 函数) ,结果为 “SQL 函数”。 LOWER(str) :将字符串中的所有字母转换为小写。例如,SELECT LOWER(MySQL Fun…...

【深度学习相关安装及配环境】Anaconda搭建虚拟环境并安装CUDA、cuDVV和对应版本的Pytorch,并在jupyter notebook上部署
目录 1. 查看自己电脑的cuda版本2.安装cuda关于环境变量的配置测试一下,安装完成 3.安装cuDVV环境变量的配置测试一下,安装完成 4.创建虚拟环境先安装镜像源下载3.11版本py 5.在虚拟环境下,下载pytorch6.验证是否安装成功7.在jupyter noteboo…...

web3-区块链基础:从区块添加机制到哈希加密与默克尔树结构
区块链基础:从区块添加机制到哈希加密与默克尔树结构 什么是区块链 抽象的回答: 区块链提供了一种让多个参与方在没有一个唯一可信方的情况下达成合作 若有可信第三方 > 不需要区块链 [金融系统中常常没有可信的参与方] 像股票市场,或者一个国家的…...