主题 : PWM换一个端口为什么就始终输出高电平呢? 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 9652
精华: 0
发帖: 20
金钱: 125 两
威望: 40 点
综合积分: 40 分
注册时间: 2009-10-09
最后登录: 2011-12-27
楼主  发表于: 2010-09-21 17:36

 PWM换一个端口为什么就始终输出高电平呢?

我在驱动中把PWM的输出口从GPB0改成了GPB1,编译后用示波器看GPB1口,也就是CON4上面的32口,结果是始终输出高电平。代码如下在PWM_Set_Freq( unsigned long freq )里面 s3c2410_gpio_cfgpin(S3C2410_GPB1, S3C2410_GPB1_TOUT1);
void PWM_Stop( void ){ s3c2410_gpio_cfgpin(S3C2410_GPB1, S3C2410_GPB1_OUTP); s3c2410_gpio_setpin(S3C2410_GPB1, 0);}其它地方没有做改动莫非还有其它什么地方需要修改吗?
级别: 新手上路
UID: 9652
精华: 0
发帖: 20
金钱: 125 两
威望: 40 点
综合积分: 40 分
注册时间: 2009-10-09
最后登录: 2011-12-27
1楼  发表于: 2010-09-27 16:01
呼唤版主解答一下吧!
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
2楼  发表于: 2010-09-27 22:48
抱歉,我没有你的源代码,不知道你遇到了什么问题
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 9652
精华: 0
发帖: 20
金钱: 125 两
威望: 40 点
综合积分: 40 分
注册时间: 2009-10-09
最后登录: 2011-12-27
3楼  发表于: 2010-09-28 15:09

 回 2楼(kasim) 的帖子

其实就是把例子中的pwm程序中的GPB0全部改成了GPB1,编译过后运行时,GPB1对应的口start以后就一直是高电平,stop就是低电平,用示波器完全看不到方波
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#include <linux/clk.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>

#define DEVICE_NAME     "pwm"

#define PWM_IOCTL_SET_FREQ        1
#define PWM_IOCTL_STOP            2

static struct semaphore lock;

/* freq:  pclk/50/16/65536 ~ pclk/50/16
  * if pclk = 50MHz, freq is 1Hz to 62500Hz
  * human ear : 20Hz~ 20000Hz
  */
static void PWM_Set_Freq( unsigned long freq )
{
    unsigned long tcon;
    unsigned long tcnt;
    unsigned long tcfg1;
    unsigned long tcfg0;

    struct clk *clk_p;
    unsigned long pclk;

    //set GPB0 as tout0, pwm output
    /* s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_TOUT0); */
    s3c2410_gpio_cfgpin(S3C2410_GPB1, S3C2410_GPB1_TOUT1);

    tcon = __raw_readl(S3C2410_TCON);
    tcfg1 = __raw_readl(S3C2410_TCFG1);
    tcfg0 = __raw_readl(S3C2410_TCFG0);

    //prescaler = 50
    tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
    tcfg0 |= (50 - 1);

    //mux = 1/16
    tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK;
    tcfg1 |= S3C2410_TCFG1_MUX0_DIV16;

    __raw_writel(tcfg1, S3C2410_TCFG1);
    __raw_writel(tcfg0, S3C2410_TCFG0);

    clk_p = clk_get(NULL, "pclk");
    pclk  = clk_get_rate(clk_p);
    tcnt  = (pclk/50/16)/freq;
    
    __raw_writel(tcnt, S3C2410_TCNTB(0));
    __raw_writel(tcnt/2, S3C2410_TCMPB(0));
                
    tcon &= ~0x1f;
    tcon |= 0xb;        //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
    __raw_writel(tcon, S3C2410_TCON);
    
    tcon &= ~2;            //clear manual update bit
    __raw_writel(tcon, S3C2410_TCON);
}

void PWM_Stop( void )
{
    /* s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP); */
    s3c2410_gpio_cfgpin(S3C2410_GPB1, S3C2410_GPB1_OUTP);
    /* s3c2410_gpio_setpin(S3C2410_GPB0, 0); */
    s3c2410_gpio_setpin(S3C2410_GPB1, 0);
}

static int s3c24xx_pwm_open(struct inode *inode, struct file *file)
{
    if (!down_trylock(&lock))
        return 0;
    else
        return -EBUSY;
}


static int s3c24xx_pwm_close(struct inode *inode, struct file *file)
{
    up(&lock);
    return 0;
}


static int s3c24xx_pwm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
    switch (cmd) {
        case PWM_IOCTL_SET_FREQ:
            if (arg == 0)
                return -EINVAL;
            PWM_Set_Freq(arg);
            break;

        case PWM_IOCTL_STOP:
            PWM_Stop();
            break;
    }

    return 0;
}


static struct file_operations dev_fops = {
    .owner   =   THIS_MODULE,
    .open    =   s3c24xx_pwm_open,
    .release =   s3c24xx_pwm_close,
    .ioctl   =   s3c24xx_pwm_ioctl,
};

static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops = &dev_fops,
};

static int __init dev_init(void)
{
    int ret;

    init_MUTEX(&lock);
    ret = misc_register(&misc);

    printk (DEVICE_NAME"\tinitialized\n");
        return ret;
}

static void __exit dev_exit(void)
{
    misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");
MODULE_DESCRIPTION("S3C2410/S3C2440 PWM Driver");
级别: 新手上路
UID: 63557
精华: 0
发帖: 39
金钱: 200 两
威望: 40 点
综合积分: 78 分
注册时间: 2012-02-21
最后登录: 2017-09-13
4楼  发表于: 2012-05-24 11:08

 回 3楼(zhangweiguo8) 的帖子

定时器1是控制pwm1的,你的程序里定时器没有修改