分类 嵌入式&系统 下的文章 - 我的学记|刘航宇的博客
首页
📊归档
⏳时光机
📬留言
🐾友链
资助名单
推荐
🎓843课程班
🎵音乐
🏞️壁纸
搜 索
1
【NPN/PNP三极管】放大电路饱和失真和截止失真的区别
12,710 阅读
2
论文写作中如何把word里面所有数字和字母替换为新罗马字体
7,155 阅读
3
【高数】形心计算公式讲解大全
6,638 阅读
4
【1】基于STM32CubeMX-STM32GPIO端口开发
5,149 阅读
5
如何判断运放是工作在线性区还是非线性区
4,995 阅读
🌻微语&随笔
励志美文
我的随笔
写作办公
📖电子&通信
嵌入式&系统
通信&信息处理
编程&脚本笔记
🗜️IC&系统
FPGA&ASIC
VLSI&IC验证
EDA&虚拟机
💻电子&计算机
IP&SOC设计
机器学习
软硬件算法
登录
搜 索
标签搜索
嵌入式
ASIC/FPGA
VLSI
SOC设计
机器学习
天线设计
C/C++
EDA&虚拟机
软件算法
小实验
信号处理
电子线路
通信&射频
随笔
笔试面试
硬件算法
Verilog
软件无线电
Python
DL/ML
刘航宇
嵌入式系统&数字IC爱好者博客
累计撰写
302
篇文章
累计收到
527
条评论
首页
栏目
🌻微语&随笔
励志美文
我的随笔
写作办公
📖电子&通信
嵌入式&系统
通信&信息处理
编程&脚本笔记
🗜️IC&系统
FPGA&ASIC
VLSI&IC验证
EDA&虚拟机
💻电子&计算机
IP&SOC设计
机器学习
软硬件算法
页面
📊归档
⏳时光机
📬留言
🐾友链
资助名单
推荐
🎓843课程班
🎵音乐
🏞️壁纸
用户登录
登录
嵌入式&系统(共66篇)
找到
66
篇与
嵌入式&系统
相关的结果
FPGA&Matlab联合开发之滤波器模块(带通滤波器为例)
在通信或者信号处理中,数字滤波器是非常重要的模块,前面有关博文中提到FIR滤波器的一步步Verilog设计,如https://ee.ac.cn/index.php/archives/511.html本文以带通滤波器为例,利用Matlab进行高效开发MATLAB生成低通滤波器设计步骤:(1)在MATLAB命令窗口中输入“filterDesigner”或“fdatool”出现如下对话框设置FIR滤波器为和需要的阶数滤波器,选择窗函数的类型为海明窗函数,海明窗函数可以得到旁瓣更小的效果,能量更加集中在主瓣中设置带通滤波器的上下截至频率分别为4MHz 和 5MHz(2)量化输入输出,点击工作栏左边的量化选项,即“set quantization parameters”选项,选择定点,设置输入字长为8,其他选择默认,如下图示:(3)根据自己需求,细化一些配置。这里不难探索设置完成后,点击Targets中Generate HDL,选择生成Verilog 代码,设置路径,MATLAB即可生成设计好的滤波器Verilog HDL 代码以及测试文件:(4)根据需求,配置输出.v文件的全局信号、测试文件,点击生成,生成后,Matlab主页面会提示.v生成的文件路径Modelsim仿真上述文件可以看到输入信号在4MHZ~5MHZ备保留,设计无误。需要注意一点,一般Modelsim仿真输出波形都是离散的01信号,这里需要配置一下,在上图被选中的信号中,在左侧右键鼠标。右击,format,analog(automatic);右击,radix,decimal;这两个步骤完成之后,就出现上图模拟信号的效果
2023年05月21日
297 阅读
0 评论
2 点赞
2022-10-16
UART串行接口设计及通信实现
通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种异步收发传输器。异步串行、接口原理分析串行通信电气特性通常,UART串行接口采用RS-232-C电气标准进行通信。RS-232-C是美国电子工业协会EIA(Electronic Industry Association)制定的一种串行物理接口标准。对于一般的通信,不需要掌握RS-232-C的所有信号的定义,只需要使用其中的2个信号TXD(数据发送)和RXD(数据接收),另外,参加通信的设备要将GND(地)要连到一起(共地)。数据线TxD和RxD的电平标准为: 逻辑1=-3V~-15V;逻辑0=+3~+15VRS-232-C标准规定的数据传输速率为9600、19200、115200等波特率。波特率是衡量资料传送速率的指标,表示每秒钟传送的符号数。如果波特率为9600,那么发送和接收数据都应该为9600bits/s。本节采用9600bit/s进行通信。UART串行数据格式起始位(逻辑0 )+数据位(本节为8位数据位)+奇偶校验位(本节为偶校验)+停止位(本节使用1位停止位)+空闲位(逻辑1)通信的安全性问题串行异步通信,发送方和接收方使用各自的时钟。例如从FPGA电路板和计算机之间的通信,因此,不能保证两者的时钟完全相同。为保证接收数据的准确性,因此需要用较高的采样率进行采样,本节采用16倍的采样率进行采样,简单的选取中间采样点的值作为接收的数据。如图采用16倍波特率的采样率执行采样,一个比特可采集16个点,选取中间点即从第一个采样点开始的第8或第9个采样点(笑脸附近上升沿)采集该位数据,在接收双方始终频率相差不大的情况下,能够正确的完成通信。功能设计和演示预计实现的功能(演示):将拨码开关代表的数据发送到串口(8位);从串口接收电脑发来的数据,以数码管显示(8位)。主模块设计⚫ 调用分频模块⚫ 调用数码管显示IP⚫ 调用按键消抖动IP⚫ 调用串口发送模块⚫ 调用串口接收模块module v1( input clk, input [11:0] sw, input [3:0] btn,//行列键盘的输入 output [3:0] row,//行列键盘的行输出 output [7:0] seg, output [5:0] an, output [11:0] led, output txd, input rxd ); wire clk_ms,clk_20ms,clk_16x,clk_x; wire [3:0] btnout; wire [23:0] data_disp; wire data_ready; wire data_error; assign row[3:0]=1;//输出全部为高电平, 本例程只用4个 divclk my_divclk(.clk(clk),.clk_ms(clk_ms),.btnclk(clk_20ms),.clk_16x(clk_16x),.clk_x(clk_x)); //调用分频模块 ip_disp_0 uut_disp(//调用显示IP .clk(clk), .rst(0), .dispdata(), .seg(seg), .an(an) ); ip_ajxd_0 uut_ajxd(//调用按键消抖动IP .btn_clk(clk_20ms), .btn_in(btn), .btn_out(btnout) ); uart_tx (.clk_x(clk_x),.data_in(sw[7:0]),.btn(btnout),.txd(txd),.led(led)); //调用串口发送模 块 uart_rx(.clk_16x(clk_16x),.rst(btnout[0]),.rxd(rxd),.data_disp(data_disp),.data_ready(data_rea dy),.data_error(data_error));//调用串口发送模块 endmodule串口发送程序设计串口接收程序设计
2022年10月16日
366 阅读
0 评论
0 点赞
2022-10-11
读懂史密斯圆图
史密斯圆图能干啥用?史密斯圆图,就是做高频电路之间的阻抗匹配用的。所谓阻抗是电路对电的阻碍能力,它是个矢量,也就是说阻抗值是个复数。这里面既包括实部电阻成分一即与电力 "顶牛儿”的那部分阻力;也包括虚部电抗成分一就是把电力拉偏的那部分阻力。两者加一块,就叫阻抗。阻抗匹配,是电路之间连接的一-个基本要求,简单讲就是输入阻抗和输出阻抗大致相当,方向相反。如果阻抗不匹配呢?轻者电路工作效率低,重者.工作异常或直接烧毁。具体到高频电路来说,这些危害不仅都有,而且比数字电路、低频模拟电路上的危害要严重得多。那高频电路的阻抗匹配是啥标准呢?就是让输入端电阻和输出端电阻是纯阻性,而且最好等于509或752 。那原来阻抗不匹配,现在咋弄它就匹配了呢?就是在两个电路之间,接上电容、电感、传输线,微带线、变压器之类的东西。把阻抗值矫正到阻抗相等面来。史密斯圆图的主要用途,一是计算接到电路里的那些电容器、电感器的参数值的。二是用来显示某一电路的频率一阻抗特性的。史密斯圆图怎么用?史密斯圆图,它相当于一个地图,它上面每一个点, 都代表一个复数形式的阻抗值,而其圆心叫做匹配点,它代表了实部50om,虚部0om的理想阻抗,那就是我们要到达的地方。做阻抗匹配,就是规划一条从阻抗点走到匹配点的线路。然后呢?然后就是利用这些点位之间的差值做计算了。这个事儿我就不讲了。因为过去用纸本史密斯圆图才需要自己算,现在有很多专用软件能替我们做,不仅能算刚才我提到的那个匹配元件的电容量、电感量,还能算出谐振电路的Q值,驻波比,衰减量等等,这就用不着咱们算了,诸位知道这些概念是啥意思,就行了!至于具体怎么用史密斯圆图软件?怎么看这些数据?怎么评价匹配的效果?别着急,我们后边再聊。史密斯圆图第二节史密斯圆图该咋看?简言之,是看一线、两弧和两圆。我们说过,史密斯圆图上的每个点,都有实部值和虚部值,那么图上的线,其实也只有两种,一是等实部线,二是等虚部线。读史密斯圆图,就是先沿等虚部线,找到实部值,再沿着等实部线找到虚部值。那么一线和两弧,都是等虚部线;两圆,是等实部线!接下来我们就从一线讲起,说说史密斯圆图的刻度划分刻度值线一一根特殊的等虚部线史密斯圆图被一条名为电阻线的蓝色横线分成 上下两个半区,上半部分叫电感区, 那里所有点的虛部值都为正;下半部分叫电容区,那里所有点的虚部值都为负。而电阻线本身的虚部阻抗值不正不负,他上面每一个点的阻抗值均为0欧。所以电阻线是一根特殊的虚部线,它是我们查找实部值的一把尺子。电阻线上有三个点,最左侧的叫短路点,他表示实部值0欧姆,虚部值也为0欧姆的情况;最右侧的叫断路点,他表示实部值无穷大,虚部值也为0欧姆的情况;而中间点,也就是圆心那是匹配点,那里的阻值是“标准阻值”,一般情况下他是50欧姆。“三点” 是史密斯圆图的基点,也是我们校正天线分析仪的起点,一定记住。归一化处理但是请注意!虽然电阻线是一把测量实部阻值的尺子,但是这把尺子上标的不一定是实部阻值。纸本的史密斯圆图标注的是阻抗值/标准阻值的比值,这叫归-化处理,这个值叫归-化阻抗值。下图中的小红字标的是阻抗值,而大红字标的是归一化阻抗值9。咱们先说图.上的大红字,那就是归一化之后的阻抗值。如果我们是在纸本史密斯圆图上标图,那第一步应该把阻抗值转换成归一化阻抗值。以标准阻抗50欧姆为例。我们要找100欧姆的实部值,就去电阻线上找归一化阻抗值为100欧姆/50欧姆=2的点,而图上显示"0.2" 归一化阻抗值的地方,其实际阻抗值就是0.2*50欧姆= 10欧姆,而匹配点的归一化阻抗值永远为1,这是归一化阻抗标注法的一个识别标志。为什么要用归一化阻抗值标注刻度呢?因为很多时候,我们不是要把电路匹配到50欧姆上,而是要匹配到75欧姆或者300欧姆等阻抗上。请看下图,这是75欧姆标准电阻时,史密斯原图上的情况,其中电阻线下方写的红字是阻抗值。电阻线上方的写的红字是归一化阻抗值。第二套刻度一一导纳值和归一化导纳值等电阻线是一把度量实部值的尺子,它有阻抗值和归一化阻抗值和两种标注方法,其实在电脑版史密斯圆图的等电阻线上,还有一套刻度。就是用大绿字标注的归一化导纳值和用小绿字标注的导纳值。有人想问导纳值是啥?导是电阻值的倒数,纳是电抗值的倒数,导纳加一块就是导纳值,它是阻抗值的倒数,导纳值的单位是西门子,写作“S",1S等于= 1000mS。给导纳值做归一化,也就是将导纳值除以0.02S标准导纳值(0.02S, 其实就是1/50欧姆)。这两种标法的值,是等价的。例如,电阻线上25Ω那个点,它的导纳值为1/25Ω=0.04S,它的归一化导纳值就是0.04S/0.02S为=2。导纳值既然和阻抗值完全等价,用法也一样,那我们要这个玩意做啥呢?简单讲,我们在标注初始阻抗点时,要根据红色的阻抗值坐标系做,而在做阻抗匹配时,则要用到绿色的导纳值坐标系。两圆两弧---等实部圆和等虚部弧两圆---两种等实部线讲特殊的电阻线--也就是0欧姆等虚部线之后,我们看看与电阻线相切的那些圆形。这些圆圈都是等实部线,那上面每一条线的实部值都相等。其中红色的圆圈都叫阻抗圆,而绿色的圆圈都叫导纳圆,我们在电阻线.上找到实部阻抗值或者实部导纳值之后,就要沿着阻抗圆或者电纳圆去找虚部值。其中电阻线以上的点是正值,代表阻抗点的虚部值呈现感性,电阻线以下的点是负值,代表阻抗点的虚部值呈现容性。和看电阻线的规矩一-样,我们在标注初始阻抗值时只看红色的。两弧---两种等虚部线那么虚部值到那去查?从断路点发出,向史密斯圆图边界放射的红线叫等电抗弧;而从短路点发出,向史密斯圆图边界反射的绿线都叫等电纳弧9。这些都是等虚部线,我们找到实部值后,就是沿着实部线9到找到特定值的等虚部线,那虚部线的值标哪儿了呢,在史密斯圆图的外边界上。和刚才-个规矩,我们标初始阻抗值时是根据红色数字做的。总结一下,到底怎么读图?总结一下,到底怎么读图?第一步,用阻抗值除以标准电阻,得到归一化实部阻抗值和归一化虚部阻抗值。第二步,在等电阻线上,找到归一化实部阻抗值对应的阻抗圆。第三步,沿着阻抗圆,向上或向下旋转,找与归一化虚部阻抗值对应的等电抗弧。第四步,做个记号,就算OK。 举个栗子~! 1002-j50Ω滴点在哪儿?第一步,计算归一化实部阻抗值为100Ω/50Ω=2;归一化虚部阻抗值为-50Ω/50Ω=-1。第二步,在等电阻线上,找到归一化阻抗值为2的阻抗圆。第三步,沿着归一化阻抗值为2的阻抗圆下旋,转到-1 那个电抗弧上。第四步,做个记号!我标的是X。那如果图.上标的是阻抗值呢?如果是在电脑上识图,图上直接标注的阻抗值,那就更方便了,实部阻抗值标在阻抗圆上,虚部阻抗值写在电抗弧末端。我们标图的时候,不用换算,先根据实部阻抗值找到对应的阻抗圆,再沿着阻抗圆去查对应虚部阻抗值的电抗弧,然后做个记号,就OK啦~例如:我要查100Ω+j50Ω的点,先找到100Ω阻抗圆,然后沿着它的轨迹上旋,到达虚部值为502的地方,然后做个标记,就是Y点。归一化导纳值呢?简单讲,导纳值坐标系和阻抗值的查法、标注方法完全一样。第一步,用导纳值除以标准导纳值,得到归一化导纳值,第二步,在等电阻线上,找到归一化实部导纳值对应的那个导纳圆。第三步,沿着导纳圆向上或向下旋转,找与归一化虚部导纳值对应的等电纳弧。第四步,做个记号,就算OK。 再举个栗子 0.04S+j0.02S的点在哪儿?第一步,计算归一化实部导纳值为0.04S/0.02S=2;归一化虚部导纳值为0.02S/0.02S=1.第二步,在等电阻线上,找到归一化导纳值为2的导纳圆。第三步,沿着归一化导纳值为2的导纳圆上旋,转到导纳值为1的那个电纳弧上。第四步,做个记号!即Z。那如果图上标的是导纳值呢?那也简单,先根据实部导纳值找到对应的导纳圆,再沿着导纳圆去查对应虚部导纳值的电纳弧,然后做个记号,就OK啦~.例如:我要查0.04S-j0.02S的点,先找到0.04S导纳圆,然后沿着它的轨迹下旋,到达虚部值为-0.02S的地方,然后做个标记,那就是S点。好了~!关于怎么查史密斯圆图的事儿,我讲完了,接下来请大家做点练习,看看是否理解了。下一次我们学习如何用史密斯圆图做阻抗匹配。读图练习第一题,1点的阻抗值为50Ω+j50N,请问1点在图上什么位置?第二题,2点的归一化阻抗值为0.5+j0.5,请问2点在图.上什么位置?第三题,3点导纳值为0.04S-j0.02S,请问3点在图上什么位置?第四题,4点归一化导纳值为0.5-j0.2,请问4点在图上什么位置?请把上图打印出来,试着标一下,然后再看文末那个答案。 答案 史密斯圆图第三节怎么用史密斯圆图软件做阻抗匹配史密斯圆图软件做阻抗匹配有六句口诀:先设参数,后选起点,下容上感,左并右串,顺着圆走,往圆心转。smithV3.1软件的界面,然后按着口诀顺序,一点点说。然后举个设计例子,最后讲讲注意事项。软件界面简介打开SmithV3.1,首先看到左侧-一个有个史密斯圆图,那是我们的操作区域。这里我要着重强调一下,电脑软件上标的都是实际阻抗值,而不是归一化阻抗值,所以我们做阻抗匹配的时候不用换算数据了,但是要在匹配之前设置好频率值和标准电阻值,否则做出来的数据会和现实完全对不上的。右侧有几个重要窗口,最顶上的是Schematic窗口,当我们在左侧史密斯圆图上用鼠标做匹配的时候,这个窗口里会显示相应的电路图,比如我图.上画的这个匹配路径对应到电路上,就是先双联13.9p电容,再并联23.4nH电感。下方这个Cursor窗口也很重要哦。它里面标注的是光标所在点的具体参数,这其中最重要的当然是VSWR驻波比、和Z阻抗值, Zo标准电阻值, Freq频率值。 这其中后两项参数是需要我们在做匹配之前要手工输入的。先设参数,再选起点,先设参数:就是要设置工作频率和标准阻抗这两个值。再选起点:就是要把阻抗点的具体位置设到史密斯圆图.上。我们点击这个图标,然后在这个页面的左下角General这输入标准阻抗值50Ω,在datapoint那儿输入工作频率,默认设置是500MHz。然后我们点击按钮,软件都会弹出这个窗口。我们在这选中impedance (Ω), 并在下面两个空里填写阻抗点的实部阻抗值和虚部阻抗值,这就样就设好起点了.然后呢?然后就该我们添加元件了。下容上感,左并右串我们点击工具栏的这个部分,就可以在阻抗点上连接电容或电感了。怎么接线呢?这有两句口诀:下容上感,左并右串。那我们参照下图看一看。”下容上感”,是说史密斯圆图的电阻线上方是电感区,下方是电容区,因此呢,我们要往下移动阻抗点,就得接电容;要往上移动阻抗点,就得接电感。那具体是串电容还是并电容,又或者是串电感还是并电感呢?我们来看下一-句左并右串。“左并右串”,是说如果我们要沿着左侧这组蓝色的导纳圆移动阻抗点,就点击“并联元件”,也就是点工具栏上这两个按钮;如果我们要沿着右侧这组红色的阻抗圆移动阻抗点,就点击“串联元件”,就点工具栏上的这两个按钮顺着圆走,往圆心转那我们究竟怎么走到标准阻抗点呢?那第五句和第六句说的问题。所谓“顺着圆走”,是说顺着右侧的50阻抗圆或顺着左侧那个20mS导纳圆走,为什么呢?因为这两个圆都与匹配点相切,所以无论我们走什么路径去匹配点,都得经过其中-一个圆,而“往圆心转”是说我们无论沿着.上面哪条弧线旋转,最终都是往史密斯圆图的中心旋转。等我们把阻抗点挪到自己认为合适的位置后,右侧Schemat窗口里也就画出来了我们的阻抗匹配电路。一个栗子某功率放大器的要放大100M信号,其输入阻抗值为252+j352,而信号源阻抗为50Q,现在要在两者之间接一个匹配电路,为此我要如此操作。先设参数:我们点击这个图标,然后在这个页面的左下角General这输入标准阻抗值50Ω,在Datapoint那儿输入工作频率100MHz。然后点ok按钮。再选起点:我们点击按钮,软件都会弹出这个窗口我们在这选中impedance,然后在下面的两个空里填入实部值25欧姆、虚部值+35欧姆,点ok就行了。这时候我们发现,史密斯圆图上会出现一个方形坐标点DP1.下容上感,左并右串。顺着圆走,往圆心转那接下来,我们就要通过连接元件,改变阻抗点的阻抗了。由于DP1位于史密斯圆图的电感区,所以我们要让他往下转,那旋转是有很多路径,我们先说最简单的,从DP1直接转到20mS导纳圆上,在顺着20mS导纳圆上继续下旋到圆心。当然这是我们的设想,实际不一定能实现,我们就先以此为目标,试试看吧。那由于我是要向下移动阻抗点,也就是向电容区移动阻抗点,所以我要连接电容。由于我是沿着右侧的25欧姆阻抗线向下移动,左并右串,所以我应该选串联电容,也就是点我们点了串联电容按钮之后,会发现光标不能自由移动了,它只能是沿着红色的25欧姆阻抗圆移动,这就是smithV3.1软件的便利之处,他能防止我们走错路。那我们按软件限定的路线,沿着25欧姆阻抗圆下旋,发现有两次机会转到20mS导纳线上,我选哪一次呢?我们设想中是选第一次机会,但是我看到右侧Schenatic窗口里,要添加的串联电容是155pf就改主意了,因为这是个非标容量,说白了我让谁买也买不来这型号的电容。于是我继续沿着25欧姆阻抗圆向下旋转,到第二个交汇点去碰碰运气。那我到达25欧姆阻抗线与20mS导纳线第二次相交的地方一看,发现右侧Schenatic窗口里显示的是串联的是26p电容,这个参数与27p极为接近,那这容量的电容有地方买,所以我就在这儿点下鼠标左键,图片上就出现了DP2点。那接下来,我是要由DP2沿着20mS导纳圆上旋对吧?因为下容上感,所以我们要接电感,因为左并右串,我们要沿着左侧圆走,所以要并联电感,那我们点和第一步一样,我们还是要沿着电脑规划的线路边走边看,走到圆心时,我们发现右侧Schemat窗口里,显示的电感值是80nH左右,这个电感没啥制作难度,所以我就再次点击鼠标左键,史密斯圆图中心附近就会多出来一个DP3。 也就是路径4这个图。那我们到了这个DP3又意味着什么呢?我们别挪动光标,我们把鼠标停在DP3上,把视线挪到Cursor这个小窗上,在这我们会看到Q值0.005, VSWR1.03等参数。显然,VSWR约等于1,是个很好的结果,实际小信号的SWR匹配到1 .5就以很好了。而大功率的通讯设备,需要尽量往小了做,做到1.2以下。两个问题首先,我们还可以有别的匹配路径么?当然可以,条条大路通罗马。刚才我们走的路径是先串后并,用了一一个电容一个电感,走20mS导纳圆到的中点,也就是图上的路径1。那如果我们改走右边的509阻抗圆行么?行啊,完全可以。我们可以先并联16pf电容,再串联51pf电容。这就是路径2。那还有别的路可走么?有啊,比如我们可以选用阻抗匹配变压器,也就是先串联47pf电容,下旋到电阻线,再使用1:1 .4的阻抗变压器,沿着等Q值弧线(也就是从短路点、断路点之间的蓝色弧线,参见文末的图例)向右移动到圆心,这就是路径39。那还有别的么?有啊,我们还可以接电阻,走等虚部弧。比如我们可以走路径4,即先串联电阻,从DP1进到右边50Q阻抗圆.上,然后再串电容沿着50Q阻抗圆继续下旋,这也是可以的。只不过要注意两个问题,第- -点, 我们接电阻走等虚部线的时候,虽然匹配上了,但是会增加电路损耗的。第二点,由于现实中可没有合用的负阻元件卖,所以我们做匹配时绝不能沿着等虚部线退着走,也就是说不能接负阻器件,这- -点smith3.1软件考虑到了,他会限制我们那么做,但是其他软件或纸本的史密斯圆图就得注意这问题。其次,如果我们做匹配时转不到史密斯圆图的正中心(不太可能),或者实际制作中对不到史密斯圆图中心(很常见),那又 意味着什么?请看下图,图上这些棕色圆圈是等VSWR圆,也就是等驻波比圆,这个驻波比圆的特点是越靠近圆心,驻波比越小,比如圆心那- -点是1.也就是说输入端送出进去多少信号,负载端就吸收多少信号,能量一点没糟践;驻波比1.5, 意味着有4%的功率撞到输出端又撞回输入端了。驻波比29,就意味着有11%的能量撞回去了。通常来说,小信号阻抗匹配电路对驻波比要求比较低,达到1.5就算良好匹配了。如果体积有限制,还可以进一步放宽一些。 但是如果是强信号,电台天线那种场合,SWR控制的就比较严格了,大功率电台,通信基站要控制在1.2以内。
2022年10月11日
2,198 阅读
0 评论
4 点赞
高速电路系统-传输线阻抗匹配
传输线反射系数●当传输线的传播的信号到达某个阻抗不连续点时,信号会发生反射,●就像水流通过不同口径的管道接口时,水面产生波动一样。●根据反射电压和入射电压的比值, 可以定义传输线上的反射系数。$\Gamma=\frac}}=\frac$信号反射分析在信号跳变的瞬间,源端和负载端的电压变化信号阻抗匹配设计优点:RS无需电源,低功耗,对于驱动高容性负载起到限流作用,有效的避免了一些噪声。缺点:信号源加电阻占空间,对扇出不好。(C)优点RC隔直流,消除直流损耗。电容有充电时间,RC饱和时间大于2倍传输线延迟,也就是源端发射信号到RC电路之前没有饱和。调试办法在射频电路中进行阻抗匹配测试时,可按照如下步骤进行射频匹配网络调试:1:校准矢量网络分析仪2:用矢网测量开口线,保存S1P文件。在ADS中新建工程,按照如下原理图,插入开口线的S1P文件,使用ADS调谐调整微带线的长度,使开口线位于smith圆图的最右边使其处于开路状态,更新原理图参数。3:测量前级的输出阻抗将开口线焊接在焊点1的位置,利用矢网测量出前级网络的输出阻抗,保存S1P文件,利用上面抵消开口线参数影响后更新后ADS原理图,插入前级网络S1P文件,在ADS里读出对应频率点的阻抗Z14:测量下级的输出阻抗将开口线焊接在焊点2的位置,利用矢网测量出后级网络的输出阻抗,保存S1P文件,利用上面抵消开口线参数影响后更新后ADS原理图,插入后级网络S1P文件,在ADS里读出对应频率点的阻抗Z25:利用ADS的Smith Chart Utility 进行阻抗匹配将前级网络的输出阻抗Z1取共轭,负载网络的输入阻抗为Z2,代入到Utility进行阻抗匹配,最后将匹配后的元件值焊接到板子上进行测试
2022年10月10日
488 阅读
0 评论
2 点赞
2022-04-20
HAL库开发stm32 DHT11传感器
PB1引脚设置output即可,不想用PB1,修改引脚办法,修改dht11.c文件中的所有端口和引脚现象dht11.h#ifndef __HT11_H_ #define __HT11_H_ #include "main.h" #include "stm32f1xx_hal.h" //函数原型 //void delay_us(uint8_t); //微妙延时函数,启用了一个定时器。因为DHT11通讯过程涉及微妙延时 void GPIO_Input(void); //GPIO 状态转变的函数 CUBEMX默认的GPIO初始化我只开启了相关总线的使能 //把GPIO状态(输入 输出)封装成了两个函数 void GPIO_Output(void); void DHT11_Rst(void); //主机开始采集的信号 uint8_t DHT11_Check(void); //检查DHT是否回应 uint8_t DHT11_Init(void); //初始化函数 uint8_t DHT11_ReadBit(void); //读取一位 uint8_t DHT11_ReadByte(void); //读取一个字节 uint8_t DHT11_ReadData(uint8_t *); //读取数据(40个位) #endif dht11.c#include "dht11.h" #define CPU_FREQUENCY_MHZ 72 // CPU主频,根据实际进行修改 static void delay_us(uint32_t delay) { int last, curr, val; int temp; while (delay != 0) { temp = delay > 900 ? 900 : delay; last = SysTick->VAL; curr = last - CPU_FREQUENCY_MHZ * temp; if (curr >= 0) { do { val = SysTick->VAL; } while ((val < last) && (val >= curr)); } else { curr += CPU_FREQUENCY_MHZ * 1000; do { val = SysTick->VAL; } while ((val <= last) || (val > curr)); } delay -= temp; } } void GPIO_Input(void) { GPIO_InitTypeDef GPIO_InitStruct = ; /*Configure GPIO pin : PB1 */ GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } void GPIO_Output(void) { GPIO_InitTypeDef GPIO_InitStruct = ; /*Configure GPIO pin : PB1 */ GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } void DHT11_Rst(void) //主机开始信号 { GPIO_Output(); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET); HAL_Delay(20); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET); delay_us(30); } uint8_t DHT11_Check(void) { uint8_t retry = 0; GPIO_Input(); while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) && retry <100) //等待回应拉位低电平 { retry++; delay_us(1); } if(retry >= 100)return 1;else retry = 0; //当变量值大于100 返回1 说明无响应 返回 0 则为正确响应 while(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) && retry <100) //等待变为高电平 { retry++; delay_us(1); } if(retry >= 100)return 1; return 0; } uint8_t DHT11_Init(void) { DHT11_Rst(); return DHT11_Check(); } uint8_t DHT11_ReadBit(void) //读取一个位 { uint8_t retry = 0; while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) && retry <100) //等待变为低电平 { retry++; delay_us(1); } retry = 0; while(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) && retry <100) //等待变为高电平 { retry++; delay_us(1); } delay_us(40); //40us 后如果为低电平 数据为0 高电平数据为1 if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1))return 1;else return 0; } uint8_t DHT11_ReadByte(void) //读取一个字节 返回值位采集值 { uint8_t i,dat; dat = 0; for(i = 0;i < 8;i++) { dat <<= 1; //数据左移一位 dat |= DHT11_ReadBit(); //每读取到一个位 放到dat的最后一位 } return dat; } uint8_t DHT11_ReadData(uint8_t *h) { uint8_t buf[5]; uint8_t i; DHT11_Rst(); if(DHT11_Check() == 0){ for(i = 0;i < 5;i++) { buf[i] = DHT11_ReadByte(); } if(buf[0] + buf[1] + buf[2] + buf[3] == buf[4]) { *h = buf[0]; h++; *h = buf[2]; } }else return 1; return 0; } main.c添加//你自己要完成OLED显示出温度湿度哈,这个我就不写代码了,不然真的是再喂饭了呜呜 #include "dht11.h" //引入头文件 #include "stdio.h" uint8_t data[2]; //定义一个数据数组 uint8_t buff1[]="dht11 ok\r\n"; uint8_t buff2[]="dht11 error"; uint8_t str_buff[64]; //int main 死循环外面 if(DHT11_Init() == 0) { //这里显示了“温度”“湿度等字符” HAL_UART_Transmit(&huart1,buff1,sizeof(buff1),10000); } else{ //OLED_ShowStr(0,0,"DHT11 error!",1); HAL_UART_Transmit(&huart1,buff2,sizeof(buff2),10000); } HAL_Delay(1000); while (1) { if(DHT11_ReadData(data) == 0) { //显示相关数据 sprintf((char *)str_buff,"温度%d%d;湿度%d%d\r\n",data[0] /10 ,data[0] %10,data[1] /10,data[1] /10); HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000); } HAL_Delay(1000); //DHT11每次采集一定要间隔1s //你自己要完成OLED显示出温度湿度哈,这个我就不写代码了,不然真的是再喂饭了呜呜! }
2022年04月20日
822 阅读
0 评论
15 点赞
2022-04-12
【视频课程】STM32系统开发与protues仿真快速入门课
STM32系统开发与protues仿真快速入门课,上课层次分明,包含gpio与按键开发,中断,定时器,AD/DA转化,传感器,串口通信,远程通信技术,OLED液晶显示等等,由间到难,条理清晰。GPIO&键盘扫描定时器&OLED串口&TIM+串口传感器基础&OLED动态显示传感器原理&ADC基础OLED动态显示本节OLED配置允许不设置PB12-P15 output,直接基本三步后可以创建工程文件解决1us实现办法关于传感器代码移植,可以下载网上开源的驱动文件xx.h和xx.c文件,类似OLED驱动文件一样分别添加到工程文件夹中的Inc和Src中,最后用keill5打开用ADD进行文件添加!此处忘了可以回放第二节课OLED课delay_ms实现static inline void delay_ms(uint32_t delay) { HAL_Delay(delay); }delay_us实现#define CPU_FREQUENCY_MHZ 72 // CPU主频,根据实际进行修改 static void delay_us(uint32_t delay) { int last, curr, val; int temp; while (delay != 0) { temp = delay > 900 ? 900 : delay; last = SysTick->VAL; curr = last - CPU_FREQUENCY_MHZ * temp; if (curr >= 0) { do { val = SysTick->VAL; } while ((val < last) && (val >= curr)); } else { curr += CPU_FREQUENCY_MHZ * 1000; do { val = SysTick->VAL; } while ((val <= last) || (val > curr)); } delay -= temp; } } 远程通信&结语串口调试工具综合视频
2022年04月12日
1,271 阅读
0 评论
15 点赞
西北大学数字电子技术个人考研笔记
警告 若个人或辅导机构 擅自复制本文直接或间接盈利 、请向我举报,举报方式见下面,本人以 著作权法 追查! 本站域名由sciarm.com更变为ee.ac.cn 和下文页面中信息不冲突举报方式1.邮箱hyliu@ee.ac.cn2.点击博客中留言或私聊都可
2022年04月07日
1,294 阅读
0 评论
20 点赞
2022-04-07
西北大学模拟电子技术个人考研笔记
警告 若个人或辅导机构 擅自复制本文直接或间接盈利 、请向我举报,举报方式见下面,本人以 著作权法 追查到底!同时核查该机构/个人 是否有非法出书情况 、是否有 出版权与书号 , 一并交于公安机关追查 ! 本站域名由sciarm.com更变为ee.ac.cn 和下文页面中信息不冲突举报方式-请携带证据举报1.邮箱hyliu@ee.ac.cn2.点击博客中留言或私聊都可
2022年04月07日
1,512 阅读
0 评论
32 点赞
2022-03-13
数字电路基础-最大项与最小项
目录1.定义最小项:n个变量的逻辑乘,即与形式,每个变量以原变量或者反变量的形式出现一次。n个变量共有2n个最小项。用m表示,如ABC,表示为m0。最大项:n个变量的逻辑和,即或形式,每个变量以原变量或者反变量的形式出现一次。n个变量共有2n个最大项。用M表示,如A+B+C,表示为M0。如下为三变量最小项和最大项的表示方法: 2.性质对于n个变量来说,若给定这些变量确定的值,那么2n个最小项中仅有一组值为1,其余全为0;2n个最大项中仅有一组值为0,其余全为1.全部最小项之和恒等于1;全部最大项之积恒等于0。(可由第一条性质中看出)任意两个最小项之积等于0;任意两个最大项之和等于1。(可由第一条性质中看出)若干个最小项的和等于其余最小项和的反。简单可以记做为卡诺图上分成两部分,他们之间为反关系。3.关系最小项的反是最大项,最大项的反是最小项。
2022年03月13日
1,399 阅读
0 评论
6 点赞
SIM900A发送与接受短信
目录一.SMS简介SMS(Short Messaging Service)中文名称短信服务,短信是当下每一部手机上必备的功能之一,顾名思义,它是在手机之间发送文字信息或从个人计算机或手持设备向手机发送信息的一种方式,其文本信息的最大发送量为160个字符(字母、数字或者拉丁字母中的字符),对于中文一般最大发送量为70个字符。这里我想用SIM900A模块实现短信的收发。 二.短信的控制模式与编码先说一下:我采用的是Text Mode下使用GSM编码收发英文短信、使用UCS2编码收发中文短信对于短信的控制一共有三种模式:Block Mode、基于AT指令的Text Mode、基于AT指令的PDU Mode 。目前手机中默认使用PDU Mode,通过PDU编码的短信可以是文字、声音或者图像。Text Mode只能用于发送ANSI范围的字符,发送方式比较简单。SIM900A模块只提供Text Mode 和PDU Mode。中文短信中,所有汉字和字符都是采用UNICODE编码。1.Text ModeText Mode下,发送及接收到的数据均以ASCII码的显示来表示,可以发送指令"AT+CMGF=1",将GSM短信发送方式更改为文本模式。文本模式下接收的数据会自动解码,比如你收到一条短信息,GSM会返回:+CMGR: “REC UNREAD”,"+8613806XXXXXX",“11/10/21,13:22:13+32”hello (短信内容会自动换行)不需要自己解码,便可得到短信的发送者、发送时间和短信内容,比较容易操作。理论上Text Mode下,是只能够收发英文短信,但是SIM900A模块可以在Text Mode下使用UCS2编码,从而可以发送接收中文短信。2.PDU ModePDU相当于一个数据包,它由SMS的信息组成,作为一种数据单元,必须包含源地址、目的地址、有效时间、数据格式、协议类型、正文、正文长度(可达140字节),这些信息都以十六进制表示。PUD Mode被所有手机支持,可以使用任何字符集,其编码方式分为:7bit、8bit、UCS2。7-bit编码用于发送普通的ASCII字符,它将一串7-bit的字符(最高位为0)编码成8-bit的数据,每8个字符可“压缩”成7个;8-bit编码通常用于发送数据消息,比如图片和铃声等;而UCS2编码用于发送Unicode字符。在这三种编码方式下,PDU串的用户信息(TP-UD)段最大容量(可以发送的短消息的最大字符数)分别是160、140和70。这里,将一个英文字母、一个汉字和一个数据字节都视为一个字符。理论上发送中文短信需要使用PDU Mode的UCS2编码,上面也说了,SIM900A模块可以使用Text Mode发送UCS2编码,而且PDU Mode比Text Mode更加复杂,所以我采用了Text Mode收发中英文短信。PDU Mode的详细讲解可以借鉴此博客:点击链接跳转3.GSM编码在GSM编码模式下,收发消息的内容和电话号码,都是以ASCII字符的形式显示的,发送英文短信时使用十分方便。所以我使用GSM编码来收发英文短信。4.UCS2编码谈到UCS2编码就不得不说UNICODE,UNICODE又叫统一码、万国码,是计算机科学领域里的一项行业标准,包括字符集、编码方案等。UNICODE 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。简单来说,UNICODE编码可以表示世界上任意一种语言(有点夸张),自然也可以表示中文。而UCS2编码是UNICODE的一种,UCS2中每个字符都占俩个字节。使用UCS2编码后,发送短信的手机号码、短信内容都要经过UCS2编码转换才可以,但UCS2编码发送的消息在手机上可以直接显示为中文。所以,需要UCS2与中文的转换软件,如下,可以实现中文和UCS2的双向转换 三.收发英文短信1.AT+CPMS查询短信数量2.AT+CNMI设置新消息提示类型3.AT+CMGF选择短信模式4.AT+CSCS设置编码 5.AT+CSMP设置短信文本模式使用Text Mode的GSM编码时,短信文本模式设置为:AT+CSMP=17,167,0,240(消息显示在终端)AT+CSMP=17,167,0,241(消息存储在SIM卡中) 6.AT+CMGS发送消息到指定手机号使用Text Mode的GSM编码时,直接AT+CMGS="手机号"即可,然后,在>后输入要发送的内容(不要勾选发送新行),最后发送HEX(十六进制)的:1A 即可。如图,我使用本机向本机发送了一条短信,而且,本机收到短信后在终端中显示出来了。 这是SIM公司给出的例子:CTRL-Z 代表十六进制:1A使用SIM900A向本机发送一条英文短信的完整步骤如下: 四.收发中文短信收发中文短信利用的是Text Mode下的UCS2编码。相比于收发英文短信,收发中文短信需要修改的地方有:修改编码:AT+CSCS=“UCS2”修改短信文本模式:AT+CSMP=17,167,0,24(短消息显示在终端,25:存储在SIM中)手机号码要用UNICODE码发送的消息要用UNICODE码(有专门的转换软件)这是SIM公司给出的例子: 我要发送信息:可爱的小白鼠,女朋友收到后回复消息,用软件将UNICODE码转换为中文,串口操作界面如示: 发消息如示: 收消息如示: 这是我的SIM900A
2022年02月16日
726 阅读
0 评论
1 点赞
HAL_STM32_DS18B20开发
1.设置一个如PA0作为DS18B20模块接口2.添加下面2个文件,注意程序已经集成us延时ds18b20.c#include "ds18b20.h" static inline void delay_ms(uint32_t delay) { HAL_Delay(delay); } #define CPU_FREQUENCY_MHZ 72 // CPU主频,根据实际进行修改 static void delay_us(uint32_t delay) { int last, curr, val; int temp; while (delay != 0) { temp = delay > 900 ? 900 : delay; last = SysTick->VAL; curr = last - CPU_FREQUENCY_MHZ * temp; if (curr >= 0) { do { val = SysTick->VAL; } while ((val < last) && (val >= curr)); } else { curr += CPU_FREQUENCY_MHZ * 1000; do { val = SysTick->VAL; } while ((val <= last) || (val > curr)); } delay -= temp; } } //复位DS18B20 void DS18B20_Rst(void) { DS18B20_IO_OUT(); //SET PA0 OUTPUT DS18B20_DQ_OUT=0; //拉低DQ delay_us(750); //拉低750us DS18B20_DQ_OUT=1; //DQ=1 delay_us(15); //15US } //等待DS18B20的回应 //返回1:未检测到DS18B20的存在 //返回0:存在 uint8_t DS18B20_Check(void) { uint8_t retry=0; DS18B20_IO_IN();//SET PA0 INPUT while (DS18B20_DQ_IN&&retry<200) { retry++; delay_us(1); }; if(retry>=200)return 1; else retry=0; while (!DS18B20_DQ_IN&&retry<240) { retry++; delay_us(1); }; if(retry>=240)return 1; return 0; } //从DS18B20读取一个位 //返回值:1/0 uint8_t DS18B20_Read_Bit(void) // read one bit { uint8_t data; DS18B20_IO_OUT();//SET PA0 OUTPUT DS18B20_DQ_OUT=0; delay_us(2); DS18B20_DQ_OUT=1; DS18B20_IO_IN();//SET PA0 INPUT delay_us(12); if(DS18B20_DQ_IN)data=1; else data=0; delay_us(50); return data; } //从DS18B20读取一个字节 //返回值:读到的数据 uint8_t DS18B20_Read_Byte(void) // read one byte { uint8_t i,j,dat; dat=0; for (i=1;i<=8;i++) { j=DS18B20_Read_Bit(); dat=(j<<7)|(dat>>1); } return dat; } //写一个字节到DS18B20 //dat:要写入的字节 void DS18B20_Write_Byte(uint8_t dat) { uint8_t j; uint8_t testb; DS18B20_IO_OUT();//SET PA0 OUTPUT; for (j=1;j<=8;j++) { testb=dat&0x01; dat=dat>>1; if (testb) { DS18B20_DQ_OUT=0;// Write 1 delay_us(2); DS18B20_DQ_OUT=1; delay_us(60); } else { DS18B20_DQ_OUT=0;// Write 0 delay_us(60); DS18B20_DQ_OUT=1; delay_us(2); } } } //开始温度转换 void DS18B20_Start(void)// ds1820 start convert { DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0x44);// convert } //初始化DS18B20的IO口 DQ 同时检测DS的存在 //返回1:不存在 //返回0:存在 uint8_t DS18B20_Init(void) { DS18B20_Rst(); return DS18B20_Check(); } //从ds18b20得到温度值 //精度:0.1C //返回值:温度值 (-550~1250) short DS18B20_Get_Temp(void) { uint8_t temp; uint8_t TL,TH; short tem; DS18B20_Start (); // ds1820 start convert DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0xbe);// convert TL=DS18B20_Read_Byte(); // LSB TH=DS18B20_Read_Byte(); // MSB if(TH>7) { TH=~TH; TL=~TL; temp=0;//温度为负 }else temp=1;//温度为正 tem=TH; //获得高八位 tem<<=8; tem+=TL;//获得底八位 tem=(float)tem*0.625;//转换 if(temp)return tem; //返回温度值 else return -tem; } ds18b20.h#ifndef __DS18B20_H #define __DS18B20_H #include "main.h" #include "stm32f1xx_hal.h" //#include "delay.h" #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) #define GPIOA_ODR_Addr (GPIOA_BASE+12) #define GPIOB_ODR_Addr (GPIOB_BASE+12) #define GPIOC_ODR_Addr (GPIOC_BASE+12) #define GPIOD_ODR_Addr (GPIOD_BASE+12) #define GPIOE_ODR_Addr (GPIOE_BASE+12) #define GPIOF_ODR_Addr (GPIOF_BASE+12) #define GPIOG_ODR_Addr (GPIOG_BASE+12) #define GPIOA_IDR_Addr (GPIOA_BASE+8) #define GPIOB_IDR_Addr (GPIOB_BASE+8) #define GPIOC_IDR_Addr (GPIOC_BASE+8) #define GPIOD_IDR_Addr (GPIOD_BASE+8) #define GPIOE_IDR_Addr (GPIOE_BASE+8) #define GPIOF_IDR_Addr (GPIOF_BASE+8) #define GPIOG_IDR_Addr (GPIOG_BASE+8) #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //IO方向设置 #define DS18B20_IO_IN() #define DS18B20_IO_OUT() //IO操作函数 #define DS18B20_DQ_OUT PAout(0) //数据端口 PA0 #define DS18B20_DQ_IN PAin(0) //数据端口 PA0 uint8_t DS18B20_Init(void); //初始化DS18B20 short DS18B20_Get_Temp(void); //获取温度 void DS18B20_Start(void); //开始温度转换 void DS18B20_Write_Byte(uint8_t dat);//写入一个字节 uint8_t DS18B20_Read_Byte(void); //读出一个字节 uint8_t DS18B20_Read_Bit(void); //读出一个位 uint8_t DS18B20_Check(void); //检测是否存在DS18B20 void DS18B20_Rst(void); //复位DS18B20 #endif程序进行调用使用温度=DS18B20_Get_Temp();进行调用数值,可见精度达到要求了
2022年02月03日
975 阅读
4 评论
11 点赞
2022-01-31
【10】基于STM32CubeMX-STM32ADC与OLED开发
目录实训案例:ADC与OLED综合训练在XMF07A或XMF07C开发板上,利用STM32CubeMX和Keil5协同开发,完成以下的功能:【1】 上电开机后,首选在OLED上显示“强国图志”图片,然后让LED1与LED2依次点亮,然后熄灭,进行灯光检测。灯光检测结束后,OLED切换至数据显示界面,分3行:第1行显示:“ sciarm.com ”第2行显示:“采样值:”第3行显示:“电压值:”【2】在主程序中,采用查询的方式,每隔0.3秒对ADC_IN0通道的光敏传感器进行一次电压数据采集,并将采样到的12位数据换算成对应的实际电压值。LED1作为A/D采样指示灯,每采样一次闪烁一下。【3】每进行完一次光敏传感器的数据采样和电压换算后,将其结果更新到OLED显示屏中相应的位置。如果光敏传感器的电压值小于1.3V,则将LED2灯点亮,反之,将LED2灯关闭。//首先需要进行OLED的底层驱动函数移植,生成相应的文字和图片数据 /* USER CODE BEGIN Includes */ //====引入OLED底层驱动的头文件======== #include "XMF_OLED_STM32Cube.h" #include "stdio.h" /* USER CODE END Includes */extern unsigned char BMP1[]; #define LED1_ON() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9,GPIO_PIN_SET) #define LED2_ON() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,GPIO_PIN_SET) #define LED1_OFF() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9,GPIO_PIN_RESET) #define LED2_OFF() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,GPIO_PIN_RESET) uint16_t ADC0_Value = 0; uint16_t ADC_Volt = 0; uint8_t str_buff[64];//LED灯流水点亮检测 void LED_Check() { LED1_ON(); HAL_Delay(500); LED2_ON(); HAL_Delay(500); LED1_OFF(); HAL_Delay(500); LED2_OFF(); HAL_Delay(500); }//显示开机LOGO图片 void OLED_display_pic() { OLED_Clear(); OLED_DrawBMP(0,0,128,8,BMP1); }//显示数据显示界面 void OLED_display_info() { OLED_Clear(); OLED_ShowString(6,0,(uint8_t *)"sciarm.com"); HAL_Delay(200); OLED_ShowCHinese(0,3,24); OLED_ShowCHinese(18,3,25); OLED_ShowCHinese(36,3,26); OLED_ShowString(54,3,(uint8_t *)":"); HAL_Delay(200); OLED_ShowCHinese(0,6,16); OLED_ShowCHinese(18,6,17); OLED_ShowCHinese(36,6,26); OLED_ShowString(54,6,(uint8_t *)":"); HAL_Delay(200); }//更新ADC采样数据与换算结果 void OLED_display_dat() { sprintf((char*)str_buff, "%4d", ADC0_Value); OLED_ShowString(64,3,(uint8_t *)str_buff); sprintf((char*)str_buff, "%d.%d%dV", ADC_Volt/100, (ADC_Volt%100/10), ADC_Volt%10); OLED_ShowString(64,6,(uint8_t *)str_buff); }//ADC采样过程与灯光自动控制 void Get_ADC0_Value() { HAL_ADC_Start(&hadc1); if(HAL_OK == HAL_ADC_PollForConversion(&hadc1, 30)) { ADC0_Value = HAL_ADC_GetValue(&hadc1); ADC_Volt = ADC0_Value * 330 / 4096; if(ADC_Volt < 130) { LED2_ON(); } else { LED2_OFF(); } } HAL_ADC_Stop(&hadc1); }/* USER CODE BEGIN 2 */ OLED_Init(); //初始化OLED OLED_display_pic(); //显示开机LOGO图片 LED_Check(); //灯光检测 OLED_display_info(); //显示数据界面 /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { LED1_ON(); //ADC采样指示灯点亮 Get_ADC0_Value(); //进行一次ADC采样及逻辑处理 OLED_display_dat(); //更新OLED中的采样数据 HAL_Delay(200); //延时0.2秒 LED1_OFF(); //ADC采样指示灯关闭 /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */
2022年01月31日
848 阅读
0 评论
13 点赞
1
2
3
...
6