RT-Thread: STM32F103的DAC 操作、DAC驱动

说明:文档记录基于RT-Thread的STM32F103外设DAC操作。

1.DAC的GPIO配置

函数位于 drivers\stm32f1xx_hal_msp.c

//DAC底层驱动,时钟配置,引脚 配置
//此函数会被HAL_DAC_Init()调用
//hdac:DAC句柄
void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_DAC_CLK_ENABLE();             //使能DAC时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟

    GPIO_Initure.Pin=GPIO_PIN_4;            //PA4
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);

    //新增DAC2
    GPIO_Initure.Pin=GPIO_PIN_5;            //PA4
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}
void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hdac->Instance==DAC)
  {
  /* USER CODE BEGIN DAC_MspInit 0 */

  /* USER CODE END DAC_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_DAC_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**DAC GPIO Configuration
    PA4     ------> DAC_OUT1
    PA5     ------> DAC_OUT2
    */
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN DAC_MspInit 1 */

  /* USER CODE END DAC_MspInit 1 */
  }

}

2.调试代码

        以下是成功调试的代码,开发板是野火的 霸道STM32,这个开发板只有DAC2 ;PA5能用,所以代码是在 原子的 DAC1,PAC4的基础上增加了DAC2, 关于RT Thread 线程部分也只做了 DAC2部分的。

备注:关于DAC1,DAC2 的引脚配置的函数位于 drivers \ stm32f1xx_hal_msp.c

void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac) 函数,里面对DAC1,DAC2的IO进行了配置,如果只用到其中一个,需要到这个函数里面把其一关闭。

 GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;//这段代码同时配置了DAC1,DAC2即 PA4,PA5,如果只需其一,删掉其一即可。

2.1 DAC_DRIVERS.h

#include 
#include 
#include "board.h"

extern DAC_HandleTypeDef DAC1_Handler;//DAC句柄
extern DAC_HandleTypeDef DAC2_Handler;//DAC句柄


void DAC2_test(void);

2.2 DAC_DRIVERS.c

#include "DAC_DRIVERS.h"

DAC_HandleTypeDef DAC1_Handler; //DAC句柄
DAC_HandleTypeDef DAC2_Handler; //DAC句柄
//初始化DAC1
void DAC1_Init(void)
{
    DAC_ChannelConfTypeDef DACCH1_Config;

    DAC1_Handler.Instance = DAC;
    HAL_DAC_Init(&DAC1_Handler);                            //初始化DAC

    DACCH1_Config.DAC_Trigger = DAC_TRIGGER_NONE;             //不使用触发功能
    DACCH1_Config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;             //DAC1输出缓冲关闭
    HAL_DAC_ConfigChannel(&DAC1_Handler, &DACCH1_Config, DAC_CHANNEL_1);             //DAC通道1配置

    HAL_DAC_Start(&DAC1_Handler, DAC_CHANNEL_1);             //开启DAC通道1
}

//初始化DAC2
void DAC2_Init(void)
{
    DAC_ChannelConfTypeDef DACCH2_Config;

    DAC2_Handler.Instance = DAC;
    HAL_DAC_Init(&DAC2_Handler);                            //初始化DAC

    DACCH2_Config.DAC_Trigger = DAC_TRIGGER_NONE;             //不使用触发功能
    DACCH2_Config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;             //DAC1输出缓冲关闭
    HAL_DAC_ConfigChannel(&DAC2_Handler, &DACCH2_Config, DAC_CHANNEL_2);             //DAC通道1配置

    HAL_DAC_Start(&DAC2_Handler, DAC_CHANNEL_2);             //开启DAC通道1
}


//设置通道1输出电压
//vol:0~3300,代表0~3.3V
void DAC1_Set_Vol(rt_uint16_t vol)
{
    double temp = vol;
    temp /= 1000;
    temp = temp * 4096 / 3.3;
    HAL_DAC_SetValue(&DAC1_Handler, DAC_CHANNEL_1, DAC_ALIGN_12B_R, temp);   //12位右对齐数据格式设置DAC值
}

//设置通道2输出电压
//vol:0~3300,代表0~3.3V
void DAC2_Set_Vol(rt_uint16_t vol)
{
    double temp=vol;
    temp /= 1000;
    temp = temp * 4096 / 3.3;
    HAL_DAC_SetValue(&DAC2_Handler, DAC_CHANNEL_2, DAC_ALIGN_12B_R, temp);   //12位右对齐数据格式设置DAC值
}


/* 线程 DAC2_entry 的入口函数 */
static void DAC2_entry(void *param)
{
    DAC2_Init();
    rt_uint16_t vout = 1300;
    while (1)
    {

        DAC2_Set_Vol(vout);
        rt_kprintf("DAC2, PA5= %d mV \n", 1300);
        rt_thread_mdelay(2000);             //以ms为单位延时,函数自动去算出设置的时间需要多少时钟节拍。

    }

}
//线程创建函数
void DAC2_test(void)
{
    rt_thread_t tid1;     //创建线程控制块指针来接收线程创建函数的返回值,目的是通过返回值判断线程是否创建ok

    /* 创建线程 1,名称是 DAC2,入口是 DAC2_entry*/
    tid1 = rt_thread_create("DAC2", DAC2_entry, RT_NULL, 5000,  //设置内存堆栈大小
            10, 10);   //设置优先级,时间片参数,时间片是在有多个相同优先级线程时,这个线程每次被执行多少个时间片

    /* 如果获得线程控制块,启动这个线程 */
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);
}
//INIT_APP_EXPORT(DAC2_test);

你可能感兴趣的:(RT-Thread,STM32,stm32,嵌入式硬件,单片机,RT-Thread)