目录
1 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.}