|
做的基于stm32控制的直流开关电源
这边是代码
#include "stm32f10x.h"
#define VOLTAGE _PA_2 // 电压检测口
#define PWM1 _PA_7 // PWM输出口1
#define PWM2 _PC_6 // PWM输出口2
#define F_CPU 72000000L // CPU频率
#define BAUD 9600 // 波特率
void init_gpio(); // 初始化GPIO口
void init_timer(); // 初始化定时器
void init_adc(); // 初始化ADC
void init_usart(); // 初始化USART
void set_duty(uint8_t); // 设置PWM占空比
int main(void)
{
init_gpio();
init_adc();
init_timer();
init_usart();
uint16_t voltage; // 电压值
uint8_t duty = 50; // PWM占空比初始化为50%
while(1)
{
voltage = (ADC1->DR * 33) / 4096; // 电压检测,转换为实际电压
if(voltage < 10) duty = 0; // 电压低于10V,PWM占空比为0
else if(voltage > 10 && voltage < 15) duty = 25; // 10V < 电压 < 15V,PWM占空比为25%
else if(voltage > 15 && voltage < 20) duty = 50; // 15V < 电压 < 20V,PWM占空比为50%
else duty = 75; // 电压大于20V,PWM占空比为75%
set_duty(duty); // 设置PWM占空比
}
}
void init_gpio()
{
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN; // 使能GPIOA和GPIOC时钟
GPIOA->CRL &= ~GPIO_CRL_MODE2; // 电压检测口输入模式
GPIOA->CRL &= ~GPIO_CRL_CNF2; // 浮空输入模式
GPIOA->CRL |= GPIO_CRL_CNF2_1;
GPIOA->CRL |= GPIO_CRL_MODE7_1; // PWM输出口1为复用推挽输出
GPIOA->CRL |= GPIO_CRL_CNF7_1;
GPIOC->CRL |= GPIO_CRL_MODE6_1; // PWM输出口2为复用推挽输出
GPIOC->CRL |= GPIO_CRL_CNF6_1;
}
void init_adc()
{
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // 使能ADC时钟
RCC->CFGR |= RCC_CFGR_ADCPRE_DIV8; // 设置ADC时钟分频系数为8
ADC1->CR2 |= ADC_CR2_CAL; // ADC自校准
while(ADC1->CR2 & ADC_CR2_CAL);
ADC1->CR2 |= ADC_CR2_JEXTSEL; // 外部触发
ADC1->CR2 |= ADC_CR2_JEXTTRIG; // 启动
ADC1->CR2 |= ADC_CR2_ADON; // 启动ADC
while(!(ADC1->SR & 0x00000040));
}
void init_timer()
{
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // 使能TIM3时钟
TIM3->PSC = (F_CPU/1000000) - 1; // 设置预分频数为72-1,得到1MHz时钟
TIM3->ARR = 99; // 设置计数器自动重载值为99,得到10kHz的PWM频率
TIM3->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // PWM模式1
TIM3->CCMR2 |= 0x00007800; // PWM模式1
TIM3->CCR1 = 50; // PWM占空比初始化为50%
TIM3->CCR2 = 50;
TIM3->CCER |= TIM_CCER_CC1E; // 使能CC1通道输出
TIM3->CCER |= TIM_CCER_CC2E; // 使能CC2通道输出
TIM3->CR1 |= TIM_CR1_CEN; // 启动TIM3
}
void init_usart()
{
RCC->APB2ENR |= RCC_APB2ENR_USART1EN; // 使能USART1时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // 使能GPIOA时钟
GPIOA->CRH |= GPIO_CRH_CNF9_1; // USART1_TX为复用推挽输出
GPIOA->CRH |= GPIO_CRH_MODE9_0; // 最大输出速度为10MHz
GPIOA->CRH |= GPIO_CRH_CNF10_0; // USART1_RX为输入模式
USART1->BRR = F_CPU/BAUD; // 设置波特率为9600
USART1->CR1 |= USART_CR1_TE; // 使能USART1发送
USART1->CR1 |= USART_CR1_RE; // 使能USART1接收
USART1->CR1 |= USART_CR1_UE; // 启动USART1
}
void set_duty(uint8_t duty)
{
TIM3->CCR1 = duty; // 设置PWM占空比
TIM3->CCR2 = duty;
} |
|