让mini2440从GPB1输出PWM

本文档详细介绍了如何通过C语言在mini2440开发板上配置GPB1引脚,使其能够输出PWM信号。内容包括定时器设置、分频操作和结构体的使用,旨在帮助开发者实现这一功能。
摘要由CSDN通过智能技术生成

之前在友善之臂论坛上发表了一篇文章 从GPB1输出PWM,我打算以后集中在CSDN上发,所以这算是复制了以前写的东西。

/* 因为需要输出两路PWM,示例代码中只写了从GPB0输出,也就是蜂鸣器。
折腾了好几天才知道怎么从GPB1也输出PWM。
在原先的mini2440_pwm.c里面
只需要修改PWM_Set_Freq( unsigned long freq )
和PWM_Stop( void )这两个函数就可以了 */
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); */   
    /*这里是设置pwm输出口的地方,之前一直不成功,有一方面原因就是只修改了这里*/   
    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)的0~7位是timer0和timer1共用的*/  
    tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;  
    tcfg0 |= (50 - 1); 
    //mux = 1/16 
    /* tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK; */   
    /* tcfg1 |= S3C2410_TCFG1_MUX0_DIV16; */  
    /*这里是比较关键的地方,因为分频寄存器中,timer0和timer1使用的数据位不一样     
     * 分频器的0~3位是给timer0用的, 4~7位是给timer1用的,所以对于timer1要左移4位  
     * #define S3C2410_TCFG1_MUX0_DIV16  (3<<0)  
     * #define S3C2410_TCFG1_MUX0_MASK  (15<<0)  
     * #define S3C2410_TCFG1_MUX1_DIV16  (3<<4)  
     * #define S3C2410_TCFG1_MUX1_MASK  (15<<4)  
     * 从它们的宏定义中就可以看出来了           */  
    tcfg1 &= ~S3C2410_TCFG1_MUX1_MASK;  
    tcfg1 |= S3C2410_TCFG1_MUX1_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(1));  
    __raw_writel(tcnt/2, S3C2410_TCMPB(1));    
    /* 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); */   
    /*这里是最后一个关键的地方     
     *TCON是定时器位置控制寄存器,0~4位是timer0的,8~11位是timer1的  
     * 这就是为什么原来的代码是 tcon &= ~0x1f,而现在是tcon &= ~0x0f00
     既然是位置控制寄存器,当然要说说它们的作用了: 
     对于timer0:         
         bit0:停止或开始timer0计时         
         bit1:手动更新TCNTB0和TCMPB0        
         bit2:TOUT0是否进行电平翻转       
         bit3:使用脉冲模式还是自动装载模式         
         bit4:是否使用死区功能    
     对于timer1:       
         8~11的功能分别对应了0~3    
         这就是我们这里用tcon |= 0x0b00的原因*/  
    tcon &= ~0x0f00;
    tcon |= 0x0b00;
    __raw_writel(tcon, S3C2410_TCON);
    /*这里是我一直没有想明白的地方,为什么要把这一位清掉?还请知道的兄弟解答一下*/
    /*后来有一位网友的回答:那个之所以要设置第二位为0是因为不需要更新TCNTB0 & TCMPB0的值*/   
    tcon &= ~0x0200; 
    __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);
}
/* 改完这些你就可以用示波器在GPB1(也就是文档上说的CON4的32口)上看到波形了。
*关于PWM定时器方面的内容在光盘上的s3c2440a_um_rev014_040712.pdf里面都有介绍,可以参考一下 */




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值