冰楓論壇

標題: STM32F103RCT6 [打印本頁]

作者: 洪嵐峰    時間: 2023-4-24 19:21
標題: STM32F103RCT6
製作數控可調直流穩壓電源所需零件:

STM32F103RCT6 微控制器
2x16 LCD 顯示屏
10K 電位器
LM317 穩壓芯片
MOSFET 集成電路
電感和電容
電路板、連接器和電線等常用電子元件


STM32F103RCT6 微控制器的引腳配置如下:

引腳        功能
PA0        電源開關
PA1        調節旋鈕
PA2        輸出電壓檢測
PB0        LCD 數據線
PB1        LCD 數據線
PB6        LCD 使能信號
PB7        LCD RS 信號
PB8        MOSFET 控制信號


程式碼:

以下是 STM32F103RCT6 微控制器的示例代碼
用於控制電源的開關、輸出電壓和 LCD 顯示:


#include "stm32f10x.h"
#include "delay.h"
#include "lcd.h"

#define AD_MAX 4096     // A/D 轉換器最大值
#define AD_REF 3.3f     // A/D 參考電壓
#define V_OUT_MIN 1.25f // 輸出電壓最小值
#define V_OUT_MAX 31.0f  // 輸出電壓最大值

float v_set = 5.0f;     // 輸出電壓設定值
float v_out = 0.0f;     // 實際輸出電壓
uint16_t ad_value = 0;  // A/D 轉換器讀取值

void ADC_Init()
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    ADC_InitTypeDef ADC_InitStructure;
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_Cmd(ADC1, ENABLE);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_55Cycles5);

    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ad_value;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 1;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc =
    DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel1, ENABLE);

ADC_DMACmd(ADC1, ENABLE);

ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1));

ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1));
}

void PWM_Init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 1000 - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_Pulse = 500;
TIM_OC1Init(TIM4, &TIM_OCInitStructure);

TIM_Cmd(TIM4, ENABLE);
}

void GPIO_Init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}

int main(void)
{
ADC_Init();
PWM_Init();
GPIO_Init();
LCD_Init();
LCD_Clear();
LCD_WriteString("DC Power Supply");
LCD_SetCursor(0, 1);
LCD_WriteString("Voltage: 0.00V");

while (1)
{
    // 讀取調節旋鈕
    uint16_t ad_value_set = ADC_GetConversionValue(ADC1);
    float v_set_temp = V_OUT_MAX * ad_value_set / AD_MAX;
    if (v_set_temp < V_OUT_MIN)
    {
        v_set_temp = V_OUT_MIN;
    }
    else if (v_set_temp > V_OUT_MAX)
    {
        v_set_temp = V_OUT_MAX;
    }
    v_set = v_set_temp;

    // 讀取輸出電壓
    v_out = V_OUT_MAX * ad_value / AD_MAX;

    // 控制輸出電壓
    float duty_cycle = (v_set / V_OUT_MAX) * 100;
    TIM_SetCompare1(TIM4, duty_cycle * 10);

    // 顯示輸出電壓
    char buffer[16];

    snprintf(buffer, sizeof(buffer), "Voltage: %.2fV", v_out);
    LCD_SetCursor(0, 1);
    LCD_WriteString(buffer);

    // 判斷是否需要輸出警告信息
    if (v_out < v_set - V_ERR_RANGE || v_out > v_set + V_ERR_RANGE)
    {
        LCD_SetCursor(0, 2);
        LCD_WriteString("Warning!");
    }
    else
    {
        LCD_SetCursor(0, 2);
        LCD_WriteString("         ");
    }

    delay_ms(100);
}
}

void delay_ms(uint16_t ms)
{
volatile uint32_t nCount;
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
nCount = (RCC_Clocks.HCLK_Frequency / 10000) * ms;
for (; nCount != 0; nCount--);
}




歡迎光臨 冰楓論壇 (https://bingfong.com/) Powered by 冰楓