瑞萨RA系列FSP库开发实战指南之电压值转换和生成正弦波数据表
26.3
电压值转换
如果我们直接通过输入一个有效位数为12位的数字值,通过DAC来输出其相应的电压,这样并没有那么直观。但是如果我们可以输入一个电压值,然后通过软件代码把这个电压转换为与其对应的数字值,再把这个数字值写入DA数据寄存器,这样中间经过了一个电压值到DA数据寄存器值的映射转换,可以让我们设置DAC输出电压时变得更加直观
那么如何实现这样的转换呢?以下是D/A数据寄存器值与输出电压值之间的转换公式:

点击可查看大图
因此在ADC转换完成之后,我们可以调用FSP库函数R_ADC_Read(),从ADC的数据寄存器里读出上述等式中X的值,从而再经过计算得出对应的电压值。
在上面的公式中:
3.3V表示的是D/A转换的参考基准电压为3.3V;
“Output Voltage”为要输出的目标电压值;
4096等于2的12次方,对应的是DAC的分辨率是12位;
“Setting in DADRn”表示的是输出目标电压值对应需要设置的DA数据寄存器值的值。
最终,我们根据上面的公式写成如下的函数。函数中最后一行通过调用FSP库函数R_DAC_Write()计算结果即“Setting in DADRn”的值写入DA数据寄存器。
左右滑动查看完整内容
/**
*@brief设置当前的电压
*@param需要控制的电压(范围为0~3.3V)
*@retval无
*/
voidDAC_SetVoltage(float voltage)
{
uint16_t dac_data;
dac_data = (uint16_t)(4096*((voltage)/3.3f));
R_DAC_Write(&g_dac0_ctrl, dac_data);
}
26.4
生成正弦波数据表
要输出正弦波,实质是要控制DAC以v=sin(t)的正弦函数关系输出电压,其中v为电压输出,t为时间。
而由于模拟信号连续而数字信号是离散的,所以使用DAC产生正弦波时,只能按一定时间间隔输出正弦曲线上的点,在该时间段内输出相同的电压值,若缩短时间间隔,提高单个周期内的输出点数,可以得到逼近连续正弦波的图形,见图26_3,若在外部电路加上适当的电容滤波,可得到更完美的图形。
图26‑3 DAC按点输出正弦波数据
(左:32个点,右:128个点)
由于正弦曲线是周期函数,所以只需要得到单个周期内的数据后按周期重复即可,而单个周期内取样输出的点数又是有限的,所以为了得到呈v=sin(t)函数关系电压值的数据通常不会实时计算获取,而是预先计算好函数单个周期内的电压数据表,并且转化成以DAC寄存器表示的值。
如sin函数值的范围为[-1: +1],而RA6M5的DAC输出电压范围为[0~3.3]V,按12位DAC分辨率表示的方法,可写入寄存器的最大值为212=4096,即范围为[0:4096]。所以,实际输出时,会进行如下处理:
1)抬升sin函数的输出为正值:v=sin(t)+1,此时,v的输出范围为[0:2];
2)扩展输出至DAC的全电压范围:v=3.3*(sin(t)+1)/2,此时,v的输出范围为[0:3.3],正是DAC的电压输出范围,扩展至全电压范围可以充分利用DAC的分辨率;
3)把电压值以DAC寄存器的形式表示:Reg_val=212/3.3 * v=211*(sin(t)+1),此时,存储到DAC寄存器的值范围为[0:4095];
4)实践证明,在sin(t)的单个周期内,取32个点进行电压输出已经能较好地还原正弦波形,所以在t∈[0:2π]区间内等间距根据上述Reg_val公式运算得到32个寄存器值,即可得到正弦波表;
5)控制DAC输出时,每隔一段相同的时间从上述正弦波表中取出一个新数据进行输出,即可输出正弦波。改变间隔时间的单位长度,可以改变正弦波曲线的周期。
为方便起见,我们使用了Python和Matlab脚本制作正弦波表,脚本的代码存储在本工程的目录下,感兴趣可以打开文件查看,以下列出Python脚本代码,见代码清单26‑1。
列表1:代码清单26‑1
制作正弦波数据表的python脚本
(工程目录下的sinWave.py文件)
左右滑动查看完整内容
#! python3
#coding=utf-8
"""
Python 版本:3.x
外部库:matplotlib1.5.3、numpy1.11.2
运行方式:
在命令行中输入:python sinWave.py
运行结果:
命令行中会打印计算得的各点数据,
在当前目录下会生成py_dac_sinWav.c 文件,包含上述数据,
并且会弹出描绘曲线的对话框。
"""
importmatplotlib.pyplotasplt
importnumpyasnp
importmath
# 修改本变量可以更改点数,如16、32、64 等
POINT_NUM =32
pi = math.pi
# 一个周期POINT_NUM 个点
n = np.linspace(0,2*pi,POINT_NUM)
# 计算POINT_NUM 个点的正弦值
a =map(math.sin,n)
r =[]
foriina:
# 调整幅值至在0~1 区间
i+=1
# 按3.3V 电压调整幅值
i*=3.3/2
# 求取dac 数值,12 位dac LSB = 3.3V/2**12
ri =round(i*2**12/3.3)
# 检查参数
ifri >=4095:
ri =4095
# 得到dac 数值序列
r.append( ri )
print(list(map(int,r)))
# 写入序列到文件
withopen("py_dac_sinWav.c",'w',encoding='gb2312')asf:
print(list(map(int,r)),file= f)
# 绘图
plt.plot(n,r,"-o")
plt.show()
Python脚本的实现原理就是前面介绍的正弦波数据表的制作过程,运行后,该脚本把得到的正弦波表数据输出到目录下的py_dac_sinWav.c文件中,见代码清单26‑2,并且根据取样点描绘出示意图,见图26‑4。Matlab脚本原理相同,此处不再列出,使用C语言也能制作正弦波表。
列表2:代码清单26‑2 生成的正弦波数据表
左右滑动查看完整内容
[2048, 2460, 2856, 3218, 3532, 3786, 3969, 4072, 4093, 4031, 3887, 3668, 3382, 3042, 2661, 2255, 1841, 1435, 1054, 714, 428, 209, 65, 3, 24, 127, 310, 564, 878, 1240, 1636, 2048]
图26‑4 python脚本根据正弦波表描绘的曲线图
