打印
[应用方案]

使用EmBITZ1.0驱动LED(GPIO)

[复制链接]
776|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Lbsonggz|  楼主 | 2017-2-22 13:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
新唐官方提高了Direct-register-access方法也就是寄存器直接赋值的方法驱动LED的例程,那个例程可以在Keil for ARM中直接编译,也可直接运行。作者把例程移植到EmBITZ1.0中,并成功运行,主要修改为:
1)修改了启动文件startup.s,按照新唐官方文件增加了M0516外部中断表
2)修改了配置文件gcc_arm.ld,
3)使用syscalls.c替代了常见的retarget.c串口重定向文件,实现了UART0的输出,此例程中没有使用已经删除
4)定义了一个_BV函数(来自于winavr软件,书写ATmega MCU习惯了这个函数),定义在sfr_defs.h文件中,也可以直接定义在main.c函数中
例如, #define _BV(bit) (1 << (bit)),就可以删除sfr_defs.h文件了
5)编译后下载到NuTiny-EVB-M051_V3.0开发板中,就可以看到LED闪烁了。
如何修改配置文件和启动文件,如何建立工程,如何增加新唐ARM,请见作者其他技术帖子。

M0516gpio.zip

116.06 KB

GPIO(LED)驱动实例

沙发
玛尼玛尼哄| | 2017-2-27 21:48 | 只看该作者
不如再贴上代码吸引人

/************************************************************************************
*  File:     main.c
*  Purpose:  Cortex-M0/0+/1 main file.
*            Replace with your code.
*  Date:     05 July 2013
*  Info:     If __NO_SYSTEM_INIT is defined in the Build options,
*            the startup code will not branch to SystemInit()
*            and the function can be removed
************************************************************************************/
/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright(c) 2010 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/

/***************************************************************************************
  本代码演示GPIO功能,P0/1/2/3会输出高低电平
****************************************************************************************/
void SystemInit (void) {}
#include "common.h"

#define P0_MODE               0x5555
#define P1_MODE               0x5555
#define P2_MODE               0x5555
#define P3_MODE                      0x5555

//void TMR0_Delay1ms(uint32_t ulCNT);
//void Timer0_Init(void);

/***************************************************************************************
   参数 :   ulCNT, 延迟时间,毫秒
   描述     用Timer0定时
****************************************************************************************/

void TMR0_Delay1ms(uint32_t ulCNT)
{
    TCMPR0 = 12000;                              //12MHz/96000 = 0.125KHz
    TCSR0 |= CEN | TMR_IE;                       //启动定时器Timer0并使能Timer0中断
    while (ulCNT != 1)
    {
        while((TISR0&TMR_TIF) != TMR_TIF);       //定时时间到否?
               TISR0 |= TMR_TIF;                        //定时器清标志位
        ulCNT--;
    }
    TCSR0 &= ~CEN;                               //停止Timer0定时器
}
/***************************************************************************************
描述 :   初始化定时器Timer0,周期模式
****************************************************************************************/
void Timer0_Init()
{
    APBCLK |= TMR0_CLKEN;                                  //使能APB时钟
    CLKSEL1 = CLKSEL1 & (~TM0_CLK) | TM0_12M;              //选择外部晶振作为定时器时钟源
    //CLKSEL1 |= TM0_12M;
    TCSR0  |= CRST;                                        //复位定时器
    TCSR0  &= 0xFFFFFF00 ;                                 //时钟不分频
    TCSR0   = TCSR0 & (~TMR_MODE) | MODE_PERIOD;           //周期模式
    //TCSR0   |= MODE_PERIOD;
}

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

    P0_PMD = P0_MODE;                                      //配置P0口所有引脚为输出模式
    P1_PMD = P1_MODE;                                      //配置P1口所有引脚为输出模式
    P2_PMD = P2_MODE;                                      //配置P2口所有引脚为输出模式
    //P3_PMD = P3_MODE;                                      //配置P3口所有引脚为输出模式
    P3_PMD |= (1<<12);     //p3.6 out mode
    //P3_DOUT |= (1<<6);
    Timer0_Init();
    //P3_DOUT = 0x00;
    while(1)
    {
        P0_DOUT = 0x00;                                    //P0口所有引脚输出0
        P1_DOUT = 0x00;                                    //P1口所有引脚输出0
        P2_DOUT = 0x00;                                    //P2口所有引脚输出0
        //P3_DOUT = 0x00;                                    //P3口所有引脚输出0
        P3_DOUT |= (1<<6);
        TMR0_Delay1ms(500);

        P0_DOUT = 0xFF;                                    //P0口所有引脚输出1
        P1_DOUT = 0xFF;                                    //P1口所有引脚输出1
        P2_DOUT = 0xFF;                                    //P2口所有引脚输出1
        P3_DOUT &= ~(1<<6);
        //P3_DOUT = 0xFF;                                    //P3口所有引脚输出1
        TMR0_Delay1ms(500);
    }
    return 0;
}

使用特权

评论回复
板凳
huangcunxiake| | 2017-2-27 22:10 | 只看该作者
以前用过类似的用法:
set_bit();
clr_bit();

使用特权

评论回复
地板
heisexingqisi| | 2017-4-11 08:13 | 只看该作者
下载学习一下这些非主流的怎么玩。

使用特权

评论回复
5
yiy| | 2017-4-11 22:39 | 只看该作者
TMR0_Delay1ms(500);
延时500毫秒?最大能延时多少毫秒?

使用特权

评论回复
6
wahahaheihei| | 2017-4-12 11:11 | 只看该作者
#define _BV(bit) (1 << (bit))
这种用法经常用的。

使用特权

评论回复
7
Lbsonggz|  楼主 | 2017-4-12 16:47 | 只看该作者
TMR0_Delay1ms()是按照延时1ms设计的,至于打算延时多少ms,直接写在括号里面就行。但不建议太长时间延时,以免影响CPU效率。另外说一句,与外部晶振精度有关,这个延时不是太准,除非使用高精度晶振

使用特权

评论回复
8
heisexingqisi| | 2017-4-12 18:30 | 只看该作者
让所有的引脚都闪烁起来。。

使用特权

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

本版积分规则

33

主题

240

帖子

7

粉丝