精华内容
下载资源
问答
  • PWM

    2020-03-23 19:34:48
    PWM:即Pulse width modulation,中文脉冲宽度调制。 PWM是一种模拟控制方式 PWM 方法种类: 相电压控制PWM 脉宽PWM 随机PWM SPWM 线电压控制PWM 在镍氢电池智能充电器中采用的脉宽PWM法,它是把每一脉冲宽度均...

    PWM:即Pulse width modulation,中文脉冲宽度调制
    PWM是一种模拟控制方式

    PWM 方法种类:

    1. 相电压控制PWM
    2. 脉宽PWM
    3. 随机PWM
    4. SPWM
    5. 线电压控制PWM

    在镍氢电池智能充电器中采用的脉宽PWM法,它是把每一脉冲宽度均相等的脉冲列作为PWM波形,通过改变脉冲列的周期可以调频,改变脉冲的宽度或占空比可以调压,采用适当控制方法即可使电压与频率协调变化,可以通过调整PWM的周期、PWM的占空比而达到控制充电电流的目的。

    展开全文
  • pwm

    2013-12-26 22:02:00
    pwm_dev.c: #include <linux/init.h>#include <linux/module.h>#include <linux/ioport.h>#include <linux/platform_device.h>#include "pwm.h" struct resource pwm_dev_resource[] = { ...

    pwm_dev.c:

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/ioport.h>
    #include <linux/platform_device.h>
    #include "pwm.h"

    struct resource pwm_dev_resource[] = {
    [0]={
    .start = PWM_TCFG,
    .end = PWM_TCFG + S_T36 - 1,
    .flags = IORESOURCE_MEM,
    },
    };
    static void pwm_release(struct device *dev)
    {

    }

    struct platform_device pwm_plat_dev ={
    .name = "s5pc_pwm",
    .id = -1,
    .num_resources = ARRAY_SIZE(pwm_dev_resource),
    .resource = pwm_dev_resource,
    .dev = {
    .release = pwm_release,
    },
    };


    static int __init pwm_dev_init(void)
    {
    platform_device_register(&pwm_plat_dev);
    return 0;
    }

    static void __exit pwm_dev_exit(void)
    {
    platform_device_unregister(&pwm_plat_dev);
    }

    module_init(pwm_dev_init);
    module_exit(pwm_dev_exit);
    MODULE_LICENSE("GPL");

     

     

    pwm_drv.c

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/fs.h> //file_operations
    #include <linux/device.h> //class_create device_create
    #include <linux/cdev.h> //Struct cdev
    #include <linux/slab.h> //kmalloc
    #include <asm/io.h> //ioremap,writel,readl
    #include <asm/uaccess.h> //copy_from_user
    #include <asm-generic/poll.h>
    #include <linux/sched.h>
    #include <linux/platform_device.h>
    #include "pwm.h"

    #define PWM_DENO 252

    struct pwm_device {
    unsigned int pwm_major;
    struct cdev *pwm_cdev;
    struct class *pwm_class;
    struct device *pwm_device;
    void __iomem *pwm_base;
    void __iomem *pwm_gdpcon;
    dev_t devno;
    };

    struct pwm_device *pwm_dev = NULL;


    static int pwm_open(struct inode *inode, struct file *file)
    {
    writel(readl(pwm_dev->pwm_gdpcon) & (~(0xf<<4)), pwm_dev->pwm_gdpcon);
    writel(readl(pwm_dev->pwm_gdpcon) | ((0x2<<4)), pwm_dev->pwm_gdpcon);

    writel(readl(pwm_dev->pwm_base + PWM_TCFG0) & (~(0xff<<0)), pwm_dev->pwm_base + PWM_TCFG0);
    writel(readl(pwm_dev->pwm_base + PWM_TCFG0) | (249<<0), pwm_dev->pwm_base + PWM_TCFG0);

    writel(readl(pwm_dev->pwm_base + PWM_TCFG1) & (~(0xf<<4)), pwm_dev->pwm_base + PWM_TCFG1);
    writel(readl(pwm_dev->pwm_base + PWM_TCFG1) | (0x4<<4), pwm_dev->pwm_base + PWM_TCFG1);

    return 0;
    }
    static ssize_t pwm_write(struct file *file, const char __user *user_buf, size_t size, loff_t *offset)
    {
    char buf[10];
    unsigned length = size;

    if(copy_from_user(buf, user_buf, length))
    {
    return -EINVAL;
    }else{
    writel(6666, pwm_dev->pwm_base + PWM_TCNTB1);
    writel(3456, pwm_dev->pwm_base + PWM_TCMPB1);

    writel(readl(pwm_dev->pwm_base + PWM_TCON) | (0xf<<8), pwm_dev->pwm_base + PWM_TCON);
    writel(readl(pwm_dev->pwm_base + PWM_TCON) & (~(0x1<<9)), pwm_dev->pwm_base + PWM_TCON);
    }
    return length;
    }

    static int pwm_close(struct inode *inode, struct file *file)
    {
    writel(readl(pwm_dev->pwm_base + PWM_TCON) | (0xf<<8), pwm_dev->pwm_base + PWM_TCON);
    writel(readl(pwm_dev->pwm_gdpcon) & (~(0xf<<4)), pwm_dev->pwm_gdpcon);
    return 0;
    }


    struct file_operations pwm_fops = {
    .owner = THIS_MODULE,
    .open = pwm_open,
    .write = pwm_write,
    .release = pwm_close,
    };


    static int pwm_drv_probe(struct platform_device *pdev)
    {
    int ret;
    struct resource *res;
    pwm_dev = kmalloc(sizeof(struct pwm_device), GFP_KERNEL);
    if(pwm_dev == NULL)
    {
    printk(KERN_INFO "pwm_dev kmalloc failed!\n");
    ret = -EINVAL;
    }

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

    if(PWM_DENO){
    pwm_dev->devno = MKDEV(PWM_DENO, 0);
    ret = register_chrdev_region(pwm_dev->devno, 1, "pwm_dev");
    if(ret < 0){
    printk(KERN_INFO "pwm_dev->devno register_chrdev_region failed!\n");
    ret = -EINVAL;
    goto output0;
    }
    }else{
    ret = alloc_chrdev_region(&pwm_dev->devno, 252, 1, "pwm_dev");
    if(ret < 0){
    printk(KERN_INFO "pwm_dev->devno register_chrdev_region failed!\n");
    ret = -EINVAL;
    goto output0;
    }
    }


    pwm_dev->pwm_base = ioremap(res->start, res->end - res->start +1);
    if(pwm_dev->pwm_base == NULL)
    {
    printk(KERN_INFO"pwm_dev->pwm_base remap failed! \n");
    ret = -EINVAL;
    goto output1;
    }

    pwm_dev->pwm_cdev = cdev_alloc();
    if(IS_ERR(&pwm_dev->pwm_cdev))
    {
    printk(KERN_INFO "pwm_dev->cdev alloc failed!\n");
    ret = -EINVAL;
    goto output2;
    }
    cdev_init(pwm_dev->pwm_cdev, &pwm_fops);
    cdev_add(pwm_dev->pwm_cdev, pwm_dev->devno, 1);

    pwm_dev->pwm_class = class_create(THIS_MODULE, "pwm_class");
    if(IS_ERR(&pwm_dev->pwm_class))
    {
    printk(KERN_INFO"pwm_dev->pwm_class create failed!\n");
    ret = -EINVAL;
    goto output3;
    }

    pwm_dev->pwm_device = device_create(pwm_dev->pwm_class, NULL, pwm_dev->devno, NULL, "pwm");
    if(IS_ERR(&pwm_dev->pwm_device))
    {
    printk(KERN_INFO"pwm_dev->pwm_device create failed!\n");
    ret = -EINVAL;
    goto output4;
    }

    pwm_dev->pwm_gdpcon = ioremap(PWM_GPDCON, 4);
    if(!pwm_dev->pwm_gdpcon)
    {
    printk(KERN_INFO "tm_dev->pwm_GDPCON ioremap failed!\n");
    ret = -EINVAL;
    goto output5;
    }
    return 0;

    output5:
    device_destroy(pwm_dev->pwm_class, pwm_dev->devno);
    output4:
    class_destroy(pwm_dev->pwm_class);
    output3:
    cdev_del(pwm_dev->pwm_cdev);
    output2:
    iounmap(pwm_dev->pwm_base);
    output1:
    unregister_chrdev_region(pwm_dev->devno, 1);
    output0:
    kfree(pwm_dev);

    return ret;
    }

    static int pwm_drv_remove(struct platform_device *pdev)
    {
    iounmap(pwm_dev->pwm_gdpcon);
    device_destroy(pwm_dev->pwm_class, pwm_dev->devno);
    class_destroy(pwm_dev->pwm_class);
    cdev_del(pwm_dev->pwm_cdev);
    iounmap(pwm_dev->pwm_base);
    unregister_chrdev_region( pwm_dev->devno, 1);
    kfree(pwm_dev);
    return 0;
    }


    struct platform_driver plat_drv={
    .probe = pwm_drv_probe,
    .remove = pwm_drv_remove,
    .driver = {
    .owner = THIS_MODULE,
    .name = "s5pc_pwm",
    },
    };


    static int __init pwm_drv_init(void)
    {
    platform_driver_register(&plat_drv);
    return 0;
    }

    static void __exit pwm_drv_exit(void)
    {
    platform_driver_unregister(&plat_drv);
    }

    module_init(pwm_drv_init);
    module_exit(pwm_drv_exit);
    MODULE_LICENSE("GPL");

     

     

    pwm_test.c:


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fcntl.h>

    int main(void)
    {
    int fd = 0;
    int ret;
    char buf[10];

    fd = open("/dev/pwm", O_RDWR);
    if(fd <= 0)
    {
    perror("open failed!\n");
    exit(1);
    }

    printf("please input \"start\" or \"quit\"\n");
    while(1)
    {
    memset(buf, 0, 10);
    fgets(buf, 10, stdin);
    if(strncmp(buf, "start", 5) == 0){
    if(write(fd, buf, 10)!=10)
    {
    perror("write failed!\n");
    exit(1);
    }
    }else{
    break;
    }
    }

    close(fd);
    return 0;
    }

     

     

     

    makefile:

    ifeq ($(KERNELRELEASE),)
    KERNELDIR ?=/home/farsight/Linux_source/linux-2.6.35.5
    PWD :=$(shell pwd)
    modules:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
    arm-unknown-linux-gnueabi-gcc -o pwm_test pwm_test.c
    cp pwm_drv.ko pwm_dev.ko pwm_test /opt/rootfs/s5pc100_drv
    modules_install:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
    clean:
    rm -rf pwm_test *.o *~core *.ko *.mod.c .tmp_versions Module.symvers modules.order
    else
    obj-m :=pwm_drv.o pwm_dev.o
    endif

     

    pwm.h:

    #ifndef __PWM_H_
    #define __PWM_H_

    #define PWM_GPDCON 0xE0300080
    #define PWM_TCFG 0xEA000000
    #define PWM_TCFG0 0x0
    #define PWM_TCFG1 0x4
    #define PWM_TCON 0x8
    #define PWM_TCNTB1 0x18
    #define PWM_TCMPB1 0x1C
    #define PWM_TCNTO1 0x20
    #define S_T36 0x24
    #define PWM_MAJOR 251

    #endif

     

    转载于:https://www.cnblogs.com/weat/p/3493164.html

    展开全文
  • 【STM32】通用定时器的PWM输出(实例:PWM输出)

    万次阅读 多人点赞 2018-04-19 15:22:43
    STM32F1xx官方资料: ...STM32的通用定时器分为TIM2、TIM3、TIM4、TIM5,而每个定时器都有独立的4个通道可以用来作为:输入捕获、输出比较、PWM输出、单脉冲模式输出等。 STM32的定时器除了TIM6和TIM7(基本定时器...

    STM32F1xx官方资料:

    《STM32中文参考手册V10》-第14章  通用定时器

     

    通用定时器PWM概述

    STM32定时器输出通道引脚

    这里以TIM3为例来讲解。STM32的通用定时器分为TIM2、TIM3、TIM4、TIM5,而每个定时器都有独立的4个通道可以用来作为:输入捕获、输出比较、PWM输出、单脉冲模式输出等。

    STM32的定时器除了TIM6和TIM7(基本定时器)之外,其他的定时器都可以产生PWM输出。其中,高级定时器TIM1、TIM8可以同时产生7路PWM输出,而通用定时器可以同时产生4路PWM输出,这样STM32最多可以同时产生30路PWM输出!

    从图中的内容可以看出,TIM3的4个通道相对应的各个引脚以及重映射情况下的各个引脚的位置。

    PWM的工作原理

    在通用定时器框图中,主要涉及到最顶上的一部分(计数时钟的选择)、中间部分(时基单元)、右下部分(PWM输出)这三个部分。这里主要讲解一下右下部分(PWM输出),其他两个部分可以参考文章:【STM32】通用定时器的基本原理(实例:定时器中断)

    下面以向上计数为例,简单地讲述一下PWM的工作原理:

    • 在PWM输出模式下,除了CNT(计数器当前值)、ARR(自动重装载值)之外,还多了一个值CCRx(捕获/比较寄存器值)。
    • 当CNT小于CCRx时,TIMx_CHx通道输出低电平;
    • 当CNT等于或大于CCRx时,TIMx_CHx通道输出高电平。

    这个时候就可以对其下一个准确的定义了:所谓脉冲宽度调制模式(PWM模式),就是可以产生一个由TIMx_ARR寄存器确定频率,由TIMx_CCRx寄存器确定占空比的信号。它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。

    PWM的通道概览

    每一个捕获/比较通道都是围绕着一个捕获/比较寄存器(包含影子寄存器),包括捕获的输入部分(数字滤波、多路复用和预分频器),和输出部分(比较器和输出控制)。

    捕获/比较模块由一个预装载寄存器和一个影子寄存器组成。读写过程仅操作预装载寄存器。

    • 在捕获模式下,捕获发生在影子寄存器上,然后再复制到预装载寄存器中。 
    • 在比较模式下,预装载寄存器的内容被复制到影子寄存器中,然后影子寄存器的内容和计数器进行比较。

    • CCR1寄存器:捕获/比较值寄存器:设置比较值;
    • CCMR1寄存器:OC1M[2:0]位:对于PWM方式下,用于设置PWM模式1或者PWM模式2;
    • CCER寄存器:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。
    • CCER寄存器:CC1E位:输入/捕获1输出使能。0:关闭,1:打开。

    PWM输出的模式区别

    通过设置寄存器TIMx_CCMR1的OC1M[2:0]位来确定PWM的输出模式

    • PWM模式1:在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。
    • PWM模式2:在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。

    注意:PWM的模式只是区别什么时候是有效电平,但并没有确定是高电平有效还是低电平有效。这需要结合CCER寄存器的CCxP位的值来确定。

    例如:若PWM模式1,且CCER寄存器的CCxP位为0,则当TIMx_CNT<TIMx_CCR1时,输出高电平;同样的,若PWM模式1,且CCER寄存器的CCxP位为2,则当TIMx_CNT<TIMx_CCR1时,输出低电平。

    PWM的计数模式

    向上计数模式

    下面是一个PWM模式1的例子。当TIMx_CNT<TIMx_CCRx时PWM信号参考OCxREF为高,否则为低。如果TIMx_CCRx中的比较值大于自动重装载值(TIMx_ARR),则OCxREF保持为’1’。如果比较值为0,则OCxREF保持为’0’。

    向下计数模式

    在PWM模式1,当TIMx_CNT>TIMx_CCRx时参考信号OCxREF为低,否则为高。如果TIMx_CCRx中的比较值大于TIMx_ARR中的自动重装载值,则OCxREF保持为’1’。该模式下不能产生0%的PWM波形。

    中央对齐模式

    当TIMx_CR1寄存器中的CMS位不为’00’时,为中央对齐模式(所有其他的配置对OCxREF/OCx信号都有相同的作用)。根据不同的CMS位设置,比较标志可以在计数器向上计数时被置’1’、在计数器向下计数时被置’1’、或在计数器向上和向下计数时被置’1’。TIMx_CR1寄存器中的计数方向位(DIR)由硬件更新,不要用软件修改它。

     

    自动加载的预加载寄存器

    在TIMx_CCMRx寄存器中的OCxM位写入’110’(PWM模式1)或’111’(PWM模式2),能够独立地设置每个OCx输出通道产生一路PWM。必须设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器,最后还要设置TIMx_CR1寄存器的ARPE位,(在向上计数或中心对称模式中)使能自动重装载的预装载寄存器。

    在TIMx_CRx寄存器的ARPE位,决定着是否使能自动重装载的预加载寄存器。

    根据TIMx_CR1位的APRE位的设置,APRE=0时,预装载寄存器的内容就可以随时传送到影子寄存器,此时两者是互通的;APRE=1时,在每一次更新事件时,才将预装在寄存器的内容传送至影子寄存器。

    简单的说:ARPE=1,ARR立即生效;APRE=0,ARR下个比较周期生效。

     

    PWM相关配置寄存器

    捕获/比较模式寄存器1(TIMx_CCMR1)

    捕获/比较模式寄存器总共2个,TIMx_CCMR1和TIMx_CCMR2。TIMx_CCMR1控制CH1和CH2,TIMx_CCMR2控制CH3和CH4。该寄存器的某些位在不同模式下功能不一样,上面一层对应输出而下面一层对应输入。

    其中模式设置位OCxM位,此位由3位组成,一共可以配置成7种模式,我们使用的是PWM模式,所以这三位必须为110/111。

    作用:在PWM输出模式下,确定PWM的模式、使能相应的预装载寄存器等操作。

    捕获/比较使能寄存器(TIMx_CCER)

    作用:在PWM输出模式下,确定PWM的输出极性和输出使能

    捕获/比较寄存器1(TIMx_CCR1)

    作用:在PWM输出模式下,确定比较的值

     

    PWM相关配置库函数

    • 1个输出初始化函数
    void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
    void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
    void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
    void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

    作用:在四个通道中选择一个,初始化PWM输出模式、比较输出极性、比较输出使能、比较值CCRx的值

    • 1个参数设置函数
    void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
    void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
    void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
    void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);

    作用:在四个通道中选择一个,设置比较值。通常在初始化函数中已经设置了比较值,此函数用于除初始化之外的修改。

    • 2个使能函数
    void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
    void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
    void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
    void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
    void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

    作用:前者在四个通道中选择一个,使能输出比较预装载,后者使能自动重装载的预装载寄存器允许位。

     

    PWM的一般步骤

    实例要求:使用TIM3来产生PWM输出,并使用TIM3的通道2,把通道2重映射到PB5,产生PWM来控制DS0的亮度。

    • 使能定时器和相关IO口时钟。调用函数:RCC_APB1PeriphClockCmd();RCC_APB2PeriphClockCmd();
    • 初始化IO口为复用功能输出。调用函数:GPIO_Init();  
    • 这里我们是要把PB5用作定时器的PWM输出引脚,所以要重映射配置,所以需要开启AFIO时钟。同时设置重映射。调用函数:RCC_APB2PeriphClockCmd();GPIO_PinRemapConfig();
    • 初始化定时器。调用函数:ARR,PSC等:TIM_TimeBaseInit();
    • 初始化输出比较参数。调用函数:TIM_OC2Init();
    • 使能预装载寄存器。调用函数:TIM_OC2PreloadConfig();
    • 使能定时器。调用函数:TIM_Cmd();
    • 不断改变比较值CCRx,达到不同的占空比效果。调用函数:TIM_SetCompare2()。

    下面按照这个一般步骤来进行一个简单的PWM输出程序:

    //TIM3 PWM部分初始化 
    //PWM输出初始化
    //arr:自动重装值
    //psc:时钟预分频数
    void TIM3_PWM_Init(u16 arr,u16 psc)
    {  
    	GPIO_InitTypeDef GPIO_InitStructure;
    	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    	TIM_OCInitTypeDef  TIM_OCInitStructure;
    	
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	//使能定时器3时钟
     	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
    	
    	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5    
     
       //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形	GPIOB.5
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
     
       //初始化TIM3
    	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
    	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
    	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    	
    	//初始化TIM3 Channel2 PWM模式	 
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
    	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
    
    	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
     
    	TIM_Cmd(TIM3, ENABLE);  //使能TIM3
    	
    
    }
    
     int main(void)
     {		
     	u16 led0pwmval=0;
    	u8 dir=1;	
    	delay_init();	    	 //延时函数初始化	  
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    	uart_init(115200);	 //串口初始化为115200
     	LED_Init();			     //LED端口初始化
     	TIM3_PWM_Init(899,0);	 //不分频。PWM频率=72000000/900=80Khz
       	while(1)
    	{
     		delay_ms(10);	 
    		if(dir)led0pwmval++;
    		else led0pwmval--;
    
     		if(led0pwmval>300)dir=0;
    		if(led0pwmval==0)dir=1;										 
    		TIM_SetCompare2(TIM3,led0pwmval);		   
    	}	 
     }

     

    展开全文
  • PWM

    2008-01-25 11:48:00
    Consider the average, garden-variety square wave shown in Figure 1.Figure 1. A ubiquitous square waveThe width of the high is equal to the width of the low, so this wave is said to have a 50% du

    Consider the average, garden-variety square wave shown in Figure 1.

    Figure 1. A ubiquitous square wave

    The width of the high is equal to the width of the low, so this wave is said to have a 50% duty cycle. In other words, it is high for exactly half the cycle. Now, if the amplitude of this square wave is 5V, for example, the average voltage over the cycle is 2.5V. It is as though we had a constant voltage of 2.5V.

    Now consider the square wave in Figure 2.

    Figure 2. 10% duty cycle

    This wave has a 10% duty cycle, which means that the average voltage over the cycle is 0.5V.

    A low-pass (averaging) filter on the PWM output will convert the pulses to an analog voltage, proportional to the duty cycle of the PWM signal. By varying the duty cycle, we can vary the analog voltage. Hey, presto!—we have digital-to-analog conversion without a DAC. That's the basic idea behind PWM.

     

    PWM can also be used to drive a LED and thereby get varying light intensities from a signal that is essentially either on or off. PWM can also be used to generate audio. Early desktop computers, such as the Apple ][, used PWM to drive a speaker. Steve Wozniak, the designer of the Apple ][, used a spare chip select of the address decoder as his PWM signal. By changing how frequently a particular address was accessed, he was able to change the frequency and duty cycle of his PWM signal and was therefore able to generate simple audio with varying volume and pitch. Sound out of an address decoder!

     

     

    展开全文
  • PWM原理 PWM频率与占空比详解

    万次阅读 多人点赞 2020-01-28 22:38:34
    什么是PWM ​ 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多...
  • PWM模块:边沿对齐PWM和中心对齐PWM

    千次阅读 2019-08-17 10:31:09
    PWM模块:边沿对齐PWM和中心对齐PWMPWM 时基工作在自由运行模式时,模块产生边沿对齐的PWM 信号。给定PWM 通道的输出1. 边沿对齐模式 信号的周期由装入PTPER 的值指定, 其占空比由相应的PDCx 寄存器指定...
  • PWM frequency

    2021-01-07 21:46:34
    Stm32f103 Pwm(Pulse width modulation) signal generation using internal timers, keil MDK-ARMv6 and Stmcubemx Ide PWM INPUT using Input Capture in STM32 setting the frequency of a PWM on a STM32 STM...
  • 一、 PWM输出原理 二、STM32 PWM工作过程 三、定时器PWM功能常用函数 四、PWM输出配置步骤
  • PWM DAC

    2020-06-14 16:19:13
    PWM DAC硬件## PWM DAC 1、PWM DAC原理 PWM本质上其实就是是一种周期一定,而高低电平占空比可调的方波。 其中:T是单片机中计数脉冲的基本周期,也就是STM32定时器的计数频率的倒数。N是PWM波一个周期的计数脉冲个...
  • PWM1与PWM2

    千次阅读 2018-11-17 19:39:54
    好了,言归正传,最近总看到很多朋友对于PWM这个实验有很多的疑惑,看到原子也在极力的回复也挺累的(体谅一下幸苦的原子大神,(*^__^*) ),所以我打算写这么一篇文字来阐述一下我个人对STM32的PWM的理解。...
  • PWM简介

    2020-10-23 22:47:33
    PWM简介概念PWM信号图频率和占空比 概念 PWM 全称是 Pulse WidthModulation,也就是脉冲宽度调制。 PWM信号图 频率和占空比 PWM 信号有两个关键的术语:频率和占空比。 频率:就是开关速度,把一次开关算作一个周期...
  • PWM 简介

    2020-10-10 17:23:19
    PWM 简介1、概念2、PWM信号图3、频率4、占空比 1、概念 PWM 全称是 Pulse WidthModulation,也就是脉冲宽度调制 2、PWM信号图 3、频率 频率就是开关速度,把一次开关算作一个周期,那么频率就是 1 秒内进行了多少次...
  • 80C52输出PWM 80C52输出PWM 80C52输出PWM
  • STM32——PWM基本知识及配置过程

    万次阅读 多人点赞 2018-11-02 20:37:16
    STM32——PWM基本知识及配置过程 将通用定时器分为四个部分: 1,选择时钟 2,时基电路 3,输入捕获 4,输出比较 本节定时器PWM输出主要涉及到定时器框图右下方部分,即输出比较部分 和上一讲相同,时基时钟来源...
  • PWM实验

    千次阅读 2018-10-11 22:18:01
    1.PWM简介 脉冲宽度调制(PWM),是利用微处理器的数字输出来对模拟电路 进行控制的 一种非常有效的技术,即就是对脉冲宽度的控制。 STM32的定时器除了TIM6和7,其他的定时器都可以用来产生PWM输出。其中高级...
  • 在上面一章,我们介绍了pwm子系统的框架以及数据结构等内容,而pwm 子系统中pwm_chip的注册与注销接口也就是实现pwm_chip与pwm_device之间的关联,并将pwm_chip放入系统pwm_chip链表中,而这些接口实现也较简单,就...
  • PWM整流器及其控制

    2020-10-06 22:45:35
    PWM整流器及其控制PWM整流器及其控制PWM整流器及其控制PWM整流器及其控制PWM整流器及其控制PWM整流器及其控制PWM整流器及其控制PWM整流器及其控制PWM整流器及其控制PWM整流器及其控制
  • PWM算法

    千次阅读 2018-05-17 10:13:45
    PWM用于直流斩波,可以用于直流电升压或降压,常见的PWM用于降压。PWM利用占空比来调节单位时间内能量输出的密度,在宏观上体现为输出电压与输入电压不同。 狭义上的PWM只有一种算法,通过线性函数与常量的比较来...
  • Linux PWM接口

    千次阅读 2018-12-23 22:36:23
    脉冲宽度调制(PWM)接口1.识别PWM2.使用PWM3.将PWM与sysfs接口配合使用4.实现PWM驱动程序5.锁6.求助 0.脉冲宽度调制(PWM)接口 这提供了有关Linux PWM接口的概述 PWM通常用于控制手机中的LED,风扇或振动器。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,099
精华内容 9,239
关键字:

PWM