找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 683|回复: 0
打印 上一主题 下一主题
收起左侧

Proteus仿真stm32单片机但是示波器测不出pwm信号

[复制链接]
跳转到指定楼层
楼主
做的基于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;
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表