以下是关于HAL库版本
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./USMART/usmart.h"
#include "./BSP/KEY/key.h"
#include "./BSP/PWMDAC/pwmdac.h"
#include "./BSP/ADC/adc.h"
extern TIM_HandleTypeDef g_tim9_handler;
int main(void)
{
uint16_t adcx;
float temp;
uint8_t t = 0;
uint8_t key;
uint16_t pwmval = 0;
HAL_Init();
sys_stm32_clock_init(336, 8, 2, 7);
delay_init(168);
usart_init(115200);
usmart_dev.init(84);
led_init();
lcd_init();
key_init();
adc_init();
pwmdac_init(256 - 1, 0);
lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
lcd_show_string(30, 70, 200, 16, 16, "PWM DAC TEST", RED);
lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
lcd_show_string(30, 110, 200, 16, 16, "KEY_UP:+ KEY1:-", RED);
lcd_show_string(30, 130, 200, 16, 16, "PWM VAL:", BLUE);
lcd_show_string(30, 150, 200, 16, 16, "DAC VOL:0.000V", BLUE);
lcd_show_string(30, 170, 200, 16, 16, "ADC VOL:0.000V", BLUE);
__HAL_TIM_SET_COMPARE(&g_tim9_handler, PWMDAC_TIMX_CHY, pwmval);
while (1)
{
t++;
key = key_scan(0);
if (key == WKUP_PRES)
{
if (pwmval < 250)
{
pwmval += 10;
}
__HAL_TIM_SET_COMPARE(&g_tim9_handler, PWMDAC_TIMX_CHY, pwmval);
}
else if (key == KEY1_PRES)
{
if (pwmval > 10)
{
pwmval -= 10;
}
else
{
pwmval = 0;
}
__HAL_TIM_SET_COMPARE(&g_tim9_handler, PWMDAC_TIMX_CHY, pwmval);
}
if (t == 10 || key == KEY1_PRES || key == WKUP_PRES)
{
adcx = __HAL_TIM_GET_COMPARE(&g_tim9_handler,PWMDAC_TIMX_CHY);
lcd_show_xnum(94, 130, adcx, 3, 16, 0, BLUE);
temp = (float)adcx * (3.3 / 256);
adcx = temp;
lcd_show_xnum(94, 150, temp, 1, 16, 0, BLUE);
temp -= adcx;
temp *= 1000;
lcd_show_xnum(110, 150, temp, 3, 16, 0X80, BLUE);
adcx = adc_get_result_average(ADC_ADCX_CHY, 10);
temp = (float)adcx * (3.3 / 4096);
adcx = temp;
lcd_show_xnum(94, 170, temp, 1, 16, 0, BLUE);
temp -= adcx;
temp *= 1000;
lcd_show_xnum(110, 170, temp, 3, 16, 0X80, BLUE);
LED0_TOGGLE();
t = 0;
}
delay_ms(5);
}
}
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./USMART/usmart.h"
#include "./BSP/KEY/key.h"
#include "./BSP/PWMDAC/pwmdac.h"
#include "./BSP/ADC/adc.h"
extern TIM_HandleTypeDef g_tim9_handler;声明了一个外部的定时器句柄,用于操作定时器 9。
int main(void)
{
uint16_t adcx;用于存储 ADC 转换结果或经过计算的值。
float temp;用于临时存储浮点数计算结果。
uint8_t t = 0;一个计数器变量。
uint8_t key;用于存储按键扫描结果。
uint16_t pwmval = 0;PWM 占空比的值。
HAL_Init(); 初始化 HAL 库。
sys_stm32_clock_init(336, 8, 2, 7); 初始化 STM32 的时钟,具体参数可能根据不同的需求设置时钟频率等。
delay_init(168); 初始化延迟函数。
usart_init(115200); 初始化串口通信,设置波特率为 115200。
usmart_dev.init(84); 初始化智能设备驱动,具体功能取决于该驱动的实现。
led_init(); 初始化 LED。
lcd_init(); 初始化 LCD 显示屏。
key_init(); 初始化按键。
adc_init(); 初始化 ADC。
pwmdac_init(256 - 1, 0);初始化 PWM DAC,参数可能用于设置相关的参数,如分辨率等。
lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
lcd_show_string(30, 70, 200, 16, 16, "PWM DAC TEST", RED);
lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
lcd_show_string(30, 110, 200, 16, 16, "KEY_UP:+ KEY1:-", RED);
lcd_show_string(30, 130, 200, 16, 16, "PWM VAL:", BLUE);
lcd_show_string(30, 150, 200, 16, 16, "DAC VOL:0.000V", BLUE);
lcd_show_string(30, 170, 200, 16, 16, "ADC VOL:0.000V", BLUE);
__HAL_TIM_SET_COMPARE(&g_tim9_handler, PWMDAC_TIMX_CHY, pwmval);
while (1)
{
t++;计数器变量 t 自增。
key = key_scan(0); 扫描按键,获取按键状态。
if (key == WKUP_PRES)
{
if (pwmval < 250)
{
pwmval += 10;
}如果按下 WKUP且pwmval < 250
,则将pwmval
增加 10,并更新定时器的比较值以改变 PWM 占空比。
__HAL_TIM_SET_COMPARE(&g_tim9_handler, PWMDAC_TIMX_CHY, pwmval);
}
else if (key == KEY1_PRES)
{
if (pwmval > 10)
{
pwmval -= 10;
}
else
{
pwmval = 0;
}如果按下 KEY1 且pwmval > 10
,则将pwmval
减少 10,若pwmval
不大于 10,则将其设置为 0,并更新定时器的比较值。
__HAL_TIM_SET_COMPARE(&g_tim9_handler, PWMDAC_TIMX_CHY, pwmval);
}
if (t == 10 || key == KEY1_PRES || key == WKUP_PRES) 当计数器变量t
等于 10 或者检测到特定按键(KEY1 按下或 WKUP 按下)被按下时,执行以下操作。
{
adcx = __HAL_TIM_GET_COMPARE(&g_tim9_handler,PWMDAC_TIMX_CHY); 获取定时器 9 的特定通道(PWMDAC_TIMX_CHY)的比较值,并将其存储在变量adcx
中。
lcd_show_xnum(94, 130, adcx, 3, 16, 0, BLUE); 在 LCD 屏幕的特定位置(横坐标 94,纵坐标 130)以蓝色显示获取到的定时器比较值,显示格式为 3 位数字,16 号字体大小,无特殊显示属性。
temp = (float)adcx * (3.3 / 256); 根据获取到的定时器比较值adcx
计算对应的模拟电压值,假设参考电压为 3.3V,并且根据某种比例关系(这里是除以 256)进行计算,结果存储在临时变量temp
中。
adcx = temp;将计算得到的模拟电压值重新赋值给adcx
。
lcd_show_xnum(94, 150, temp, 1, 16, 0, BLUE); 在 LCD 屏幕的特定位置(横坐标 94,纵坐标 150)以蓝色显示计算得到的模拟电压值,显示格式为 1 位数字,16 号字体大小,无特殊显示属性。
temp -= adcx;临时变量temp
减去当前的模拟电压值adcx
temp *= 1000;将差值乘以 1000。
lcd_show_xnum(110, 150, temp, 3, 16, 0X80, BLUE); 在 LCD 屏幕的特定位置(横坐标 110,纵坐标 150)以蓝色显示经过上述计算后的结果,显示格式为 3 位数字,16 号字体大小,具有特定显示属性(0X80,具体含义取决于程序上下文)。
adcx = adc_get_result_average(ADC_ADCX_CHY, 10); 调用函数获取 ADC 通道(ADC_ADCX_CHY)的平均转换结果,参数 10 可能表示取平均的次数。
temp = (float)adcx * (3.3 / 4096);根据 ADC 转换结果计算对应的模拟电压值,假设参考电压为 3.3V,并且根据某种比例关系(这里是除以 4096)进行计算,结果存储在临时变量temp
中。
adcx = temp;将计算得到的模拟电压值重新赋值给adcx
lcd_show_xnum(94, 170, temp, 1, 16, 0, BLUE); 在 LCD 屏幕的特定位置(横坐标 94,纵坐标 170)以蓝色显示计算得到的模拟电压值,显示格式为 1 位数字,16 号字体大小,无特殊显示属性。
temp -= adcx;临时变量temp
减去当前的模拟电压值adcx
。
temp *= 1000;将差值乘以 1000。
lcd_show_xnum(110, 170, temp, 3, 16, 0X80, BLUE); 在 LCD 屏幕的特定位置(横坐标 110,纵坐标 170)以蓝色显示经过上述计算后的结果,显示格式为 3 位数字,16 号字体大小,具有特定显示属性(0X80,具体含义取决于程序上下文)。
LED0_TOGGLE(); 切换 LED0 的状态,可能是让其亮灭状态反转。
t = 0;将计数器变量t
重置为 0,为下一次循环的条件判断做准备。
}
delay_ms(5);延迟 5 毫秒,控制程序的执行速度,避免过快地循环执行可能导致的资源占用过高或其他问题。
}
}
ADC的一些代码
#include "./BSP/ADC/adc.h"
#include "./SYSTEM/delay/delay.h"
ADC_HandleTypeDef g_adc_handle;
void adc_init(void)
{
g_adc_handle.Instance = ADC_ADCX;
g_adc_handle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
g_adc_handle.Init.Resolution = ADC_RESOLUTION_12B;
g_adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
g_adc_handle.Init.ScanConvMode = DISABLE;
g_adc_handle.Init.ContinuousConvMode = DISABLE;
g_adc_handle.Init.NbrOfConversion = 1;
g_adc_handle.Init.DiscontinuousConvMode = DISABLE;
g_adc_handle.Init.NbrOfDiscConversion = 0;
g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
g_adc_handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
g_adc_handle.Init.DMAContinuousRequests = DISABLE;
HAL_ADC_Init(&g_adc_handle);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
if(hadc->Instance == ADC_ADCX)
{
GPIO_InitTypeDef GPIO_Initure;
ADC_ADCX_CHY_CLK_ENABLE();
ADC_ADCX_CHY_GPIO_CLK_ENABLE();
GPIO_Initure.Pin = ADC_ADCX_CHY_GPIO_PIN;
GPIO_Initure.Mode = GPIO_MODE_ANALOG;
GPIO_Initure.Pull = GPIO_PULLUP;
HAL_GPIO_Init(ADC_ADCX_CHY_GPIO_PORT, &GPIO_Initure);
}
}
void adc_channel_set(ADC_HandleTypeDef *adc_handle, uint32_t ch, uint32_t rank, uint32_t stime)
{
ADC_ChannelConfTypeDef adc_channel;
adc_channel.Channel = ch;
adc_channel.Rank = rank;
adc_channel.SamplingTime = stime;
HAL_ADC_ConfigChannel( adc_handle, &adc_channel);
}
uint32_t adc_get_result(uint32_t ch)
{
adc_channel_set(&g_adc_handle, ch, 1, ADC_SAMPLETIME_480CYCLES);
HAL_ADC_Start(&g_adc_handle);
HAL_ADC_PollForConversion(&g_adc_handle, 10);
return (uint16_t)HAL_ADC_GetValue(&g_adc_handle);
}
uint32_t adc_get_result_average(uint32_t ch, uint8_t times)
{
uint32_t temp_val = 0;
uint8_t t;
for (t = 0; t < times; t++)
{
temp_val += adc_get_result(ch);
delay_ms(5);
}
return temp_val / times;
}
#include "./BSP/ADC/adc.h"引入特定的 ADC 相关头文件,可能包含了与 ADC 初始化、配置和操作相关的函数声明和宏定义。
#include "./SYSTEM/delay/delay.h"引入延迟函数相关的头文件,用于在程序中实现延迟功能。
ADC_HandleTypeDef g_adc_handle; 定义了一个全局的 ADC 句柄变量,用于操作 ADC 外设。
void adc_init(void)这段代码主要是对 ADC(模数转换器)进行初始化设置
{
g_adc_handle.Instance = ADC_ADCX;指定要初始化的 ADC 实例为ADC_ADCX
,这可能是一个特定的 ADC 外设编号或名称。
g_adc_handle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4; 设置 ADC 的时钟预分频器为系统时钟(PCLK)的四分之一。这决定了 ADC 的时钟频率,较低的时钟频率可能有助于降低功耗和提高转换精度。
g_adc_handle.Init.Resolution = ADC_RESOLUTION_12B; 选择 ADC 的分辨率为 12 位。这意味着 ADC 可以将模拟输入信号转换为 12 位的数字值,提供较高的分辨率和精度。
g_adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; 设置 ADC 的数据对齐方式为右对齐。在右对齐方式下,数字值的最低有效位(LSB)位于数据的最低位,这是常见的对齐方式。
g_adc_handle.Init.ScanConvMode = DISABLE; 禁用扫描转换模式。扫描转换模式通常用于同时转换多个通道,但在这里被禁用,可能是因为只需要转换一个通道。
g_adc_handle.Init.ContinuousConvMode = DISABLE; 禁用连续转换模式。在连续转换模式下,ADC 会自动连续进行转换,而在这里被禁用,可能是因为只需要在特定的时候进行单次转换。
g_adc_handle.Init.NbrOfConversion = 1; 设置要转换的通道数量为 1。这与前面禁用扫描转换模式和连续转换模式相呼应,表明只需要转换一个特定的通道。
g_adc_handle.Init.DiscontinuousConvMode = DISABLE; 禁用不连续转换模式。不连续转换模式通常用于在特定的触发条件下进行非连续的转换,但在这里被禁用。
g_adc_handle.Init.NbrOfDiscConversion = 0;
- 设置不连续转换的次数为 0。这进一步确认了不连续转换模式被禁用。
g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
- 设置外部触发转换为软件触发。这意味着 ADC 的转换将由软件控制而不是外部触发信号触发。
g_adc_handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
- 设置外部触发转换的边沿为无。这与前面设置为软件触发相匹配,因为不需要外部触发边沿。
g_adc_handle.Init.DMAContinuousRequests = DISABLE;
- 禁用 DMA(直接内存访问)连续请求。这意味着 ADC 的转换结果不会自动通过 DMA 传输到内存,可能是通过其他方式读取转换结果。
HAL_ADC_Init(&g_adc_handle); 调用 HAL(Hardware Abstraction Layer)库中的函数来初始化 ADC。这个函数会根据前面设置的参数对 ADC 进行初始化,使 ADC 准备好进行转换
}
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)这个函数主要用于在使用特定的 ADC(模数转换器)实例(这里假设为ADC_ADCX
)时,进行与该 ADC 相关的 GPIO(通用输入输出端口)的初始化配置。
{
if(hadc->Instance == ADC_ADCX)检查传入的ADC_HandleTypeDef
类型指针hadc
所指向的 ADC 实例是否为ADC_ADCX
。只有当条件满足时,才会执行后续的初始化操作。
{
GPIO_InitTypeDef GPIO_Initure;定义一个GPIO_InitTypeDef
类型的结构体变量GPIO_Initure
,用于存储 GPIO 的配置参数。
ADC_ADCX_CHY_CLK_ENABLE(); 使能与特定 ADC 通道相关的时钟。具体的宏定义ADC_ADCX_CHY_CLK_ENABLE()
可能根据不同的硬件平台和开发环境而有所不同,但通常用于开启与 ADC 通道相关的时钟源,以确保后续对该通道的操作能够正常进行。
ADC_ADCX_CHY_GPIO_CLK_ENABLE(); 使能与特定 ADC 通道对应的 GPIO 端口的时钟。这是为了确保可以对该 GPIO 端口进行配置和操作。
GPIO_Initure.Pin = ADC_ADCX_CHY_GPIO_PIN;设置要配置的 GPIO 引脚为特定的 ADC 通道对应的引脚,宏定义ADC_ADCX_CHY_GPIO_PIN
代表具体的引脚编号。
GPIO_Initure.Mode = GPIO_MODE_ANALOG;将 GPIO 引脚的模式设置为模拟输入模式。这是因为 ADC 需要连接到模拟输入引脚,以便将模拟信号转换为数字值。
GPIO_Initure.Pull = GPIO_PULLUP;设置 GPIO 引脚的上拉模式为上拉。这可以在没有外部信号输入时,确保引脚处于一个已知的状态。
HAL_GPIO_Init(ADC_ADCX_CHY_GPIO_PORT, &GPIO_Initure);调用 HAL 库中的函数HAL_GPIO_Init
,根据前面设置的参数对特定的 GPIO 端口进行初始化。这里的ADC_ADCX_CHY_GPIO_PORT
代表要初始化的 GPIO 端口,而&GPIO_Initure
是指向前面配置好的结构体变量的指针。
}
}
void adc_channel_set(ADC_HandleTypeDef *adc_handle, uint32_t ch, uint32_t rank, uint32_t stime)函数用于设置 ADC(模数转换器)的通道配置。
{
ADC_ChannelConfTypeDef adc_channel;
adc_channel.Channel = ch;
adc_channel.Rank = rank;
adc_channel.SamplingTime = stime;
HAL_ADC_ConfigChannel( adc_handle, &adc_channel);
}
uint32_t adc_get_result(uint32_t ch)函数用于获取特定 ADC 通道的转换结果。
{
adc_channel_set(&g_adc_handle, ch, 1, ADC_SAMPLETIME_480CYCLES);
HAL_ADC_Start(&g_adc_handle);
HAL_ADC_PollForConversion(&g_adc_handle, 10);
return (uint16_t)HAL_ADC_GetValue(&g_adc_handle);
}
uint32_t adc_get_result_average(uint32_t ch, uint8_t times)函数用于获取特定 ADC 通道的多次转换结果的平均值。
ch
:要获取平均值的 ADC 通道号。times
:进行 ADC 转换的次数,用于计算平均值。
{
uint32_t temp_val = 0;定义一个uint32_t
类型的变量temp_val
,用于累加多次 ADC 转换结果。
uint8_t t;定义一个循环变量t
。
for (t = 0; t < times; t++) 这是一个循环,循环次数由参数times
决定。
{
temp_val += adc_get_result(ch);在每次循环中,调用adc_get_result(ch)
函数获取指定通道ch
的 ADC 转换结果,并累加到temp_val
中。
delay_ms(5);每次获取 ADC 转换结果后,延迟 5 毫秒,可能是为了给 ADC 足够的时间稳定或者避免过快地连续读取导致不准确的结果。
}
return temp_val / times; 循环结束后,将累加的总和temp_val
除以循环次数times
,得到指定通道ch
的多次 ADC 转换结果的平均值,并返回这个平均值。
}
PWM的相关代码
#include "./BSP/PWMDAC/pwmdac.h"
TIM_HandleTypeDef g_tim9_handler;
TIM_OC_InitTypeDef g_tim9_ch2handler;
void pwmdac_init(uint16_t arr, uint16_t psc)
{
g_tim9_handler.Instance = PWMDAC_TIMX;
g_tim9_handler.Init.Prescaler = psc;
g_tim9_handler.Init.CounterMode = TIM_COUNTERMODE_UP;
g_tim9_handler.Init.Period = arr;
HAL_TIM_PWM_Init(&g_tim9_handler);
g_tim9_ch2handler.OCMode = TIM_OCMODE_PWM1;
g_tim9_ch2handler.Pulse = arr / 2;
g_tim9_ch2handler.OCPolarity = TIM_OCPOLARITY_HIGH;
HAL_TIM_PWM_ConfigChannel(&g_tim9_handler, &g_tim9_ch2handler, PWMDAC_TIMX_CHY);
HAL_TIM_PWM_Start(&g_tim9_handler, PWMDAC_TIMX_CHY);
}
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
GPIO_InitTypeDef gpio_init_struct;
if (htim->Instance == PWMDAC_TIMX)
{
PWMDAC_TIMX_CLK_ENABLE();
PWMDAC_GPIO_CLK_ENABLE();
gpio_init_struct.Pin = PWMDAC_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_AF_PP;
gpio_init_struct.Pull = GPIO_PULLUP;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
gpio_init_struct.Alternate = PWMDAC_GPIO_AFTIMX;
HAL_GPIO_Init(PWMDAC_GPIO_PORT, &gpio_init_struct);
}
}
void pwmdac_set_voltage(uint16_t vol)
{
float temp = vol;
temp /= 100;
temp = temp * 256 / 3.3f;
__HAL_TIM_SET_COMPARE(&g_tim9_handler, PWMDAC_TIMX_CHY, temp);
}
#include "./BSP/PWMDAC/pwmdac.h"引入了与 PWM DAC(脉宽调制数模转换)相关的头文件,可能包含了函数声明、宏定义和结构体定义等,用于实现特定硬件平台上的 PWM DAC 功能。
TIM_HandleTypeDef g_tim9_handler; 定义了一个定时器句柄,用于操作定时器 9,可能用于生成 PWM 信号。
TIM_OC_InitTypeDef g_tim9_ch2handler; 定义了一个定时器输出比较初始化结构体,用于配置定时器 9 的特定通道(可能是通道 2)的输出比较功能,与生成 PWM 信号的参数设置相关。
void pwmdac_init(uint16_t arr, uint16_t psc)该函数用于初始化 PWM DAC。
{
g_tim9_handler.Instance = PWMDAC_TIMX; 设置要使用的定时器实例为PWMDAC_TIMX
,可能是一个特定的定时器编号。
g_tim9_handler.Init.Prescaler = psc; 设置定时器的预分频值为传入的参数psc
,用于确定定时器时钟频率。
g_tim9_handler.Init.CounterMode = TIM_COUNTERMODE_UP; 设置定时器为向上计数模式。
g_tim9_handler.Init.Period = arr; 设置定时器的自动重装载值为传入的参数arr
,决定了 PWM 信号的周期。
HAL_TIM_PWM_Init(&g_tim9_handler); 调用 HAL 库函数初始化定时器的 PWM 功能。
g_tim9_ch2handler.OCMode = TIM_OCMODE_PWM1; 设置定时器通道的输出比较模式为 PWM1 模式。
g_tim9_ch2handler.Pulse = arr / 2; 设置初始的脉冲宽度为自动重装载值的一半,可能对应 50% 的占空比。
g_tim9_ch2handler.OCPolarity = TIM_OCPOLARITY_HIGH; 设置输出比较极性为高电平有效。
HAL_TIM_PWM_ConfigChannel(&g_tim9_handler, &g_tim9_ch2handler, PWMDAC_TIMX_CHY); 配置定时器的特定通道(可能是通道 2)的 PWM 参数。
HAL_TIM_PWM_Start(&g_tim9_handler, PWMDAC_TIMX_CHY); 启动定时器的特定通道的 PWM 输出。
}
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)是一个特定于硬件抽象层(HAL)的回调函数,用于在使用特定定时器的 PWM(脉宽调制)功能时进行底层的 GPIO(通用输入输出端口)初始化。
TIM_HandleTypeDef *htim
:指向定时器句柄的指针,通过这个句柄可以访问定时器的配置和状态信息。
{
GPIO_InitTypeDef gpio_init_struct;定义一个GPIO_InitTypeDef
类型的结构体变量gpio_init_struct
,用于存储 GPIO 的初始化参数。
if (htim->Instance == PWMDAC_TIMX)检查传入的定时器句柄所对应的定时器实例是否为PWMDAC_TIMX
。只有当条件满足时,才会执行后续的 GPIO 初始化操作。
{
PWMDAC_TIMX_CLK_ENABLE();
PWMDAC_GPIO_CLK_ENABLE(); 分别使能与特定定时器(PWMDAC_TIMX
)相关的时钟和与该定时器对应的 GPIO 端口的时钟。这是确保可以对定时器和 GPIO 进行配置和操作的前提。
gpio_init_struct.Pin = PWMDAC_GPIO_PIN;设置要初始化的 GPIO 引脚为特定的引脚,宏定义PWMDAC_GPIO_PIN
代表具体的引脚编号。
gpio_init_struct.Mode = GPIO_MODE_AF_PP;将 GPIO 引脚的模式设置为复用推挽输出模式。在这种模式下,GPIO 引脚可以作为定时器的输出引脚,用于产生 PWM 信号。
gpio_init_struct.Pull = GPIO_PULLUP;设置 GPIO 引脚的上拉模式为上拉。这可以在没有外部信号输入时,确保引脚处于一个已知的状态。
gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;设置 GPIO 引脚的输出速度为低速度。这可以根据实际需求调整,较低的速度可能有助于降低功耗和电磁干扰。
gpio_init_struct.Alternate = PWMDAC_GPIO_AFTIMX;设置 GPIO 引脚的复用功能为特定的定时器复用功能,宏定义PWMDAC_GPIO_AFTIMX
代表具体的复用功能编号。
HAL_GPIO_Init(PWMDAC_GPIO_PORT, &gpio_init_struct); 调用 HAL 库中的函数HAL_GPIO_Init
,根据前面设置的参数对特定的 GPIO 端口进行初始化。这里的PWMDAC_GPIO_PORT
代表要初始化的 GPIO 端口,而&gpio_init_struct
是指向前面配置好的结构体变量的指针
}
}
void pwmdac_set_voltage(uint16_t vol)该函数用于设置 PWM DAC 的输出电压
{
float temp = vol;将传入的电压值参数存储在临时变量temp
中。
temp /= 100; 可能是将输入的电压值转换为特定的单位。
temp = temp * 256 / 3.3f; 根据特定的比例关系计算出对应的定时器比较值。
__HAL_TIM_SET_COMPARE(&g_tim9_handler, PWMDAC_TIMX_CHY, temp); 设置定时器的特定通道的比较值,从而改变 PWM 占空比以实现输出特定的电压。
}