找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1333|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

Proteus仿真stm32單片機(jī)但是示波器測(cè)不出pwm信號(hào)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
做的基于stm32控制的直流開關(guān)電源不知道是仿真電路有問題還是程序有問題



單片機(jī)源程序如下:
#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;
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表