众所周知,LaTeX中拥有强大的绘图宏包TikZ,但是其并不能很好的支持电路图的绘制,而基于TikZ的CircuiTikZ宏包则包含了各种元器件的定义,并且样式和种类都非常丰富,使用它可以方便地绘制出各种电路图。

一个简单的例子

首先在导言区引入宏包circuitikz

1
\usepackage{circuitikz}

然后在正文加入

1
2
3
4
5
\begin{circuitikz}
\draw (0,0) to[V=1V] (0,2)
to[R=$1\Omega$] (2,2)
to[C=1F] (2,0) -- (0,0);
\end{circuitikz}

生成PDF的效果

My First Circuit

代码中使用\draw来表示绘制的开始,注意不要忘记最后的;(0,0) to[V=1V] (0,2)表示绘制一个从点(0,0)到点(0,2)的电压源,1V表示元件的标签,绘制后的元件会处于给定的两点的中央位置;--表示直接用线将两点连接即短路,也可以用to[short]来代替。

总结起来,绘制的语法是(<坐标>) [<元件>] (<坐标>) [<元件>] (<坐标>) ...,短路也可以看作是一种元件。

多个回路的情况

观察下面的例子

1
2
3
4
5
6
\begin{circuitikz}
\draw (0,0) to[V=1V] (0,2)
to[R=$1\Omega$] (2,2) -- (4,2)
to[C=1F] (4,0) -- (0,0);
\draw (2,2) to[L=1H, *-*] (2,0);
\end{circuitikz}
Two Loops

代码首先绘制了“电压源-电阻-电容”这条回路,然后再重新使用一个\draw命令绘制了电感,当然,也可以先绘制“电压源-电阻-电感”这条回路再绘制电容。

(2,2) to[L=1H, *-*] (2,0)与上面的例子有些不同,连线变成了*-*,这条命令可以绘制连接处的黑点。试试-**-,它们分别表示只在起点和只在终点的黑点,而-oo-o-o则是空心点。

更多元器件和标注方式

1
2
3
4
5
6
7
\begin{circuitikz}
\draw (0,0) to[I] (0,2);
\draw (2,0) to[D] (2,2);
\draw (4,0) to[vR] (4,2);
\draw (6,0) to[lamp] (6,2);
\draw (8,0) to[eC] (8,2);
\end{circuitikz}
More Components

如上面所展示的,CircuiTikZ宏包还提供了各种各样的元器件,这些都可以在参考手册中找到。

对于元件的标注方式,下面的几种写法都是基本一致的

1
2
3
\draw (0,0) to[R=$1\Omega$] (0,2);
\draw (0,0) to[R, l=$1\Omega$] (0,2);
\draw (0,0) to[R, a=$1\Omega$] (0,2);

如果想让标签到另一侧,可以将l改成l_,或者a改成a^。而如果想在元件上添加两个标签,则可以用

1
\draw (0,0) to[R, l=$R_1$, a=$1\Omega$] (0,2);
Component Labels

这样标签就会分别位于元件的两侧,那么问题来了:如果我想让标签都在一侧怎么办?你可能会想到使用断行\\

1
\draw (0,0) to[R, l={$R_1$\\$1\Omega$}] (0,2);

但是这样会报错,因为CircuiTikZ的Label并不支持多行,在这里推荐一种方法,用pbox宏包来解决这个问题。

在导言区加入

1
2
\usepackage{pbox}
\newcommand{\ctikzlabel}[2]{\pbox{\textwidth}{#1\\#2}} % 元件多行标签

上面的代码表示定义了\ctikzlabel命令,\pbox具有两个参数,的第一个是指定盒子的最大宽度,使用当前的文本行宽\textwidth可以保证绝对够用,第二个参数是#1\\#2,为标签两行的内容。与\pbox类似的还有parbox宏包的\parbox命令,不过它的第一个参数定义的是盒子宽度而不是最大宽度,有时候会不好确定,因此推荐使用自动宽度的\pbox

这样我们就可以使用\ctikzlabel来定义在一侧的多行标签了,下面的代码就实现了这个效果

1
2
3
\begin{circuitikz}
\draw (0,0) to[R, l=\ctikzlabel{$R_1$}{$1\Omega$}] (0,2);
\end{circuitikz}
Component Labels on Both Sides

如果想在某个指定的节点加入文字,可以使用

1
2
3
4
5
\begin{circuitikz}
\draw (0,0) node[below]{Start}
to[R, l=$R_1$]
(0,2) node[above]{End};
\end{circuitikz}
Add Node Name

在坐标后添加node[<样式>]{<文字>},其中<样式>可以是位置(包括left、right、above、below,它们可以组合使用)、颜色等,也可以省略,<文字>是必选的。

多端元件

这里以典型的三端元件NPN三极管为例,通过下面的代码可以绘制出一个三极管

1
2
3
4
5
6
\begin{circuitikz}
\draw (2,0) node[npn](transistor){};
\draw (transistor.E) node[below]{E};
\draw (transistor.C) node[above]{C};
\draw (transistor.B) node[left]{B};
\end{circuitikz}
NPN Transistor

通过node[npn](transistor){}来绘制一个三极管,{}内的空白可以填写器件的名称,(transistor)是为了方便调用元件坐标而设置的唯一名称,\draw (transistor.E) node[below]{E}中的(transistor.E)是发射极E的坐标,.E的名称是宏包已经定义的,不可以修改,这条命令只有起点没有终点,因此相当于在该点处添加了描述文字。如果想将元件连接某个引脚,把(transistor.E)当成坐标处理即可。

芯片的绘制

CircuiTikZ只是提供了一些基本元件的模型,并没有绘制芯片的命令,因此,我们需要手工去完成这项工作

在导言区加入下面的代码用来调整字体大小和基准长度大小。基准长度为双极元件bipole的长度,其他元件的大小都是根据该长度缩放而来的,修改这个参数可以等比例改变所有元器件的大小。使用relsize红包来设置字体大小,在LaTeX中有\tiny, \scriptsize, \footnotesize, \small, \normalsize, \large, \Large, \LARGE, \huge, \Huge这几种字体大小,默认为\normalsize,而参数-1-2则是从\normalsize向左数的\small\footnotesize

1
2
3
4
5
6
7
8
\usepackage{relsize} % 用于调整字体大小
\tikzset{
pin/.style = {font = \relsize{-2}} % 引脚字体大小
}
\ctikzset{
bipoles/length = 2em, % 基准元件大小
font = \relsize{-1}, % 默认字体大小
}

下面是绘制NE555芯片的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
\begin{circuitikz}
% U1 NE555
\draw [thick] (5.5,2) coordinate (u1) rectangle ++(2,3); % 外形
\draw [pin] (u1) ++ (0,0.5) coordinate (u1 con)
node[right]{CON}
node[above left]{5}; % CON
\draw [pin] (u1) ++ (0,1) coordinate (u1 tri)
node[right]{TRI}
node[above left]{2}; % TRI
\draw [pin] (u1) ++ (0,1.5) coordinate (u1 thr)
node[right]{THR}
node[above left]{6}; % THR
\draw [pin] (u1) ++ (0,2) coordinate (u1 dis)
node[right]{DIS}
node[above left]{7}; % DIS
\draw [pin] (u1) ++ (0,2.5) coordinate (u1 rst)
node[right]{RST}
node[above left]{4}; % RST
\draw [pin] (u1) ++ (1,3) coordinate (u1 vcc)
node[below]{VCC}
node[above left]{8}; % VCC
\draw [pin] (u1) ++ (1,0) coordinate (u1 gnd)
node[above]{GND}
node[below left]{1}; % GND
\draw [pin] (u1) ++ (2,2.5) coordinate (u1 out)
node[left]{OUT}
node[above right]{3}; % GND
\draw (u1) ++ (2,0)
node[right]{\ctikzlabel{$U_1$}{NE555}}; % NE555P
% U1 NE555 引脚连接
\draw (u1 con) -- ++ (-1,0); % CON
\draw (u1 tri) -- ++ (-1,0); % TRI
\draw (u1 thr) -- ++ (-1,0); % THR
\draw (u1 dis) -- ++ (-1,0); % DIS
\draw (u1 rst) -- ++ (-1,0); % RST
\draw (u1 vcc) -- ++ (0,1); % VCC
\draw (u1 gnd) -- ++ (0,-1); % GND
\draw (u1 out) -- ++ (1,0); % OUT
\end{circuitikz}
NE555

首先,使用\draw [thick] (5.5,2) coordinate (u1) rectangle ++(2,3)来绘制芯片的矩形外框,(5.5,2)为起点,++(2,3)是相对坐标,在上一次的坐标基础上进行运算,因此最终坐标是(7.5,5)coordinate (u1)相当于将(5.5,2)赋值给u1,方便之后的相对坐标运算。

然后使用\draw [pin] (u1) ++ (0,0.5) coordinate (u1 con) node[right]{CON} node[above left]{5}来绘制一个引脚,我们将这条命令分开来看,[pin]是在导言区中设置的字体大小样式,这样使得绘制出的芯片更加美观,(u1) ++ (0,0.5)依然为相对坐标运算,计算的结果赋值给u1 connode[]{}则是用于添加引脚名称,使用两条命令在不同的位置添加了两个标签。

\draw (u1) ++ (2,0) node[right]{\ctikzlabel{$U_1$}{NE555}}同理,在芯片右下角添加了序号和型号。

\draw (u1 con) -- ++ (-1,0)用来绘制引脚的引线,起点为(u1 con),终点为(u1 con)的坐标加上(-1,0),也是相对坐标运算。

由此可见,使用相对坐标的好处是如果需要变动芯片的位置,只需要改变(5.5,2)这个点就可以实现移动了,而不需要逐个修改引脚,大大提高了效率。