搜索
bottom↓
回复: 16

【分享】基于MQX4.0创建并移植K10 BSP包的方法——转帖

[复制链接]

出0入0汤圆

发表于 2014-8-21 13:46:57 | 显示全部楼层 |阅读模式
1. K10 BSP包的创建

   在基于MQX4.0对Kinetis系列MCU进行开发时,通常需要相应MCU的BSP的支持。但是在MQX4.0中,并没有针对K10的现成的BSP包,所以需要由用户进行创建。比较简便的创建方法是从现有的Kinetis BSP包中选择一个型号最接近的MCU的BSP作为模板,然后在其基础上进行修改和移植。本文介绍了对BSP进行修改和移植的具体步骤和方法。
目前已有的典型的BSP包包括:
• 支持Kinetis 50MHz 的器件的BSP包为twrk20d50m
• 支持Kinetis 72MHz 的器件的BSP包为twrk20d72m
• 支持Kinetis 100MHz的器件,针对版本1.x的BSP有3个,分别是twrk40x256,twrk53n512和twrk60n512
• 支持Kinetis 100MHz的器件,针对版本2.x可选择的BSP有2个,分别是twrk40d100m和twrk60d100m
• 支持Kinetis 120MHz的器件的BSP包有2个,分别是twrk60f120m和twrk70f120m
  例如对于K10DN512ZVLQ10,其掩膜号为 4N30D,对应版本是1.x,而且其主频是100MHz,所以可使用twrk60n512的BSP为模板,在此基础上进行修改和移植。

2. BSP包代码的生成

首先从Freescale官网 https://www.freescale.com/mqx下载并安装MQX4.0。在这里也可以找到其他的早期版本,如MQX3.8、 MQX3.7等,其中都带有MQX BSP Cloning Wizard工具。可以使用此工具,参照如下步骤进行BSP的创建和移植。
2.1新建BSP
在File菜单中选择NEW MQX BSP Clone后,出现如下图1所示的界面,在Name中输入取名为K10DN512,然后选择twrk60n512作为其Board Base,最后点击Finish完成。

图1. 新建一个BSP
紧接着会出现如图2所示的窗口,可以在该界面下选择CW10.x或者IAR或者KEIL作为开发平台,以及是否需要生成BSP,PSP,MFS,RTCS,USB等库和例程的选择项。需要注意的是,由于K10本身不包括USB和以太网模块,所以不要选择相应的选项。

图2. 选择开发平台和相关的软件库

2.2 生成BSP包

为了简化操作,这里只选择IAR的开发环境,而且只选择生成BSP,PSP以及MQX例程,然后点击Generate MQX Projects,开始创建新的BSP代码,如图 3所示。

图3 点击生成BSP包的工程

接着在C:\Freescale\Freescale_MQX_4_0\config\K10DN512目录中,找到刚才生成的针对IAR的BSP代码,使用IAR开发环境选择File->Open->Workspace,打开build_libs.eww工程。如图4所示。

图4 打开IAR BSP工程

注意: 在 打开此工程时会提示RTCS、 MFS、 USB等库是否要加载。由于本文档只针对基本的BSP、PSP包进行移植,而且在图2中只勾选了这两项,所以这里可以忽略除BSP、 PSP以外的 MFS、 RTCS、USB等包的加载,直接点击确认完成就可以了。如果在实际应用中需要使用其他的包,需要将图2中相应的Libraries库和参考代码的选项勾选上,然后再进行代码生成即可。

3. BSP包代码的修改

在C:\Freescale\Freescale_MQX_4_0\mqx\source\psp\cortex_m文件夹里的psp_cpudef.h文件中可以找到支持Kinetis K10/K20/K30/K40/K50/K60/K70等相关芯片的PSP宏定义,例如支持K10DN512的宏定义为:

#define PSP_CPU_MK10DN512Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K1X, 2))
同时在该文件中还可以找到所有Freescale指定PSP处理器支持包所支持内核的宏定义,如ColdFire,PPC,Cortex-A5,Cortex-A8等。
在本文中,我们创建的是针对K10DN512的BSP开发包,所以需要用上述的宏定义,将user_config.h文件中的MQX_CPU定义
#define MQX_CPU                PSP_CPU_MK60DN512Z
修改为:
#define MQX_CPU                PSP_CPU_MK10DN512Z  
   
此时点击编译按钮会出现错误提示,如下图5所示。

图5. 头文件错误

出现这个错误是由于在C:\Freescale\Freescale_MQX_4_0\mqx\source\psp\cortex_m\kinetis.h中找不到头文件MK10DZ10.h,需要从以下的IAR安装目录中寻找:
C:\Program Files\IAR Systems\Embedded Workbench 6.5\arm\inc\Freescale
然后将该文件拷贝到C:\Freescale\Freescale_MQX_4_0\mqx\source\psp\cortex_m\cpu中进行编译。

编译仍有错误出现,如下图6所示。


这个错误主要是由于移植使用的是K60的BSP包,因此里面含有以太网ENET部分和USB部分的代码,而在K10芯片中是没有这些功能模块的,在IAR IDE Workspace工作台环境下,需要将外围I/O驱动(Peripheral IO Drivers)中的ENET和USB等文件夹删除,同时将K10DN512 BSP Files文件夹中的 init_usb.c和init_enet.c文件删除。另外在K10DN512 BSP Files中,由于在MQX安装目录C:\Freescale\Freescale_MQX_4_0\mqx\source\bsp\K10DN512 文件下的init_gpio.c和bsp.h中初始化了ent和usb部分的,需要打开这两个文件,找到_bsp_ent_io_init和bsp_usb_io_init的代码部分,然后直接进行删除。此时再进行编译,则应该没有错误出现了。

图6以太网及USB相关的文件编译错误

下一步需要修改的,是系统的时钟设置。针对K60DN512, MQX默认的外部时钟是50MHz。 对于K20系列MQX默认的外部时钟是8MHz,如果目标板的时钟和默认的外部时钟不一样,则需要重新配置。例如,如果这里选择25MHz的无源晶体作为外接时钟,那么就需要修改bsp_cm.h中的时钟设置,将CPU_XTAL_CLK_HZ的时钟修改为25MHz。当然根据实际项目设计有时也需要配置不同的总线时钟频率,内核时钟频率等,可以参照如下的代码对bsp_cm.h中的宏定义进行相应的修改:

#define CPU_BUS_CLK_HZ                  48000000U /*初始化总线时钟频率为48MHz*/
修改为
#define CPU_BUS_CLK_HZ                  50000000U /*初始化总线时钟频率为50MHz*/
#define CPU_CORE_CLK_HZ             96000000U /* 初始化内核、系统时钟频率为96MHz */
修改为
#define CPU_CORE_CLK_HZ             100000000U /* 初始化内核、系统时钟频率为100MHz */
#define CPU_CLOCK_CONFIG_NUMBER         0x03U /* 定义时钟配置的个数,时钟配置有0,1和2,共3种可以选择*/
#define CPU_BUS_CLK_HZ_CLOCK_CONFIG0    48000000U /*在时钟配置0中的总线时钟频率为48MHz */
修改为
#define CPU_BUS_CLK_HZ_CLOCK_CONFIG0    50000000U /*在时钟配置0中的总线时钟频率为50MHz */
#define CPU_CORE_CLK_HZ_CLOCK_CONFIG0   96000000U /* 在时钟配置0中的内核、系统时钟频率为96MHz*/
修改为
#define CPU_CORE_CLK_HZ_CLOCK_CONFIG0   100000000U /* 在时钟配置0中的内核、系统时钟频率为100MHz*/
#define CPU_XTAL_CLK_HZ                 50000000U /* 外部晶体或者振荡器的时钟频率为50MHz*/
修改为
#define CPU_XTAL_CLK_HZ                 25000000U /* 外部晶体或者振荡器的时钟频率为25MHz*/

相应的,对于使用的时钟配置0或者1或者2也需要修改,如果目标配置使用的是时钟配置0,可以参照如下代码修改。如果不使用时钟配置1或者2,则不需要做修改。

/* 在时钟配置0中的CPU时钟频率 */
#define CPU_CLOCK_CONFIG_0              0x00U /* 时钟配置0的定义 */
修改内核时钟频率,默认的是96MHz,改为100MHz。
#define CPU_CORE_CLK_HZ_CONFIG_0        100000000UL /* 内核时钟频率为100MHz*/
修改总线时钟频率,默认是48MHz,修改为50MHz。
#define CPU_BUS_CLK_HZ_CONFIG_0         50000000UL /* 总线时钟频率为50MHz*/
修改Flash时钟频率,默认是24MHz,修改为25MHz。
#define CPU_FLASH_CLK_HZ_CONFIG_0       25000000UL /* FLASH时钟频率为25MHz*/
#define CPU_PLL_FLL_CLK_HZ_CONFIG_0     100000000UL /* PLL/FLL时钟频率为100MHz*/
#define CPU_OSCER_CLK_HZ_CONFIG_0       50000000UL

/*在时钟配置0中的系统OSC 外部参考时钟 */

手工书写代码相对繁琐,更方便的方法是使用Freescale的Processor Expert 工具,根据硬件的需要来设置时钟,生成的如下的代码。通过PE工具来对CPU和各种外设进行设置,只需了解它的原理和用法,而不用把精力花在了解寄存器的具体细节上。打开PE后,参照图7的配置进行设置,点击Project->Generator Processor Expert Code即可生成代码。记住重新修改配置后需要点击Project->Clean,清掉上次生成的代码,然后再执行生成代码的操作。

void __pe_initialize_hardware(void)
{
  _bsp_watchdog_disable();
   /* 关闭 WDOG 模块 */
  WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520);
  WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928);
WDOG_STCTRLH = WDOG_STCTRLH_STNDBYEN_MASK |                 WDOG_STCTRLH_WAITEN_MASK | WDOG_STCTRLH_STOPEN_MASK |                WDOG_STCTRLH_ALLOWUPDATE_MASK | WDOG_STCTRLH_CLKSRC_MASK;                       
  /* 系统时钟初始化 */
  /* SIM_SCGC5: PORTA=1 */
  SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV2(0x01) | SIM_CLKDIV1_OUTDIV3(0x03) |
  SIM_CLKDIV1_OUTDIV4(0x03); /* 更新系统预分频器 */
  SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL_MASK);
  PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));                                                   
  PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));                                                   
  /*切换到FBE 模式*/
   OSC_CR = OSC_CR_ERCLKEN_MASK;                                                   
  SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_MCGCLKSEL_MASK);                                                   
  MCG_C2 = (MCG_C2_RANGE(0x02) | MCG_C2_EREFS_MASK);                                                   
  MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x05) | MCG_C1_IRCLKEN_MASK);                                                   
  MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));                                                   
  MCG_C5 = MCG_C5_PRDIV(0x07);                                                   
  MCG_C6 = MCG_C6_VDIV(0x08);                                                   
  while((MCG_S & MCG_S_OSCINIT_MASK) == 0x00U) { /*判断晶振是否运行?*/
  }
  while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) {
/* 判断FLL参考源是否为外部参考时钟 */
  }
  while((MCG_S & 0x0CU) != 0x08U) {    //等待,直到外部参考时钟作为MCG的输出
  }
  /* 切换到 PBE 模式*/
  OSC_CR = OSC_CR_ERCLKEN_MASK;                                                   
  SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_MCGCLKSEL_MASK);                                                   
  MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x05) | MCG_C1_IRCLKEN_MASK);                                                   
  MCG_C2 = (MCG_C2_RANGE(0x02) | MCG_C2_EREFS_MASK);                                                   
  MCG_C5 = MCG_C5_PRDIV(0x07);                                                   
  MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV(0x08));                                                   
  while((MCG_S & 0x0CU) != 0x08U) {    /*等待,直到外部参考时钟作为MCG输出*/
  }
  while((MCG_S & MCG_S_LOCK_MASK) == 0x00U) { /* 等待直到锁住*/
  }
  /* 切换到 PEE模式 */
  OSC_CR = OSC_CR_ERCLKEN_MASK;                                                   
  SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_MCGCLKSEL_MASK);                                                   
  MCG_C1 = (MCG_C1_FRDIV(0x05) | MCG_C1_IRCLKEN_MASK);                                                   
  MCG_C2 = (MCG_C2_RANGE(0x02) | MCG_C2_EREFS_MASK);                                                   
  MCG_C5 = MCG_C5_PRDIV(0x07);                                                   
  MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV(0x08));                                                   
  while((MCG_S & 0x0CU) != 0x0CU) {    /* 等待,直到PLL输出*/
  }
}



图7. PE设置

MQX4.0中PE的时钟初始化代码在bsp_cm.c文件的void __pe_initialize_hardware(void)函数中。可以将上述PE生成的代码直接粘贴在该文件中。调试可能会出现系统时钟配置错误。当出现此类错误时,程序可能会停在图8所示的dispatch.s文件中的等待中断的语句cpsid.n  i处。这种错误往往是由于只修改了部分的时钟寄存器设置或者是直接使用其他系列的Kinetis的BSP包中的时钟配置,而没有做相应的修改所造成的。例如,直接使用K60  BSP包的默认时钟部分代码,在K10的25Mhz外部时钟环境中进行调试就会出现上述错误。这里不建议手工书写代码或者直接拷贝其他Kinetis系列的不同时钟配置的代码,建议使用PE来配置生成时钟代码,对于有错误的部分PE中会有相关的红色提示符标示出来,因此不用担心那些时钟寄存器配置错误或被遗漏了。


图8. dispatch.s代码

一般地,在user_config.h配置中,RTC是默认使能的,也就是外部的32.768Khz晶振是需要外接的,如果不外接,可以将配置文件user_config.h中的宏定义语句:
#define BSPCFG_ENABLE_RTCDEV     1    修改为   
#define BSPCFG_ENABLE_RTCDEV    0
另外由于K10中不包含USB和以太网的代码,所以需要将相关的USB,Ethernet的文件删除,并将user_config.h头文件中的宏定义修改为:
#define RTCSCFG_ENABLE_ICMP      0
#define RTCSCFG_ENABLE_UDP       0
#define RTCSCFG_ENABLE_TCP       0
#define RTCSCFG_ENABLE_STATS     0
#define RTCSCFG_ENABLE_GATEWAYS  0
#define FTPDCFG_USES_MFS         0
#define RTCSCFG_ENABLE_SNMP      0
#define TELNETDCFG_NOWAIT        FALSE
#define HTTPDCFG_POLL_MODE       0
#define HTTPDCFG_STATIC_TASKS    0
#define HTTPDCFG_DYNAMIC_TASKS   0

4. BSP包代码的调试

4.1. 创建一个 简单任务并运行

为了证明所创建的BSP是可以正常工作的,这里建一个最简单的IAR的工程,如图9所示,它包含了我们所创建的基于MQX 4.0的 K10DN512 的BSP库。


图9 建立一个IAR工程

选择保存工程的文件目录位置如下:C:\Freescale\Freescale_MQX_4_0\demo\K10DN512 Demo。在main.c中添加如下的代码:
#include
#include
#define MAIN_TASK  15
#define STACK_SIZE   1024
#define MAIN_STACK   STACK_SIZE
extern void main_task(uint_32);
extern "C" const TASK_TEMPLATE_STRUCT  MQX_template_list[] =  
{   
  // Task Index,   Function,    Stack,  Priority,   Name,     Attributes,     Param,   Time Slice */
   { MAIN_TASK,  main_task, MAIN_STACK,    11,        "main_task",  MQX_AUTO_START_TASK,  0,   0 },
   { 0 }
};
void main_task(uint_32   parameter)
{
   while(1)
   {
    puts("A");
  }
}

需要将C:\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\bsp中的bsp.a库文件,以及C:\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\psp中的psp.a库文件添加到工程中去。如下图10所示,点击main选择右键option for node “main”,并在C/C++ Compiler的预处理器preprocessor和Assembler中设置文件的路径如下。
C:\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\bsp
C:\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\psp
C:\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\bsp\Generated_Code
C:\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug

图10. 在Option选项中设置

        注意需要将 文件拷贝到C:\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\psp文件夹中。
       编译完成后,通过JLINK等烧写工具将软件下载到目标板后开始运行,系统运行的界面如图11所示。如果系统进不了main函数,说明MQX  bsp系统移植还有问题,需要按照前面介绍的步骤进行仔细的检查。

图11 复位后运行进入main函数
      
系统进入main函数,在mqx函数处设置断点,点击图标go运行,程序进入mqx初始化部分,如图12所示。


图12 mqx初始化
         
在main_task中设置断点,再次运行,如图13所示,在IAR 的JLINK任务栏中可以找到TASK LIST列表。这里需要注意的是,需要在IAR的环境下,将option下debug插件的MQX勾选,如图14所示,勾选后才可以看到MQX的TASK等任务信息。


图13 主任务运行


图14 选取MQX

4.2 GPIO配置与任务调试
         
在MQX4.0安装目录C:\Freescale\Freescale_MQX_4_0\mqx\examples下可以找到很多参考例程,包括ADC、 Hello、 I2C、 Lowpower、 Timer等。这里采用使用的最多的GPIO例程来验证BSP是否能正常工作。
        
由于在默认的bsp包中user_config.h中没有配置使能BSPCFG_ENABLE_GPIODEV外设,需要在该文件中加入语句#define BSPCFG_ENABLE_GPIODEV 1,如下图15所示。

图15 使能GPIO任务配置

在这里,为了验证MQX4.0版本操作系统对于MQX3.8等早期版本软件代码的兼容性,本例使用的源程序 代码,可以在MQX3.8版本的安装目录中C:\Freescale\Freescale MQX 3.8\mqx\examples\gpio找到。直接将该文件添加到工程中,如图16所示,在IAR的主程序中,在读IO状态处设置断点,系统执行到此断点处,如果开启IAR任务栏的TASK List, 在Stack Uage Summary窗口可以看到任务和栈的运行情况。



图16 GPIO任务 运行

       这里需要注意的是,代码中用到了一些BSP_BUTTON1,BSP_LED1等宏定义,这些宏定义在MQX4.0的安装目录C:\Freescale\Freescale_MQX_4_0\mqx\source\bsp\K10DN512的K10DN512.H文件中可以找到,例如BSP_LED1中的宏定义如下:
#define BSP_LED1                    (GPIO_PORT_A | GPIO_PIN11)

       如果目标板中的LED引脚和默认的设置不一样,需要对其进行修改,然后重新编译。
另外在通过下载工具调试代码的时候,需要指定icf配置文件,如图17所示。这里K10DN512和K60DN512的Flash大小一样,不需要做修改。如果使用其他不同配置的芯片则需要对Memory Region进行调整。



图17 ICF文件的位置指定

5. 总结
本文介绍了如何基于飞思卡尔的MQX操作系统,创建并移植目标MCU的 BSP包,并可以针对不同的开发平台(CW, KEIL, IAR)定制适合目标芯片的BSP。

参考文献
1.  Freescale MQX Porting Guide
2. Kinetis 100 MHz Rev 1.x to Rev 2.x Migration Guide
3. Getting Started with Freescale MQX™ RTOS

原帖地址:http://www.chinaem.com.cn/bencandy.php?id=7116


出0入0汤圆

发表于 2014-8-21 13:50:23 | 显示全部楼层
感谢楼主的资料分享,支持下。

出0入0汤圆

发表于 2014-8-21 17:15:28 | 显示全部楼层
没有沙发抢个板凳座座也好。支持牛人。

出0入0汤圆

发表于 2014-8-21 17:40:55 | 显示全部楼层
借楼主的帖子赚点飞币,分析fsl在iar下的alloc.c实现

1)首先定义
#ifdef IAR
    #pragma section = "HEAP"
#endif

2)定义变量
typedef struct ALLOC_HDR
{
    struct
    {
        struct ALLOC_HDR     *ptr;
        unsigned int size;
    } s;
    unsigned int align;
    unsigned int pad;
} ALLOC_HDR;

static ALLOC_HDR base;
static ALLOC_HDR *freep = NULL;

3)初始化过程
       
    char* __HEAP_START  = __section_begin("HEAP");
    char* __HEAP_END    = __section_end("HEAP");


    if ((prevp = freep) == NULL)
    {
        p = (ALLOC_HDR *)__HEAP_START;
        p->s.size = ( ((uint32)__HEAP_END - (uint32)__HEAP_START)
                     / sizeof(ALLOC_HDR) );
        p->s.ptr = &base;
        base.s.ptr = p;
        base.s.size = 0;
        prevp = freep = &base;
    }
   
4)linker文件分析

/* 堆栈大小符号定义 --------------------------------------------------------- */
define symbol __ICFEDIT_size_cstack__                         = (4*1024);
define symbol __ICFEDIT_size_heap__                         = (4*1024);

/* 堆栈块定义 --------------------------------------------------------------- */
define block CSTACK                                                 with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP                                                   with alignment = 8, size = __ICFEDIT_size_heap__     { };

/* 相关段/块指定 ------------------------------------------------------------ */
place in ROM_region                                                 { readonly,  block CodeRelocate };
place in RAM_region                                                 { readwrite, block CodeRelocateRam, block CSTACK, block HEAP };


出0入0汤圆

发表于 2014-8-21 17:44:46 | 显示全部楼层
分析函数拷贝到RAM中执行

1)定义
    #pragma section = "CodeRelocate"
    #pragma section = "CodeRelocateRam"

2)执行
#if (defined(IAR))
          uint8* code_relocate_ram    = __section_begin("CodeRelocateRam");
        uint8* code_relocate        = __section_begin("CodeRelocate");
    uint8* code_relocate_end    = __section_end("CodeRelocate");
   
    /* 拷贝函数从ROM到RAM中 */
    n = code_relocate_end - code_relocate;
    while (n--) {
        *code_relocate_ram++ = *code_relocate++;
    }
#endif

3)linker文件
define block CodeRelocate                           { section .textrw_init };
define block CodeRelocateRam                        { section .textrw };

出0入0汤圆

发表于 2014-8-21 21:25:54 | 显示全部楼层
感谢楼主分享,顶个

出0入0汤圆

 楼主| 发表于 2014-8-22 08:10:19 | 显示全部楼层
似乎对MQX热情都不是很高的样子

出0入0汤圆

发表于 2014-8-22 08:36:18 | 显示全部楼层
谢楼主的资料分享,顶下。

出0入0汤圆

发表于 2014-8-22 11:56:28 | 显示全部楼层

MARK下,以后留用

出0入0汤圆

发表于 2014-9-2 13:56:35 | 显示全部楼层
高端的东西,标记一下。以后了解,

出100入101汤圆

发表于 2014-9-3 06:47:43 | 显示全部楼层
好资料,支持一下

出0入0汤圆

发表于 2014-9-3 08:59:30 | 显示全部楼层
蛮高端的样子,学习了、

出0入0汤圆

发表于 2014-9-26 16:37:05 | 显示全部楼层
正需要。
好资料。

出0入0汤圆

发表于 2014-9-27 17:07:50 | 显示全部楼层
我做了个离线的PDF文件

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2014-9-28 00:34:47 | 显示全部楼层
支持一下吧,mqx用的人少。

出0入0汤圆

发表于 2014-9-29 09:02:55 | 显示全部楼层

好资料,支持一下

出0入0汤圆

发表于 2016-1-21 15:52:20 | 显示全部楼层
FSL_TICS_ZJJ 发表于 2014-8-21 13:50
感谢楼主的资料分享,支持下。

兄弟,你有K10的一些例程么?某宝卖家不给那张光盘的资料 KEIL IAR的都可以。。。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 12:10

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表