学好单片机,看懂这个就够了
五年之前
那是在大学期间,距离现在大约有4年了吧,教我们单片机的老师要离我们而去了,因为她要去她的城市教书去了。怎么形容她呢?那是一个风度翩翩,很有才华、做事很干练不像老师的女老师。她走的时候要搬行李,我们几个学习成绩好的一块去送的她,可能是送别的时候都爱下雨吧,那天也不例外,下起了绵绵小雨,在送老师走的时候,我问的也是这个问题:“我看我们现在的教科书如同看天书,有什么好的书籍推荐吗?”老师只是很随性的一笑,说:”我们现在用的这一本书就不错,单片机之类的书都大同小异“,当时也并没有深究,我们当时用的就是标准的规中规矩的教科书,名字叫做《XXXXX基础》,具体名字就不说了,免得被当广告。
五年之后
现在想想当时老师所说的,完全就是我现在所想的,在五年之前真不晓得思想会有这样的转变,归根到底是我对51单片机深刻的理解,还有自己的工作经验和积淀,你让我推荐学习单片机的书籍,别说几本了,就是几十本,我都能给你脱口而出,像郭天祥的《51单片机C语言教程》,还有其他的《51单片机项目教程》、《实例解读51单片机完全学习与应用》等等、这些都是不错的单片机教程书,我也全都读过,如果你让我就给你推荐一本,那么很抱歉,我是真不知道哪一本更好一些,根本原因是这些书都是根据51单片机的官方数据手册所编写的,你以为那些作者凭空就能出书?关于单片机所有的用法数据手册上都解释清楚了,对于刚入门的同学可能不适应,但数据手册是最具有权威的参考资料,像我现在工作的书柜上关于专业的书很少有了,为什么呢?现在有哪里不清楚的都是去访问他的电子版的数据手册,关于51单片机的数据手册我也都给你们打包到云端了,私信笔者“数据手册”,收到之后秒回信息。
数据手册?
至于是看书还是数据手册,这得取决于你,如果你只是想玩玩,那么从我上面推荐的书里面随便选择一本对你来说就足够了,如果你以后想从事半片机的工作,读那些作者编著的书是远远不够的,或许书上已经把你要知道的已经很清楚了,但如果换一个单片机,我敢保证你照样一头雾水,唯有我们掌握了单片机的数据手册,再去读别的单片机的数据手册,你会发现都是一个套路,比如你对51单片机的数据手册已经了然于胸,我现在让你用STM32写代码,这时候我们打开STM32的数据手册写程序对我们来说是信手沾来的。
比51更优的选择
如果你是从来没有接触过单片机的新手,或许Arduino比51更适合你,为什么这么说呢?曾经带过一个要学习单片机的新人,本来他是对单片机不感兴趣的,为了让他对电子提起兴趣,我就是让他学的Arduino做的项目,不到一个星期,教会了他点亮LED、中断、红外、舵机、自动寻迹小车、WiFi小车等一系列高级项目,要知道这些在51上做出来至少得花费半年的时间。在中国提起Arduino,更多的人对他的映像是不专业,或者建高楼于浮沙,他们这么说不是没有道理,这只是因为Arduino把软件和硬件整合的天衣无缝,比如他的单片机的引脚,还有他的库编写的简洁至极。可以这么比喻,51是手动挡的汽车的话,那么Arduino就好似全自动档的汽车,即使我们不懂各种引擎、离合依旧可以轻松驾驶,难道你们会说开自动挡的人不会开车。STM32何尝不是呢?为什么STM32也是库函数配置,之所以人们很少说他不专业,是因为STM32的库更加的繁琐,这就是我们中国人的性情。当Arduino在全球大火的时候,在中国招致而来的确是口诛笔伐。
当我在很小的时候,一直期望从事制造出电脑、手机之类的高端工作,然我的梦想实现之后,却期望着在浩瀚无垠的草原上沐浴春风,在美丽的夜空下遥望星空,感受大自然的花香鸟语,事实永远和我们期望的永远不一样,就连上个月几十年不遇的蓝月亮都没有观看,为了赶项目,我都是偷偷的在手机上看直播,想想这是何等的悲催,想想在我们工作之后又如何谁能保持初心,现在想想学习一门知识的时候那才叫幸福,等你把需要的知识学到尽头,你会发现自己走出半生,不是少年!
Arduino读光栅数据
最近在工作中,需要使用光栅尺,但是之前的程序是电气工程师通过PLC控制,然后使用需要使用modbus协议去读取结果,使用相当的不智能,优化的话,那位电气工程师已经离职,没人接手。
为了更好的使用这个光栅尺,我决定自己来优化一下。PLC开发不太懂,但没事,我手头有个空闲的ESP32C3,使用MCU去读个脉冲信号,我觉得问题不大。
在拿到光栅尺,我看了下规格:精度1um,TTL信号输出,一个脉冲的计数为4um,接口为DB9,当然接线与传统的RS232串口定义完全不一样。
这里接线就不做过多的描述,毕竟设备不一样,光栅尺的输出信号分为了A/B/Z,然后我们来看下光栅的A/B信号:
这时候有使用arduino玩过编码器,一看就知道,这不就是编码器,于是顺手把USB逻辑分析仪拿出来,运动一下光栅,看下数据波形,一个波形的时间大约在3-400ms。
于是arduino的开发就简单了,两个pin脚中断触发,然后读编码器一般计数就行了。为了让使用过程中能实现自动上报数据,于是我增加了一个pin脚中断,在上升或者下降触发的时候能自动把计数数据发到串口,这样在到达我需要测试数据的时候,ESP32C3能把数据自动上报。
所以arduino的代码我设计为3块:
1、中断计数、中断上报;
2、串口协议生成;
3、串口数据通讯。
既然已经有了单片机程序,那上位机也必不可少,那就直接简单点,使用C#进行数据开发。
那就直接开发,使用arduino开发虽然不能深入了解单片机的开发精髓,但是我们要的是能拿来直接用。
中断定义:
const int A_pin = 1; // 定义A管脚引脚号
const int B_pin = 2; // 定义B管脚引脚号
const int P_pin = 3;
const int interruptPinA = digitalPinToInterrupt(A_pin);
const int interruptPinB = digitalPinToInterrupt(B_pin);
const int interruptPinP = digitalPinToInterrupt(P_pin);
在初始化中增加代码:
// 设置中断回调函数
attachInterrupt(interruptPinA, countPulseA, CHANGE);
attachInterrupt(interruptPinB, countPulseB, CHANGE);
attachInterrupt(interruptPinP, countPulseP, CHANGE);
中断函数关键代码:
A脚中断部分:
// 在A脉冲中寻找上升沿信号,若A编码器引脚为高电平,
// 若B编码器引脚为低电平,Counter计数+1,否则-1
if (digitalRead(A_pin) == HIGH) {
if (digitalRead(B_pin) == LOW) {
count = count + 1;
}
else {
count = count - 1;
}
}
else // 在A脉冲中寻找下降沿信号
{
if (digitalRead(B_pin) == HIGH) {
count = count + 1;
}
else {
count = count - 1;
}
}
B脚中断部分:
// 在B脉冲中寻找上升沿信号
if (digitalRead(B_pin) == HIGH)
{
if (digitalRead(A_pin) == HIGH) {
count = count + 1;
}
else {
count = count - 1;
}
}
else {
if (digitalRead(A_pin) == LOW) {
count = count + 1;
}
else {
count = count - 1;
}
}
P脚就是自动发送串口数据,协议是自己定义的就不具体描述,基本协议思路:
定义好协议的帧头、流水号、数据长度、数据位、数据内容、校验位以及帧尾,这样基本不会有问题。至于校验,简单的就是累加、或者直接使用现成的校验方式,比如CRC16等。
上位机就简单的使用C#进行数据收发,我选择使用winform进行编写。
当前.net的版本较多,既然支持的直接使用推荐的.net8.0,在.net8.0的环境中是没有serialport控件,需要使用nuget来获取system.io.ports控件:
功能就简洁点,直接获取串口,然后直接读数据内容:
至于功能就基于serialport控件:
搜索本地串口:
cb_comname.Items.Clear();
cb_comname.Items.AddRange(SerialPort.GetPortNames());
if (cb_comname.Items.Count > 0)
{
cb_comname.SelectedIndex = 0;
}
打开串口:
try
{
sp.PortName = comname;
sp.BaudRate = bs;
sp.Open();
isok = sp.IsOpen;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
数据收发:
sp.DataReceived += Sp_DataReceived;
处理事件的函数内容:
int len=sp.BytesToRead;
if (len > 0)
{
byte[] buf=new byte[len];
sp.Read(buf, 0, len);
//处理数据
}
顺便使用了closexml来保存记录的光栅数据,使用起来相当完美,有时间再录制一个视频。
相关问答
计算机怎么接收 数据 计算机怎么接收 单片机 发送的 数据 ?单片机怎样通过串口向计算机发送数据:单片机可以实现与计算机的发送和接收。首先,要正确配置单片机的串口,包括波特率、使用时钟源、COM口、数据位位...单片...
1、 单片机读写 外部RAM 数据 用()指令A、MOVB、MOVDC、MOVXD、M...[最佳回答]CMOV指令表示单片机内部的寄存器或者存储器之间相互传递数据(内部RAM);而MOVX则表示单片机内部的A累加器与片外的数据存储器传送数据.(这个是扩展...
访问 单片机 内部ram用什么指令?典型的51单片机内部ram是256b,8根地址线(8位),这256b共分为高128位和低128位,用户使用的区域是低128位(即00h~7fh),通过程序计数器pc寻址。51单片机的...典...
单片机 写命令与写 数据 的区别?1计算机、单片机与I/O接口芯片的信息传递分为四种情况:(1)向I/O接口芯片送控制字(2)读I/O接口芯片的状态(3)向I/O接口芯片写数据(4)读I/O接口芯...1计...
丁丁串口助手怎么接收 数据 ?首先,单片机里面要有程序。然后,电脑串口的参数要与单片机一致。例:9600,N,8,1.(9600波特率,无校验,8个数据位,1个停止位)。最后,点:“打开串口”。当...
烧录器 读 取 单片机数据 ?烧录器是一种用于将程序代码或数据写入单片机的设备。它通过连接到单片机的编程接口,读取并解析编程文件,然后将其写入单片机的存储器中。在读取单片机数据时,...
单片机 内的ROM和RAM如何储存程序与 数据 ?ROM一般用户只读不存(部份FLASH单片机的ROM可以由特殊指令进行先擦除,再改写存储),ROM掉电后数据不会丢失;RAM在上电后可由用户随意存取,但掉电后数据丢失...
电脑如何 读 取 单片机 USB接口的 数据 ?单片机串口是TTL电平输出,所以必须通过TTL-rs232转换,一般用max232芯片,很简单。本来可以直接接电脑的COM口9RS232电平)。但要求接USB口,所以,还必须要有rs...
如何用 单片机 的普通IO口接收PLC发送的 数据 ?如果发送的数据量少,用单片机的2个IO口(共16位)连接PLC的输出口,用16进制数字编码传送信息,单片机端再用查表法翻译。如果发送的数据量少,用单片机的2个IO口(...
如何用MODBUS 读 写 单片机 的32位 数据 ?使用Modbus访问16bit功能码,连续访问2个代表一个32位数据,两个16bit数据的工作需要自己完成:如PDU=功能码+数据域=0X03+[0X0000、0X0002];其中数据域...