51单片机第12步_使用stdio.h库函数仿真串口通讯
本章介绍如何使用stdio.h库函数仿真串口通讯,学会使用view下面的“serial window #1”,实现模拟串口通讯。
Keil C51中有一些关键字,需要牢记:
interrupt0:指定当前函数为外部中断0;
interrupt1:指定当前函数为定时器0中断;
interrupt2:指定当前函数为外部中断1;
interrupt3:指定当前函数为定时器1中断;
interrupt4:指定当前函数为串口中断;
using 0表示当前函数使用第0组寄存器;
using 1表示当前函数使用第1组寄存器;
using 2 表示当前函数使用第2组寄存器;
using 3 表示当前函数使用第3组寄存器;
51单片机内有4个工作组寄存器,每个工作组的寄存器是R0--R7。
R0-R7在数据存储器里的实际地址是由特殊功能寄存器PSW里的RS1、RS0位决定的。
using 0表示设置 RS1=0,RS0 =0,用第0组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(00H)....R7(07H);
using 1表示设置 RS1=0,RS0 =1,用第1组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(08H)....R7(0FH);
using 2表示设置 RS1=1,RS0 =0,用第2组寄存器,R0--R7的在数据存储区里的实际地址是08H-0FH。R0(10H)....R7(17H);
using 3表示设置 RS1=1,RS0 =1,用第3组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(18H)....R7(1FH);
#include <REG51.h> //包含头文件REG51.h,使能51内部寄存器;
#include <intrins.h> //包含头文件intrins.h,要放在stdio.h的头文件之前;
//使能函数: _nop_(); 相当于汇编的NOP指令;
//使能函数: bit _testbit_( bit bit_value ); 对bit_value进行测试,若bit_value=1,返回1,否则返回0;
//使能函数: _cror_( unsigned char x, unsigned char n ); 将字节型变量x的值,向右循环移动n位,然后将其
//值返回;
//使能函数: _iror_( unsigned int x, unsigned char n ); 将双字节型变量x的值,向右循环移动n位,然后将
//其值返回;
//使能函数: _lror_( unsigned long x, unsigned char n ); 将4字节型变量x的值,向右循环移动n位,然后将
//其值返回;
//使能函数: _crol_( unsigned char x, unsigned char n ); 将字节型变量x的值,向左循环移动n位,然后将其
//值返回;
//使能函数: _irol_( unsigned int x, unsigned char n ); 将双字节型变量x的值,向左循环移动n位,然后将
//其值返回;
//使能函数: _lrol_( unsigned long x, unsigned char n ); 将4字节型变量x的值,向左循环移动n位,然后将
//其值返回;
//以上的循环左移和循环右移,同C语言的左移和右移是不同的,使用时要小心;
#include <stdio.h> //包含头文件stdio.h
//_getkey();从串口读入一个字符;
//putchar();向串口发送一个字节;
//printf();向串口发送一串字节;
#define OSC_FREQ 11059200L
#define BAUD_Time 1
#if(BAUD_Time==1)
//若波特率加倍,则使用下面参数;
#define BAUD_57600 256 - (OSC_FREQ/192L)/57600L //255
#define BAUD_28800 256 - (OSC_FREQ/192L)/28800L //254
#define BAUD_19200 256 - (OSC_FREQ/192L)/19200L //253
#define BAUD_14400 256 - (OSC_FREQ/192L)/14400L //252
#define BAUD_9600 256 - (OSC_FREQ/192L)/9600L //250
#define BAUD_4800 256 - (OSC_FREQ/192L)/4800L //244
#define BAUD_2400 256 - (OSC_FREQ/192L)/2400L //232
#define BAUD_1200 256 - (OSC_FREQ/192L)/1200L //208
#else
//若波特率不加倍,则使用下面参数;
#define BAUD_9600 256 - (OSC_FREQ/384L)/9600L
#define BAUD_4800 256 - (OSC_FREQ/384L)/4800L
#define BAUD_1200 256 - (OSC_FREQ/384L)/1200L
#endif
#define receive_buffer_size 40
unsigned char receive_buffer[receive_buffer_size];
unsigned char next_in,next_out;
//函数功能:接收和发送中断服务函数;
void isr_UART(void) interrupt 4 using 1
{ unsigned char temp;
if(RI) //处理接收数据;
{ temp=_getkey(); //从串口接收一个字节;
receive_buffer[next_in++]=temp;
if(next_in==receive_buffer_size) next_in=0;
}
}
//函数功能:初始化串口,设置波特率为9600bps@11.0592MHz,使能接收,使用8位UART,开中断允许;
void Serial_Port_Initialization()
{ PCON = 0x80;
SCON=0x50; //串行控制寄存器: SM0,SM1,SM2,REN,TB8,RB8,TI,RI
//SM1:SM0=01,选择方式1,SM2=0,表示非多机通讯,8-bit UART;
//REN=1,使能接收;
TMOD&=0x0f;
TMOD|= 0x20;
//定时器方式控制寄存器:GATE1,C/T1,M11,M10,GATE0,C/T0,M01,M00
//GATE=0,TR置1便可以启动Timer;GATE=1,TR置1,且INT脚输入高电平,才可以启动Timer;
//M11:M10=10,选择方式2,8位自动重装载;
TH1=BAUD_9600; //TH1: reload value for 9600 baud @11.0592MHz;
TL1=TH1;
TR1=1; //启动Timer1;
//TI=1; //发送UART的第一个字节,为下次发送做准备;
TI=0; //为下次发送做准备;
RI=0;
next_in=0;
next_out=0;
ES=1; //使能串口接收和发送中断;
EA=1; //开总中断
}
//函数功能: 将接收到的数据返回给PC;
void send_data_to_pc()
{ while(next_out!=next_in) //将接收到的数据返回给PC;
{ TI=1; //为调用printf()和putchar()内部函数做准备;
printf("receive_buffer[%bd]=%c\n",next_out,receive_buffer[next_out]);
TI=0; //结束调用printf()和putchar()内部函数
next_out++;
}
}
//函数功能: Delay 50us
void delay_50us(unsigned char _50us)
{ while(_50us--)
{ _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
void main(void)
{ Serial_Port_Initialization();
//初始化串口,设置波特率为9600bps@11.0592MHz,使能接收,使用8位UART,开中断允许;
TI=1; //为调用printf()和putchar()内部函数做准备;
printf("Start:\n");
TI=0; //结束调用printf()和putchar()内部函数
for(;;)
{ _getkey(); //打开view下面的serial window #1,用键盘输入一个字符;
send_data_to_pc(); //将接收到的数据返回给PC;
delay_50us(20); //延时1ms;
TI=0; //结束调用printf()和putchar()内部函数
}
}
相关文章:
51单片机第12步_使用stdio.h库函数仿真串口通讯
本章介绍如何使用stdio.h库函数仿真串口通讯,学会使用view下面的“serial window #1”,实现模拟串口通讯。 Keil C51中有一些关键字,需要牢记: interrupt0:指定当前函数为外部中断0; interrupt1:指定当前函数为定时器0中断&…...
simulink-esp32开发foc电机
1. ESP32 和 STM32 都是流行的微控制器,但它们的刷写方式有所不同。 ESP32 ESP32 可以通过以下几种方式刷写: USB 下载模式:这是最常见的一种刷写方式。将 ESP32 连接到计算机的 USB 端口,然后将 ESP32 置于下载模式。可以使用…...
Python教程--基本技能
】TOC 5.1 解析命令行参数 在Python中,解析命令行参数是一项常见的任务,尤其是在开发命令行工具或脚本时。Python标准库提供了argparse模块,它可以帮助你轻松地编写用户友好的命令行接口。下面是使用argparse模块解析命令行参数的基本步骤&…...
干货分享:Spring中经常使用的工具类(提示开发效率)
环境:Spring5.3…30 1、资源工具类 ResourceUtils将资源位置解析为文件系统中的文件的实用方法。 读取classpath下文件 File file ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX "logback.xml") ; // ...读取文件系统文件 file Resou…...
一文讲懂npm link
前言 在本地开发npm模块的时候,我们可以使用npm link命令,将npm 模块链接到对应的运行项目中去,方便地对模块进行调试和测试 用法 包链接是一个两步过程: 1.为依赖项创建全局软链npm link。一个符号链接,简称软链&a…...
观成科技:证券行业加密业务安全风险监测与防御技术研究
摘要:解决证券⾏业加密流量威胁问题、加密流量中的应⽤⻛险问题,对若⼲证券⾏业的实际流量内容进⾏调研分析, 分析了证券⾏业加密流量⾯临的合规性⻛险和加密协议及证书本⾝存在的⻛险、以及可能存在的外部加密流量威 胁,并提出防…...
使用Swoole开发高性能的Web爬虫
使用swoole开发高性能的web爬虫 Web爬虫是一种自动化获取网络数据的工具,它可以在互联网上收集数据,并且可以被应用于各种不同的领域,如搜索引擎、数据分析、竞争对手分析等。随着互联网规模和数据量的快速增长,如何开发一个高性…...
【Elasticsearch】Elasticsearch索引创建与管理详解
文章目录 📑引言一、Elasticsearch 索引的基础概念二、创建索引2.1 使用默认设置创建索引2.2 自定义设置创建索引2.3 创建索引并设置映射 三、索引模板3.1 创建索引模板3.2 使用索引模板创建索引 四、管理索引4.1 查看索引4.2 更新索引设置4.3 删除索引 五、索引别名…...
[数据集][目标检测]棉花检测数据集VOC+YOLO格式389张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):389 标注数量(xml文件个数):389 标注数量(txt文件个数):389 标注类别…...
使用Java实现实时数据处理系统
使用Java实现实时数据处理系统 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 引言 在当今信息爆炸的时代,实时数据处理系统变得越来越重要。无论…...
整合web-socket的常见bug
整合文章连接 此文是记录我上网查找整合方案时候踩的坑,特别是注册失败的问题,比如还有什么去掉Compoent就可以,但是这样这个端点就失效了 特别是报错: at org.springframework.web.socket.server.standard.ServerEndpointExporter.registerEndpoint(ServerEndpointExporter.…...
Python 中字符串的常用操作都有哪些?
在 Python 中字符串的表达方式有四种 一对单引号 一对双引号 一对三个单引号 一对三个双引号 a ‘abc’ b “abc” c ‘’‘abc’’’ d “”“abc”"" print(type(a)) # <class ‘str’> print(type(b)) # <class ‘str’> print(type©) # <…...
FFmpeg 硬件编码加速文档介绍
介绍 硬件访问:许多平台提供了对专用硬件的访问,这些硬件可以用于执行解码、编码或过滤等视频相关操作。 性能与资源使用:使用硬件可以加快某些操作的速度或减少其他资源(特别是CPU)的使用,但可能会产生不同的结果或质量较低,或带来在使用纯软件时不存在的额外限制。 硬…...
【Matlab函数分析】imread从图形文件读取图像
🔗 运行环境:Matlab 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 #### 防伪水印——左手の明天 #### 💗 大家好🤗ᾑ…...
零基础光速入门AI绘画,SD保姆攻略
前言 大家好,我是AI绘画咪酱。一名AIGC狂热爱好者,目前正在AI绘画领域进行深入的探索。 我花了一个月时间把SD研究了一遍,秉持着用有趣、易懂的文字让小白也可以零基础光速使用SD(stable diffusion)入门AI绘画&#…...
详细配置SQL Server的链接服务器(图文操作Mysql数据库)
目录 前言1. MySQL ODBC 驱动2. 配置 SQL Server 链接服务器3. 彩蛋前言 此处配置以及安装没有什么理论知识 所以直奔主题,跟着以下步骤配置安装即可 需求:准备在10.197.0.110中链接外部的10.197.0.96的mysql数据源 已默认在10.197.0.96中安装了MySQL数据库并且知道其连接信…...
DDD学习笔记五
模型引力场:聚合 强作用力体现: 某个领域模型是另一些模型存在的前提,没有前者,后者就失去了生存的意义。 一组领域模型之间存在关联的领域逻辑,任何时候都不能违反。 一组领域模型必须以一个完整的、一致的状态呈现给…...
CAN报文的发送类型-OnChange、OnWrite、IfActive、Repetition
CAN报文的发送类型分为基本发送类型和混合发送类型两大类 CAN基本发送类型包括Cyclic周期发送、OnChange变化时发送、OnWrite写入时发送和IfActive有效时发送。基本发送类型中的Cyclic称为周期型,而其他3个类型称为事件型(Event)。发送次数是通过定义Repetition重复次数来实…...
神经网络在机器学习中的应用:手写数字识别
机器学习是人工智能的一个分支,它使计算机能够从数据中学习并做出决策或预测。神经网络作为机器学习的核心算法之一,因其强大的非线性拟合能力而广泛应用于各种领域,包括图像识别、自然语言处理和游戏等。本文将介绍如何使用神经网络对MNIST数…...
QT拖放事件之四:自定义拖放操作-利用QDrag来拖动完成数据的传输-案例demo
1、核心代码 #include "Widget.h" #include "ui_Widget.h" #include "MyButton.h"Widget::Widget(QWidget *parent): QWidget...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
