你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32F1开发PWM DAC实验经验分享

[复制链接]
攻城狮Melo 发布时间:2023-5-14 17:40
STM32F1自带的DAC模块的使用。但有时候,可能两个DAC不够用,我们可以通过PWM+RC滤波来实现一个PWM DAC。本章将向大家介绍如何利用STM32的PWM来设计一个DAC。利用按键(USMART)控制STM32的PWM输出,从而控制PWM DAC的输出电压,通过ADC1的通道1采集PWM DAC的输出电压,并在LCD模块上面显示ADC获取到的电压值以及PWM DAC的设定输出电压值等信息。


20200514191553939.png


2020051419162562.png


20200514191652697.png


20200514191718963.png


20200514191746367.png

main函数
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "key.h"
  4. #include "sys.h"
  5. #include "lcd.h"
  6. #include "usart.h"         
  7. #include "rtc.h"
  8. #include "wkup.h"
  9. #include "adc.h"         
  10. #include "dac.h"
  11. #include "timer.h"
  12. #include "usmart.h"

  13. //设置输出电压
  14. //vol:0~330,代表0~3.3V
  15. void PWM_DAC_Set(u16 vol)
  16. {
  17.         float temp=vol;
  18.         temp/=100;
  19.         temp=temp*256/3.3;
  20.         TIM_SetCompare1(TIM1,temp);
  21. }

  22. int main(void)
  23. {         
  24.         u16 adcx;
  25.         float temp;
  26.         u8 t=0;         
  27.         u16 pwmval=0;
  28.         u8 key;
  29.        
  30.         delay_init();                     //延时函数初始化          
  31.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  32.         uart_init(115200);                 //串口初始化为115200
  33.         KEY_Init();                                  //KEY初始化
  34.         LED_Init();                             //LED端口初始化
  35.         usmart_dev.init(72);        //初始化USMART       
  36.         LCD_Init();                                  //LCD初始化
  37.         Adc_Init();                                  //ADC初始化
  38.        
  39.         TIM1_PWM_Init(255,0);        //TIM1 PWM初始化,计数周期为256,Fpwm=72M/256=281.25Khz.
  40.         TIM_SetCompare1(TIM1,100);//初始值为0       
  41.              
  42.         POINT_COLOR=RED;//设置字体为红色
  43.         LCD_ShowString(60,50,200,16,16,"WarShip STM32");       
  44.         LCD_ShowString(60,70,200,16,16,"PWM DAC TEST");       
  45.         LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
  46.         LCD_ShowString(60,110,200,16,16,"2015/1/15");       
  47.         LCD_ShowString(60,130,200,16,16,"WK_UP:+  KEY1:-");       
  48.         //显示提示信息                                                                                             
  49.         POINT_COLOR=BLUE;//设置字体为蓝色
  50.         LCD_ShowString(60,150,200,16,16,"PWM VAL:");             
  51.         LCD_ShowString(60,170,200,16,16,"DAC VOL:0.000V");             
  52.         LCD_ShowString(60,190,200,16,16,"ADC VOL:0.000V");
  53.        
  54.         TIM_SetCompare1(TIM1,pwmval);//初始值                         
  55.         while(1)
  56.         {
  57.                 t++;
  58.                 key=KEY_Scan(0);                          
  59.                 if(key==WKUP_PRES)
  60.                 {                 
  61.                         if(pwmval<250)pwmval+=10;
  62.                         TIM_SetCompare1(TIM1,pwmval);                 //输出
  63.                 }else if(key==KEY1_PRES)       
  64.                 {
  65.                         if(pwmval>10)pwmval-=10;
  66.                         else pwmval=0;
  67.                         TIM_SetCompare1(TIM1,pwmval);                 //输出
  68.                 }         
  69.                
  70.                 if(t==10||key==KEY1_PRES||key==WKUP_PRES)                 //WKUP/KEY1按下了,或者定时时间到了
  71.                 {          
  72.                         adcx=TIM_GetCapture1(TIM1);
  73.                         LCD_ShowxNum(124,150,adcx,4,16,0);             //显示DAC寄存器值
  74.                         temp=(float)adcx*(3.3/256);                                //得到DAC电压值
  75.                         adcx=temp;
  76.                         LCD_ShowxNum(124,170,temp,1,16,0);             //显示电压值整数部分
  77.                         temp-=adcx;
  78.                         temp*=1000;
  79.                         LCD_ShowxNum(140,170,temp,3,16,0x80);         //显示电压值的小数部分
  80.                        
  81.                         adcx=Get_Adc_Average(ADC_Channel_1,20); //得到ADC转换值          
  82.                         temp=(float)adcx*(3.3/4096);                        //得到ADC电压值
  83.                         adcx=temp;
  84.                         LCD_ShowxNum(124,190,temp,1,16,0);             //显示电压值整数部分
  85.                         temp-=adcx;
  86.                         temp*=1000;
  87.                         LCD_ShowxNum(140,190,temp,3,16,0x80);         //显示电压值的小数部分
  88.                         t=0;
  89.                         LED0=!LED0;          
  90.                 }            
  91.                 delay_ms(10);       
  92.         }
  93. }
复制代码


pwm_dac.c函数
  1. //TIM1 CH1 PWM输出设置
  2. //PWM输出初始化
  3. //arr:自动重装值
  4. //psc:时钟预分频数
  5. void TIM1_PWM_Init(u16 arr,u16 psc)
  6. {                                                                 
  7.         GPIO_InitTypeDef GPIO_InitStructure;
  8.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  9.         TIM_OCInitTypeDef  TIM_OCInitStructure;
  10.        
  11.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能TIMx外设
  12.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA外设时钟使能
  13.          
  14.   //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
  15.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM1_CH1
  16.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用功能输出
  17.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIO

  19.         TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载周期值
  20.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值 不分频
  21.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
  22.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  23.         TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx
  24.                  
  25.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //CH1 PWM2模式       
  26.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
  27.         TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
  28.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //OC1 低电平有效
  29.         TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据指定的参数初始化外设TIMx

  30.         TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH1 预装载使能
  31.        
  32.         TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
  33.        
  34.         TIM_CtrlPWMOutputs(TIM1,ENABLE);        //MOE 主输出使能,高级定时器必须开启这个
  35.        
  36.         TIM_Cmd(TIM1, ENABLE);  //使能TIMx                                                                                             
  37. }
复制代码


————————————————
版权声明:_Amen
如有侵权请联系删除


收藏 评论0 发布时间:2023-5-14 17:40

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版