首页
📁归档
⏳时光机
📫留言
🚩友链
💰资助名单
推荐
🎧音乐
🏜️ 壁纸
❤ 捐助
Search
1
【NPN/PNP三极管】放大电路饱和失真和截止失真的区别
13,799 阅读
2
论文写作中如何把word里面所有数字和字母替换为新罗马字体
7,723 阅读
3
【高数】形心计算公式讲解大全
7,166 阅读
4
【概论】一阶矩、二阶矩原点矩,中心矩区别与概念
5,628 阅读
5
【1】基于STM32CubeMX-STM32GPIO端口开发
5,614 阅读
🪶微语&随笔
励志美文
我的随笔
写作办公
📡电子&通信
嵌入式&系统
通信&信息处理
编程&脚本笔记
⌨️IC&系统
FPGA&ASIC
VLSI&IC验证
EDA&虚拟机
💻电子&计算机
IP&SOC设计
机器学习
软硬件算法
登录
📡电子&通信(共112篇)
找到
112
篇与
📡电子&通信
相关的结果
- 第 3 页
2023-02-09
VCS、Verdi与Makefile使用简介
前期工作 1、.fsdb文件 在使用Makefile文件前,先在测试文件中加入这样一句。 initial begin $fsdbDumpfile("tb.fsdb");//这个是产生名为tb.fsdb的文件 $fsdbDumpvars; end需要注意:对于用于仿真的testbench,需要额外建立一个 initial 块,调用产生有关 fsdb 格式的波形文件: 首先调用 fsdbDumpfile 函数,产生一个叫 .fsdb 的波形文件 然后调用 fsdbDumpvars 函数,声明需要保存那些信号的波形,括号内不加任何参数,则默认全部保存。 2、 filelist.f文件 filelist.f里存放所有需要仿真的.v文件。 创建filelist.f的方法: find -name "*.v" >filelist.f 1. Makefile作用? 编写makefile文件本质上是帮组make如何一键编译,进行批处理,makefile文件包含的规则命令使我们不需要繁琐的操作,提高了开发效率。 Makefile可以根据指定的依赖规则和文件是否有修改来执行命令。常用来编译软件源代码,只需要重新编译修改过的文件,使得编译速度大大加快。 2. Makefile应用 利用Makefile 实现简单的前端设计流程,包括VCS编译,Verdi仿真,DC综合,后续流程待补充。 目录结构 图片 #use "make" for help help: @echo "make help" @echo "make com to compile" @echo "make sim to run simulation" @echo "make clean to delete temporary files" #need to midify design name design_name = div_top fsdb_name = $(design_name).fsdb # use command "make com" to run vsc and product fsdb file com: cd RTL && vcs \ -full64 \ -f flist.f \ -debug_all \ -l com.log \ +v2k \ -P ${Verdi_HOME}/share/PLI/VCS/LINUXAMD64/novas.tab ${Verdi_HOME}/share/PLI/VCS/LINUXAMD64/pli.a # cd RTL && ./simv -l sim.log +fsdbfile+$(fsdb_name) #simulation:product fsdb file and sim log sim: ./RTL/simv cd RTL && ./simv -l sim.log +fsdbfile+$(fsdb_name) # use verdi to observe the waveform verdi: cd RTL && verdi \ +v2k \ -f flist.f \ -ssf $(fsdb_name) & #use fsdb file # run dc for synthesize syn: cd dc_script && dc_shell -64bit -topographical -f top_syn.tcl | tee -i syn.log #delete all files except .v and makefile clean: #rm -rf `ls | grep -v "Makefile"|grep -v "flist.f" | grep -v "\.v" | grep -v "dc_script"` make -C RTL clean make -C dc_script clean/RTL目录下MakeFile #delete temporary files clean: rm -rf `ls | grep -v "Makefile"|grep -v "flist.f" | grep -v "\.v"` dc_script目录下Makefile #delete temporary files clean: rm -rf `ls | grep -v "Makefile"|grep -v "script" | grep -v ".*.tcl"` make com :调用vcs编译 make sim:调用vcs仿真 make verdi 波形,shifrt+l可刷新重新编译结果 make clean 删除所有子目录下的临时生成文件 详细命令 执行“make vcs” 编译仿真 执行“make verdi” 打开波形 verdi常用快捷键 ctrl+w: 添加信号到波形图 h: 在波形窗口显示详细的信号名(路径) File>save signal,命名*.rc,下次直接打开rc文件就行 c/t: 修改信号的颜色(t可以直接切换颜色) 在波形窗口显示状态机的名字: 在rtl窗口,tools>Extract internative FSM ,可选first stage(仅展开目前所指定的FSM state),all stage (展开所有的FSM state) 改变颜色填充波形: Tools>waveform>view options>waveformpane> paint waveform with specified color/pattern 在rtl窗口按x: 标注出信号的值 z: 缩小波形窗口 Z: 放大波形窗口 f: 全屏 l: 上一个视图 L: 重新加载设计波形或文件 n: 向前查找 N: 向后查找 ctrl+→: 向右移动半屏 ctrl+←: 向左移动半屏 双击信号波形: 跳转到rtl中信号位置,并高亮新号 b: 跳到波形图开头 e: 跳到波形图尾部 2.不使用Makefile直接执行 vcs -R -f flist.f -full64 -fsdb -l name.log verdi -f flist.f -ssf name.fsdb 图片
编程&脚本笔记
EDA&虚拟机
# EDA&虚拟机
# Makefile
刘航宇
2年前
0
867
2
TCL脚本语言用法简介
前言(TCL综述) TCL(Tool Command Language)是一种解释执行的脚本语言(Scripting Language)。 它提供了 通用的编程能力:支持变量、过程和控制结构;同时 TCL还拥有一个功能强大的固有的核心命令集。 由于TCL的解释器是用一个C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作一个C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,可以很容易就在C\C++应用程序中嵌入TCL,而且每个应用程序都可以根据自己的需要对TCL语言进行扩展。我们可以针对某一特定应用领域对TCL语言的核心命令集进行扩展,加入适合于自己的应用领域的扩展命令,如果需要,甚至可以加入新的控制结构,TCL解释器将把扩展命令和扩展控制结构与固有命令和固有控制结构同等看待。扩展后的TCL语言将可以继承TCL 核心部分的所有功能,包括核心命令、控制结构、数据类型、对过程的支持等。根据需要,我们甚至可以屏蔽掉TCL的某些固有命令和固有控制结构。通过对TCL的扩展、继承或屏蔽,用户用不着象平时定义一种计算机语言那样对词法、语法、语义、语用等各方面加以定义,就可以方便的为自己的应用领域提供一种功能完备的脚本语言。 TCL良好的可扩展性使得它能很好地适应产品测试的需要,测试任务常常会由于设计和需求的改变而迅速改变,往往让测试人员疲于应付。利用TCL的可扩展性,测试人员就可以迅速继承多种新技术,并针对产品新特点迅速推出扩展TCL命令集,以用于产品的测试中,可以较容易跟上设计需求的变化。 另外,因为TCL是一种比C\C++ 语言有着更高抽象层次的语言,使用TCL可以在一种更高的层次上编写程序,它屏蔽掉了编写C\C++程序时必须涉及到的一些较为烦琐的细节,可以大大地提高开发测试例的速度。而且, 使用TCL语言写的测试例脚本,即使作了修改,也用不着重新编译就可以调用TCL解释器直接执行。可以省却不少时间。TCL 目前已成为自动测试中事实上的标准。 目录 前言(TCL综述) 语法脚本,命令和单词符号 置换(substitution) 变量置换variable subtitution 命令置换command substitution反斜杠置换backslash substitution 双引号和花括号 变量简单变量 数组 append和incr expr List concat lindex llength linsert lreplace lrange lappend lsearch 控制流 if 循环命令:while 、for 、 foreach while for break和continue命令 switch source 过程(procedure) 附录(Tcl的安装) 直接打开终端(terminal),输入 sudo apt install tcl即可进行安装,这里的截图是笔者安装成功后的实例。 图片 之后输入tclsh即可 语法 脚本,命令和单词符号 一个TCL脚本可以包含一个或多个命令。命令之间必须用换行符或分号隔开,下面的两个脚本都是合法的: set a 1 set b 2 或使用分号隔开 set a 1;set b 2TCL解释器对一个命令的求值过程分为两部分:分析和执行。在分析阶段,TCL 解释器运用规则把命令分成一个个独立的单词,同时进行必要的置换(substitution); 在执行阶段,TCL 解释器会把第一个单词当作命令名,并查看这个命令是否有定义,如果有定义就激活这个命令对应的C/C++过程,并把所有的单词作为参数传递给该命令过程,让命令过程进行处理。 置换(substitution) TCL解释器在分析命令时,把所有的命令参数都当作字符串看待,例如: %set x 10 //定义变量x,并把x的值赋为10 10 %set y x+100 //y的值是x+100,而不是我们期望的110 x+100上例的第二个命令中,x被看作字符串x+100的一部分,如果我们想使用x的值’10’ ,就必须告诉 TCL解释器:我们在这里期望的是变量x的值,而非字符’x’。怎么告诉TCL解释器呢,这就要用到TCL语言中提供的置换功能。置换功能分为三种.TCL提供三种形式的置换:变量置换、命令置换和反斜杠置换。每种置换都会导致一个或多个单词本身被其他的值所代替。置换可以发生在包括命令名在内的每一个单词中,而且置换可以嵌套。 变量置换variable subtitution 变量置换由一个$符号标记,变量置换会导致变量的值插入一个单词中。例如之前的一个例子 %set x 10 //定义变量x,并把x的值赋为10 10 %set y x+100 //y的值是x+100,而不是我们期望的110 x+100 %set y $x+100 //y的值是我们期望的110 110命令置换command substitution 命令置换是由[]括起来的TCL命令及其参数,命令置换会导致某一个命令的所有或部分单词被另一个命令的结果所代替。例如: %set y [expr $x+100] 110这里当TCL解释器遇到字符’[‘时,它就会把随后的expr作为一个命令名,从而激活与expr对应的C/C++过程,并把expr和变量置换后得到的10+100传递给该命令过程进行处理。 反斜杠置换backslash substitution TCL语言中的反斜杠置换类似于C语言中反斜杠的用法,主要用于在单词符号中插入诸如换行符、空格、[、$等被TCL解释器当作特殊符号对待的字符。 %set msg money\ \$3333\ \nArray\ a\[2] //这个命令的执行结果为: money $3333 Array a[2]双引号和花括号 除了使用反斜杠外,TCL提供另外两种方法来使得解释器把分隔符和置换符等特殊字符当作普通字符,而不作特殊处理,这就要使用双引号和花括号({})。 TCL解释器对双引号中的各种分隔符将不作处理,但是对换行符 及$和[]两种置换符会照常处理。而在花括号中,所有特殊字符都将成为普通字符,失去其特殊意义,TCL解释器不会对其作特殊处理。 %set y "$x ddd" 100 ddd %set y {/n$x [expr 10+100]} /n$x [expr 10+100]注释 TCL中的注释符是#,#和直到所在行结尾的所有字符都被TCL看作注释,TCL解释器对注释将不作任何处理。不过,要注意的是,#必须出现在TCL解释器期望命令的第一个字符出现的地方,才被当作注释。 %set a 100 # Not a comment wrong # args: should be "set varName ?newValue?" %set b 101 ; # this is a comment 101变量 变量分为简单变量和数组 简单变量 一个 TCL 的简单变量包含两个部分:名字和值。名字和值都可以是任意字符串。 % set a 2 2 set a.1 4 4 % set b $a.1 2.1在最后一个命令行,我们希望把变量a.1的值付给b,但是TCL解释器在分析时只把$符号之后直到第一个不是字母、数字或下划线的字符(这里是’.’)之间的单词符号(这里是’a’)当作要被置换的变量的名字,所以TCL解释器把a置换成2,然后把字符串“2.1”付给变量b。这显然与我们的初衷不同。 当然,如果变量名中有不是字母、数字或下划线的字符,又要用置换,可以用花括号把变量名括起来。例如: %set b ${a.1} 4数组 数组是一些元素的集合。TCL的数组和普通计算机语言中的数组有很大的区别。在TCL中,不能单独声明一个数组,数组只能和数组元素一起声明。数组中,数组元素的名字包含两部分:数组名和数组中元素的名字,TCL中数组元素的名字(下标〕可以为任何字符串。 例如: set day(monday) 1 set day(tuesday) 2 set a monday set day(monday) 1 set b $day(monday) //b 的值为 1 ,即 day(monday) 的值。 set c $day($a) //c 的值为 1 ,即 day(monday) 的值。其他命令 unset % unset a b day(monday)上面的语句中删除了变量a、b和数组元素day(monday),但是数组day并没有删除,其他元素还存在,要删除整个数组,只需给出数组的名字。 append和incr 这两个命令提供了改变变量的值的简单手段。 append命令把文本加到一个变量的后面,例如: % set txt hello hello % append txt "! How are you" hello! How are youincr命令把一个变量值加上一个整数。incr要求变量原来的值和新加的值都必须是整数。 expr 可以进行基本的数学函数计算 %expr 1 + 2*3 7List list这个概念在TCL中是用来表示集合的。TCL中list是由一堆元素组成的有序集合,list可以嵌套定 义,list每个元素可以是任意字符串,也可以是list。下面都是TCL中的合法的list: {} //空list {a b c d} {a {b c} d} //list可以嵌套list是TCL中比较重要的一种数据结构,对于编写复杂的脚本有很大的帮助 list 语法: list ? value value…? 这个命令生成一个list,list的元素就是所有的value。例: % list 1 2 {3 4} 1 2 {3 4}使用置换将其相结合 % set a {1 2 3 4 {1 2}} 1 2 3 4 {1 2} % puts $a 1 2 3 4 {1 2}concat 语法:concat list ?list…? 这个命令把多个list合成一个list,每个list变成新list的一个元素。 % set a {1 2 3} 1 2 3 % set b {4 5 6} 4 5 6 % concat $a $b 1 2 3 4 5 6lindex 语法:lindex list index 返回list的第index个(0-based)元素。例: % lindex {1 2 {3 4}} 2 3 4llength 语法:llength list 返回list的元素个数。例 % llength {1 2 {3 4}} 3 % set a {1 2 3} 1 2 3 % llength $a 3linsert 语法:linsert list index value ?value…? 返回一个新串,新串是把所有的value参数值插入list的第index个(0-based)元素之前得到。例: % linsert {1 2 {3 4}} 1 7 8 {9 10} 1 7 8 {9 10} 2 {3 4} % linsert {1 2 {3 4}} 1 {1 2 3 {4 5}} 1 {1 2 3 {4 5}} 2 {3 4} % set a {1 2 3} 1 2 3 % linsert $a 1 {2 3 4} 1 {2 3 4} 2 3lreplace 语法:lreplace list first last ?value value …? 返回一个新串,新串是把list的第firs (0-based)t到第last 个(0-based)元素用所有的value参数替换得到的。如果没有value参数,就表示删除第first到第last个元素。例: % lreplace {1 7 8 {9 10} 2 {3 4}} 3 3 1 7 8 2 {3 4} % lreplace {1 7 8 2 {3 4}} 4 4 4 5 6 1 7 8 2 4 5 6 % set a {1 2 3} 1 2 3 % lreplace $a 1 2 4 5 6 7 1 4 5 6 7 % lreplace $a 1 end 1lrange 语法:lrange list first last 返回list的第first (0-based)到第last (0-based)元素组成的串,如果last的值是end。就是从第first个直到串的最后。 例: % lrange {1 7 8 2 4 5 6} 3 end 2 4 5 6 % set a {1 2 3} 1 2 3 % lrange $a 0 end 1 2 3lappend 语法:lappend varname value ?value…? 把每个value的值作为一个元素附加到变量varname后面,并返回变量的新值,如果varname不存在,就生成这个变量。例: % set a {1 2 3} 1 2 3 % lappend a 4 5 6 1 2 3 4 5 6lsearch 语法:lsearch ?-exact? ?-glob? ?-regexp? list pattern 返回list中第一个匹配模式pattern的元素的索引,如果找不到匹配就返回-1。-exact、-glob、 -regexp是三种模式匹配的技术。-exact表示精确匹配;-glob的匹配方式和string match命令的匹配方式相同;-regexp表示正规表达式匹配。缺省时使用-glob匹配。例: % set a { how are you } how are you % lsearch $a y* 2 % lsearch $a y? -1-all 返回一个列表,返回的列表中的数值就是字符在列表中的位置 默认全局匹配,返回第一个字符在列表中的位置,其位缺省状态 % lsearch {a b c d e} c 2 % lsearch -all {a b c a b c} c 2 5 % lsearch {a b c d c} c 2匹配不到返回-1 % lsearch {a b c d e} g -1控制流 主要是对于所有的控制流,包括 if、while、for、foreach、switch、break、continue 等以及过程, if 语法: if test1 body1 ?elseif test2 body2 elseif…. ? ?else bodyn? TCL先把test1当作一个表达式求值,如果值非0,则把body1当作一个脚本执行并返回所得值,否则把test2当作一个表达式求值,如果值非0,则把body2当作一个脚本执行并返回所得值……。例如: if { $x>0 } { ..... }elseif{ $x==1 } { ..... }elseif { $x==2 } { .... }else{ ..... }if { $x<0 } { puts "x is smaller than zero" } elseif {$x==1} { puts "x is equal 1" } elseif {$x==2} { puts "x is equal 2" } else { puts "x is other" } 这里需要注意的是, if 和{之间应该有一个空格,否则TCL解释器会把’if{‘作为一个整体当作一个命令名,从而导致错误。 ‘{‘一定要写在上一行,因为如果不这样,TCL 解释器会认为if命令在换行符处已结 束,下一行会被当成新的命令,从而导致错误的结果需要将}{ 分开写, 否则会报错extra characters after close-brace 循环命令:while 、for 、 foreach while 语法为: while test body 参数test是一个表达式,body是一个脚本,如果表达式的值非0,就运行脚本,直到表达式为0才停止循环,此时while命令中断并返回一个空字符串。 例如:假设变量 a 是一个链表,下面的脚本把a 的值复制到b: % #首先生成一个集合 % set a {1 2 3 4} 1 2 3 4 % set b " " % #计算生成集合的长度(从0开始这里需要减去1例如:0-3一共有四个数) % set i [expr [llength $a] -1] 3 #接下来进行判断,将集合a中的元素全部按顺序写入b中 % while {$i>=0} { #思考执行该行代码替换会有怎样的结果打印出来 #lappend b [lindex $a $i] lappend b [lindex $a [expr [llength $a] - 1 - $i]] incr i -1 } #打印观察结果 % puts $b 1 2 3 4对代码进行分析 set 变量a为一个list,b为一个空list 然后计算列表里有几个元素,将其减一后的值赋值给i,这里减一的目的是从零开始计数会多一个 开始进行循环,首先i的值是4大于0,表达式为真,开始执行脚本。 脚本为将数组a的第i个位置的元素添加到b list 里,然后给i减一同时进行下一次判断即可。 最后输出b的值 for 语法为: for init test reinit body 参数init是一个初始化脚本,第二个参数test是一个表达式,用来决定循环什么时候中断,第三个参数reinit是一个重新初始化的脚本,第四个参数body也是脚本,代表循环体。下例与上例作用相同:(注意这里复制打印顺序的不同) % set a {1 2 3 4} 1 2 3 4 % set b " " % for {set i [expr [llength $a] -1]} {$i>=0} {incr i -1} { lappend b [lindex $a $i] } % puts $b 4 3 2 1例 % for {set i 0} {$i<4} {incr i} { puts "I is: $i " } I is: 0 I is: 1 I is: 2 I is: 3 foreach 这个命令有两种语法形式 1, foreach varName list body 第一个参数varName是一个变量,第二个参数list 是一个表(有序集合),第三个参数body是循环体。每次取得链表的一个元素,都会执行循环体一次。 下例与上例作用相同: % set a {1 2 3 4} 1 2 3 4 % set b " " % foreach i $a { set b [linsert $b 0 $i] } % puts $b 4 3 2 1% foreach var {a b c d e f} { puts $var } a b c d e f2, foreach varlist1 list1 ?varlist2 list2 ...? Body 这种形式包含了第一种形式。第一个参数varlist1是一个循环变量列表,第二个参数是一个列表list1,varlist1中的变量会分别取list1中的值。body参数是循环体。 ?varlist2 list2 …?表示可以有多个变量列表和列表对出现。例如: set x {} foreach {i j} {a b c d e f} { lappend x $j $i }这时总共有三次循环,x的值为”b a d c f e”。 % foreach i {a b c} j {d e f g} { puts $i puts $j } a d b e c f gset x {} foreach i {a b c} j {d e f g} { lappend x $i $j }这时总共有四次循环, x的值为”a d b e c f {} g set x {} foreach i {a b c} {j k} {d e f g} { lappend x $i $j $k }这时总共有三次循环,x的值为”a d e b f g c {} {}”。 例子: 图片 break和continue命令 在循环体中,可以用break和continue命令中断循环。其中break命令结束整个循环过程,并从循环中跳出,continue只是结束本次循环 这里有一个特别好的例子 说明:这里首先进行给一个list,然后使用foreach循环进行写入数据当遇见break时候直接退出了循环,而continue仅仅只是跳出此次循环继续向b里写入数 % set b {} % set a {1 2 3 4 5} 1 2 3 4 5 % foreach i $a { if {$i == 4} break set b [linsert $b 0 $i] } % puts $b 3 2 1% set b {} % set a {1 2 3 4 5} 1 2 3 4 5 % foreach i $a { if {$i == 4} continue set b [linsert $b 0 $i] } % puts $b 5 3 2 1switch 和 C 语言中 switch 语句一样,TCL 中的 switch 命令也可以由 if 命令实现。只是书写起来较为烦琐。 switch 命令的语法为: switch ? options? string { pattern body ? pattern body …?} 注意这里进行的是字符匹配 图片 set x a; set t1 0;set t2 0;set t3 0; switch $x { a - b {incr t1} c {incr t2} default {incr t3} } puts "t1=$t1,t2=$t2,t3=$t3"x=a时执行的是t1加2 其中 a 的后面跟一个’-’表示使用和下一个模式相同的脚本。default 表示匹配任意值。一旦switch 命令 找到一个模式匹配,就执行相应的脚本,并返回脚本的值,作为 switch 命令的返回值。 source source 命令读一个文件并把这个文件的内容作为一个脚本进行求值 以上边的switch第一段代码为例 使用VIM新建一个文件,写入文件后保存退出 vim switch1.tcl键入wish然后输入source switch1.tcl 图片 过程(procedure) TCL 支持过程的定义和调用,在 TCL 中,过程可以看作是用 TCL 脚本实现的命令,效果与 TCL的固有命令相似。我们可以在任何时候使用 proc 命令定义自己的过程,TCL 中的过程类似于 C中的函数。 TCL 中过程是由 proc 命令产生的: 例如: % proc add {x y } {expr $x+$y} roc 命令的第一个参数是你要定义的过程的名字,第二个参数是过程的参数列表,参数之间用空格隔开,第三个参数是一个 TCL 脚本,代表过程体。 proc 生成一个新的命令,可以象固有命令一样调用: % add 1 2 3
编程&脚本笔记
# TCL脚本
刘航宇
2年前
0
874
0
2022-12-31
LoRa码元调制、编码与解调
LoRa调制链路 ●LoRa调制链路由五部分组成,分别是纠错编码机、交织器、扩频序列产生器、笛卡 尔极坐标转换器、Delta-sigma调制器。 image.png图片 纠错编码器 ●当一组数据(用户的有效载荷(Payload) )被推入数据包接口( Packet Interface)时,调制过程开始。调制器通过纠错编码机将前向纠错编码(ForwardErrorCorrection,FEC)添加到这些字节中。 ●这些有效载荷数据每个字节首先分成半字节(4比特一组)。然后,根据编码速率配置, 在1到4冗余纠错位之间选择并追加到每个半字节。调制器编码速率通过CR寄存器进行设置,表3-1为前向纠错编码配置表。 image.png图片 交织器 ●纠错编码后,产生的(4+CR)位比特段,随后被存储到交织器的存储阵列中。交织器(Interleaver) 有(4+CR)列和SF行。一旦交织器满了,它的内容将编码到码元上。每个码元都带有SF位。因此,交织器内有(4+CR) *SF 比特,独立于扩频因子SF被编码到4+CR码元上。 ●这里举一一个例子让读者理解交织器。假设此时CR=1,,, SF=7, 其交织器为7行、5列。需要传输的数据流为:00000001001000110100010101100111。先将这些比特流分为4b一组(b1,b2,b3,b4) : 0000; 0001; 0010; 0011; 0100;0101; 0110; 0111; 对上述数据增加1比特校验位(b1,b2,b3,b4,C) 后为: 00000; 00011; 00101; 00110; 01001;01010; 01100; 01111; 再将,上述数字填入交织器的存储列阵中,当35b数据进入交织器的存储列阵后,交织器存储满了,下一组数据(b1,b2,b3,b3,C) 需要填入下一个交织器中。 image.png图片 扩频序列产生器 image.png图片 门坐标转换、Delta-sigma调制输出 image.png图片 解调 image.png图片 编码 下是一个SF=7的LoRa调制编码图, 从图中可以看出码元、码片、比特速率、载荷数据之间的关系。 图中SF=7, 所以发送信号带宽切分为128(27-128)个频率段的码片。假设该系统工作频率为470MHz,BW=250kHz,相邻码片间隔为250kHz/128=1 .95kHz,此时f0=470MHz,f1=470.00195MHz,f2=470.0039MHz,.. .f127=470.24805MHz. 图3-9中有三个时间长度分别是码片率(Chip rate),比特速率(Data rate),码元率(Symbol rate),可以清楚地看出它们的对应关系. 图片 解释一下:如果要发送f64,就在f64频率出加到f127,然后再从f0加到f64 不同的SF对应带宽BW除以时间的斜率,SF越大倾斜角度越小。SF和BW对应一种LoRa调制方式,只有接收机也采用对应的SF和BW才能正常解调,否则信号在相干解 调中会淹没在噪声中。在实际的相干解调中,LoRa调制在不同的SF信号或不同的BW下都是正交的,频带可以充分利用。比如在BW=125kHz的同频段内,一个SF=7信号 Psez和一个SF=8信号Psps都在发射,频段内的噪声为N,,当两个信号都满足解调信噪比要求时(SNRsf7 >=-7.5dB; SNRsf8>=-10dB) ,两个信号都可以正常解调。这里需要注意,当计算SNRsf7时,SF=8的信号表现为此系统噪声,SNRsF7= Psp/(N0+Psf8) ; 同理当计算SNRsf8时,SF=7的信号表现为此系统噪声,SNRsf8=Psf8/(N0+Psf7). 图片
通信&信息处理
# 信号处理
刘航宇
3年前
0
710
1
【LoRa】Chirp调制
线性调频信号的表征与特征 线性调频(Linear Frequency Modulation, LFM) 是一种不需要伪随机编码序列的扩展频谱调制技术。因为线性调频信号占用的频带宽度远大于信息带宽,所以也可以获得很大的系统处理增益。线性调频信号也称为鸟声(Chirp) 信号,因为其频谱带宽落于可听范围,听着像鸟声(英文单词Chirp为鸟叫的意思),所以又称Chirp护展频谱(Chirp SpreadSpectrum,CSS)技术。LFM技术在雷达、声纳技术中有广泛应用,例如,在雷达定位技术中,它可用来增大射频脉冲宽度、加大通信距离、提高平均发射功率,同时又保持足够的信号频谱宽度,不降低雷达的距离分辨率。 将CSS技术用于扩频通信的研究发展日益活跃,尤其随着超宽带(UWB) 技术的发展,将CSS技术与UWB的宽带低功率谱相结合形成的Chi rp-UWB通信,它利用Chi rp技术产生超宽带宽,具备二者优势,增强了抗干扰与抗噪声的能力。CSS技术已成为传感网络通信标准,IEEE802. 15中物理层候选标准。 FM、FSK、CSS信号比较 图片 线性调频(LFM)信号 图片 Chirp信号调制技术的产生与检测 Chirp通信信号-般形式 通信的二元数据也可用LFM信号,常称为Chirp信号来传输。最常用做法是用围绕着中心频率f的正向和负向频率斜升变化来代表二元信码“1”与“0” 接收端采用两个相应的匹配滤波器来检测。匹配滤波器 输出是一个峰值功率正比于时间带宽积FT的压缩脉冲, 通过取样判决可以恢复出信码“1”。代表信码“0”的负斜 率Chirp信号通过对应的负斜率匹配滤波器可得出与正斜 率匹配滤波器相同结论的压缩脉冲,通过取样判决确定 信码“0”。 图片 2.信号调制 图片 3.Chirp信号解调和检测 图片 LoRa调制 图片 图片 图片
通信&信息处理
# 信号处理
刘航宇
3年前
0
1,333
2
基本微带贴片天线设计理论与尺寸算法
理论 图片 贴片形式 图片 馈电方式 图片 尺寸推导 图片 图片 尺寸算法 %微带天线尺寸算法 c=3e8; f=0.915e9 %频率915MHZ er=2.2;%板材介电常数 h=1.575e-3;%板材厚度 w=c/(2*f)*sqrt(2/(er+1)) ereff=(er+1)/2+(er-1)/2*(1+12*h/w)^(-0.5); dL=(0.412*(ereff+0.3)*(w/h+0.264)*h)/((ereff-0.258)*(w/h+0.8)); Leff=c/(2*f*sqrt(ereff)); L=Leff-2*dL erl=(er+1)/2+(er-1)/2*(1+12*h/L)^(-0.5); Xf=L/2-L/(2*sqrt(erl)) Lgnd=L+6*h; Wgnd=w+6*h;微带线馈电 图片 1/4波长变换器 图片 计算推导 图片 尺寸算法 %微带天线尺寸算法 clear all; c=3e8; f=0.915e9 %频率915MHZ er=2.2;%板材介电常数 h=1.575e-3;%板材厚度 w=c/(2*f)*sqrt(2/(er+1)) ereff=(er+1)/2+(er-1)/2*(1+12*h/w)^(-0.5); dL=(0.412*(ereff+0.3)*(w/h+0.264)*h)/((ereff-0.258)*(w/h+0.8)); Leff=c/(2*f*sqrt(ereff)); L=Leff-2*dL erl=(er+1)/2+(er-1)/2*(1+12*h/L)^(-0.5); Xf=L/2-L/(2*sqrt(erl)) Lgnd=L+6*h; Wgnd=w+6*h; %Microstrip Line feed lambda_0=c/f; if w<=lambda_0 G=w^2/(90*lambda_0^2); else G=w^2/(120*lambda_0^2); end Yin=2*G; Rin=1/Yin ZT0=sqrt(Rin*50)
通信&信息处理
# 天线设计
刘航宇
3年前
0
2,423
9
2022-11-27
【天线/射频】什么是回波损耗?什么是插入损耗?
一、前言 什么是回波损耗?什么又是插入损耗? 这个貌似很容易回答,回波损耗吗,就是Return Loss,缩写为RL,S11,插入损耗就是 Insertion Loss,IL,S21。确实没错,就是这么简单。但是为什么叫做回波呢?为什么又叫做插入呢?今天我们仔细掰扯掰扯。 二、回波损耗 回波损耗,又称为反射损耗。( 越大越好 )是电缆链路由于阻抗不匹配所产生的反射,是一对线自身的反射。不匹配主要发生在连接器的地方,但也可能发生于电缆中特性阻抗发生变化的地方,所以施工的质量是提高回波损耗的关键。回波损耗将引入信号的波动,返回的信号将被双工的千兆网误认为是收到的信号而产生混乱。 回波损耗:return loss。回波损耗是表示信号反射性能的参数。回波损耗说明入射功率的一部分被反射回到信号源。例如,如果注入1mW (0dBm)功率给放大器其中10%被反射(反弹)回来,回波损耗就是-10dB。从数学角度看,回波损耗为-10 lg [(反射功率)/(入射功率)]。回波损耗通常在输入和输出都进行规定。 三、插入损耗 插入损耗:insertion loss。( 越小越好 )指在传输系 统的某处由于元件或器件的插入而发生的负载功率的损耗,它表示为该元件或器件插入前负载上所接收到的功率与插入后同一负载上所接收到的功率以分贝为单位的比值。 1.插入损耗是指发射机与接收机之间,插入电缆或元件产生的信号损耗,通常指衰减。插入损耗以接收信号电平的对应分贝(dB)来表示。 2.插入损耗多指功率方面的损失,衰减是指信号电压的幅度相对测量插入损耗的电路原信号幅度的变小。 通道的插入损耗是指输出端口的输出光功率与输入端口输入光功率之比,以dB为单位。插入损耗与输入波长有关,也与开关状态有关。定义为:IL=-10log(Po/Pi) 四、插入损耗和回波损耗系统介绍 图片 首先,我们拿到一个系统,就是上面这个黑盒子,当电磁波信号进入这个黑盒子时,我们通常不需要去关心电磁波在里面经历了什么。我们只要知道它出来是什么就行了。但是,当电磁波从外面进入这个黑盒子时,相当于从一个介质进入到另一个介质,在交界面上会有一部分电磁波被挡在外面,这部分被挡在外面的电磁波就被反射回去了,返回去的电磁波就是回波。而进去的这部分电磁波在通过这个黑盒子时,就必然会被这个黑家伙影响到,如果这家伙有一点点贪心,肚子里装了一点点的小电阻材料,那么就留一点点买路钱就够了,就去的电磁波在交完买路钱之后,大部分会传输出去,这个被劫走的一部分电磁波能量我们就认为被损失了,无论是回波还是黑盒子吃掉的都是电磁波能量时导致的能量的损耗,都是由于黑盒子插入进来导致的损耗,所以通常被称为插入损耗。如下图所示。 图片 所以我们知道,其实一个微波元器件的插入损耗是由两部分组成的:回波损耗和电阻损耗。 回波损耗的这部分电磁波能量被端口的不匹配给反射回去了,并没有转化成热散出去,所以我们在射频系统设计和分析中,要提防着这部分回波倒灌会对系统带来的影响。通常这部分倒灌的能量不是很大,怎么计算呢? 举个简单的例子,比如上图端口1输入的电磁波功率是1W,即30dBm,如果端口1 的回波损耗RL=20dB。那么反射回去的回波的功率就是:30dBm-20dB=10dBm,也就是有10mW的功率被反射回去了。如果端口1 输入的功率是1kW,即60dBm,那么反射回去的回波功率就有10W了。如果端口1的回波损耗只有10dB,那将会有100W的功率被反射回去。这也证明了匹配的端口阻抗匹配的重要性。还有就是,功率越大,我们系统所要求的回波损耗就越小,在一些小功率的产品中,比如手机,匹匹配有个10dB就足够了。但是在电视发射系统中,因为发射机的功率通常会有上千瓦,所以,回波损耗通常要求在26dB以下。 注意,插入损耗的部分损耗也是有回波导致的啊,所以回波损耗越差,插入损耗就越大。 在端口匹配良好的系统中,插入损耗主要是由器件的电阻性材料导致的,这些电阻性材料导致的损耗,会转化成热。就像我们在衰减器中介绍的一样。其实转化成热,有时候更让我们头疼。因为热这个东西太可怕了,几乎所有的电子器件都有一个可以正常工作的温度范围,当超过这个温度了之后,工作就不正常了。长期在高温环境下工作,器件老化速率会加快,更容易损坏。
通信&信息处理
# 天线设计
刘航宇
3年前
1
2,843
1
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~+15V RS-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({data_disp[11:0],sw[11:0]}), .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图片 串口发送程序设计 图片 串口接收程序设计 图片 图片
嵌入式&系统
通信&信息处理
# ASIC/FPGA
刘航宇
3年前
0
456
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以内。 图片
嵌入式&系统
# 天线设计
# 电子线路
刘航宇
3年前
0
2,708
5
高速电路系统-传输线阻抗匹配
目录 传输线反射系数 信号反射分析 信号阻抗匹配设计 调试办法 传输线反射系数 ●当传输线的传播的信号到达某个阻抗不连续点时,信号会发生反射, ●就像水流通过不同口径的管道接口时,水面产生波动一样。 ●根据反射电压和入射电压的比值, 可以定义传输线上的反射系数。 $\Gamma=\frac{V_{r e f}}{V_{i n c}}=\frac{R_L-Z_0}{R_L+Z_0}$ 信号反射分析 图片 在信号跳变的瞬间,源端和负载端的电压变化 信号阻抗匹配设计 图片 优点:RS无需电源,低功耗,对于驱动高容性负载起到限流作用,有效的避免了一些噪声。 缺点:信号源加电阻占空间,对扇出不好。 图片 (C)优点RC隔直流,消除直流损耗。电容有充电时间,RC饱和时间大于2倍传输线延迟,也就是源端发射信号到RC电路之前没有饱和。 调试办法 图片 在射频电路中进行阻抗匹配测试时,可按照如下步骤进行射频匹配网络调试: 1:校准矢量网络分析仪 2:用矢网测量开口线,保存S1P文件。 在ADS中新建工程,按照如下原理图,插入开口线的S1P文件,使用ADS调谐调整微带线的长度,使开口线位于smith圆图的最右边使其处于开路状态,更新原理图参数。 图片 3:测量前级的输出阻抗 将开口线焊接在焊点1的位置,利用矢网测量出前级网络的输出阻抗,保存S1P文件,利用上面抵消开口线参数影响后更新后ADS原理图,插入前级网络S1P文件,在ADS里读出对应频率点的阻抗Z1 4:测量下级的输出阻抗 将开口线焊接在焊点2的位置,利用矢网测量出后级网络的输出阻抗,保存S1P文件,利用上面抵消开口线参数影响后更新后ADS原理图,插入后级网络S1P文件,在ADS里读出对应频率点的阻抗Z2 5:利用ADS的Smith Chart Utility 进行阻抗匹配 图片 将前级网络的输出阻抗Z1取共轭,负载网络的输入阻抗为Z2,代入到Utility进行阻抗匹配,最后将匹配后的元件值焊接到板子上进行测试
嵌入式&系统
通信&信息处理
刘航宇
3年前
0
610
2
GUN Radio实战信号源设计&USRP发射接收波形信号
目录 信号源设计 用 USRP 发射接收波形信号 信号源设计 目标:创建一个正弦波,并使用时域 Scope Sink 查看生成的波形。了解基本的流程图构建和常用模块的使用。 1.在终端窗口中输入:gnuradio-companion 打开 GRC 软件。 2.将 Options 模块的 ID 属性设置为 LAB2,Generate Options 属性设置为 QT GUI。 3.使用快捷键 Ctrl+F 或点击菜单栏中的 搜索图标 查找模块 signal source 信号 发生模块,和 scope sink 图形显示模块。双击或拖动模块到画布上。 图片 由于 GNU 中 scope 模块只有 WX GUI 类型的,如下图所示 图片 所以我们需要将 Options 模块的 Generate Options 属性值相应的改为 WX GUI。否则程序将会报错并不能被执行。如下图所示,连接 Signal Source 模块 和 WX GUI Scope Sink 模块,而 WX GUI Scope Sink 模块为红色,点击工具栏中的运行按钮会显示出错误原因: 图片 5.此时,若我们想在程序运行时,在 GUI 界面能够随时改变频率的值,则需要添加 WX GUI Slider 模块。 图片 6.为了防止 CPU 过载,我们添加一个 Throttle 模块。Throttle 模块主要起到限速的作用,设置高的速率,程序执行的快,设置低的速率程序行的慢。当有硬件连接的时候,我们不需要 Throttle 模块,因为硬件本身就对速率有了限制。 这里我们讲一下,为什么所有的流程图都要用 Throttle 模块,先看下使用了与没有使用 Throttle 模块的正弦波流程图上的系统资源监控对比: 图片 下图为 Throttle 为不同值时,CPU 的使用速率。 图片 Throttle 模块的作用可以理解为限速:速度越高我们流程图运行的速度越高,速度越低流程图运行的速度越低。我们如果将 Throttle 模块的采样率调到1e6比调到 1e3(CPU 配置低就调的更低一些防止跑死)的 CPU 负载要高很多。 7.在桌面创建一个 LAB-LW 的文件夹,将刚刚连接好的程序保件夹中,并将其保存为 LAB1.grc。 整体流程框图: 图片 流程结果图: 图片 用 USRP 发射接收波形信号 目标:学会使用 USRP 设备利用现有的程序进行简单的修改实现简单的发送接收。 并熟悉 UHD 模块的基本使用。 通过上一个练习我们已经知道怎样建立一个不通过外部设备即可接收到波形信号的程序,在本节练习中,我们将对上节程序进行简单的修改然后利用外部 USRP 设备进行发射接收波形信号。 将 Options 模块的 ID 属性设置为 LAB2,Generate Options 属性设置为 QT GUI。 2.由于有外部硬件连接了,所以我们不需要 Throttle 模块了, Throttle WX GUI Scope Sink 模块删除。 3.删除两个 WX GUI Slider 模块。 4.修改 Signal Source 模块的属性参数: 图片 5.从模块库中将 QT GUI Sink,UHD:USRP Sink 模块添加到 布中,将 Signal Source 模块的输出端与 QT GUI Sink 模块和 UHD:USRP S nk 模块的输入端连接到一起。其中 UHD:USRP Sink 模块用来发射波形信号,QT GUI Sink 模块用来查看发射的波形信号。 其具体的模块属性参数如下图所示: 图片 6.从模块库中将 UHD:USRP Source,QT GUI Sink 模块 加到画布中,将 UHD:USRP Source 模块的输出端连接到 QT GUI Sink 模块的输入段。其中, UHD:USRP Source 模块用来接收波形信号,QT GUI Sink 模块用来显示接收 波形。 其具体的模块属性参数如下图所示: 图片 UHD:USRP Sourc属性参数。 USRP B210 更改 A 通道或 B 通道: 图片 7.添加两个 QT GUI Range 模块,并将其 ID 改为 gain_tx,和 gain_rx。用于调整发射端和接收端的增益值。 图片 图片 8.为了方便我们查看发射和接收的波形信号,我们添加一个 QT GUI Tab Widget模块。将 ID 更改为 ab,Num Tabs 改为2,Label0名称更改为 TX,用来查看发射端的波形情况;Label1名称更改为RX,用来查看接收端的波形情况。 图片 同时,更改发射端 QT GUI Sink 模块的 GUI Hint 属性为 lab@0;更改接收端 QT GUI Sink 模块的GUI Hint 属性为 lab@1。 将连接好的程序保存在 LAB-LW 的文件夹中,并将其保存为 LAB2.grc 整体流程框图: 图片 流程结果图: (此程序采用 USRP-LW B210运行,同时将通道 A 的 TX/RX2端外接馈线或连接天线) 发射端波形: 图片 接收端波形: 图片
通信&信息处理
# 软件无线电
刘航宇
3年前
0
3,139
5
2022-05-07
智能无源感知技术简介
图片 什么是无源感知?——设备发射无线信号(例如WIFI、声波、RFID、光以及毫米波等),无线信号被待检测对象反射,特定路径的信号返回到接收设备,通过对获取的无线信号进行信号处理等流程获取待检测对象的信息。 生活中的无源感知广泛应用于人机交互、软件定义设备、健康监护及行为识别等领域,比如老人跌倒监测、Google Pixel 4手势识别、超声波VR交互、基于RFID的软件定义转速仪等。 而当今社会中的人机交互领域,目前已经催生出机械设备人机交互、可穿戴设备人机交互与无源感知人机交互三大应用,其中的无源感知由于其与设备间的隔离状态,可操作性更强、卫生性也更好。 软件定义设备,自1883年Warren S.Johnson发明全球首台恒温器,近年来已经由机械型传感器进化为固体传感器、智能MEMS传感器,时至今日,无源感知为基础的新型传感器已经成为最新的科技产物。 该技术拥有三大特点:声波的短波长提供细粒度特征、声波在空气中自由传播提供非接触感知方式、基于智能移动设备的低成本软件开发。而创新思路主要为设计具有物理强关联特征的提取方法,采用多维信号智能融合。
通信&信息处理
刘航宇
3年前
0
476
2
2022-04-20
HAL库开发stm32 DHT11传感器
目录 现象 dht11.h dht11.c main.c添加 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 = {0}; /*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 = {0}; /*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显示出温度湿度哈,这个我就不写代码了,不然真的是再喂饭了呜呜! }
嵌入式&系统
# 嵌入式
刘航宇
3年前
0
956
15
上一页
1
2
3
4
...
10
下一页