网站栏目做跳转后不显示,谷歌做网站,西宁市城乡建设网站,在线爬取网页源码技术笔记#xff01;
一、DAC简介#xff08;了解#xff09;
1.1 DAC概念 传感器信号采集改变电信号#xff0c;通过ADC转换成单片机可以处理的数字信号#xff0c;处理后#xff0c;通过DAC转换成电信号#xff0c;进而实现对系统的控制。 1.2 DAC的特性参数 1.3…技术笔记
一、DAC简介了解
1.1 DAC概念 传感器信号采集改变电信号通过ADC转换成单片机可以处理的数字信号处理后通过DAC转换成电信号进而实现对系统的控制。 1.2 DAC的特性参数 1.3 STM32各系列DAC的主要特性 二、DAC工作原理掌握
2.1 DAC框图简介 2.2 参考电压/模拟部分电压 2.3 DAC数据格式 2.4 触发源 2.5 DMA请求 2.6 DAC输出电压 三、DAC输出实验熟悉
3.1 实验简要了解 3.2 DAC寄存器介绍了解 3.3 DAC输出实验配置步骤掌握 3.4 编程实战DAC输出实验掌握
dac.c
#include ./BSP/DAC/dac.hDAC_HandleTypeDef g_dac_handle;/* DAC初始化函数 */
void dac_init(void)
{DAC_ChannelConfTypeDef dac_ch_conf;g_dac_handle.Instance DAC;HAL_DAC_Init(g_dac_handle); /* 初始化DAC */dac_ch_conf.DAC_Trigger DAC_TRIGGER_NONE; /* 不使用触发功能 */dac_ch_conf.DAC_OutputBuffer DAC_OUTPUTBUFFER_DISABLE; /* DAC输出缓冲关闭 */HAL_DAC_ConfigChannel(g_dac_handle, dac_ch_conf, DAC_CHANNEL_1); /* 配置DAC通道1 */HAL_DAC_Start(g_dac_handle, DAC_CHANNEL_1); /* 开启DAC通道1 */
}/* DAC MSP初始化函数 */
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{if (hdac-Instance DAC){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_DAC_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();gpio_init_struct.Pin GPIO_PIN_4;gpio_init_struct.Mode GPIO_MODE_ANALOG;HAL_GPIO_Init(GPIOA, gpio_init_struct);}
}/* 设置通道输出电压 */
void dac_set_voltage(uint16_t vol)
{double temp vol;temp / 1000;temp temp * 4096 / 3.3;if (temp 4096)temp 4095; /* 如果值大于等于4096, 则取4095 */HAL_DAC_SetValue(g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, temp); /* 12位右对齐数据格式设置DAC值 */
}main.c
#include ./BSP/DAC/dac.hDAC_HandleTypeDef g_dac_handle;/* DAC初始化函数 */
void dac_init(void)
{DAC_ChannelConfTypeDef dac_ch_conf;g_dac_handle.Instance DAC;HAL_DAC_Init(g_dac_handle); /* 初始化DAC */dac_ch_conf.DAC_Trigger DAC_TRIGGER_NONE; /* 不使用触发功能 */dac_ch_conf.DAC_OutputBuffer DAC_OUTPUTBUFFER_DISABLE; /* DAC输出缓冲关闭 */HAL_DAC_ConfigChannel(g_dac_handle, dac_ch_conf, DAC_CHANNEL_1); /* 配置DAC通道1 */HAL_DAC_Start(g_dac_handle, DAC_CHANNEL_1); /* 开启DAC通道1 */
}/* DAC MSP初始化函数 */
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{if (hdac-Instance DAC){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_DAC_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();gpio_init_struct.Pin GPIO_PIN_4;gpio_init_struct.Mode GPIO_MODE_ANALOG;HAL_GPIO_Init(GPIOA, gpio_init_struct);}
}/* 设置通道输出电压 */
void dac_set_voltage(uint16_t vol)
{double temp vol;temp / 1000;temp temp * 4096 / 3.3;if (temp 4096)temp 4095; /* 如果值大于等于4096, 则取4095 */HAL_DAC_SetValue(g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, temp); /* 12位右对齐数据格式设置DAC值 */
}四、DAC输出三角波实验熟悉
4.1 实验简要了解 4.2 编程实战DAC输出三角波实验掌握
dac.c
#include ./BSP/DAC/dac.h
#include ./SYSTEM/delay/delay.hDAC_HandleTypeDef g_dac_handle;/* DAC初始化函数 */
void dac_init(void)
{DAC_ChannelConfTypeDef dac_ch_conf;g_dac_handle.Instance DAC;HAL_DAC_Init(g_dac_handle);dac_ch_conf.DAC_Trigger DAC_TRIGGER_NONE;dac_ch_conf.DAC_OutputBuffer DAC_OUTPUTBUFFER_DISABLE;HAL_DAC_ConfigChannel(g_dac_handle, dac_ch_conf, DAC_CHANNEL_1);HAL_DAC_Start(g_dac_handle, DAC_CHANNEL_1);
}/* DAC MSP初始化函数 */
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{if (hdac-Instance DAC){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_DAC_CLK_ENABLE();gpio_init_struct.Pin GPIO_PIN_4;gpio_init_struct.Mode GPIO_MODE_ANALOG;HAL_GPIO_Init(GPIOA, gpio_init_struct);}
}/*** brief 设置DAC_OUT1输出三角波* note 输出频率 ≈ 1000 / (dt * samples) Khz, 不过在dt较小的时候,比如小于5us时, 由于delay_us* 本身就不准了(调用函数,计算等都需要时间,延时很小的时候,这些时间会影响到延时), 频率会偏小.* * param maxval : 最大值(0 maxval 4096), (maxval 1)必须大于等于samples/2* param dt : 每个采样点的延时时间(单位: us)* param samples: 采样点的个数, samples必须小于等于(maxval 1) * 2 , 且maxval不能等于0* param n : 输出波形个数,0~65535** retval 无*/
void dac_triangular_wave(uint16_t maxval, uint16_t dt, uint16_t samples, uint16_t n)
{uint16_t i, j;float incval; /* 递增量 */float Curval; /* 当前值 */if(samples ((maxval 1) * 2))return ; /* 数据不合法 */incval (maxval 1) / (samples / 2); /* 计算递增量 */for(j 0; j n; j){ Curval 0;HAL_DAC_SetValue(g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval); /* 先输出0 */for(i 0; i (samples / 2); i) /* 输出上升沿 */{Curval incval; /* 新的输出值 */HAL_DAC_SetValue(g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval);delay_us(dt);}for(i 0; i (samples / 2); i) /* 输出下降沿 */{Curval - incval; /* 新的输出值 */HAL_DAC_SetValue(g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval);delay_us(dt);}}
}
main.c
int main(void)
{uint8_t t 0; uint8_t key;HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */lcd_init(); /* 初始化LCD */key_init(); /* 初始化按键 */dac_init(); /* 初始化DAC1_OUT1通道 */lcd_show_string(30, 50, 200, 16, 16, STM32, RED);lcd_show_string(30, 70, 200, 16, 16, DAC Triangular WAVE TEST, RED);lcd_show_string(30, 90, 200, 16, 16, ATOMALIENTEK, RED);lcd_show_string(30, 110, 200, 16, 16, KEY0:Wave1 KEY1:Wave2, RED);lcd_show_string(30, 130, 200, 16, 16, DAC None, BLUE); /* 提示无输出 */while (1){t;key key_scan(0); /* 按键扫描 */if (key KEY0_PRES) /* 高采样率 , 100hz波形 实际只有65.5hz */{lcd_show_string(30, 130, 200, 16, 16, DAC Wave1 , BLUE);dac_triangular_wave(4095, 5, 2000, 100); /* 幅值4095, 采样点间隔5us, 2000个采样点, 100个波形 */lcd_show_string(30, 130, 200, 16, 16, DAC None , BLUE);}else if (key KEY1_PRES) /* 低采样率 , 100hz波形 实际99.5hz */{lcd_show_string(30, 130, 200, 16, 16, DAC Wave2 , BLUE);dac_triangular_wave(4095, 500, 20, 100); /* 幅值4095, 采样点间隔500us, 20个采样点, 100个波形 */lcd_show_string(30, 130, 200, 16, 16, DAC None , BLUE);}if (t 10) /* 定时时间到了 */{LED0_TOGGLE(); /* LED0闪烁 */t 0;}delay_ms(10);}
}五、DAC输出正弦波实验熟悉
5.1 实验简要了解 5.2 DAC输出正弦波实验配置步骤掌握 5.3 产生正弦波序列函数介绍熟悉 5.4 编程实战DAC输出正弦波实验掌握
dac.c
#include ./BSP/DAC/dac.hDMA_HandleTypeDef g_dma_dac_handle;
DAC_HandleTypeDef g_dac_dma_handle;extern uint16_t g_dac_sin_buf[4096]; /* 发送数据缓冲区 *//* DAC DMA输出波形初始化函数 */
void dac_dma_wave_init(void)
{DAC_ChannelConfTypeDef dac_ch_conf;__HAL_RCC_DMA2_CLK_ENABLE();g_dma_dac_handle.Instance DMA2_Channel3;g_dma_dac_handle.Init.Direction DMA_MEMORY_TO_PERIPH;g_dma_dac_handle.Init.PeriphInc DMA_PINC_DISABLE;g_dma_dac_handle.Init.MemInc DMA_MINC_ENABLE;g_dma_dac_handle.Init.PeriphDataAlignment DMA_PDATAALIGN_HALFWORD;g_dma_dac_handle.Init.MemDataAlignment DMA_MDATAALIGN_HALFWORD;g_dma_dac_handle.Init.Mode DMA_CIRCULAR;g_dma_dac_handle.Init.Priority DMA_PRIORITY_MEDIUM;HAL_DMA_Init(g_dma_dac_handle);__HAL_LINKDMA(g_dac_dma_handle, DMA_Handle1, g_dma_dac_handle);g_dac_dma_handle.Instance DAC;HAL_DAC_Init(g_dac_dma_handle);dac_ch_conf.DAC_Trigger DAC_TRIGGER_T7_TRGO;dac_ch_conf.DAC_OutputBuffer DAC_OUTPUTBUFFER_DISABLE;HAL_DAC_ConfigChannel(g_dac_dma_handle, dac_ch_conf, DAC_CHANNEL_1);HAL_DMA_Start(g_dma_dac_handle, (uint32_t)g_dac_sin_buf, (uint32_t)DAC1-DHR12R1, 0);
}/* DAC MSP初始化函数 */
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{if (hdac-Instance DAC){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_DAC_CLK_ENABLE();gpio_init_struct.Pin GPIO_PIN_4;gpio_init_struct.Mode GPIO_MODE_ANALOG;HAL_GPIO_Init(GPIOA, gpio_init_struct);}
}/*** brief DAC DMA使能波形输出* note TIM7的输入时钟频率(f)来自APB1, f 36M * 2 72Mhz.* DAC触发频率 ftrgo f / ((psc 1) * (arr 1))* 波形频率 ftrgo / ndtr; ** param ndtr : DMA通道单次传输数据量* param arr : TIM7的自动重装载值* param psc : TIM7的分频系数* retval 无*/
void dac_dma_wave_enable(uint16_t cndtr, uint16_t arr, uint16_t psc)
{TIM_HandleTypeDef tim7_handle {0};TIM_MasterConfigTypeDef tim_mater_config {0};__HAL_RCC_TIM7_CLK_ENABLE();tim7_handle.Instance TIM7;tim7_handle.Init.Prescaler psc;tim7_handle.Init.Period arr;HAL_TIM_Base_Init(tim7_handle);tim_mater_config.MasterOutputTrigger TIM_TRGO_UPDATE;tim_mater_config.MasterSlaveMode TIM_MASTERSLAVEMODE_DISABLE;HAL_TIMEx_MasterConfigSynchronization(tim7_handle, tim_mater_config);HAL_TIM_Base_Start(tim7_handle);HAL_DAC_Stop_DMA(g_dac_dma_handle, DAC_CHANNEL_1);HAL_DAC_Start_DMA(g_dac_dma_handle, DAC_CHANNEL_1, (uint32_t *)g_dac_sin_buf, cndtr, DAC_ALIGN_12B_R);
}main.c
uint16_t g_dac_sin_buf[4096]; /* 发送数据缓冲区 *//*** brief 产生正弦波序列函数* note 需保证: maxval samples/2* param maxval : 最大值(0 maxval 2048)* param samples: 采样点的个数* retval 无*/
void dac_creat_sin_buf(uint16_t maxval, uint16_t samples)
{uint8_t i;float outdata 0; /* 存放计算后的数字量 */float inc (2 * 3.1415962) / samples; /* 计算相邻两个点的x轴间隔 */if(maxval (samples / 2))return ; /* 数据不合法 */for (i 0; i samples; i){/* * 正弦波函数解析式y Asin(ωx φ b* 计算每个点的y值将峰值放大maxval倍并将曲线向上偏移maxval到正数区域* 注意DAC无法输出负电压所以需要将曲线向上偏移一个峰值的量让整个曲线都落在正数区域*/outdata maxval * sin(inc * i) maxval;if (outdata 4095)outdata 4095; /* 上限限定 *///printf(%f\r\n,outdata);g_dac_sin_buf[i] outdata;}
}int main(void)
{uint8_t t 0;uint8_t key;HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */lcd_init(); /* 初始化LCD */key_init(); /* 初始化按键 */dac_dma_wave_init();lcd_show_string(30, 50, 200, 16, 16, STM32, RED);lcd_show_string(30, 70, 200, 16, 16, DAC DMA Sine WAVE TEST, RED);lcd_show_string(30, 90, 200, 16, 16, ATOMALIENTEK, RED);lcd_show_string(30, 110, 200, 16, 16, KEY0:3Khz KEY1:30Khz, RED);dac_creat_sin_buf(2048, 100);dac_dma_wave_enable(100, 10 - 1, 72 - 1); /* 100Khz触发频率, 100个点, 得到1Khz的正弦波 */while (1){t;key key_scan(0); /* 按键扫描 */if (key KEY0_PRES) /* 高采样率 */{dac_creat_sin_buf(2048, 100);dac_dma_wave_enable(100, 10 - 1, 24 - 1); /* 300Khz触发频率, 100个点, 得到最高3KHz的正弦波. */}else if (key KEY1_PRES) /* 低采样率 */{dac_creat_sin_buf(2048, 10);dac_dma_wave_enable(10, 10 - 1, 24 - 1); /* 300Khz触发频率, 10个点, 可以得到最高30KHz的正弦波. */}if (t 40) /* 定时时间到了 */{LED0_TOGGLE(); /* LED0闪烁 */t 0;}delay_ms(5);}
}
六、PWM DAC实验熟悉
6.1 PWM DAC应用背景了解 6.2 PWM DAC技术实现原理了解
6.2.1什么是PWM DAC技术 6.2.2用分段函数表示PWM波 6.2.3将PWM波分段函数进行傅里叶级数展开 6.2.4PWM DAC的分辨率 6.2.58位分辨率下对RC滤波器的设计要求 6.2.6PWM DAC二阶低通滤波器原理图 6.3编程实战 PWM DAC实验掌握 pwmdac.c
#include ./BSP/PWMDAC/pwmdac.hTIM_HandleTypeDef g_timx_pwm_chy_handle;/* PWM DAC初始化 */
void pwmdac_init(uint16_t arr, uint16_t psc)
{TIM_OC_InitTypeDef timx_oc_pwm_chy {0};g_timx_pwm_chy_handle.Instance TIM1;g_timx_pwm_chy_handle.Init.Prescaler psc;g_timx_pwm_chy_handle.Init.Period arr;g_timx_pwm_chy_handle.Init.CounterMode TIM_COUNTERMODE_UP;g_timx_pwm_chy_handle.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_ENABLE;HAL_TIM_PWM_Init(g_timx_pwm_chy_handle);timx_oc_pwm_chy.OCMode TIM_OCMODE_PWM1;timx_oc_pwm_chy.Pulse 0;timx_oc_pwm_chy.OCPolarity TIM_OCPOLARITY_HIGH;HAL_TIM_PWM_ConfigChannel(g_timx_pwm_chy_handle, timx_oc_pwm_chy, TIM_CHANNEL_1);HAL_TIM_PWM_Start(g_timx_pwm_chy_handle, TIM_CHANNEL_1);
}/* TIM MSP初始化函数 */
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{if(htim-Instance TIM1){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_TIM1_CLK_ENABLE();gpio_init_struct.Pin GPIO_PIN_8;gpio_init_struct.Mode GPIO_MODE_AF_PP; /* 推挽复用 */gpio_init_struct.Pull GPIO_PULLUP; /* 上拉 */gpio_init_struct.Speed GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(GPIOA, gpio_init_struct);}
}/* 设置PWM DAC输出电压 */
void pwmdac_set_voltage(uint16_t vol)
{float temp vol;temp / 1000;temp temp * 256 / 3.3;__HAL_TIM_SET_COMPARE(g_timx_pwm_chy_handle, TIM_CHANNEL_1, temp);
}
main.c
int main(void)
{uint16_t adcx;float temp;HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */lcd_init(); /* 初始化LCD */adc_init(); /* 初始化ADC */pwmdac_init(256 - 1, 0);pwmdac_set_voltage(2800);lcd_show_string(30, 50, 200, 16, 16, STM32, RED);lcd_show_string(30, 70, 200, 16, 16, ADC TEST, RED);lcd_show_string(30, 90, 200, 16, 16, ATOMALIENTEK, RED);lcd_show_string(30, 110, 200, 16, 16, ADC1_CH1_VOL:0.000V, BLUE); /* 先在固定位置显示小数点 */while (1){adcx adc_get_result();temp (float)adcx * (3.3 / 4096); /* 获取计算后的带小数的实际电压值比如3.1111 */adcx temp; /* 赋值整数部分给adcx变量因为adcx为u16整形 */lcd_show_xnum(134, 110, adcx, 1, 16, 0, BLUE); /* 显示电压值的整数部分3.1111的话这里就是显示3 */temp - adcx; /* 把已经显示的整数部分去掉留下小数部分比如3.1111-30.1111 */temp * 1000; /* 小数部分乘以1000例如0.1111就转换为111.1相当于保留三位小数。 */lcd_show_xnum(150, 110, temp, 3, 16, 0X80, BLUE);/* 显示小数部分前面转换为了整形显示这里显示的就是111. */LED0_TOGGLE();delay_ms(100);}
}