用DAC产生正弦波

 

MCU: C8051F330, Fmax: 23KHz
 
#include <stdio.h>
#include <stdlib.h>

unsigned char sine_table[8] = { 0x80, 0xDA, 0xFF, 0xDA, 0x80, 0x25, 0x00, 0x25 }; /* 8KSPS, 0dB */
// unsigned char sine_table[8] = { 0x80, 0xAD, 0xC0, 0xAD, 0x80, 0x52, 0x3F, 0x52 }; /* 8KSPS, -6dB */

unsigned char *waveform_data = &sine_table[0];

/* for generate 1KHz sine wave, call it per 125us */ 
unsigned char waveform_output(void)
{
	unsigned char dac_value;

	dac_value = *waveform_data++;
	if (waveform_data >= &sine_table[8])
	{
	    waveform_data = &sine_table[0];
	}

	return dac_value;
}

int main()
{
    int i;

    for (i = 0; i < 16; i++)
    {
        printf("%02X\n", waveform_output());
    }

    return 0;
}
 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

unsigned char *sine_table = NULL;

float db2liner(float dB)
{
    return pow(10, dB / 20);
}

float liner2db(float liner)
{
   return (20 * log10(liner));
}

int waveform_generate(int freq, int sps, float dB)
{
    int i;
    int table_length;
    float A;
    float value;

    table_length = sps / freq;

    sine_table = (unsigned char *)malloc(table_length);
    memset(sine_table, 0, table_length);

    A = db2liner(dB);

    for( i = 0; i < table_length; i++)
    {
        value = A * sin(2 * M_PI * i * freq / sps);
        if (value < 1.0)
        {
            sine_table[i] = (256 / 2) + value * (256 / 2);  /* add DC offset */
        }
        else
        {
            sine_table[i] = 256 - 1;
        }
    }

    return table_length;
}

int main()
{
    int i, table_length;

    /* generate 1000Hz sine wave, sample rate: 8000Hz, gain: -6dB */
    table_length = waveform_generate(1000, 8000, -6);

    printf("unsigned char sine_table[%d] = { ", table_length);
    for (i = 0; i < table_length; i++)
    {
        printf((i != table_length - 1) ? "0x%02X, " : "0x%02X ", sine_table[i]);
    }
    printf("};\n");

    free(sine_table);

    return 0;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用STM32的DAC模块产生正弦波,可以使用以下步骤: 1. 初始化DAC模块,包括时钟使能、GPIO配置和DAC配置等; 2. 定义正弦波数组,可以使用sin函数计算出每个采样点的数值; 3. 启动定时器以固定的采样率产生DAC数据; 4. 在定时器中断中,将正弦波数组中下一个采样点数据写入DAC数据寄存器中; 5. 监测DAC中断标志位,确保数据已经输出完毕。 下面是一个基于STM32CubeMX和HAL库的DAC产生正弦波的例子代码: ```c #include "main.h" #include <math.h> #define SAMPLE_RATE 20000 // 20kHz采样率 #define SAMPLE_NUM 100 // 正弦波采样点数 DAC_HandleTypeDef hdac; TIM_HandleTypeDef htim6; static uint16_t sinewave[SAMPLE_NUM]; // 正弦波数据数组 static void MX_GPIO_Init(void); static void MX_DAC_Init(void); static void MX_TIM6_Init(void); void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); int main(void) { HAL_Init(); MX_GPIO_Init(); MX_DAC_Init(); MX_TIM6_Init(); for (int i = 0; i < SAMPLE_NUM; i++) { sinewave[i] = (uint16_t)(2048 * (1 + sin(2 * M_PI * i / SAMPLE_NUM))); // 生成正弦波数据,最大输出值为4095(12位DAC) } HAL_DAC_Start(&hdac, DAC_CHANNEL_1); HAL_TIM_Base_Start_IT(&htim6); while (1) { // Main loop } } static void MX_DAC_Init(void) { DAC_ChannelConfTypeDef sConfig = {0}; hdac.Instance = DAC; if (HAL_DAC_Init(&hdac) != HAL_OK) { Error_Handler(); } sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO; // DAC使用定时器6触发 sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK) { Error_Handler(); } } static void MX_TIM6_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; htim6.Instance = TIM6; htim6.Init.Prescaler = HAL_RCC_GetHCLKFreq() / (SAMPLE_NUM * SAMPLE_RATE) - 1; // 定时器时钟频率 = 系统时钟 / PSC htim6.Init.CounterMode = TIM_COUNTERMODE_UP; htim6.Init.Period = SAMPLE_NUM - 1; // 计数器从0到99,共100次 if (HAL_TIM_Base_Init(&htim6) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK) { Error_Handler(); } } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM6) { static uint8_t index = 0; // 当前采样点索引 uint16_t value = sinewave[index]; HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value); // 写入DAC数据寄存器 index = (index + 1) % SAMPLE_NUM; } } static void MX_GPIO_Init(void) { // DAC输出GPIO初始化 GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_4; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } void Error_Handler(void) { // 程序发生错误时停机 while (1) { } } ``` 需要注意的是,当DAC模块输出到外部电路时,需要使用一定的滤波电路来去除采样过程中可能产生的高频噪声。另外,如果要实现多声道输出,可以使用不同的DAC通道,或者使用DMA功能直接传输多通道数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值