NO9 蓝桥杯单片机串口通信之进阶版

1 回顾

串口通信的代码编写结构还是与中断一样,不同的是:

初始中断函数条件涉及到串口通信相关的寄存器和定时器1相关的寄存器(定时器1用于产生波特率),但初始条件中的中断寄存器只考虑串口通信而不考虑定时器1。

void  函数名()

{

包含两部分寄存器:定时器1+串口通信

定时器1: TMOD (选择模式),TH1和TL1(初始计时寄存器),TR1(TCON寄存器里的启动计时按钮)

串口通信:SCON(总的来说功能是模式选择),AUXR(辅助寄存器),中断开关(分开关+总开关)

}

void  函数名() interrupt  中断号

{

就是写时间到后执行什么。注意中断号要写串口通信的,而不是定时器的,因为定时器作用只是产生波特率而不是产生中断。

}

2 C语言字符串知识补充:

字符串的C语言知识发现自己还不是很懂,就简单写一下。

常用的有两种,一种是字符串常量,一种是字符串数组。

判断字符串中止的标志是“\0 ”,表示NULL。

2.1 字符串常量

公式:char  *(+指针名称如A)= “ 字符串常量内容”

表示在A指针所对应的往下连续地址中,储存字符串常量。

char *message = "Hello World!";// 上面的语句也可以拆分成下面两句
char *message;
message = "Hello World!";

2.2 字符串数组

char charArray[] = {'H','e','l','l','o'};    // 声明并初始化一个字符数组
char charArray[] = "Hello World!"; 

以上参考以下帖子,详情可点击进去查看。

C语言 -- 字符串详解 - 知乎 (zhihu.com)

3 实践

3.1 任务

3.2 思路

读题目是串口通信———那么就要写串口通信的结构

采用8位UART模式,波特率9600--------这些条件就可以确定串口通信结构的中断初始函数怎么写(NO9串口通信实践的另一篇有详细说明这里就不再赘述)

void Init_uart()
{TMOD = 0x20;TH1 = 0xfd;TL1 = 0xfd;TR1 = 1;AUXR = 0x00;SCON = 0x50;ES = 1;EA = 1;}

要上上位机发送,故要写一个发送函数,又是字符串,那么就要利用2的字符串知识补充来写

这里字符串是一个字符接一个字符来发的(但速度较快看起来就是一下子发了出来),而 while(*str != '\0') 是判断字符串是否发完了,如果没发完,那么字符串的指针就加1,即一个一个字节来发。

void SentByte(unsigned char dat)
{SBUF = dat;while(TI == 0);TI = 0;
}void SentString(unsigned char *str)
{while(*str != '\0'){SentByte(*str++);}}

通过串口发送的接收命令来进行控制操作,那么就需要一个收的操作,并且还要写一个函数来判断并执行不同命令。

这里就主要将以下这个判断命令的思路。

命令分三种,是0xa_ , 0xb_ ,和0xc0,a,b,c来判断哪一种命令,低四位则代表这种命令的相关操作。

首先就要区别abc哪一种命令,这里可以用command来储存收到的命令,用command & 0xf0 来判断是a还是b还是c,与上0xf0,即是保留command高四位去掉低四位,那么command要么是0xa0要么是0xb0要么是0xc0,然后再用一个switch-case来存放三种命令的情况。

case里面放置三种命令的具体执行。

case(0xa0):是要用command的低四位去控制灯(L1~L4),注意这里1是开灯,0是关灯。(而单片机本身是0才亮灯。)

这里用这个公式来执行此命令: P0 = ~(command & 0x0f);  break;

分析:command先与上0x0f,表示command高四位清零,低四位保留,然后在取反。

比如 command = 0xa3(1010 0011),表示L1和L2点亮。

1010 0011   

                    & 

0000 1111

                     =

0000 0011

然后~(0000 0011) = 1111 1100, 而在单片机上恰好和命令相反是0时灯才亮,所以就完成了。

(注意,判断哪种命令时使用了command&0xf0,并没有改变command的值,因为它是在switch条件里的switch(command & 0xf0)的操作,而不是command = command &0xf0,所以这里并没有改变command的值。)

case(0xb0):这里就不再解释0xb0了,和0xa0的操作思路差不多。

case(0xc0):此命令是发送字符串,那么就用到了写的sentByte函数,注意这里发送完后command要清零,不然就会循环发送字符串。

unsigned char dat;
unsigned char command = 0x00;
void Service_uart() interrupt 4
{if (RI == 1)       收操作{command = SBUF;RI =0;}}void Working()      判断并执行命令
{if(command != 0x00){switch(command & 0xf0){case(0xa0):P0 = ~(command & 0x0f);  break;case(0xb0):P0 = ~((command & 0x0f)<<4);  break;case(0xc0):SentString("The system is running...\n"); command = 0x00; break;    }}
}

3.3 完整代码

#include "stc15f2k60s2.h"void selectHC138(unsigned int n)
{switch(n){case 0:P2 = (P2 & 0x1f) | 0x00;  break;case 1:P2 = (P2 & 0x1f) | 0x20;  break;case 2:P2 = (P2 & 0x1f) | 0x40;  break; case 3: P2 = (P2 & 0x1f) | 0x60;  break; case 4:P2 = (P2 & 0x1f) | 0x80;  break; case 5:P2 = (P2 & 0x1f) | 0xa0;  break; case 6:P2 = (P2 & 0x1f) | 0xc0;  break; case 7:P2 = (P2 & 0x1f) | 0xe0;  break;}
}
//==================================
void Init_uart()
{TMOD = 0x20;TH1 = 0xfd;TL1 = 0xfd;TR1 = 1;AUXR = 0x00;SCON = 0x50;ES = 1;EA = 1;}unsigned char dat;
unsigned char command = 0x00;
void Service_uart() interrupt 4
{if (RI == 1){command = SBUF;RI =0;}}void SentByte(unsigned char dat)
{SBUF = dat;while(TI == 0);TI = 0;
}void SentString(unsigned char *str)
{while(*str != '\0'){SentByte(*str++);}}void Working()
{if(command != 0x00){switch(command & 0xf0){case(0xa0):P0 = ~(command & 0x0f);  break;case(0xb0):P0 = ~((command & 0x0f)<<4);  break;case(0xc0):SentString("The system is running...\n"); command = 0x00; break;    }}
}//===============================void close()
{selectHC138(5);P0 = 0x00;selectHC138(4);P0 = 0xff;
}void main()
{close();Init_uart();SentString("Welcome to system!\n");while(1){Working();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/772632.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot+vue+Mysql的网上图书商城

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

多功能的RSS工具RSS Funnel

什么是 RSS Funnel &#xff1f; RSS Funnel 是一个模块化的 RSS 处理管道系统。它可以以多种方式操作 RSS/Atom 源。 例如&#xff1a; 提取完整内容从 HTML 页面生成 RSS 订阅删除不需要的元素和文本使用正则表达式进行文字编辑或替换保留或删除与关键词或模式匹配的文章突出…

微服务篇:设计一个注册中心和配置中心需要从哪些方面入手

注册中心 设计一个注册中心时&#xff0c;需要关注多个关键方面&#xff0c;以确保其稳定性、可靠性、性能和可扩展性。以下是一些重要的考虑因素&#xff1a; 服务发现机制&#xff1a;注册中心的核心功能是允许服务相互发现。这意味着当一个服务实例启动时&#xff0c;它需…

2024年【熔化焊接与热切割】考试报名及熔化焊接与热切割找解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 熔化焊接与热切割考试报名考前必练&#xff01;安全生产模拟考试一点通每个月更新熔化焊接与热切割找解析题目及答案&#xff01;多做几遍&#xff0c;其实通过熔化焊接与热切割实操考试视频很简单。 1、【单选题】 下…

SE注意力模块学习笔记《Squeeze-and-Excitation Networks》

Squeeze-and-Excitation Networks 摘要引言什么是全局平均池化&#xff1f; 相关工作Deep architectures Squeeze-and-Excitation Blocks3.1. Squeeze: Global Information Embedding3.2. Excitation: Adaptive Recalibration3.3. Exemplars: SE-Inception and SE-ResNet 5. Im…

docker部署nacos(单机与集群)

拉去nacos镜像 [rootlocalhost keepalived]# docker search nacos NAME DESCRIPTION STARS OFFICIAL nacos/nacos-server This project contains a Docker image meant t… 464 …

2024.3.26学习笔记

今日学习韩顺平java0200_韩顺平Java_对象机制练习_哔哩哔哩_bilibili 今日学习p273-p285 包 包的本质实际上就是创建不同的文件夹/目录来保存类文件 包的三大作用 区分相同名字的类 当类很多时&#xff0c;可以很好的管理类 控制访问范围 包的基本语法 package com.xx…

物理研究思想(1)——朗道力学第一版序

朗道是苏联的全才式科学家&#xff0c;大科学家的这篇序言值得我们搞研究的人仔细研读&#xff0c;如果能够参透&#xff0c;必将受益终生&#xff01; 众所周知&#xff0c;物理学是由实验物理和理论物理两个学科组成的.我们已知的大量物理定律可以由为数不多的最一般规律推演…

出席2024亚太内容分发大会,火山引擎边缘云“加速”游戏体验升级

3月26日&#xff0c;第十四届亚太内容分发大会暨CDN峰会在北京成功举办&#xff0c;火山引擎边缘云产品架构高级总监许思安出席并以《火山引擎边缘云游戏行业解决方案&#xff0c;“加速”游戏体验升级》为主题&#xff0c;分享了火山引擎边缘云在游戏行业的思考和实践。同时&a…

面试经典150题【91-100】

文章目录 面试经典150题【91-100】70.爬楼梯198.打家劫舍139.单词拆分322.零钱兑换300.递增最长子序列77.组合46.全排列39.组合总和&#xff08;※&#xff09;22.括号生成79.单词搜索 面试经典150题【91-100】 五道一维dp题五道回溯题。 70.爬楼梯 从递归到动态规划 public …

前端理论总结(js)——filter、foearch、for in 、for of 、for的区别以及返回值

Filter&#xff1a; 用途&#xff1a;用于筛选数组中符合条件的元素&#xff0c;返回一个新数组。 返回值&#xff1a;返回一个新数组&#xff0c;包含经过筛选的元素。 Foreach&#xff1a; 用途&#xff1a;遍历数组中的每个元素&#xff0c;执行回调函数。 返回值&#x…

idea中Git项目遇到“Filename too long”错误 与 配置Git的ssh证书

一&#xff1a;“Filename too long”问题解决办法 错误信息&#xff1a; fatal: cannot create directory at xxxx: Filename too long warning: Clone succeeded, but checkout failed. You can inspect what was checked out with git status and retry with git restore …

24/03/26总结

面向对象练习题&#xff1a;&#xff08;封装&#xff0c;继承&#xff0c;多态) 封装&#xff1a;对象代表什么&#xff0c;就得封装对应的数据&#xff0c;并提供数据对应的行为,(把零散的数据和行为封装成一个整体&#xff1a;也就是我们说的对象&#xff09; 继承:当封装…

latex中的算法algorithm报错Undefined control sequence.

这里写目录标题 1. 错误原因2. 进行改正3. 爱思唯尔期刊与施普林格期刊对于算法的格式不太一样&#xff0c;不能直接套用总结 1. 错误原因 我在算法中使用\State 2. 进行改正 换成\STATE 3. 爱思唯尔期刊与施普林格期刊对于算法的格式不太一样&#xff0c;不能直接套用 总…

多线程执行一半后不往后走的坑

场景简单演示 首先演示一个简单的场景。 采用ThreadPoolExecutor提交线程的方式&#xff0c;直接在多线程中执行的某个地方抛出一个异常。 用submit方法提交的情况&#xff1a; 调用的地方&#xff1a; 发现一直卡在那&#xff0c;没有任何错误日志。 改成execute方法提交多…

优秀电源工程师需要的必备技能

随着电源市场的不断扩张,开关电源行业飞速发展,企业对电源工程师的需求日益增加,对电源工程师的技能要求也日渐提高,相信没有一位电源工程师会错过让自己变得更优秀的机会。作为一名数字电源从业者,今天就带大家细数一下优秀电源工程师具备的那些技能。 一、新手必备课程…

#GIT|Git Flow#Gitflow工作流程

Gitflow是一种使用功能分支和多个主分支的Git分支模型&#xff0c;它适用于有预定发布周期的项目&#xff0c;也适用于DevOps最佳实践中的持续交付。这个工作流程不会添加任何新的概念或命令&#xff0c;而是为不同的分支分配了非常具体的角色&#xff0c;并定义了它们应该如何…

大历史下的 pacing:why how

卸载一切到网卡&#xff0c;解放 cpu&#xff0c;兜售自己的设想&#xff1a;功能越来越多&#xff0c;吞吐越来越大的网卡。万物皆关联&#xff0c;吞吐越大的网卡反而更闯祸。范雅各布森的大历史视野不是每个工程师都具备的&#xff0c;更何况经理们。 事实是&#xff0c;网…

串口通信标准RS232 RS485 RS422的区别

RS-232、RS-422、RS-485是关于串口通讯的一个机械和电气接口标准&#xff08;顶多是网络协议中的物理层&#xff09;&#xff0c;不是通讯协议&#xff0c;它们之间的几个不同点如下&#xff1a; 一、硬件管脚接口定义不同 二、工作方式不同 RS232&#xff1a; 3线全双工 RS…

vue3使用clipboard.js

一、安装 npm install --save vue-clipboard3二、引入 import useClipboard from vue-clipboard3;const { toClipboard } useClipboard();三、使用 const copy async (val) > {try {await toClipboard(val);//成功要做的事 console.log(复制成功!)} catch (e) {console.l…