【STM32 标准库】PWM-DAC

目录

1 PWM-DAC

1.1 PWM_DAC简介

1.2 原理图​编辑​编辑​编辑

2 软件配置

3 硬件设计

4 软件设计

4.1 功能描述

4.2 软件实现


PWM-DAC

1.1 PWM_DAC简介

        (1)为什么要有PWM_DAC?

DAC只有2路,如果不够用时,可以用PWM+RC滤波电路构成DAC(性价比高),也可以外扩DAC芯片(成本较高)。、

        (2)怎么做?

  • PWM频率为281.25Khz,那么一次谐波频率就是281.25Khz;
  • 1阶RC滤波,幅频特性为:-10lg[1+(f/fp)^2];fp为截止频率。

        所以对一阶滤波来说,要达到-44dB的衰减,必须-10lg[1+(f/fp)^2]=-44; 得到f/fp=158.486,即fp=281.25/158.486=1.77Khz。

  • 2阶RC滤波,幅频特性为:-20lg[1+(f/fp)^2];fp为截止频率。

        所以对二阶滤波来说,要达到-44dB的衰减,必须-20lg[1+(f/fp)^2]=-44; 得到f/fp=12.549,即fp=281.25/12.549=22.41Khz。

1.2 原理图

2 软件配置

3 硬件设计

4 软件设计

4.1 功能描述

通过KEY_UP和KEY1按键控制PWM输出,从而控制PWM-DAC的电压输出,使用ADC1_IN1采集PWM-DAC输出的电压,通过串口1将 PWM-DAC输出的电压与ADC1_IN1采集的电压打印出来,同时DS0指示灯不断闪 烁,提示系统正常运行。

4.2 软件实现

        (1)初始化 PA8 管脚为 PWM 输出功能,配置 PWM 相应参数

1.#include "PWM_DAC.h"
2.
3.void TIM1_CH1_PWM_Iint(u16 per, u16 psc)
4.{
5.    //1.1使能定时器及端口时钟
6.    RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
7.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
8.
9.    
10.    //1.2初始化GPIO
11.    GPIO_InitTypeDef GPIO_InitStructure;
12.    
13.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
14.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
15.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
16.    GPIO_Init(GPIOA, &GPIO_InitStructure);
17.    
18.    //1.3设置引脚复用器映射
19.    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
20.    
21.    //2.初始化定时器参数,包含自动重装值,分频系数,计数方式等
22.    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
23.    
24.    TIM_TimeBaseInitStructure.TIM_Period=per;
25.    TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
26.    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
27.    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
28.    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);
29.    
30.    //3.初始化PWM输出参数,包含PWM模式、输出极性,使能等
31.    TIM_OCInitTypeDef TIM_OCInitStructure;
32.    
33.    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;
34.    TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
35.    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
36.    TIM_OCInitStructure.TIM_Pulse=0;
37.    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
38.    
39.    //5.使能TIMx在CCRx上的预装载寄存器
40.    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
41.    
42.    //6.使能 TIMx 在 ARR 上的预装载寄存器允许位
43.    TIM_ARRPreloadConfig(TIM1, ENABLE);
44.    
45.    TIM_CtrlPWMOutputs(TIM1, ENABLE);
46.    TIM_SetCompare1(TIM1,0);
47.    //4.开启定时器
48.    TIM_Cmd(TIM1, ENABLE); 
49.}

        (2)编写主函数

1./* Includes ------------------------------------------------------------------*/
2.#include "system.h"
3.#include "LED.h"
4.#include "SysTick.h"
5.#include "USART.h"
6.#include "KEY.h"
7.#include "PWM_DAC.h"
8.#include "ADC.h"
9.
10./* 主函数main() --------------------------------------------------------------*/
11.int main()
12.{   
13.    // 自定义变量
14.    u8 i = 0;
15.    u8 key=0;
16.    int pwm_val=0;
17.    u8 pwm=0;
18.    float pwm_vol=0;
19.    
20.    int adc_val=0;
21.    float adc_vol=0;
22.    // 初始化
23.    SysTick_Iint(72);
24.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 中断分组
25.    LED_Init();
26.    KEY_Iint();
27.    USART1_Iint(115200);
28.    TIM1_CH1_PWM_Iint(255,0);
29.    ADCx_Iint();
30.    
31.    while(1)
32.    {
33.        key=KEY_Scan(0);
34.        if(key==KEY_UP_PRESS)
35.        {
36.            pwm_val += 10;
37.            if(pwm_val>=250) pwm_val=255;
38.            TIM_SetCompare1(TIM1,pwm_val);
39.        }
40.        else if(key==KEY0_PRESS)
41.        {
42.            pwm_val -= 10;
43.            if(pwm_val<=10) pwm_val=0;
44.            TIM_SetCompare1(TIM1,pwm_val);
45.        }
46.        
47.       i++;
48.        if(i%20==0)
49.        {
50.            LED0 = !LED0;
51.        }
52.        delay_ms(10);
53.        
54.        if(i%100==0)
55.        {
56.            pwm = TIM_GetCapture1(TIM1);
57.            pwm_vol = (float)pwm_val*(3.3/256);  //8位
58.            printf("pwm输出电压为:%.3f\r\n", pwm_vol);
59.            
60.            adc_val = Get_ADC_Value(ADC_Channel_1,20);
61.            adc_vol = (float)adc_val*(3.3/4096);  //12位
62.            printf("ADC检测到电压为:%.3f\r\n", adc_vol);
63.        }
64.    }
65.}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值