[入门教程] 新唐Cortex-M0通用头文件NUC1xxM051Seriescfg.h使用说明

[复制链接]
7396|13
 楼主| hotpower 发表于 2011-3-29 02:13 | 显示全部楼层 |阅读模式
本帖最后由 Cube 于 2011-3-29 16:42 编辑

  1.            新唐Cortex-M0通用头文件NUC1xxM051Seriescfg.h使用说明
  2. 菜农HotPower@163.com  2011.3.28 于雁塔菜地
  3.     菜农HotPower长期致力于MCU头文件的研究,头文件NUC1xxM051Seriescfg.h归属菜农的红杏系列。
  4. 它的宗旨是简化特殊寄存器的**,快捷地访问并可控制到位。
  5. 1.文件路径
  6.   NUC1xxM051Seriescfg.h包含了对新唐Cortex-M0两大系列NUC1xx和M05x所有寄存器的定义。可以
  7. 共用,也可分别引用。
  8. 对于NUC1xx系列:可将本文件拷贝到...\CMSIS\CM0\DeviceSupport\Nuvoton\NUC1xx内。
  9. 对于M05x系列:  可将本文件拷贝到...\CMSIS\CM0\DeviceSupport\Nuvoton\M051Series内。
  10. 2.工程引用
  11.   NUC1xxM051Seriescfg.h是对新唐头文件<NUC1xx.h>或<M051Series.h>的扩展和兼容,而非替代。
  12. 对于Nuc1xx用户:
  13.   #include "nuc1xx.h"
  14.   #include "NUC1xxM051Seriescfg.h"
  15. 对于M05x用户:
  16.   #include "M051Series.h"
  17.   #include "NUC1xxM051Seriescfg.h"
  18. 3.使用方法
  19.   现在以菜农新唐Cortex-M0助学开发板上的发光二极管的控制为例说明红杏头文件的使用。
  20. 该发光二极管L6位于NUC120RE3AN的GPA12.
  21. 在target.h中有如下宏定义:
  22.   #define PortLed  PAs//Led端口GPIO
  23.   #define PmdLed   PMD12//Led位Px.Pin12
  24.   #define PinLed   Pin12//Led位Px.Pin12
  25. 故Led被绑定在GPA12上。其初始化在system.cpp中,Led初始化代码被添加在PortInit()函数中。
  26. void SystemObj:ortInit(void)
  27. {
  28. PortLed.PMD.Bits.PmdLed = GPIO_PMD_OUTPUT;//设置LED为输出模式
  29. }
  30. 此写法是红杏系列的手法,其特点就是不易出错,想错都难。
  31. 其功劳在于Bits位域结构与联合。Bits显式地指明其后的PmdLed是PortLed.PMD寄存器的一个位.
  32. 3.1 假若想用寄存器的结构方法写,可有如下多种表示方法:
  33.   PortLed.PMD.Regs |= GPIO_PMD_OUTPUT << GPIO_PMD_PMD12;
  34.   PAs.PMD.Regs |= GPIO_PMD_OUTPUT << GPIO_PMD_PMD12;
  35.   PORTs.Px[0].PMD.Regs |= GPIO_PMD_OUTPUT << GPIO_PMD_PMD12;//0-PA,1-PB,2...
  36.   PORTs.PA.PMD.Regs |= GPIO_PMD_OUTPUT << GPIO_PMD_PMD12;
  37. 3.2 假若想用位域的结构方法写,可有如下多种表示方法:
  38.   PortLed.PMD.Bits.PMD12 = GPIO_PMD_OUTPUT;
  39.   PAs.PMD.Bits.PMD12 = GPIO_PMD_OUTPUT;
  40.   PORTs.Px[0].PMD.Bits.PMD12 = GPIO_PMD_OUTPUT;//0-PA,1-PB,2...
  41.   PORTs.PA.PMD.Bits.PMD12 = GPIO_PMD_OUTPUT;
  42. 3.3 假若想用寄存器的结构指针方法写,可有如下多种表示方法:
  43.   Px(0)->MD.Regs |= GPIO_PMD_OUTPUT << GPIO_PMD_PMD12;//0-PA,1-PB,2...
  44.   PORTx(0)->MD.Regs |= GPIO_PMD_OUTPUT << GPIO_PMD_PMD12;//0-PA,1-PB,2...
  45. 3.4 假若想用位域的结构指针方法写,可有如下多种表示方法:
  46.   Px(0)->MD.Bits.PMD12 = GPIO_PMD_OUTPUT;//0-PA,1-PB,2...
  47.   PORTx(0)->MD.Bits.PMD12 = GPIO_PMD_OUTPUT;//0-PA,1-PB,2...
  48. 红杏方法太多,这里只列举常用的四种写法。
  49. 其中结构数组或结构指针数组适应于未知端口号的场合。

  50. 4.位域的安全性
  51.   红杏系列以Bits指出右值为位域的值,以Regs指出右值为寄存器的值。首先这样减少了出错的机会。
  52. 由于寄存器操作某个位实际是由“读、改、写”三个阶段组成的,故寄存器的写法可能会产生错误。
  53. 如上的PMD寄存器,它的位域PMDxx由2个位及4种IO方式组成:
  54.   GPIO_PMD_INPUT=0,GPIO_PMD_OUTPUT=1,GPIO_PMD_OPENDRAIN=2,GPIO_PMD_QUASI=3
  55. 寄存器写法:
  56.   PAs.PMD.Regs |= GPIO_PMD_OUTPUT << GPIO_PMD_PMD12;
  57. 此写法可能产品错误,因为“|=”是置位,应该先清除之。完整正确的方法如下:
  58.   PAs.PMD.Regs &= ~(0x03 << GPIO_PMD_PMD12);
  59.   PAs.PMD.Regs |= GPIO_PMD_OUTPUT << GPIO_PMD_PMD12;
  60. 而用位域则不需要这种考虑:
  61.   PAs.PMD.Bits.PMD12 = GPIO_PMD_OUTPUT;
  62. 故位域要比寄存器的写法直观和安全。
  63. 5.位域的效率低下
  64.   以上主要讲解了位域的优点,当需要对某个端口的数个位同时操作时,就显示出了位域的效率低下的
  65. 问题。
  66.   对于一位控制,下面的写法与寄存器的一样简洁:
  67.   PortLed.DOUT.Bits.PinLed = 1;//LED灭(高电平)
  68.   PortLed.DOUT.Bits.PinLed = 0;//LED亮(低电平)
  69. 但是对于超过一位控制或要求一个端口同时控制多个位时,显然必须用寄存器的写法:
  70.   PAs.DOUT.Regs |= ((1 << Bit0) | (1 << Bit1) | (1 << Bitn));
  71.   PAs.DOUT.Regs &= ~((1 << Bit0) | (1 << Bit1) | (1 << Bitn));
  72. 显然寄存器的写法效率明显要超过位域的写法,代码要优化很多。
  73. 6.红杏与库效率的差距
  74.   现在以库函数DrvGPIO_Open()为例,比较其差距。
  75. int32_t DrvGPIO_Open(E_DRVGPIO_PORT port, int32_t i32Bit, E_DRVGPIO_IO mode)
  76. {
  77.     volatile uint32_t u32Reg;
  78.    
  79.     if ((i32Bit < 0) || (i32Bit > 16))
  80.     {
  81.         return E_DRVGPIO_ARGUMENT;
  82.     }   
  83.     u32Reg = (uint32_t)&GPIOA->MD + (port*PORT_OFFSET);   
  84.     if ((mode == E_IO_INPUT) || (mode == E_IO_OUTPUT) || (mode == E_IO_OPENDRAIN))
  85.     {
  86.         outpw(u32Reg, inpw(u32Reg) & ~(0x3<<(i32Bit*2)));
  87.         if (mode == E_IO_OUTPUT)
  88.         {
  89.             outpw(u32Reg, inpw(u32Reg) | (0x1<<(i32Bit*2)));
  90.         }else
  91.         if (mode == E_IO_OPENDRAIN)
  92.         {
  93.             outpw(u32Reg, inpw(u32Reg) | (0x2<<(i32Bit*2)));
  94.         }
  95.     }else
  96. if (mode == E_IO_QUASI)
  97.     {
  98.         outpw(u32Reg, inpw(u32Reg) | (0x3<<(i32Bit*2)));
  99.     }else
  100.     {
  101.         return E_DRVGPIO_ARGUMENT;
  102.     }
  103.         
  104. return E_SUCCESS;
  105. }
  106. 红杏的写法:
  107.   PORTs.Px[port].PMD.Regs |= mode << (16 + (i32Bit *2));
  108.   Px(port)->MD.Regs |= mode << (16 + (i32Bit *2));



Swallow_0322 发表于 2011-3-29 10:02 | 显示全部楼层
顶大叔的红杏,虽然一直对红杏垂涎三尺,但还无力驾驭!
 楼主| hotpower 发表于 2011-3-29 11:06 | 显示全部楼层
今晚就讲讲如何红杏出墙
xuyaosong 发表于 2011-3-29 11:42 | 显示全部楼层
期待晚上的课程,虽然还没用过
HotWC3 发表于 2011-3-29 12:03 | 显示全部楼层
不知神农批准否…
X-Hawk 发表于 2011-3-29 20:15 | 显示全部楼层
挺不错的!
 楼主| hotpower 发表于 2011-3-30 07:04 | 显示全部楼层
哈哈,惊现国军进入上海滩!!!
SYHDJF 发表于 2011-8-26 17:33 | 显示全部楼层
收藏以后再看了
老鱼探戈 发表于 2011-8-28 01:13 | 显示全部楼层
大叔给力,顶起~
lixiaoxu2meng 发表于 2011-8-29 09:31 | 显示全部楼层
顶 留着以后看
 楼主| hotpower 发表于 2011-8-30 07:21 | 显示全部楼层
有时几种方法结合会更好的。
ddllxxrr 发表于 2011-9-10 15:05 | 显示全部楼层
好东东顶一下
tanghaikun 发表于 2012-2-17 18:48 | 显示全部楼层
我用了这个头文件,编译时报错。不知道哪里搞错了。
..\..\..\..\CMSIS\CM0\DeviceSupport\Nuvoton\NUC1xx\NUC1xxM051Seriescfg.h(3446): error:  #20: identifier "CAN_AMR_T" is undefined

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
Swallow_0322 发表于 2012-2-18 07:53 | 显示全部楼层
13# tanghaikun

大叔的红杏头文件是基于新唐的头文件的,使用前要#include "nuc1xx.h"
(对于Nuc1xx用户),且nuc1xx.h为之前的旧版本,请见附件!祝你好运!大叔的红杏头文件非常给力!


旧版本头文件压缩包:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:[url=http://www.21ic.com/tools/HotWC3_V1.23.html]

1460

主题

21617

帖子

508

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