- UID
- 373967
- 帖子
- 8779
- 主題
- 2609
- 精華
- 0
- 積分
- 993
- 楓幣
- 2637
- 威望
- 970
- 存款
- 31556
- 贊助金額
- 0
- 推廣
- 0
- GP
- 1205
- 閱讀權限
- 50
- 在線時間
- 451 小時
- 註冊時間
- 2023-1-12
- 最後登入
- 2024-11-5
|
製作數控可調直流穩壓電源所需零件:
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--);
} |
|