[应用方案] 使用EmBITZ1.0驱动LED(GPIO)

[复制链接]
971|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, 下载次数: 17

GPIO(LED)驱动实例

玛尼玛尼哄 发表于 2017-2-27 21:48 | 显示全部楼层
不如再贴上代码吸引人

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

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

  20. #define P0_MODE               0x5555
  21. #define P1_MODE               0x5555
  22. #define P2_MODE               0x5555
  23. #define P3_MODE                      0x5555

  24. //void TMR0_Delay1ms(uint32_t ulCNT);
  25. //void Timer0_Init(void);

  26. /***************************************************************************************
  27.    参数 :   ulCNT, 延迟时间,毫秒
  28.    描述     用Timer0定时
  29. ****************************************************************************************/

  30. void TMR0_Delay1ms(uint32_t ulCNT)
  31. {
  32.     TCMPR0 = 12000;                              //12MHz/96000 = 0.125KHz
  33.     TCSR0 |= CEN | TMR_IE;                       //启动定时器Timer0并使能Timer0中断
  34.     while (ulCNT != 1)
  35.     {
  36.         while((TISR0&TMR_TIF) != TMR_TIF);       //定时时间到否?
  37.                TISR0 |= TMR_TIF;                        //定时器清标志位
  38.         ulCNT--;
  39.     }
  40.     TCSR0 &= ~CEN;                               //停止Timer0定时器
  41. }
  42. /***************************************************************************************
  43. 描述 :   初始化定时器Timer0,周期模式
  44. ****************************************************************************************/
  45. void Timer0_Init()
  46. {
  47.     APBCLK |= TMR0_CLKEN;                                  //使能APB时钟
  48.     CLKSEL1 = CLKSEL1 & (~TM0_CLK) | TM0_12M;              //选择外部晶振作为定时器时钟源
  49.     //CLKSEL1 |= TM0_12M;
  50.     TCSR0  |= CRST;                                        //复位定时器
  51.     TCSR0  &= 0xFFFFFF00 ;                                 //时钟不分频
  52.     TCSR0   = TCSR0 & (~TMR_MODE) | MODE_PERIOD;           //周期模式
  53.     //TCSR0   |= MODE_PERIOD;
  54. }

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

  63.     P0_PMD = P0_MODE;                                      //配置P0口所有引脚为输出模式
  64.     P1_PMD = P1_MODE;                                      //配置P1口所有引脚为输出模式
  65.     P2_PMD = P2_MODE;                                      //配置P2口所有引脚为输出模式
  66.     //P3_PMD = P3_MODE;                                      //配置P3口所有引脚为输出模式
  67.     P3_PMD |= (1<<12);     //p3.6 out mode
  68.     //P3_DOUT |= (1<<6);
  69.     Timer0_Init();
  70.     //P3_DOUT = 0x00;
  71.     while(1)
  72.     {
  73.         P0_DOUT = 0x00;                                    //P0口所有引脚输出0
  74.         P1_DOUT = 0x00;                                    //P1口所有引脚输出0
  75.         P2_DOUT = 0x00;                                    //P2口所有引脚输出0
  76.         //P3_DOUT = 0x00;                                    //P3口所有引脚输出0
  77.         P3_DOUT |= (1<<6);
  78.         TMR0_Delay1ms(500);

  79.         P0_DOUT = 0xFF;                                    //P0口所有引脚输出1
  80.         P1_DOUT = 0xFF;                                    //P1口所有引脚输出1
  81.         P2_DOUT = 0xFF;                                    //P2口所有引脚输出1
  82.         P3_DOUT &= ~(1<<6);
  83.         //P3_DOUT = 0xFF;                                    //P3口所有引脚输出1
  84.         TMR0_Delay1ms(500);
  85.     }
  86.     return 0;
  87. }
huangcunxiake 发表于 2017-2-27 22:10 | 显示全部楼层
以前用过类似的用法:
set_bit();
clr_bit();
heisexingqisi 发表于 2017-4-11 08:13 | 显示全部楼层
下载学习一下这些非主流的怎么玩。
yiy 发表于 2017-4-11 22:39 | 显示全部楼层
TMR0_Delay1ms(500);
延时500毫秒?最大能延时多少毫秒?
wahahaheihei 发表于 2017-4-12 11:11 | 显示全部楼层
#define _BV(bit) (1 << (bit))
这种用法经常用的。
 楼主| Lbsonggz 发表于 2017-4-12 16:47 | 显示全部楼层
TMR0_Delay1ms()是按照延时1ms设计的,至于打算延时多少ms,直接写在括号里面就行。但不建议太长时间延时,以免影响CPU效率。另外说一句,与外部晶振精度有关,这个延时不是太准,除非使用高精度晶振
heisexingqisi 发表于 2017-4-12 18:30 | 显示全部楼层
让所有的引脚都闪烁起来。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

240

帖子

9

粉丝
快速回复 在线客服 返回列表 返回顶部