139 lines
No EOL
4.7 KiB
Markdown
139 lines
No EOL
4.7 KiB
Markdown
---
|
|
title: Le CAN
|
|
subject: Cours
|
|
export:
|
|
- format: pdf
|
|
template: courstex
|
|
kernelspec:
|
|
name: python3
|
|
display_name: Python 3
|
|
abbreviations:
|
|
CAN: Convertisseur Analogique Numérique
|
|
---
|
|
|
|
# Définition
|
|
|
|
:::{prf:definition} CAN
|
|
:nonumber: true
|
|
Un convertisseur analogique-numérique est un dispositif électronique dont la fonction est de traduire une grandeur analogique en une valeur numérique codée sur plusieurs bits. Le signal converti est généralement une tension électrique.
|
|
|
|
Source : Article _[Convertisseur analogique-numérique](http://fr.wikipedia.org/wiki/Convertisseur_analogique-num%C3%A9rique)_ de [Wikipédia en français](https://fr.wikipedia.org/) ([auteurs](http://fr.wikipedia.org/w/index.php?title=Convertisseur_analogique-num%C3%A9rique&action=history))
|
|
:::
|
|
|
|
# L'échantillonage du signal
|
|
L'échantillonage du signal est la prise d'une valeur à un intervalle régulier de temps. L'intervalle entre deux valeurs s'appelle **période d'échantillonage**. On la note $T_e$ (en secondes). On parle aussi de **fréquence d'échantillonage** $f_e=\frac{1}{T_e}$ (en Hertz), qui correspond au nombre de valeurs prises chaque seconde.
|
|
|
|
Le **quantum** correspond au plus petit écart quantifiable (la "hauteur d'une marche"). On le note $q$ et son unité est celle du signal d'entrée (généralement le Volt).
|
|
|
|
La **tension de pleine échelle** ou **tension de référence** est la tension maximale quantifiable par le CAN. On la note $V_\text{pe}$ ou $V_\text{ref}$.
|
|
|
|
Le nombre de valeurs que peut générer le convertisseur se note $N$ et dépend du nombre de bits $n$ du convertisseur. Ainsi : $N=2^n$.
|
|
|
|
On obtient la relation suivante : $q=\frac{V_\text{pe}}{N}=\frac{V_\text{pe}}{2^n}$.
|
|
|
|
# Exemple de conversion
|
|
On donne en @fig:exemple-can l'exemple d'un CAN de tension de référence 5 V fonctionnant sur 3 bits avec une fréquence d'échantillonage de 2 Hz.
|
|
|
|
La **caractéristique** du CAN est la courbe représentant la valeur numérique en sortie en fonction de la valeur analogique en entrée (@fig:carac-can).
|
|
|
|
::::{figure}
|
|
:label: fig:exemple-can
|
|
:::{code-cell} python
|
|
:tags: [remove-input]
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib import ticker
|
|
import numpy as np
|
|
from scipy.interpolate import CubicSpline
|
|
from scipy.stats import qmc
|
|
|
|
rng = np.random.default_rng(50)
|
|
|
|
n = 20
|
|
t_max = 8
|
|
n_interp = t_max * 100 + 1
|
|
|
|
t_base = np.linspace(0, t_max, n)
|
|
lhs = (qmc.LatinHypercube(d=n-2, rng=rng).random(1)[0] - .5) * t_max/n
|
|
t = t_base + np.concatenate(([0], lhs, [0]))
|
|
t = t_base
|
|
s = 5 * rng.random(n)
|
|
|
|
t_interp = np.linspace(0, t_max, n_interp)
|
|
s_interp = np.clip(CubicSpline(t, s)(t_interp), 0, 5)
|
|
s_n = np.full_like(t_interp[::50], np.nan)
|
|
s_n = np.floor(s_interp[::50] * 8 / 5)
|
|
s_n[s_n == 8] = 7
|
|
|
|
fig, ax = plt.subplots()
|
|
ax2 = ax.twinx()
|
|
|
|
ax.plot(t_interp, s_interp, lw=3)
|
|
ax2.scatter(t_interp[::50], s_n, color="C1")
|
|
|
|
ax.grid(False, axis="y")
|
|
ax.grid(True, axis="x", which="both")
|
|
ax2.grid(True)
|
|
|
|
ax.set(
|
|
xlim=(0, t_max),
|
|
ylim=(-.5, 5.5),
|
|
xlabel="Temps (s)",
|
|
)
|
|
ax.set_ylabel("Signal analogique (V)", color="C0")
|
|
ax2.set(
|
|
ylim=(-8/5*.5, 8/5*5.5),
|
|
)
|
|
ax2.set_ylabel("Signal numérique", color="C1")
|
|
|
|
ax.yaxis.set_major_locator(ticker.MultipleLocator(1))
|
|
ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
|
|
ax.xaxis.set_minor_locator(ticker.MultipleLocator(.5))
|
|
ax2.set_yticks(np.arange(9), np.concatenate((np.arange(8), [""])))
|
|
|
|
arr = ax2.annotate("", xy=(0, 0), xytext=(0.5, 0), arrowprops=dict(arrowstyle="<->"))
|
|
ax2.annotate("$T_e$", (0.5, 1), xycoords=arr, ha="center", va="bottom")
|
|
|
|
arr2 = ax2.annotate("", xy=(0.5, 0), xytext=(0.5, 1), arrowprops=dict(arrowstyle="<->"))
|
|
ax2.annotate("$q$", (1, 0.5), xycoords=arr2, ha="left", va="center")
|
|
|
|
arr3 = ax2.annotate("", xy=(1, 0), xytext=(1, 8), arrowprops=dict(arrowstyle="<->"))
|
|
ax2.annotate("$V_{pe}$", (1, 0.5), xycoords=arr3, ha="left", va="center");
|
|
:::
|
|
Signal analogique et signal numérisé.
|
|
::::
|
|
|
|
::::{figure}
|
|
:label: fig:carac-can
|
|
:::{code-cell} python
|
|
:tags: [remove-input]
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib import ticker
|
|
import numpy as np
|
|
|
|
N = 8
|
|
s_n = np.arange(N)
|
|
s_a = np.linspace(0, 5, N+1)
|
|
|
|
fig, ax = plt.subplots()
|
|
|
|
ax.stairs(s_n, s_a, color="C1", lw=3, baseline=None)
|
|
|
|
ax.set(
|
|
yticks=s_n,
|
|
xlabel="Signal analogique (V)",
|
|
ylabel="Signal numérique",
|
|
)
|
|
ax.set_xticks(s_a, [f"{v:.3f}" for v in s_a], rotation=45, ha="right", rotation_mode="anchor")
|
|
ax.set_aspect(5/8, "datalim")
|
|
arr4 = ax.annotate(
|
|
"", xy=(s_a[0], 0), xytext=(s_a[1], 0), arrowprops=dict(arrowstyle="<->")
|
|
)
|
|
ax.annotate("$q$", (0.5, 1), xycoords=arr4, ha="center", va="bottom")
|
|
|
|
arr5 = ax.annotate(
|
|
"", xy=(s_a[0], 1.5), xytext=(s_a[-1], 1.5), arrowprops=dict(arrowstyle="<->")
|
|
)
|
|
ax.annotate("$V_{pe}$", (0.5, 1), xycoords=arr5, ha="center", va="bottom");
|
|
:::
|
|
Caractéristique du CAN.
|
|
:::: |