電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 718|回復(fù): 0
收起左側(cè)

Proteus仿真stm32示波器測(cè)不出pwm信號(hào)想問問大佬們?cè)趺锤?/span>

[復(fù)制鏈接]

604

主題

970

帖子

5115

積分

四級(jí)會(huì)員

Rank: 4

積分
5115
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2023-4-17 15:18:09 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
做的基于stm32控制的直流開關(guān)電源

這邊是代碼
#include "stm32f10x.h"


#define VOLTAGE _PA_2   // 電壓檢測(cè)口


#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();      // 初始化定時(shí)器
void init_adc();        // 初始化ADC
void init_usart();      // 初始化USART


void set_duty(uint8_t); // 設(shè)置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;  // 電壓檢測(cè),轉(zhuǎn)換為實(shí)際電壓
        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); // 設(shè)置PWM占空比
    }
}


void init_gpio()
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN; // 使能GPIOA和GPIOC時(shí)鐘


    GPIOA->CRL &= ~GPIO_CRL_MODE2;      // 電壓檢測(cè)口輸入模式
    GPIOA->CRL &= ~GPIO_CRL_CNF2;       // 浮空輸入模式
    GPIOA->CRL |= GPIO_CRL_CNF2_1;      


    GPIOA->CRL |= GPIO_CRL_MODE7_1; // PWM輸出口1為復(fù)用推挽輸出
    GPIOA->CRL |= GPIO_CRL_CNF7_1;      


    GPIOC->CRL |= GPIO_CRL_MODE6_1; // PWM輸出口2為復(fù)用推挽輸出
    GPIOC->CRL |= GPIO_CRL_CNF6_1;
}


void init_adc()
{
    RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;    // 使能ADC時(shí)鐘
    RCC->CFGR |= RCC_CFGR_ADCPRE_DIV8;     // 設(shè)置ADC時(shí)鐘分頻系數(shù)為8


    ADC1->CR2 |= ADC_CR2_CAL;              // ADC自校準(zhǔn)
    while(ADC1->CR2 & ADC_CR2_CAL);


    ADC1->CR2 |= ADC_CR2_JEXTSEL;          // 外部觸發(fā)
    ADC1->CR2 |= ADC_CR2_JEXTTRIG;         // 啟動(dòng)


    ADC1->CR2 |= ADC_CR2_ADON;             // 啟動(dòng)ADC
    while(!(ADC1->SR & 0x00000040));
}


void init_timer()
{
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;    // 使能TIM3時(shí)鐘
    TIM3->PSC = (F_CPU/1000000) - 1;      // 設(shè)置預(yù)分頻數(shù)為72-1,得到1MHz時(shí)鐘
    TIM3->ARR = 99;                       // 設(shè)置計(jì)數(shù)器自動(dòng)重載值為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;              // 啟動(dòng)TIM3
}


void init_usart()
{
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;  // 使能USART1時(shí)鐘
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;    // 使能GPIOA時(shí)鐘


    GPIOA->CRH |= GPIO_CRH_CNF9_1;        // USART1_TX為復(fù)用推挽輸出
    GPIOA->CRH |= GPIO_CRH_MODE9_0;       // 最大輸出速度為10MHz


    GPIOA->CRH |= GPIO_CRH_CNF10_0;       // USART1_RX為輸入模式


    USART1->BRR = F_CPU/BAUD;             // 設(shè)置波特率為9600


    USART1->CR1 |= USART_CR1_TE;          // 使能USART1發(fā)送
    USART1->CR1 |= USART_CR1_RE;          // 使能USART1接收


    USART1->CR1 |= USART_CR1_UE;          // 啟動(dòng)USART1
}


void set_duty(uint8_t duty)
{
    TIM3->CCR1 = duty; // 設(shè)置PWM占空比
    TIM3->CCR2 = duty;
}

發(fā)表回復(fù)

本版積分規(guī)則

關(guān)閉

站長推薦上一條 /1 下一條


聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表