【GD32L233C-START】DAC输出(正弦波、锯齿波、方波)
【GD32L233C-START】DAC输出(正弦波、锯齿波、方波)
1.介绍
GD32L233C采用的是一款M23的内核。这个芯片据说功耗非常的低,低到什么程度呢?等后面我们再进行测试,今天我们主要来测试GD32L233C-START的DAC,既然要测试DAC,示波器是不可少的,这个实验在家做,然而LZ家里并没有示波器,不过最近看到一款好东西,LOTO虚拟示波器,看过这款示波器的参数,还不错。所以入手了一款,测量芯片输出的DAC应该没什么问题,接下来开始测试吧。
2.设计
首先需要输出让芯片输出DAC,而且还需要输出波形,这个稍微费点功夫,之前在GD32L233C-START移植了RTThread,现在在这个代码的基础上添加DAC的输出程序,这个程序移植了其他网友的,代码我也贴出来,经过测试,代码没有啥问题:
比较麻烦的是正弦波的代码:
const float sinus_I_quarter[91] =
{
0.0000, 0.0175, 0.0349, 0.0523, 0.0698, 0.0872, 0.1045, 0.1219, 0.1392, 0.1564, // 00 .. 09
0.1736, 0.1908, 0.2079, 0.2250, 0.2419, 0.2588, 0.2756, 0.2924, 0.3090, 0.3256, // 10 .. 19
0.3420, 0.3584, 0.3746, 0.3907, 0.4067, 0.4226, 0.4384, 0.4540, 0.4695, 0.4848, // 20 .. 29
0.5000, 0.5150, 0.5299, 0.5446, 0.5592, 0.5736, 0.5878, 0.6018, 0.6157, 0.6293, // 30 .. 39
0.6428, 0.6561, 0.6691, 0.6820, 0.6947, 0.7071, 0.7193, 0.7314, 0.7431, 0.7547, // 40 .. 49
0.7660, 0.7771, 0.7880, 0.7986, 0.8090, 0.8192, 0.8290, 0.8387, 0.8480, 0.8572, // 50 .. 59
0.8660, 0.8746, 0.8829, 0.8910, 0.8988, 0.9063, 0.9135, 0.9205, 0.9272, 0.9336, // 60 .. 69
0.9397, 0.9455, 0.9511, 0.9563, 0.9613, 0.9659, 0.9703, 0.9744, 0.9781, 0.9816, // 70 .. 79
0.9848, 0.9877, 0.9903, 0.9925, 0.9945, 0.9962, 0.9976, 0.9986, 0.9994, 0.9998, // 80 .. 89
1.0000 // 90
};
#define CIRCLE_QUARTER_1 1
#define CIRCLE_QUARTER_2 2
#define CIRCLE_QUARTER_3 3
#define CIRCLE_QUARTER_4 4
float sinus_lookup (unsigned int angle)
{
float sin_value;
unsigned int circle_quarter;
// correct angles outside the accepted angle range into 0 .. 359
if (angle > 359u)
angle = angle % 360u;
circle_quarter = 1 + (angle / 90u);
switch (circle_quarter)
{
case CIRCLE_QUARTER_1: // 00 .. 89
sin_value = sinus_I_quarter[angle];
break;
case CIRCLE_QUARTER_2: // 90 .. 179
sin_value = sinus_I_quarter[180 - angle];
break;
case CIRCLE_QUARTER_3: // 180 .. 269
sin_value = -sinus_I_quarter[angle - 180];
break;
case CIRCLE_QUARTER_4: // 270 .. 359
sin_value = -sinus_I_quarter[360 - angle];
break;
}
return sin_value;
}
void plot_sin(uint32_t f, uint32_t delta_f)
{
/* 定时周期为T=1/delta_f, f=1/(pMax*T) */
static uint32_t point = 0;
uint32_t pMAX = delta_f/f;
uint32_t value = 0;
if (point++ > pMAX) point = 0;
value = (uint32_t)((sinus_lookup(360*point/pMAX)+1)*10000)*2047/10000;
dac_software_trigger_enable();
dac_data_set(DAC_ALIGN_12B_R, value);
}
接下来是锯齿波和方波的代码,这两个代码比较简单:
void plot_triangle(uint32_t f, uint32_t delta_f)
{
/* 定时周期为T=1/delta_f, f=1/(pMax*T) */
static uint32_t point = 0;
uint32_t pMAX = delta_f/f;
uint32_t pMAX2 = pMAX/2;
uint32_t value = 0;
if (++point > pMAX) point = 0;
if (point < pMAX2)
{
value = point * 4095 / pMAX2;
}
else
{
value = (pMAX - point) * 4095 / pMAX2;
}
dac_software_trigger_enable();
dac_data_set(DAC_ALIGN_12B_R, value);
}
void plot_square(uint32_t f, uint32_t delta_f)
{
/* 定时周期为T=1/delta_f, f=1/(pMax*T) */
static uint32_t point = 0;
uint32_t pMAX = delta_f/f;
uint32_t pMAX2 = pMAX/2;
uint32_t value = 0;
if (++point > pMAX) point = 0;
if (point < pMAX2)
{
value = 0;
}
else
{
value = 0xFFF;
}
dac_software_trigger_enable();
dac_data_set(DAC_ALIGN_12B_R, value);
}
最后需要开启一个定时器,还有DAC的初始化:
void timerx_init(uint32_t timer_periph, uint16_t period, uint16_t prescaler)
{
/* TIMER1 configuration: input capture mode -------------------
the external signal is connected to TIMER1 CH0 pin (PA0)
the rising edge is used as active edge
the TIMER1 CH0CV is used to compute the frequency value
------------------------------------------------------------ */
timer_parameter_struct timer_initpara;
timer_ic_parameter_struct timer_icinitpara;
/* enable the peripherals clock */
rcu_periph_clock_enable(RCU_TIMER2);
/* deinit a TIMER */
timer_deinit(timer_periph);
/* initialize TIMER init parameter struct */
timer_struct_para_init(&timer_initpara);
/* TIMER1 configuration */
timer_initpara.prescaler = prescaler;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = period;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(timer_periph, &timer_initpara);
/* TIMER1 CH0 input capture configuration */
timer_icinitpara.icpolarity = TIMER_IC_POLARITY_RISING;
timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
timer_icinitpara.icfilter = 0x00;
timer_input_capture_config(timer_periph, TIMER_CH_0, &timer_icinitpara);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(timer_periph);
/* clear channel 0 interrupt bit */
timer_interrupt_flag_clear(timer_periph, TIMER_INT_CH0);
/* channel 0 interrupt enable */
timer_interrupt_enable(timer_periph, TIMER_INT_CH0);
/* enable a TIMER */
timer_enable(timer_periph);
}
#define DAC_WAVE_TEST
void timer2_init(void)
{
timer_deinit(TIMER2);
rcu_periph_clock_enable(RCU_TIMER2);
#ifdef DAC_WAVE_TEST
timerx_init(TIMER2, 639, 9); // 100KHz 0.1ms
#endif
timer_interrupt_enable(TIMER2, TIMER_INT_UP);
nvic_irq_enable(TIMER2_IRQn, 3);
}
void TIMER2_IRQHandler(void)
{
#ifdef DAC_WAVE_TEST
plot_sin(100, 10000); //正弦波
//plot_triangle(1, 10000); //锯齿波
//plot_square(1, 10000); //方波
#endif
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
}
void dac1_init(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_DAC);
gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4);
dac_deinit();
/* software trigger */
dac_trigger_enable();
dac_trigger_source_config(DAC_TRIGGER_SOFTWARE);
/* no noise wave */
dac_wave_mode_config(DAC_WAVE_DISABLE);
/* noise wave - triangle */
//dac_wave_mode_config(DAC_WAVE_MODE_TRIANGLE);
//dac_triangle_noise_config(DAC_TRIANGLE_AMPLITUDE_4095);
/* noise wave - lfsr */
//dac_wave_mode_config(DAC_WAVE_MODE_LFSR);
//dac_lfsr_noise_config(DAC_LFSR_BITS11_0);
dac_output_buffer_enable();
/* enable DAC and set data */
dac_enable();
dac_software_trigger_enable();
dac_data_set(DAC_ALIGN_12B_R, 0);
}
这样就可以输出正弦波、锯齿波和方波了。
3.波形测量
接下来我们来看一下输出的波形是否符合要求,首先需要将【GD32L233C-START】开发板连接LOTO示波器,分别连接GND和PA4管教,连接效果图如下图1所示。
图1
然后让DAC输出正弦波,看一下波形如何。
图2
从上图2中可以看到,一个周期大约在10ms,所以正弦波的周期为100Hz,输出还是听精准的。
然后输出锯齿波看看波形如何。
图3
从上图3可以得出,锯齿波的波形频率为1Hz。
最后我们来看看方波的波形图如何。
图4
从上图4可以看到,方波的波形频率为1Hz。
从上面波形可以得出,【GD32L233C-START】的定时器比较精准,DAC的输出值也比较稳定,性能还是不错的!
4.总结
刚入手的LOTO示波器还不错,测量的精度挺高的,不过还有好多设置没弄明白,等后续多琢磨琢磨。做电子的示波器是必不可少的,我先替你们测试测试这个示波器如何。
GD32L233C是新出来的芯片,整体功能还需要多进行测试,它最突出的低功耗后续要好好测量一下,这次就先到这里了。
【GD32L233C-START】DAC输出(正弦波、锯齿波、方波)的更多相关文章
- 002_89C52_Proteus_DAC0832_输出50HZ,正弦波,三角波,矩形波,锯齿波
(一)非常感谢:89C51与ad0832 输出正弦波,三角波,矩形波,锯齿波 (二)在上面的情况下进行程序的修改,实现50HZ的输出 (三)电路图 (三)输出方波 (四)输出锯齿波 (五)输出三角波 ...
- 电赛初探(一)——正弦波、方波、锯齿波转换
一.题目要求: 1.使用555做出脉冲方波 2.使用TL084运放做出方波和锯齿波 3.使用TLM314稳压做直流偏置 4.方波要求峰峰值为1V,正弦波要求峰值为0~2V,锯齿波要求峰峰值为1V. 二 ...
- 几种比较经典的波形及其FFT变换(正弦波,三角波,方波和锯齿波)
之前上学时我的信号学得最差了,主要原因还是我高数学得不怎么样.可能是人总敬畏自己最不会的,所以我觉得我学过诸多科目中,数学是最博大精深而最妙的,从最开始的一次函数到反比例函数,二次三次函数和双曲线,椭 ...
- STM32 使用DMA+DAC+TIMER 输出正弦波
之前已经简单论述过,根据我个人菜鸟的了解与认识,对之前的知识进行整理回顾: DMA:我的理解就是一个通道,或者是一座桥梁.在静态内存到静态内存,或者外设到静态内存间的一个通讯的通道.建立这个通道的好处 ...
- stm32 DAC输出音频
#define DAC_DHR8R1_Address 0x40007410 // Init Structure definition DAC_InitTypeDef DAC_InitStructure ...
- 如何使用Python输出一个[斐波那契数列]
如何使用Python输出一个[斐波那契数列]Fibonacci 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonac ...
- 速度上手LM4F LaunchPad 输出多路PWM波
最近转战到TI的Cortex M4平台后,发现网上关于TI的LM4F120 Launchpad 资料太少了,而且其中大部分都是TI员工或者其合作伙伴提供的,例程太少,导致新手上手很慢. 我只是要实现几 ...
- python面试题之如何用Python输出一个斐波那契数列
so eary! 1 a,b = 0, 1 2 while b<100: 3 print (b), 4 a, b = b, a+b 本文转载自:python黑洞网 原文链接:http://www ...
- TMS320VC5509的DAC输出TLV5620
1. TLV5620的SPI数据是11位的 但是看图3和图4,感觉用2个字节应该也可以的,不知道行不行,可以试一试吧 2. 不过可惜的是5509A的SPI没有11位的,有点麻烦,只能先试试用两个字节行 ...
- 如何用Python输出一个斐波那契Fibonacci数列
a,b = 0, 1 while b<100: print (b), a, b = b, a+b
随机推荐
- NC50615 取石子游戏 2
题目链接 题目 题目描述 有一种有趣的游戏,玩法如下: 玩家:2人: 道具:N堆石子,每堆石子的数量分别为 \(X_1,X_2,...,X_n\) : 规则: 游戏双方轮流取石子: 每人每次 ...
- 盘点 Udemy 上最受欢迎的免费编程课程
之前给大家推荐过一些油管上的免费学习资源,如果您还没有看过的话可以点击这里前往. 今天再给大家推荐一批Udemy上超高质量并且免费的编程课程,有需要的小伙伴可以学起来了. 1. JavaScript ...
- Java设计模式-原型模式Prototype
介绍 当我们有一个类的实例(Prototype)并且我们想通过复制原型来创建新对象时,通常使用Prototype模式. 原型模式是一种创建型设计模式.能够复制已有对象, 而又无需使代码依赖它们所属的类 ...
- docker基于commit方式为镜像添加SSH服务
下载启动镜像 docker pull ubuntu: 18.04 docker run -it ubuntu:18.04 bash 配置软件源 备份/etc/apt/sources.list#备份cp ...
- 深入理解Go语言(08):sync.WaitGroup源码分析
一.sync.WaitGroup简介 1.1 sync.WaitGroup 解决了什么问题 在编程的时候,有时遇到一个大的任务,为了提高计算速度,会用到并发程序,把一个大的任务拆分成几个小的独立的任务 ...
- zookeeper源码(09)follower处理客户端请求
在zookeeper中,follower也可以接收客户端连接,处理客户端请求,本文将分析follower处理客户端请求的流程: 读请求处理 写请求转发与响应 follower接收转发客户端请求 网络层 ...
- Jetpack Compose(2) —— 入门实践
一.项目中使用 Jetpack Compose 从此节开始,为方便起见,如无特殊说明,Compose 均指代 Jetpack Compose. 开发工具: Android Studio 1.1 创建支 ...
- 如何在矩池云使用 Poetry 管理项目环境
官网介绍:Poetry is a tool for dependency management and packaging in Python. It allows you to declare th ...
- 【Azure 应用服务】Java ODBC代码中,启用 Managed Identity 登录 SQL Server 报错 Managed Identity authentication is not available
问题描述 在App Service中启用Identity后,使用系统自动生成 Identity. 使用如下代码连接数据库 SQL Server: SQLServerDataSource dataSou ...
- 【Azure 事件中心】开启 Apache Flink 制造者 Producer 示例代码中的日志输出 (连接 Azure Event Hub Kafka 终结点)
问题描述 Azure Event Hub 在标准版以上就默认启用的Kafka终结点,所以可以通过Apache Kafka协议连接到Event Hub进行消息的生产和消费.通过示例代码下载到本地运行后, ...