打印
[应用方案]

使用EmBITZ1.0开发M0516之PWM

[复制链接]
987|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Lbsonggz|  楼主 | 2017-3-8 09:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
新唐官方提供了Direct-register-access方法也就是寄存器直接赋值的方法驱动PWM0-3的例程,那个例程可以在Keil for ARM中直接编译,也可直接运行。作者把例程移植到EmBITZ1.0中,并成功运行,主要修改为:
1)修改了启动文件startup.s,按照新唐官方文件增加了M0516外部中断表
2)修改了配置文件gcc_arm.ld,
3)定义了PWM0~3的四个宏周期定义PWM0_Period~PWM3_Period,以及PWM0~3的四个宏占空比定义PWM0_duty~PWM3_duty,只要修改这几个参数就可以方便的输出不同的PWM信号
如何修改配置文件和启动文件,如何建立工程,如何增加新唐ARM,请见作者其他技术帖子。

M0516pwm.zip

82.4 KB

沙发
zhuotuzi| | 2017-3-8 11:26 | 只看该作者
/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright(c) 2010 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/

/***************************************************************************************
  M051 PWM demo代码,PWM通道0~3(P2.0~3)会输出设定的PWM波形。
****************************************************************************************/
void SystemInit (void) {}

#include "common.h"

#define DEAD_ZONE_INTERVAL      0xC8FF0000
#define PWM_PRESCALAE           0x0000C763

#define   PWM0_Period    0x1000       //pwm0周期
#define   PWM1_Period    0x1000       //pwm1周期
#define   PWM2_Period    0x1000       //pwm2周期
#define   PWM3_Period    0x1000       //pwm3周期

#define   PWM0_duty      0x800        //pwm0占空比
#define   PWM1_duty      0x800        //pwm1占空比
#define   PWM2_duty      0x400        //pwm2占空比
#define   PWM3_duty      0x400        //pwm3占空比
/***************************************************************************************
描述 :   PWM中断处理函数
****************************************************************************************/
void PWMA_IRQHandler(void)
{
    PIIRA = PIIRA;                                           //清除PWM中断标志
}

int main(void)
{
    Un_Lock_Reg();                                           //解锁被保护的寄存器位,以便用户访问
    PWRCON |= XTL12M_EN;                                     //使能外部12MHz晶振
    while((CLKSTATUS & XTL12M_STB) == 0);                    //等12M晶振时钟稳定
    CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M;                //选外部12MHz晶振为系统时钟
    //CLKSEL0 &= (~HCLK);
    //CLKSEL0 |= HCLK_12M;;
    Lock_Reg();
                                           //重新锁被保护的寄存器位
    P3_PMD |= (1<<12);     //P3.6 out mode
    P3_DOUT |= (1<<6);

    P2_MFP  &= ~(P20_AD8_PWM0 |
                 P21_AD9_PWM1 |
                 P22_AD10_PWM2|
                 P23_AD11_PWM3);
    P2_MFP  |= (PWM0 | PWM1 | PWM2 | PWM3);                  //设置P2.0~3为PWM0~3功能

    P2_PMD  &= ~(Px0_PMD | Px1_PMD | Px2_PMD | Px3_PMD);
    P2_PMD  |= (Px0_OUT | Px1_OUT | Px2_OUT | Px3_OUT);      //设置P2.0~3为推挽输出模式

    APBCLK  |= (PWM01_CLKEN | PWM23_CLKEN);                  //使能PWM0,1和PWM2,3时钟

    CLKSEL1  = CLKSEL1 & (~(PWM01_CLK | PWM23_CLK));
    CLKSEL1 |= (PWM01_12M | PWM23_12M);                      //选择外部12MHz晶振输入作为PWM0,1和PWM2,3时钟源

    PPRA  = PWM_PRESCALAE | DEAD_ZONE_INTERVAL;              //设置PWM0,1和pWM2,3时钟预分频值和PWM2,3死区长度

    CSRA  = CSRA & (~(CSR0 | CSR1 | CSR2 | CSR3));
    CSRA |= (CSR0_CLK_2|CSR1_CLK_4|CSR2_CLK_8|CSR3_CLK_16);  //设置PWM0~3时钟分频值

    PCRA |= (CH2INV_ON | DZEN23);                            //设定PWM2,3为互补输出模式,并且PWM2反向
    PCRA |= (CH0_AU_RL | CH1_AU_RL | CH2_AU_RL | CH3_AU_RL); //设定PWM0,1,2,3为自动重载模式

    //CNR0A = CNR1A = CNR2A = CNR3A = 0x1000;                  //设定PWM0,1,2,3周期
    CNR0A=PWM0_Period;
    CNR1A=PWM1_Period;
    CNR2A=PWM2_Period;
    CNR3A=PWM3_Period;
    //CMR0A = CMR1A = 0x800;                                   //设定PWM0,1高占空比50%
    CMR0A=PWM0_duty;
    CMR1A=PWM1_duty;
    //CMR2A = CMR3A = 0x400;                                   //设定PWM2,3高占空比25%
    CMR2A=PWM2_duty;
    CMR3A=PWM3_duty;
    PIERA |= (PWMIE0 | PWMIE1 | PWMIE2 | PWMIE3);         //使能PWM0~3中断
    NVIC_ISER = PWMA_INT;                                    //使能NVIC PWMA中断向量

    POEA |= (PWM0_OE | PWM1_OE | PWM2_OE | PWM3_OE);         //输出使能
    PCRA |= (CH0EN | CH1EN | CH2EN | CH3EN);                 //使能PWM计数器开始计数

    while(1);

    return 1;
}

使用特权

评论回复
板凳
wahahaheihei| | 2017-3-11 22:56 | 只看该作者
学习下这个如何玩转PWM。

使用特权

评论回复
地板
zhuotuzi| | 2017-3-12 23:18 | 只看该作者
楼主申请授权,申请成功了没?

使用特权

评论回复
5
heisexingqisi| | 2017-3-12 23:46 | 只看该作者
直接可以支持官方提供的示例代码吗

使用特权

评论回复
6
Lbsonggz|  楼主 | 2017-3-13 00:00 | 只看该作者
1)使用我修改的ld文件,启动文件和says ally.c文件可完美支持新唐官方的寄存器操作的例程,如何添加其他芯片和如何使用可见其他技术贴。经过测试,无法完美支持API例程,主要是串口输出波特率异常和无**常启动,在寻找原因中
2)EmBITZ 作者说英语是最通用语言,不同意进行汉化,我在劝说出一个中文汉化包,还未有得到答复,

使用特权

评论回复
7
heisexingqisi| | 2017-3-13 00:04 | 只看该作者
Lbsonggz 发表于 2017-3-13 00:00
1)使用我修改的ld文件,启动文件和says ally.c文件可完美支持新唐官方的寄存器操作的例程,如何添加其他芯 ...


那个作者太死脑筋了。

使用特权

评论回复
8
wdliming| | 2019-3-21 16:24 | 只看该作者
heisexingqisi 发表于 2017-3-13 00:04
那个作者太死脑筋了。

同感~~~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

240

帖子

7

粉丝