党国特派员 发表于 2015-6-4 23:30:12

NUCLEO-STM32F303 之 GPIO模拟PWM(三)

PWM说白了就是高低电平占不同比例的IO输出,GPIO就是可以设置成高低电平,所以用GPIO配合定时器也可以做到PWM的功能。
实验目的:
使用GPIO和定时器模拟周期为20ms,占空比为25%的PWM输出
电路图:

实验代码:
#include "mbed.h"

Timeout timer;
DigitalOut my_led(LED1);
DigitalOut my_pwm(D10); //pwm_io 函数使用的IO

int on_delay = 0;
int off_delay = 0;

void toggleOff(void);

void toggleOn(void) {
    my_pwm = 1;//PB6输出高电平
    //
    timer.attach_us(toggleOff, on_delay);
}

void toggleOff(void) {
    my_pwm = 0;//PB6输出低电平
    timer.attach_us(toggleOn, off_delay);
}

// p_us = 信号周期,单位毫秒
// dc   = 信号占空比 (0.0 to 1.0)
void pwm_io(int p_us, float dc) {
    timer.detach();
    //周期、占空比为0直接输出低电平
    if ((p_us == 0) || (dc == 0)) {
      my_pwm = 0;
      return;
    }
    //周期大于等1直接输出高电平
    if (dc >= 1) {
      my_pwm = 1;
      return;
    }
    on_delay = (int)(p_us * dc);//计算高电平时间
    off_delay = p_us - on_delay;//计算低电平时间
    toggleOn();
}

int main() {

    pwm_io(20000, 0.25); // 20ms - 25%

    while(1) {
      my_led = !my_led;
      wait(0.5);
    }
}mbed的Timeout对象主要用来在给定的时间后执行给定的函数
实验结果:
用Saleae logic采集的逻辑电平图如下:



叶♂子 发表于 2018-7-6 11:41:34

我用F334的想要GPIO位操作一直不成功,楼主可以帮忙看看吗?
#define        EEPROM_SCL_Pin                                                        GPIO_Pin_0                                                                /* PB.00 */
        #define        EEPROM_SCL_GPIOx                                                GPIOB
       
        #define        EEPROM_SDA_Pin                                                        GPIO_Pin_1                                                                /* PB.01 */
        #define        EEPROM_SDA_GPIOx                                                GPIOB
        /* IIC×ÜÏߣ¬SDAÊý¾ÝÏßµÄÊä³ö·½ÏòÉèÖà */
        #define IIC_SDA_IN()                {EEPROM_SDA_GPIOx->MODER&=~(3 << (1*2));EEPROM_SDA_GPIOx->MODER|=0 << (1*2);}
        #define IIC_SDA_OUT()                {EEPROM_SDA_GPIOx->MODER&=~(3 << (1*2));EEPROM_SDA_GPIOx->MODER|=1 << (1*2);}
       
        #define        EEPROM_GPIOB_Pin                                                EEPROM_SCL_Pin|EEPROM_SDA_Pin
       
        #define        EEPROM_RCC_GPIOx                                                RCC_AHBPeriph_GPIOB
       
        /* IO¿Ú²Ù×÷ºê¶¨Òå */
        #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
        #define MEM_ADDR(addr)*((volatile unsigned long*)(addr))
        #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
       
        /* IO¿ÚµØÖ·Ó³Éä */
        #define GPIOA_ODR_Addr                                (GPIOA_BASE+0x14)
        #define GPIOB_ODR_Addr                                (GPIOB_BASE+0x14)
        #define GPIOC_ODR_Addr                                (GPIOC_BASE+0x14)
        #define GPIOD_ODR_Addr                                (GPIOD_BASE+0x14)

        #define GPIOA_IDR_Addr                                (GPIOA_BASE+0x10)
        #define GPIOB_IDR_Addr                                (GPIOB_BASE+0x10)
        #define GPIOC_IDR_Addr                                (GPIOC_BASE+0x10)
        #define GPIOD_IDR_Addr                  (GPIOD_BASE+0x10)
       
        /* IO¿Ú²Ù×÷£¬Ö»¶Ôµ¥Ò»µÄIO¿Ú */
        #define        IIC_SCL                                        BIT_ADDR(GPIOB_ODR_Addr,0)
        #define        IIC_SDA                                        BIT_ADDR(GPIOB_ODR_Addr,1)
        #define        Read_SDA                                BIT_ADDR(GPIOB_IDR_Addr,1)

党国特派员 发表于 2018-7-30 09:35:02

叶♂子 发表于 2018-7-6 11:41
我用F334的想要GPIO位操作一直不成功,楼主可以帮忙看看吗?
#define        EEPROM_SCL_Pin                                                        GPIO_Pin_0                               ...

不成功现像是什么?

党国特派员 发表于 2015-6-5 17:45:32

semon12345 发表于 2015-6-5 15:43
看了!还是没看出来!不明显啊!

因为占空比是写死了的。

Paderboy 发表于 2015-6-5 04:26:38

多谢分享

netlhx 发表于 2015-6-5 08:35:53

基于MBED的,不错,现在论坛这方面的资源还不多呵,欢迎继续分享

aoxiangwode2008 发表于 2015-6-5 09:09:48

很好,看看 了。

小小超 发表于 2015-6-5 09:20:26

还不如用硬件PWM。:L:L

苏浅叶 发表于 2015-6-5 11:18:55

最新的金币已经奖励了!

党国特派员 发表于 2015-6-5 12:44:21

ts2000 发表于 2015-6-5 09:20
还不如用硬件PWM。

之所以模拟是为了学习。

风子 发表于 2015-6-5 12:54:45

谢谢分享

me浩 发表于 2015-6-5 13:56:03

谢谢分享

semon12345 发表于 2015-6-5 14:54:22

怎么波形没有变化?

党国特派员 发表于 2015-6-5 15:19:00

semon12345 发表于 2015-6-5 14:54
怎么波形没有变化?

注意看第4个通道。

semon12345 发表于 2015-6-5 15:42:27

党国特派员 发表于 2015-6-5 15:19
注意看第4个通道。

看了!还是没看出来!不明显啊

semon12345 发表于 2015-6-5 15:43:02

党国特派员 发表于 2015-6-5 15:19
注意看第4个通道。

看了!还是没看出来!不明显啊!

左岸右岸 发表于 2015-6-5 16:55:24

赞啊!有想法:D
页: [1] 2
查看完整版本: NUCLEO-STM32F303 之 GPIO模拟PWM(三)