用stm32f103c8t6的库函数写一段dac输出可调占空比的正弦波
时间: 2023-09-05 18:13:25 浏览: 43
好的,下面是示例代码:
```
#include "stm32f10x.h"
#define DAC_VAL_MAX 4095 // DAC输出的最大值
#define DAC_SINE_TABLE_SIZE 256 // 正弦波表的大小
uint16_t dac_sine_table[DAC_SINE_TABLE_SIZE] = {
2048, 2098, 2148, 2198, 2248, 2298, 2348, 2398,
2447, 2496, 2545, 2594, 2642, 2690, 2738, 2785,
2832, 2878, 2924, 2969, 3014, 3059, 3102, 3146,
3188, 3230, 3271, 3311, 3351, 3390, 3428, 3466,
3502, 3538, 3572, 3606, 3639, 3670, 3701, 3730,
3759, 3786, 3813, 3838, 3863, 3886, 3908, 3929,
3949, 3968, 3985, 4001, 4016, 4030, 4042, 4054,
4064, 4073, 4081, 4087, 4092, 4095, 4095, 4095,
4092, 4087, 4081, 4073, 4064, 4054, 4042, 4030,
4016, 4001, 3985, 3968, 3949, 3929, 3908, 3886,
3863, 3838, 3813, 3786, 3759, 3730, 3701, 3670,
3639, 3606, 3572, 3538, 3502, 3466, 3428, 3390,
3351, 3311, 3271, 3230, 3188, 3146, 3102, 3059,
3014, 2969, 2924, 2878, 2832, 2785, 2738, 2690,
2642, 2594, 2545, 2496, 2447, 2398, 2348, 2298,
2248, 2198, 2148, 2098, 2048, 1997, 1947, 1897,
1847, 1797, 1747, 1697, 1648, 1599, 1550, 1501,
1453, 1405, 1357, 1310, 1263, 1217, 1171, 1126,
1081, 1036, 992, 949, 906, 863, 821, 780,
739, 698, 659, 620, 581, 544, 507, 471,
436, 401, 367, 334, 302, 270, 240, 210,
181, 153, 126, 100, 75, 51, 28, 6,
0, 0, 0, 6, 28, 51, 75, 100,
126, 153, 181, 210, 240, 270, 302, 334,
367, 401, 436, 471, 507, 544, 581, 620,
659, 698, 739, 780, 821, 863, 906, 949,
992, 1036, 1081, 1126, 1171, 1217, 1263, 1310,
1357, 1405, 1453, 1501, 1550, 1599, 1648, 1697,
1747, 1797, 1847, 1897, 1947, 1997
};
void TIM3_Init(void);
void DAC_Init(void);
int main(void) {
TIM3_Init();
DAC_Init();
while (1) {
// 等待TIM3中断
}
}
void TIM3_Init(void) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 71; // 设置计数周期,72Mhz时钟下,1us
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM3, ENABLE);
}
void TIM3_IRQHandler(void) {
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
static uint16_t dac_val_idx = 0;
uint16_t dac_val = dac_sine_table[dac_val_idx];
DAC_SetChannel1Data(DAC_Align_12b_R, dac_val);
DAC_SoftwareTriggerCmd(DAC_Channel_1, ENABLE);
dac_val_idx++;
if (dac_val_idx >= DAC_SINE_TABLE_SIZE) {
dac_val_idx = 0;
}
}
}
void DAC_Init(void) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStruct);
DAC_InitTypeDef DAC_InitStruct;
DAC_InitStruct.DAC_Trigger = DAC_Trigger_T3_TRGO;
DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
DAC_Init(DAC_Channel_1, &DAC_InitStruct);
DAC_Cmd(DAC_Channel_1, ENABLE);
}
```
该代码使用了定时器TIM3,每隔1us触发一次中断,在中断处理函数中将正弦波表中的值依次输出到DAC通道1,并且DAC的触发源设置为TIM3的TRGO事件,以便控制DAC的输出占空比。正弦波表中的值是经过归一化处理的,所以DAC输出的值需要乘以一个系数才能得到实际的电压值。