返回列表 发新帖我要提问本帖赏金: 150.00元(功能说明)

[MM32生态] 从零起步,MM32开发环境:从构建到部署的全过程

[复制链接]
 楼主| xld0932 发表于 2024-3-6 15:58 | 显示全部楼层 |阅读模式
<
本帖最后由 xld0932 于 2024-3-6 16:12 编辑

#申请原创#   @21小跑堂

目录
  • 前言
  • 创建SVD
  • 下载算法
  • Keil Pack
  • 模板工程
  • 让LED灯闪烁
  • 附件

1.前言
先问大家一个问题:基于Keil MDK-Arm集成开发环境,准备使用某一款ARM芯片进行开发之前,都需要准备些啥?一般我们需要芯片的数据手册来了解芯片的功能特性、需要用户手册用来在编程设计时做参考、需要勘误手册来避免设计上的一些漏洞、当然还需要官方的库函数及例程,这可以使我们开发的效率得到大大的提升;但除此之外,基于Keil MDK-Arm集成开发环境,我们要使用这款芯片,首先还是得让Keil MDK-Arm集成开发环境认识我们所选择的芯片,这就是我们这篇文章需要跟大家讲解的内容,从最基础、最开始的地方,从零起步,从构建到部署,搭建我们芯片开发的软件包。

如何让Keil MDK-Arm集成开发环境认识一款芯片,我们只需要安装一个芯片对应的Keil Pack支持包,这个支持包可以让Keil MDK-Arm集成开发环境在创建工程的时候可以选择到我们的芯片型号,可以通过Keil MDK-Arm集成开发环境在线下载程序,当然也可以让Keil MDK-Arm集成开发环境在线调试我们的芯片寄存器等等,这些都是Keil Pack支持包最基础的功能,更详细的可以通过Open-CMSIS-Pack Project(https://www.open-cmsis-pack.org/)官网来了解。

下面我们以MM32G0001芯片为例作为讲解。

2.创建SVD
SVD文件是描述一个芯片所有资源的一个集合,包含了基于Arm Cortex-M处理器的微控制器系统的描述,特别是外围设备的内存映射寄存器。在我们使用Keil MDK-Arm集成开发环境在线调试功能时,可以很直观的看到寄存的值、状态、中断配置等等:
1.png

SVD的创建一般是由芯片原厂提供的,每个原厂应该都有一套自己的创建方法;但如果我们要自己创建SVD文件可不可以呢,当然是可以的哈!需要哪些步骤呢:
第一:创建SVD文件我们需要获取到芯片的用户手册,根据用户手册中提供的资讯做为我们SVD的数据源,MM32G0001的资料我们可以从灵动官方上来获取(www.mindmotion.com.cn),我们在官网,产品中选中MM32G0超值型系列的MM32G0001,在文档中可以下载我们需要的用户手册:
2.png

第二:我们需要了解SVD文件的组成结构,这可以通过SVD官网说明来了解(https://open-cmsis-pack.github.io/svd-spec/main/index.html):
3.png

SVD文件它是使用XML来对芯片进行描述的,包含了Device层、CPU层、Peripherals外设层、Registers寄存器层、以及寄存器位域Fields层;我们在Device层可以描述芯片名称、SVD文件版本、概要描述等;可以在CPU层描述芯片的内核、版本、大小端、是否带有MPU\FPU\DSP等等一些属性;可以在Peripherals外设层根据用户手册添加外设描述,每个外设描述包含1个或多个寄存器描述,每个寄存器又包含1个或多个位域描述,每个位域描述又可以定义1个或多个枚举值,这们的层级结构组成了一个完整的SVD文件。

第三:我们要有SVD的生成工具,通过上面的了解,要完成一个SVD文件的工作量是巨大的,如果没有工具而靠手动的去敲,很容易出错,也不容易检查问题;在GitHub上有人分享了一个svd_editor(https://github.com/dmitrystu/svd_editor),但使用下来感觉有点不智能,不太方便!所以我们就自己造工具吧^^

2.1.构建SVD数据源
SVD的数据源我们使用YAML来描述,第一是看上去很直接,其次就是后面维护移植起来方便!我们根据SVD的文件结构来定义了不同的层级,分别为cpu.yml、interrupt.yml、peripheral.yml,这3层作为最先被定义的yml文件,分别定义了MCU的一些特性,中断向量表、以及MCU所具备的外设,然后通过Python来自动构建具体的“外设.yml”,比如CRC.yml/ADC1.yml/GPIOA.yml等,然后在“外设.yml”中添加相应的寄存器描述,Python会根据寄存器描述自动构建“寄存器.yml”,最后我们在“寄存器.yml”中添加位域的描述,这们就数据源就构建OK啦,当然这也是一个耗时的任务,但对于一个MCU原厂来说,相同的外设其定义都差不多,所以可以在不同MCU型号中进行移植,哪怕是修改也是很方便的,所以就辛苦在第一次从无到有的这样一个过程了,加油!
cpu.yml:这个是参考用户手册第一章节:系统和存储架构提取的
  1. MM32G0001 :
  2.   name                : 'CM0'
  3.   revision            : 'r0p0'
  4.   endian              : 'little'
  5.   mpuPresent          : 'false'
  6.   fpuPresent          : 'false'
  7.   fpuDP               : 'false'
  8.   dspPresent          : 'false'
  9.   icachePresent       : 'false'
  10.   dcachePresent       : 'false'
  11.   itcmPresent         : 'false'
  12.   dtcmPresent         : 'false'
  13.   vtorPresent         : 'false'
  14.   nvicPrioBits        : '2'
  15.   vendorSystickConfig : 'false'

interrupt:这个是参考用户手册7.3.2 中断和异常向量
  1. IWDG :
  2.   description : 'IWDG Interrupt'
  3.   value       : '0'
  4.   peripheral  : 'IWDG'

  5. PVD :
  6.   description : 'PVD Interrupt'
  7.   value       : '1'
  8.   peripheral  : 'PWR'

  9. FLASH :
  10.   description : 'Flash Global Interrupt'
  11.   value       : '3'
  12.   peripheral  : 'FLASH'

  13. RCC :
  14.   description : 'RCC Global Interrupt'
  15.   value       : '4'
  16.   peripheral  : 'RCC'

  17. EXTI0_1 :
  18.   description : 'EXTI Line[1:0] Interrupt'
  19.   value       : '5'
  20.   peripheral  : 'EXTI'

  21. EXTI2_3 :
  22.   description : 'EXTI Line[3:2] Interrupt'
  23.   value       : '6'
  24.   peripheral  : 'EXTI'

  25. ......

peripheral.yml:这个是参考1.2.1 存储器映像和寄存器编址
  1. TIM3 :
  2.   description : '16-Bit General-Purpose Timer'
  3.   groupName   : 'TIM3'
  4.   baseAddress : '0x40000400'
  5.   offset      : '0x0'
  6.   size        : '0x400'

  7. IWDG :
  8.   description : 'IWDG Independent watchdog'
  9.   groupName   : 'IWDG'
  10.   baseAddress : '0x40003000'
  11.   offset      : '0x0'
  12.   size        : '0x400'

  13. USART2 :
  14.   description : 'Universal Synchronous Asynchronous Receiver Transmitter'
  15.   groupName   : 'USART'
  16.   baseAddress : '0x40004400'
  17.   offset      : '0x0'
  18.   size        : '0x400'

  19. I2C1 :
  20.   description : 'Inter-Integrated Circuit Interface'
  21.   groupName   : 'I2C1'
  22.   baseAddress : '0x40005400'
  23.   offset      : '0x0'
  24.   size        : '0x400'

  25. PWR :
  26.   description : 'Power Controller'
  27.   groupName   : 'PWR'
  28.   baseAddress : '0x40007000'
  29.   offset      : '0x0'
  30.   size        : '0x400'

  31. SYSCFG :
  32.   description : 'System Controller'
  33.   groupName   : 'SYSCFG'
  34.   baseAddress : '0x40010000'
  35.   offset      : '0x0'
  36.   size        : '0x400'

  37. EXTI :
  38.   description : 'Interrupt and Event'
  39.   groupName   : 'EXTI'
  40.   baseAddress : '0x40010400'
  41.   offset      : '0x0'
  42.   size        : '0x400'

  43. ......

ADC1.yml :这个是参考8.12.1 寄存器总览
  1. ADDATA :
  2.   description   : 'A/D data register'
  3.   addressOffset : '0x00'
  4.   access        : 'read-only'
  5.   resetValue    : '0x00000000'
  6.   size          : '32'

  7. ADCFG :
  8.   description   : 'A/D configuration register'
  9.   addressOffset : '0x04'
  10.   access        : 'read-write'
  11.   resetValue    : '0x00000000'
  12.   size          : '32'

  13. ADCR :
  14.   description   : 'A/D control register'
  15.   addressOffset : '0x08'
  16.   access        : 'read-write'
  17.   resetValue    : '0x00000000'
  18.   size          : '32'

  19. ADCMPR :
  20.   description   : 'A/D analog watchdog comparison register'
  21.   addressOffset : '0x10'
  22.   access        : 'read-write'
  23.   resetValue    : '0x00000000'
  24.   size          : '32'

  25. ADSTA :
  26.   description   : 'A/D status register'
  27.   addressOffset : '0x14'
  28.   access        : 'read-write'
  29.   resetValue    : '0x00000000'
  30.   size          : '32'

  31. ......

ADC1中的寄存器 ADDATA.yml:这个是参考8.12.2 A/D数据寄存器(ADC_ADDATA)
  1. DATA :
  2.   description : '12-bit A/D conversion result'
  3.   bitRange    : '[15:0]'
  4.   access      : 'read-only'

  5. CHANNELSEL :
  6.   description : '4 bits show the channel corresponding to the current data'
  7.   bitRange    : '[19:16]'
  8.   access      : 'read-only'

  9. OVERRUN :
  10.   description : 'Data Overrun Flag'
  11.   bitRange    : '[20:20]'
  12.   access      : 'read-only'

  13. VAILD :
  14.   description : 'Data Valid Flag'
  15.   bitRange    : '[21:21]'
  16.   access      : 'read-only'


2.2.Python自动化生成SVD文件
我们安装最新的Python 3.12.0以及PyCharm社区版集成开发环境,添加和安装PyYAML组件,通过对SVD文件结构和SVD数据源的提取,最终来自动化一键生成SVD文件:
2.2.1.SVD整体创建
  1. def svd_generate(chip):
  2.     if not os.path.exists(fr'D:\PyCharm\{chip}'):
  3.         os.mkdir(fr'D:\PyCharm\{chip}')

  4.     with open(fr'D:\PyCharm\{chip}\{chip}.svd', mode='w') as svd_file:
  5.         svd_file.write('<?xml version="1.0" encoding="utf-8"?>\n')
  6.         svd_file.write('<device schemaVersion="1.3" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" '
  7.                        'xs:noNamespaceSchemaLocation="CMSIS-SVD.xsd">\n')
  8.         svd_file.write(f'\t<name>{chip}</name>\n')
  9.         svd_file.write('\t<version>0.0.1</version>\n')
  10.         svd_file.write(f'\t<description>{chip}:ARM 32-bit Cortex-M Microcontroller based device</description>\n')
  11.         svd_cpu(chip, svd_file)
  12.         svd_peripheral(chip, svd_file)
  13.         svd_file.write('</device>\n')
  14.         svd_file.close()

2.2.2.创建CPU层
  1. def svd_cpu(chip, svd_file):
  2.     if not os.path.exists(fr'D:\PyCharm\{chip}\cpu.yml'):
  3.         with open(fr'D:\PyCharm\{chip}\cpu.yml', mode='w') as cpu_file:
  4.             print('create cpu.yml')
  5.     else:
  6.         with open(fr'D:\PyCharm\{chip}\cpu.yml', mode='r') as cpu_file:
  7.             cpu_data = yaml.safe_load(cpu_file)
  8.             if cpu_data is None:
  9.                 print('cpu.yml is empty!')
  10.             else:
  11.                 svd_file.write('\t<cpu>\n')
  12.                 svd_file.write(f'\t\t<name>{cpu_data[chip]['name']}</name>\n')
  13.                 svd_file.write(f'\t\t<revision>{cpu_data[chip]['revision']}</revision>\n')
  14.                 svd_file.write(f'\t\t<endian>{cpu_data[chip]['endian']}</endian>\n')
  15.                 svd_file.write(f'\t\t<mpuPresent>{cpu_data[chip]['mpuPresent']}</mpuPresent>\n')
  16.                 svd_file.write(f'\t\t<fpuPresent>{cpu_data[chip]['fpuPresent']}</fpuPresent>\n')
  17.                 svd_file.write(f'\t\t<fpuDP>{cpu_data[chip]['fpuDP']}</fpuDP>\n')
  18.                 svd_file.write(f'\t\t<icachePresent>{cpu_data[chip]['icachePresent']}</icachePresent>\n')
  19.                 svd_file.write(f'\t\t<dcachePresent>{cpu_data[chip]['dcachePresent']}</dcachePresent>\n')
  20.                 svd_file.write(f'\t\t<itcmPresent>{cpu_data[chip]['itcmPresent']}</itcmPresent>\n')
  21.                 svd_file.write(f'\t\t<dtcmPresent>{cpu_data[chip]['dtcmPresent']}</dtcmPresent>\n')
  22.                 svd_file.write(f'\t\t<nvicPrioBits>{cpu_data[chip]['nvicPrioBits']}</nvicPrioBits>\n')
  23.                 svd_file.write(f'\t\t<vendorSystickConfig>{cpu_data[chip]['vendorSystickConfig']}</vendorSystickConfig>\n')
  24.                 svd_file.write('\t</cpu>\n')
  25.                 svd_file.write('\n')
  26.     cpu_file.close()

2.2.3.创建Peripherals层
  1. def svd_peripheral(chip, svd_file):
  2.     if not os.path.exists(fr'D:\PyCharm\{chip}\peripheral.yml'):
  3.         with open(fr'D:\PyCharm\{chip}\peripheral.yml', mode='w') as peripheral_file:
  4.             print('create peripheral.yml')
  5.     else:
  6.         with open(fr'D:\PyCharm\{chip}\peripheral.yml', mode='r') as peripheral_file:
  7.             peripheral_data = yaml.safe_load(peripheral_file)
  8.             if peripheral_data is None:
  9.                 print('peripheral.yml is empty!')
  10.             else:
  11.                 svd_file.write('\t<peripherals>\n')
  12.                 # create register folder
  13.                 if not os.path.exists(fr'D:\PyCharm\{chip}\peripheral'):
  14.                     os.mkdir(fr'D:\PyCharm\{chip}\peripheral')

  15.                 for peripheral in peripheral_data:
  16.                     svd_file.write('\t\t<peripheral>\n')
  17.                     svd_file.write(f'\t\t\t<name>{peripheral}</name>\n')
  18.                     svd_file.write(f'\t\t\t<description>{peripheral_data[peripheral]['description']}</description>\n')
  19.                     svd_file.write(f'\t\t\t<groupName>{peripheral_data[peripheral]['groupName']}</groupName>\n')
  20.                     svd_file.write(f'\t\t\t<baseAddress>{peripheral_data[peripheral]['baseAddress']}</baseAddress>\n')
  21.                     svd_file.write(f'\t\t\t<addressBlock>\n')
  22.                     svd_file.write(f'\t\t\t\t<offset>{peripheral_data[peripheral]['offset']}</offset>\n')
  23.                     svd_file.write(f'\t\t\t\t<size>{peripheral_data[peripheral]['size']}</size>\n')
  24.                     svd_file.write(f'\t\t\t\t<usage>registers</usage>\n')
  25.                     svd_file.write(f'\t\t\t</addressBlock>\n')

  26.                     svd_interrupt(chip, peripheral, svd_file)

  27.                     # print('{:6s}'.format(peripheral), hex(peripheral_data[peripheral]))
  28.                     if not os.path.exists(fr'D:\PyCharm\{chip}\peripheral\{peripheral}.yml'):
  29.                         with open(fr'D:\PyCharm\{chip}\peripheral\{peripheral}.yml', mode='w') as register_file:
  30.                             print(f'create {peripheral}.yml...')
  31.                     else:
  32.                         svd_register(chip, peripheral, svd_file)

  33.                     svd_file.write('\t\t</peripheral>\n')
  34.                 svd_file.write('\t</peripherals>\n')
  35.     peripheral_file.close()

2.2.4.添加Interrupt属性
  1. def svd_interrupt(chip, peripheral, svd_file):
  2.     if not os.path.exists(fr'D:\PyCharm\{chip}\interrupt.yml'):
  3.         with open(fr'D:\PyCharm\{chip}\interrupt.yml', mode='w') as interrupt_file:
  4.             print('create interrupt.yml')
  5.     else:
  6.         with open(fr'D:\PyCharm\{chip}\interrupt.yml', mode='r') as interrupt_file:
  7.             interrupt_data = yaml.safe_load(interrupt_file)
  8.             if interrupt_data is None:
  9.                 print('interrupt.yml is empty!')
  10.             else:
  11.                 for interrupt in interrupt_data:
  12.                     if interrupt_data[interrupt]['peripheral'] == peripheral:
  13.                         svd_file.write('\t\t\t<interrupt>\n')
  14.                         svd_file.write(f'\t\t\t\t<name>{interrupt}</name>\n')
  15.                         svd_file.write(f'\t\t\t\t<description>{interrupt_data[interrupt]['description']}</description>\n')
  16.                         svd_file.write(f'\t\t\t\t<value>{interrupt_data[interrupt]['value']}</value>\n')
  17.                         svd_file.write('\t\t\t</interrupt>\n')
  18.     interrupt_file.close()

2.2.5.创建Registers层
  1. def svd_register(chip, peripheral, svd_file):
  2.     with open(fr'D:\PyCharm\{chip}\peripheral\{peripheral}.yml', mode='r') as register_file:
  3.         register_data = yaml.safe_load(register_file)
  4.         if register_data is None:
  5.             print(f'{peripheral}.yml is empty!')
  6.         else:
  7.             # Create REG Folder
  8.             if not os.path.exists(fr'D:\PyCharm\{chip}\peripheral\register'):
  9.                 os.mkdir(fr'D:\PyCharm\{chip}\peripheral\register')

  10.             if not os.path.exists(fr'D:\PyCharm\{chip}\peripheral\register\{peripheral}'):
  11.                 os.mkdir(fr'D:\PyCharm\{chip}\peripheral\register\{peripheral}')

  12.             svd_file.write('\t\t\t<registers>\n')

  13.             for register in register_data:
  14.                 if not os.path.exists(fr'D:\PyCharm\{chip}\peripheral\register\{peripheral}\{register}.yml'):
  15.                     with open(fr'D:\PyCharm\{chip}\peripheral\register\{peripheral}\{register}.yml', mode='w') as field_file:
  16.                         print(f'create {register}.yml...')
  17.                 else:
  18.                     svd_file.write('\t\t\t\t<register>\n')
  19.                     svd_file.write(f'\t\t\t\t\t<name>{register}</name>\n')
  20.                     svd_file.write(f'\t\t\t\t\t<description>{register_data[register]['description']}</description>\n')
  21.                     svd_file.write(f'\t\t\t\t\t<addressOffset>{register_data[register]['addressOffset']}</addressOffset>\n')
  22.                     svd_file.write(f'\t\t\t\t\t<access>{register_data[register]['access']}</access>\n')
  23.                     svd_file.write(f'\t\t\t\t\t<resetValue>{register_data[register]['resetValue']}</resetValue>\n')
  24.                     svd_file.write(f'\t\t\t\t\t<size>{register_data[register]['size']}</size>\n')

  25.                     svd_field(chip, peripheral, register, svd_file)

  26.                     svd_file.write('\t\t\t\t</register>\n')

  27.             svd_file.write('\t\t\t</registers>\n')
  28.         register_file.close()

2.2.6.创建Field层
  1. def svd_field(chip, peripheral, register, svd_file):
  2.     with open(fr'D:\PyCharm\{chip}\peripheral\register\{peripheral}\{register}.yml', mode='r') as field_file:
  3.         field_data = yaml.safe_load(field_file)
  4.         if field_data is None:
  5.             print(f'{register}.yml is empty')
  6.         else:
  7.             svd_file.write('\t\t\t\t\t<fields>\n')

  8.             for field in field_data:
  9.                 svd_file.write('\t\t\t\t\t\t<field>\n')
  10.                 svd_file.write(f'\t\t\t\t\t\t\t<name>{field}</name>\n')
  11.                 svd_file.write(f'\t\t\t\t\t\t\t<description>{field_data[field]['description']}</description>\n')
  12.                 svd_file.write(f'\t\t\t\t\t\t\t<bitRange>{field_data[field]['bitRange']}</bitRange>\n')
  13.                 svd_file.write(f'\t\t\t\t\t\t\t<access>{field_data[field]['access']}</access>\n')
  14.                 svd_file.write('\t\t\t\t\t\t</field>\n')

  15.             svd_file.write('\t\t\t\t\t</fields>\n')
  16.         field_file.close()

2.3.生成SVD文件
4.png

2.4.SVD文件校验
CMSIS提供了一个SVD生成和检验工具,“SVDConv.exe”通过这个工具,我们可以生成芯片的头文件,在生成头文件时还可以检测SVD文件的正确性,确保SVD文件是0 Errors,0 Warnings!在制作的过程中,有些是因为XML语法的问题,有些是寄存器属性和位域属性不一致,通过细心的修改,都是可以解决掉的。
5.png

2.5.SVD文件产生头文件
产生头文件的3种方式:
第一:SVDConv.exe  MM32G0001.svd --generate=header,这种方式只会产生最基础的头文件,仅包含了中断、外设和寄存的定义和描述;
  1. typedef struct {                                /*!< ([url=home.php?mod=space&uid=72445]@[/url] 0x40000400) TIM3 Structure                                             */
  2.   __IOM uint32_t  CR1;                          /*!< ([url=home.php?mod=space&uid=72445]@[/url] 0x00000000) Control Register 1                                         */
  3.   __IOM uint32_t  CR2;                          /*!< ([url=home.php?mod=space&uid=72445]@[/url] 0x00000004) Control Register 2                                         */
  4.   __IOM uint32_t  SMCR;                         /*!< (@ 0x00000008) Slave Mode Control Register                                */
  5.   __IOM uint32_t  DIER;                         /*!< (@ 0x0000000C) Interrupt Enable Register                                  */
  6.   __IOM uint32_t  SR;                           /*!< (@ 0x00000010) Status Register                                            */
  7.   __OM  uint32_t  EGR;                          /*!< (@ 0x00000014) Event Generation Register                                  */
  8.   __IOM uint32_t  CCMR1;                        /*!< (@ 0x00000018) Compare Mode Register 1                                    */
  9.   __IOM uint32_t  CCMR2;                        /*!< (@ 0x0000001C) Compare Mode Register 2                                    */
  10.   __IOM uint32_t  CCER;                         /*!< (@ 0x00000020) Compare Enable Register                                    */
  11.   __IOM uint32_t  CNT;                          /*!< (@ 0x00000024) Counter                                                    */
  12.   __IOM uint32_t  PSC;                          /*!< (@ 0x00000028) Prescaler                                                  */
  13.   __IOM uint32_t  ARR;                          /*!< (@ 0x0000002C) Auto Reload Register                                       */
  14.   __IM  uint32_t  RESERVED;
  15.   __IOM uint32_t  CCR1;                         /*!< (@ 0x00000034) Compare Register 1                                         */
  16.   __IOM uint32_t  CCR2;                         /*!< (@ 0x00000038) Compare Register 2                                         */
  17.   __IOM uint32_t  CCR3;                         /*!< (@ 0x0000003C) Compare Register 3                                         */
  18.   __IOM uint32_t  CCR4;                         /*!< (@ 0x00000040) Compare Register 4                                         */
  19.   __IM  uint32_t  RESERVED1[3];
  20.   __IOM uint32_t  OR;                           /*!< (@ 0x00000050) Input Option Register                                      */
  21. } TIM3_Type;                                    /*!< Size = 84 (0x54)                                                          */

第二:SVDConv.exe  MM32G0001.svd --generate=header --fields=macro,这种方式在第一种的基础上,添加了寄存器位域的宏定义,包含了位域的起始位置和掩码值;
  1. /* =========================================================================================================================== */
  2. /* ================                                           TIM3                                            ================ */
  3. /* =========================================================================================================================== */

  4. /* ==========================================================  CR1  ========================================================== */
  5. #define TIM3_CR1_CEN_Pos                  (0UL)                     /*!< CEN (Bit 0)                                           */
  6. #define TIM3_CR1_CEN_Msk                  (0x1UL)                   /*!< CEN (Bitfield-Mask: 0x01)                             */
  7. #define TIM3_CR1_UDIS_Pos                 (1UL)                     /*!< UDIS (Bit 1)                                          */
  8. #define TIM3_CR1_UDIS_Msk                 (0x2UL)                   /*!< UDIS (Bitfield-Mask: 0x01)                            */
  9. #define TIM3_CR1_URS_Pos                  (2UL)                     /*!< URS (Bit 2)                                           */
  10. #define TIM3_CR1_URS_Msk                  (0x4UL)                   /*!< URS (Bitfield-Mask: 0x01)                             */
  11. #define TIM3_CR1_OPM_Pos                  (3UL)                     /*!< OPM (Bit 3)                                           */
  12. #define TIM3_CR1_OPM_Msk                  (0x8UL)                   /*!< OPM (Bitfield-Mask: 0x01)                             */
  13. #define TIM3_CR1_DIR_Pos                  (4UL)                     /*!< DIR (Bit 4)                                           */
  14. #define TIM3_CR1_DIR_Msk                  (0x10UL)                  /*!< DIR (Bitfield-Mask: 0x01)                             */
  15. #define TIM3_CR1_CMS_Pos                  (5UL)                     /*!< CMS (Bit 5)                                           */
  16. #define TIM3_CR1_CMS_Msk                  (0x60UL)                  /*!< CMS (Bitfield-Mask: 0x03)                             */
  17. #define TIM3_CR1_ARPE_Pos                 (7UL)                     /*!< ARPE (Bit 7)                                          */
  18. #define TIM3_CR1_ARPE_Msk                 (0x80UL)                  /*!< ARPE (Bitfield-Mask: 0x01)                            */
  19. #define TIM3_CR1_CKD_Pos                  (8UL)                     /*!< CKD (Bit 8)                                           */
  20. #define TIM3_CR1_CKD_Msk                  (0x300UL)                 /*!< CKD (Bitfield-Mask: 0x03)                             */
  21. /* ==========================================================  CR2  ========================================================== */
  22. #define TIM3_CR2_MMS_Pos                  (4UL)                     /*!< MMS (Bit 4)                                           */
  23. #define TIM3_CR2_MMS_Msk                  (0x70UL)                  /*!< MMS (Bitfield-Mask: 0x07)                             */
  24. #define TIM3_CR2_TI1S_Pos                 (7UL)                     /*!< TI1S (Bit 7)                                          */
  25. #define TIM3_CR2_TI1S_Msk                 (0x80UL)                  /*!< TI1S (Bitfield-Mask: 0x01)                            */
  26. /* =========================================================  SMCR  ========================================================== */
  27. #define TIM3_SMCR_SMS_Pos                 (0UL)                     /*!< SMS (Bit 0)                                           */
  28. #define TIM3_SMCR_SMS_Msk                 (0x7UL)                   /*!< SMS (Bitfield-Mask: 0x07)                             */
  29. #define TIM3_SMCR_TS_Pos                  (4UL)                     /*!< TS (Bit 4)                                            */
  30. #define TIM3_SMCR_TS_Msk                  (0x70UL)                  /*!< TS (Bitfield-Mask: 0x07)                              */
  31. #define TIM3_SMCR_MSM_Pos                 (7UL)                     /*!< MSM (Bit 7)                                           */
  32. #define TIM3_SMCR_MSM_Msk                 (0x80UL)                  /*!< MSM (Bitfield-Mask: 0x01)                             */
  33. /* =========================================================  DIER  ========================================================== */
  34. #define TIM3_DIER_UIE_Pos                 (0UL)                     /*!< UIE (Bit 0)                                           */
  35. #define TIM3_DIER_UIE_Msk                 (0x1UL)                   /*!< UIE (Bitfield-Mask: 0x01)                             */
  36. #define TIM3_DIER_CC1IE_Pos               (1UL)                     /*!< CC1IE (Bit 1)                                         */
  37. #define TIM3_DIER_CC1IE_Msk               (0x2UL)                   /*!< CC1IE (Bitfield-Mask: 0x01)                           */
  38. #define TIM3_DIER_CC2IE_Pos               (2UL)                     /*!< CC2IE (Bit 2)                                         */
  39. #define TIM3_DIER_CC2IE_Msk               (0x4UL)                   /*!< CC2IE (Bitfield-Mask: 0x01)                           */
  40. #define TIM3_DIER_CC3IE_Pos               (3UL)                     /*!< CC3IE (Bit 3)                                         */
  41. #define TIM3_DIER_CC3IE_Msk               (0x8UL)                   /*!< CC3IE (Bitfield-Mask: 0x01)                           */
  42. #define TIM3_DIER_CC4IE_Pos               (4UL)                     /*!< CC4IE (Bit 4)                                         */
  43. #define TIM3_DIER_CC4IE_Msk               (0x10UL)                  /*!< CC4IE (Bitfield-Mask: 0x01)                           */
  44. #define TIM3_DIER_TIE_Pos                 (6UL)                     /*!< TIE (Bit 6)                                           */
  45. #define TIM3_DIER_TIE_Msk                 (0x40UL)                  /*!< TIE (Bitfield-Mask: 0x01)                             */
  46. /* ==========================================================  SR  =========================================================== */
  47. #define TIM3_SR_UIF_Pos                   (0UL)                     /*!< UIF (Bit 0)                                           */
  48. #define TIM3_SR_UIF_Msk                   (0x1UL)                   /*!< UIF (Bitfield-Mask: 0x01)                             */
  49. #define TIM3_SR_CC1IF_Pos                 (1UL)                     /*!< CC1IF (Bit 1)                                         */
  50. #define TIM3_SR_CC1IF_Msk                 (0x2UL)                   /*!< CC1IF (Bitfield-Mask: 0x01)                           */
  51. #define TIM3_SR_CC2IF_Pos                 (2UL)                     /*!< CC2IF (Bit 2)                                         */
  52. #define TIM3_SR_CC2IF_Msk                 (0x4UL)                   /*!< CC2IF (Bitfield-Mask: 0x01)                           */
  53. #define TIM3_SR_CC3IF_Pos                 (3UL)                     /*!< CC3IF (Bit 3)                                         */
  54. #define TIM3_SR_CC3IF_Msk                 (0x8UL)                   /*!< CC3IF (Bitfield-Mask: 0x01)                           */
  55. #define TIM3_SR_CC4IF_Pos                 (4UL)                     /*!< CC4IF (Bit 4)                                         */
  56. #define TIM3_SR_CC4IF_Msk                 (0x10UL)                  /*!< CC4IF (Bitfield-Mask: 0x01)                           */
  57. #define TIM3_SR_TIF_Pos                   (6UL)                     /*!< TIF (Bit 6)                                           */
  58. #define TIM3_SR_TIF_Msk                   (0x40UL)                  /*!< TIF (Bitfield-Mask: 0x01)                             */
  59. #define TIM3_SR_CC1OF_Pos                 (9UL)                     /*!< CC1OF (Bit 9)                                         */
  60. #define TIM3_SR_CC1OF_Msk                 (0x200UL)                 /*!< CC1OF (Bitfield-Mask: 0x01)                           */
  61. #define TIM3_SR_CC2OF_Pos                 (10UL)                    /*!< CC2OF (Bit 10)                                        */
  62. #define TIM3_SR_CC2OF_Msk                 (0x400UL)                 /*!< CC2OF (Bitfield-Mask: 0x01)                           */
  63. #define TIM3_SR_CC3OF_Pos                 (11UL)                    /*!< CC3OF (Bit 11)                                        */
  64. #define TIM3_SR_CC3OF_Msk                 (0x800UL)                 /*!< CC3OF (Bitfield-Mask: 0x01)                           */
  65. #define TIM3_SR_CC4OF_Pos                 (12UL)                    /*!< CC4OF (Bit 12)                                        */
  66. #define TIM3_SR_CC4OF_Msk                 (0x1000UL)                /*!< CC4OF (Bitfield-Mask: 0x01)                           */
  67. /* ==========================================================  EGR  ========================================================== */
  68. #define TIM3_EGR_UG_Pos                   (0UL)                     /*!< UG (Bit 0)                                            */
  69. #define TIM3_EGR_UG_Msk                   (0x1UL)                   /*!< UG (Bitfield-Mask: 0x01)                              */
  70. #define TIM3_EGR_CC1G_Pos                 (1UL)                     /*!< CC1G (Bit 1)                                          */
  71. #define TIM3_EGR_CC1G_Msk                 (0x2UL)                   /*!< CC1G (Bitfield-Mask: 0x01)                            */
  72. #define TIM3_EGR_CC2G_Pos                 (2UL)                     /*!< CC2G (Bit 2)                                          */
  73. #define TIM3_EGR_CC2G_Msk                 (0x4UL)                   /*!< CC2G (Bitfield-Mask: 0x01)                            */
  74. #define TIM3_EGR_CC3G_Pos                 (3UL)                     /*!< CC3G (Bit 3)                                          */
  75. #define TIM3_EGR_CC3G_Msk                 (0x8UL)                   /*!< CC3G (Bitfield-Mask: 0x01)                            */
  76. #define TIM3_EGR_CC4G_Pos                 (4UL)                     /*!< CC4G (Bit 4)                                          */
  77. #define TIM3_EGR_CC4G_Msk                 (0x10UL)                  /*!< CC4G (Bitfield-Mask: 0x01)                            */
  78. #define TIM3_EGR_TG_Pos                   (6UL)                     /*!< TG (Bit 6)                                            */
  79. #define TIM3_EGR_TG_Msk                   (0x40UL)                  /*!< TG (Bitfield-Mask: 0x01)                              */
  80. /* =========================================================  CCMR1  ========================================================= */
  81. #define TIM3_CCMR1_CC1S_Pos               (0UL)                     /*!< CC1S (Bit 0)                                          */
  82. #define TIM3_CCMR1_CC1S_Msk               (0x3UL)                   /*!< CC1S (Bitfield-Mask: 0x03)                            */
  83. #define TIM3_CCMR1_OC1FE_Pos              (2UL)                     /*!< OC1FE (Bit 2)                                         */
  84. #define TIM3_CCMR1_OC1FE_Msk              (0x4UL)                   /*!< OC1FE (Bitfield-Mask: 0x01)                           */
  85. #define TIM3_CCMR1_OC1PE_Pos              (3UL)                     /*!< OC1PE (Bit 3)                                         */
  86. #define TIM3_CCMR1_OC1PE_Msk              (0x8UL)                   /*!< OC1PE (Bitfield-Mask: 0x01)                           */
  87. #define TIM3_CCMR1_OC1M_Pos               (4UL)                     /*!< OC1M (Bit 4)                                          */
  88. #define TIM3_CCMR1_OC1M_Msk               (0x70UL)                  /*!< OC1M (Bitfield-Mask: 0x07)                            */
  89. #define TIM3_CCMR1_CC2S_Pos               (8UL)                     /*!< CC2S (Bit 8)                                          */
  90. #define TIM3_CCMR1_CC2S_Msk               (0x300UL)                 /*!< CC2S (Bitfield-Mask: 0x03)                            */
  91. #define TIM3_CCMR1_OC2FE_Pos              (10UL)                    /*!< OC2FE (Bit 10)                                        */
  92. #define TIM3_CCMR1_OC2FE_Msk              (0x400UL)                 /*!< OC2FE (Bitfield-Mask: 0x01)                           */
  93. #define TIM3_CCMR1_OC2PE_Pos              (11UL)                    /*!< OC2PE (Bit 11)                                        */
  94. #define TIM3_CCMR1_OC2PE_Msk              (0x800UL)                 /*!< OC2PE (Bitfield-Mask: 0x01)                           */
  95. #define TIM3_CCMR1_OC2M_Pos               (12UL)                    /*!< OC2M (Bit 12)                                         */
  96. #define TIM3_CCMR1_OC2M_Msk               (0x7000UL)                /*!< OC2M (Bitfield-Mask: 0x07)                            */
  97. /* =========================================================  CCMR2  ========================================================= */
  98. #define TIM3_CCMR2_CC3S_Pos               (0UL)                     /*!< CC3S (Bit 0)                                          */
  99. #define TIM3_CCMR2_CC3S_Msk               (0x3UL)                   /*!< CC3S (Bitfield-Mask: 0x03)                            */
  100. #define TIM3_CCMR2_OC3FE_Pos              (2UL)                     /*!< OC3FE (Bit 2)                                         */
  101. #define TIM3_CCMR2_OC3FE_Msk              (0x4UL)                   /*!< OC3FE (Bitfield-Mask: 0x01)                           */
  102. #define TIM3_CCMR2_OC3PE_Pos              (3UL)                     /*!< OC3PE (Bit 3)                                         */
  103. #define TIM3_CCMR2_OC3PE_Msk              (0x8UL)                   /*!< OC3PE (Bitfield-Mask: 0x01)                           */
  104. #define TIM3_CCMR2_OC3M_Pos               (4UL)                     /*!< OC3M (Bit 4)                                          */
  105. #define TIM3_CCMR2_OC3M_Msk               (0x70UL)                  /*!< OC3M (Bitfield-Mask: 0x07)                            */
  106. #define TIM3_CCMR2_CC4S_Pos               (8UL)                     /*!< CC4S (Bit 8)                                          */
  107. #define TIM3_CCMR2_CC4S_Msk               (0x300UL)                 /*!< CC4S (Bitfield-Mask: 0x03)                            */
  108. #define TIM3_CCMR2_OC4FE_Pos              (10UL)                    /*!< OC4FE (Bit 10)                                        */
  109. #define TIM3_CCMR2_OC4FE_Msk              (0x400UL)                 /*!< OC4FE (Bitfield-Mask: 0x01)                           */
  110. #define TIM3_CCMR2_OC4PE_Pos              (11UL)                    /*!< OC4PE (Bit 11)                                        */
  111. #define TIM3_CCMR2_OC4PE_Msk              (0x800UL)                 /*!< OC4PE (Bitfield-Mask: 0x01)                           */
  112. #define TIM3_CCMR2_OC4M_Pos               (12UL)                    /*!< OC4M (Bit 12)                                         */
  113. #define TIM3_CCMR2_OC4M_Msk               (0x7000UL)                /*!< OC4M (Bitfield-Mask: 0x07)                            */
  114. /* =========================================================  CCER  ========================================================== */
  115. #define TIM3_CCER_CC1E_Pos                (0UL)                     /*!< CC1E (Bit 0)                                          */
  116. #define TIM3_CCER_CC1E_Msk                (0x1UL)                   /*!< CC1E (Bitfield-Mask: 0x01)                            */
  117. #define TIM3_CCER_CC1P_Pos                (1UL)                     /*!< CC1P (Bit 1)                                          */
  118. #define TIM3_CCER_CC1P_Msk                (0x2UL)                   /*!< CC1P (Bitfield-Mask: 0x01)                            */
  119. #define TIM3_CCER_CC1NP_Pos               (3UL)                     /*!< CC1NP (Bit 3)                                         */
  120. #define TIM3_CCER_CC1NP_Msk               (0x8UL)                   /*!< CC1NP (Bitfield-Mask: 0x01)                           */
  121. #define TIM3_CCER_CC2E_Pos                (4UL)                     /*!< CC2E (Bit 4)                                          */
  122. #define TIM3_CCER_CC2E_Msk                (0x10UL)                  /*!< CC2E (Bitfield-Mask: 0x01)                            */
  123. #define TIM3_CCER_CC2P_Pos                (5UL)                     /*!< CC2P (Bit 5)                                          */
  124. #define TIM3_CCER_CC2P_Msk                (0x20UL)                  /*!< CC2P (Bitfield-Mask: 0x01)                            */
  125. #define TIM3_CCER_CC2NP_Pos               (7UL)                     /*!< CC2NP (Bit 7)                                         */
  126. #define TIM3_CCER_CC2NP_Msk               (0x80UL)                  /*!< CC2NP (Bitfield-Mask: 0x01)                           */
  127. #define TIM3_CCER_CC3E_Pos                (8UL)                     /*!< CC3E (Bit 8)                                          */
  128. #define TIM3_CCER_CC3E_Msk                (0x100UL)                 /*!< CC3E (Bitfield-Mask: 0x01)                            */
  129. #define TIM3_CCER_CC3P_Pos                (9UL)                     /*!< CC3P (Bit 9)                                          */
  130. #define TIM3_CCER_CC3P_Msk                (0x200UL)                 /*!< CC3P (Bitfield-Mask: 0x01)                            */
  131. #define TIM3_CCER_CC3NP_Pos               (11UL)                    /*!< CC3NP (Bit 11)                                        */
  132. #define TIM3_CCER_CC3NP_Msk               (0x800UL)                 /*!< CC3NP (Bitfield-Mask: 0x01)                           */
  133. #define TIM3_CCER_CC4E_Pos                (12UL)                    /*!< CC4E (Bit 12)                                         */
  134. #define TIM3_CCER_CC4E_Msk                (0x1000UL)                /*!< CC4E (Bitfield-Mask: 0x01)                            */
  135. #define TIM3_CCER_CC4P_Pos                (15UL)                    /*!< CC4P (Bit 15)                                         */
  136. #define TIM3_CCER_CC4P_Msk                (0x8000UL)                /*!< CC4P (Bitfield-Mask: 0x01)                            */
  137. /* ==========================================================  CNT  ========================================================== */
  138. #define TIM3_CNT_CNT_Pos                  (0UL)                     /*!< CNT (Bit 0)                                           */
  139. #define TIM3_CNT_CNT_Msk                  (0xffffUL)                /*!< CNT (Bitfield-Mask: 0xffff)                           */
  140. /* ==========================================================  PSC  ========================================================== */
  141. #define TIM3_PSC_PSC_Pos                  (0UL)                     /*!< PSC (Bit 0)                                           */
  142. #define TIM3_PSC_PSC_Msk                  (0xffffUL)                /*!< PSC (Bitfield-Mask: 0xffff)                           */
  143. /* ==========================================================  ARR  ========================================================== */
  144. #define TIM3_ARR_ARR_Pos                  (0UL)                     /*!< ARR (Bit 0)                                           */
  145. #define TIM3_ARR_ARR_Msk                  (0xffffUL)                /*!< ARR (Bitfield-Mask: 0xffff)                           */
  146. /* =========================================================  CCR1  ========================================================== */
  147. #define TIM3_CCR1_CCR1_Pos                (0UL)                     /*!< CCR1 (Bit 0)                                          */
  148. #define TIM3_CCR1_CCR1_Msk                (0xffffUL)                /*!< CCR1 (Bitfield-Mask: 0xffff)                          */
  149. /* =========================================================  CCR2  ========================================================== */
  150. #define TIM3_CCR2_CCR2_Pos                (0UL)                     /*!< CCR2 (Bit 0)                                          */
  151. #define TIM3_CCR2_CCR2_Msk                (0xffffUL)                /*!< CCR2 (Bitfield-Mask: 0xffff)                          */
  152. /* =========================================================  CCR3  ========================================================== */
  153. #define TIM3_CCR3_CCR3_Pos                (0UL)                     /*!< CCR3 (Bit 0)                                          */
  154. #define TIM3_CCR3_CCR3_Msk                (0xffffUL)                /*!< CCR3 (Bitfield-Mask: 0xffff)                          */
  155. /* =========================================================  CCR4  ========================================================== */
  156. #define TIM3_CCR4_CCR4_Pos                (0UL)                     /*!< CCR4 (Bit 0)                                          */
  157. #define TIM3_CCR4_CCR4_Msk                (0xffffUL)                /*!< CCR4 (Bitfield-Mask: 0xffff)                          */
  158. /* ==========================================================  OR  =========================================================== */
  159. #define TIM3_OR_ETR_RMP_Pos               (0UL)                     /*!< ETR_RMP (Bit 0)                                       */
  160. #define TIM3_OR_ETR_RMP_Msk               (0x3UL)                   /*!< ETR_RMP (Bitfield-Mask: 0x03)                         */

第三:SVDConv.exe  MM32G0001.svd --generate=header --fields=macro --fields=struct,这种方式在第二种的基础上,添加了寄存器结构体定义时的具体化,在把寄存器都定义出来的同时,把每一个寄存器的位域都做了共用体,这样在编写代码时方便了不少!
  1. typedef struct {                                /*!< (@ 0x40000400) TIM3 Structure                                             */
  2.   
  3.   union {
  4.     __IOM uint32_t CR1;                         /*!< (@ 0x00000000) Control Register 1                                         */
  5.    
  6.     struct {
  7.       __IOM uint32_t CEN        : 1;            /*!< [0..0] Counter enable                                                     */
  8.       __IOM uint32_t UDIS       : 1;            /*!< [1..1] Update disable                                                     */
  9.       __IOM uint32_t URS        : 1;            /*!< [2..2] Update request source                                              */
  10.       __IOM uint32_t OPM        : 1;            /*!< [3..3] one-pulse mode                                                     */
  11.       __IOM uint32_t DIR        : 1;            /*!< [4..4] Count direction                                                    */
  12.       __IOM uint32_t CMS        : 2;            /*!< [6..5] Center alignment mode selection                                    */
  13.       __IOM uint32_t ARPE       : 1;            /*!< [7..7] Auto reload preload enable                                         */
  14.       __IOM uint32_t CKD        : 2;            /*!< [9..8] Clock division                                                     */
  15.             uint32_t            : 22;
  16.     } CR1_b;
  17.   } ;
  18.   
  19.   union {
  20.     __IOM uint32_t CR2;                         /*!< (@ 0x00000004) Control Register 2                                         */
  21.    
  22.     struct {
  23.             uint32_t            : 4;
  24.       __IOM uint32_t MMS        : 3;            /*!< [6..4] Master mode selection                                              */
  25.       __IOM uint32_t TI1S       : 1;            /*!< [7..7] TI1 selection                                                      */
  26.             uint32_t            : 24;
  27.     } CR2_b;
  28.   } ;
  29.   
  30.   union {
  31.     __IOM uint32_t SMCR;                        /*!< (@ 0x00000008) Slave Mode Control Register                                */
  32.    
  33.     struct {
  34.       __IOM uint32_t SMS        : 3;            /*!< [2..0] Slave mode selection                                               */
  35.             uint32_t            : 1;
  36.       __IOM uint32_t TS         : 3;            /*!< [6..4] Trigger selection                                                  */
  37.       __IOM uint32_t MSM        : 1;            /*!< [7..7] Master/slave mode                                                  */
  38.             uint32_t            : 24;
  39.     } SMCR_b;
  40.   } ;
  41.   
  42.   union {
  43.     __IOM uint32_t DIER;                        /*!< (@ 0x0000000C) Interrupt Enable Register                                  */
  44.    
  45.     struct {
  46.       __IOM uint32_t UIE        : 1;            /*!< [0..0] Update interrupt enable                                            */
  47.       __IOM uint32_t CC1IE      : 1;            /*!< [1..1] Compare 1 interrupt enable                                         */
  48.       __IOM uint32_t CC2IE      : 1;            /*!< [2..2] Compare 2 interrupt enable                                         */
  49.       __IOM uint32_t CC3IE      : 1;            /*!< [3..3] Compare 3 interrupt enable                                         */
  50.       __IOM uint32_t CC4IE      : 1;            /*!< [4..4] Compare 4 interrupt enable                                         */
  51.             uint32_t            : 1;
  52.       __IOM uint32_t TIE        : 1;            /*!< [6..6] Trigger interrupt enable                                           */
  53.             uint32_t            : 25;
  54.     } DIER_b;
  55.   } ;
  56.   
  57.   union {
  58.     __IOM uint32_t SR;                          /*!< (@ 0x00000010) Status Register                                            */
  59.    
  60.     struct {
  61.       __IOM uint32_t UIF        : 1;            /*!< [0..0] Update interrupt flag                                              */
  62.       __IOM uint32_t CC1IF      : 1;            /*!< [1..1] Compare 1 interrupt flag                                           */
  63.       __IOM uint32_t CC2IF      : 1;            /*!< [2..2] Compare 2 interrupt flag                                           */
  64.       __IOM uint32_t CC3IF      : 1;            /*!< [3..3] Compare 3 interrupt flag                                           */
  65.       __IOM uint32_t CC4IF      : 1;            /*!< [4..4] Compare 4 interrupt flag                                           */
  66.             uint32_t            : 1;
  67.       __IOM uint32_t TIF        : 1;            /*!< [6..6] Trigger interrupt flag                                             */
  68.             uint32_t            : 2;
  69.       __IOM uint32_t CC1OF      : 1;            /*!< [9..9] Capture/Compare 1 overcapture flag                                 */
  70.       __IOM uint32_t CC2OF      : 1;            /*!< [10..10] Capture/Compare 2 overcapture flag                               */
  71.       __IOM uint32_t CC3OF      : 1;            /*!< [11..11] Capture/Compare 3 overcapture flag                               */
  72.       __IOM uint32_t CC4OF      : 1;            /*!< [12..12] Capture/Compare 4 overcapture flag                               */
  73.             uint32_t            : 19;
  74.     } SR_b;
  75.   } ;
  76.   
  77.   union {
  78.     __OM  uint32_t EGR;                         /*!< (@ 0x00000014) Event Generation Register                                  */
  79.    
  80.     struct {
  81.       __OM  uint32_t UG         : 1;            /*!< [0..0] Update generation                                                  */
  82.       __OM  uint32_t CC1G       : 1;            /*!< [1..1] Compare 1 generation                                               */
  83.       __OM  uint32_t CC2G       : 1;            /*!< [2..2] Compare 2 generation                                               */
  84.       __OM  uint32_t CC3G       : 1;            /*!< [3..3] Compare 3 generation                                               */
  85.       __OM  uint32_t CC4G       : 1;            /*!< [4..4] Compare 4 generation                                               */
  86.             uint32_t            : 1;
  87.       __OM  uint32_t TG         : 1;            /*!< [6..6] Trigger generation                                                 */
  88.             uint32_t            : 25;
  89.     } EGR_b;
  90.   } ;
  91.   
  92.   union {
  93.     __IOM uint32_t CCMR1;                       /*!< (@ 0x00000018) Compare Mode Register 1                                    */
  94.    
  95.     struct {
  96.       __IOM uint32_t CC1S       : 2;            /*!< [1..0] Capture/Compare 1 selection                                        */
  97.       __IOM uint32_t OC1FE      : 1;            /*!< [2..2] Output compare 1 fast enable                                       */
  98.       __IOM uint32_t OC1PE      : 1;            /*!< [3..3] Output compare 1 preload enable                                    */
  99.       __IOM uint32_t OC1M       : 3;            /*!< [6..4] Output compare 1 mode                                              */
  100.             uint32_t            : 1;
  101.       __IOM uint32_t CC2S       : 2;            /*!< [9..8] Capture/Compare 2 selection                                        */
  102.       __IOM uint32_t OC2FE      : 1;            /*!< [10..10] Output compare 2 fast enable                                     */
  103.       __IOM uint32_t OC2PE      : 1;            /*!< [11..11] Output compare 2 preload enable                                  */
  104.       __IOM uint32_t OC2M       : 3;            /*!< [14..12] Output compare 2 mode                                            */
  105.             uint32_t            : 17;
  106.     } CCMR1_b;
  107.   } ;
  108.   
  109.   union {
  110.     __IOM uint32_t CCMR2;                       /*!< (@ 0x0000001C) Compare Mode Register 2                                    */
  111.    
  112.     struct {
  113.       __IOM uint32_t CC3S       : 2;            /*!< [1..0] Capture/Compare 3 selection                                        */
  114.       __IOM uint32_t OC3FE      : 1;            /*!< [2..2] Output compare 3 fast enable                                       */
  115.       __IOM uint32_t OC3PE      : 1;            /*!< [3..3] Output compare 3 preload enable                                    */
  116.       __IOM uint32_t OC3M       : 3;            /*!< [6..4] Output compare 3 mode                                              */
  117.             uint32_t            : 1;
  118.       __IOM uint32_t CC4S       : 2;            /*!< [9..8] Capture/Compare 4 selection                                        */
  119.       __IOM uint32_t OC4FE      : 1;            /*!< [10..10] Output compare 4 fast enable                                     */
  120.       __IOM uint32_t OC4PE      : 1;            /*!< [11..11] Output compare 4 preload enable                                  */
  121.       __IOM uint32_t OC4M       : 3;            /*!< [14..12] Output compare 4 mode                                            */
  122.             uint32_t            : 17;
  123.     } CCMR2_b;
  124.   } ;
  125.   
  126.   union {
  127.     __IOM uint32_t CCER;                        /*!< (@ 0x00000020) Compare Enable Register                                    */
  128.    
  129.     struct {
  130.       __IOM uint32_t CC1E       : 1;            /*!< [0..0] Compare 1 output enable                                            */
  131.       __IOM uint32_t CC1P       : 1;            /*!< [1..1] Compare 1 output polarity                                          */
  132.             uint32_t            : 1;
  133.       __IOM uint32_t CC1NP      : 1;            /*!< [3..3] Compare 1 complementary output polarity                            */
  134.       __IOM uint32_t CC2E       : 1;            /*!< [4..4] Compare 2 output enable                                            */
  135.       __IOM uint32_t CC2P       : 1;            /*!< [5..5] Compare 2 output polarity                                          */
  136.             uint32_t            : 1;
  137.       __IOM uint32_t CC2NP      : 1;            /*!< [7..7] Compare 2 complementary output polarity                            */
  138.       __IOM uint32_t CC3E       : 1;            /*!< [8..8] Compare 3 output enable                                            */
  139.       __IOM uint32_t CC3P       : 1;            /*!< [9..9] Compare 3 output polarity                                          */
  140.             uint32_t            : 1;
  141.       __IOM uint32_t CC3NP      : 1;            /*!< [11..11] Compare 3 complementary output polarity                          */
  142.       __IOM uint32_t CC4E       : 1;            /*!< [12..12] Compare 4 output enable                                          */
  143.             uint32_t            : 2;
  144.       __IOM uint32_t CC4P       : 1;            /*!< [15..15] Compare 4 complementary output polarity                          */
  145.             uint32_t            : 16;
  146.     } CCER_b;
  147.   } ;
  148.   
  149.   union {
  150.     __IOM uint32_t CNT;                         /*!< (@ 0x00000024) Counter                                                    */
  151.    
  152.     struct {
  153.       __IOM uint32_t CNT        : 16;           /*!< [15..0] Counter value                                                     */
  154.             uint32_t            : 16;
  155.     } CNT_b;
  156.   } ;
  157.   
  158.   union {
  159.     __IOM uint32_t PSC;                         /*!< (@ 0x00000028) Prescaler                                                  */
  160.    
  161.     struct {
  162.       __IOM uint32_t PSC        : 16;           /*!< [15..0] Prescaler value                                                   */
  163.             uint32_t            : 16;
  164.     } PSC_b;
  165.   } ;
  166.   
  167.   union {
  168.     __IOM uint32_t ARR;                         /*!< (@ 0x0000002C) Auto Reload Register                                       */
  169.    
  170.     struct {
  171.       __IOM uint32_t ARR        : 16;           /*!< [15..0] Auto-reload value                                                 */
  172.             uint32_t            : 16;
  173.     } ARR_b;
  174.   } ;
  175.   __IM  uint32_t  RESERVED;
  176.   
  177.   union {
  178.     __IOM uint32_t CCR1;                        /*!< (@ 0x00000034) Compare Register 1                                         */
  179.    
  180.     struct {
  181.       __IOM uint32_t CCR1       : 16;           /*!< [15..0] Channel 1 compare value                                           */
  182.             uint32_t            : 16;
  183.     } CCR1_b;
  184.   } ;
  185.   
  186.   union {
  187.     __IOM uint32_t CCR2;                        /*!< (@ 0x00000038) Compare Register 2                                         */
  188.    
  189.     struct {
  190.       __IOM uint32_t CCR2       : 16;           /*!< [15..0] Channel 2 compare value                                           */
  191.             uint32_t            : 16;
  192.     } CCR2_b;
  193.   } ;
  194.   
  195.   union {
  196.     __IOM uint32_t CCR3;                        /*!< (@ 0x0000003C) Compare Register 3                                         */
  197.    
  198.     struct {
  199.       __IOM uint32_t CCR3       : 16;           /*!< [15..0] Channel 3 compare value                                           */
  200.             uint32_t            : 16;
  201.     } CCR3_b;
  202.   } ;
  203.   
  204.   union {
  205.     __IOM uint32_t CCR4;                        /*!< (@ 0x00000040) Compare Register 4                                         */
  206.    
  207.     struct {
  208.       __IOM uint32_t CCR4       : 16;           /*!< [15..0] Channel 4 compare value                                           */
  209.             uint32_t            : 16;
  210.     } CCR4_b;
  211.   } ;
  212.   __IM  uint32_t  RESERVED1[3];
  213.   
  214.   union {
  215.     __IOM uint32_t OR;                          /*!< (@ 0x00000050) Input Option Register                                      */
  216.    
  217.     struct {
  218.       __IOM uint32_t ETR_RMP    : 2;            /*!< [1..0] ETR multiplex                                                      */
  219.             uint32_t            : 30;
  220.     } OR_b;
  221.   } ;
  222. } TIM3_Type;                                    /*!< Size = 84 (0x54)                                                          */

我也是比较喜欢第三种生成方式,比较详细!!!

3.下载算法
下载算法可以让Keil MDK-Arm集成开发环境在线下载程序到芯片中,他的实现是通过将下载算法函数加载到SRAM中运行,通过SRAM将数据写入到芯片FLASH当中,具体的技术文档可以参考:https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/flashAlgorithm.html

我们可以在“C:\Keil_v5\ARM\Flash\_Template”中,或者在CMSIS中“C:\Users\xld0932\AppData\Local\Arm\Packs\ARM\CMSIS\5.9.0\Device\_Template_Flash”获取下载算法的模板工程,下载算法中提供了一些函数接口,有必要实现的,也有可选实现的:
6.png

我们完善必要实现的函数功能就可以了,在实现函数功能时,我们需要注意一下芯片看门狗,如果看门狗在打开的状态下,芯片烧录时间超过了喂狗时间,会导致芯片下载中断而失败,所以需要在下载算法中耗时的位置添加喂狗操作!最后就是通过SVD生成的头文件中的寄存器和宏定义,在FlashPrg.c文件中来实现函数功能,具体函数实现如下所示:
  1. #include "FlashOS.h"                   // FlashOS Structures
  2. #include <stdint.h>

  3. #define M8(adr)  (*((volatile unsigned char  *)(adr)))
  4. #define M16(adr) (*((volatile unsigned short *)(adr)))
  5. #define M32(adr) (*((volatile unsigned long  *)(adr)))

  6. /* following defines should be used for structure members */
  7. #define     __IM     volatile const    /*! Defines 'read only' structure member permissions */
  8. #define     __OM     volatile          /*! Defines 'write only' structure member permissions */
  9. #define     __IOM    volatile          /*! Defines 'read / write' structure member permissions */

  10. /* =========================================================================================================================== */
  11. /* ================                                           IWDG                                            ================ */
  12. /* =========================================================================================================================== */

  13. /**
  14.   * [url=home.php?mod=space&uid=247401]@brief[/url] IWDG Independent watchdog (IWDG)
  15.   */

  16. typedef struct                         /*!< (@ 0x40003000) IWDG Structure                                             */
  17. {
  18.     __OM  uint32_t  KR;                /*!< (@ 0x00000000) Key register                                               */
  19.     __IOM uint32_t  PR;                /*!< (@ 0x00000004) Prescaler register                                         */
  20.     __IOM uint32_t  RLR;               /*!< (@ 0x00000008) Reload register                                            */
  21.     __IM  uint32_t  SR;                /*!< (@ 0x0000000C) Status register                                            */
  22.     __IOM uint32_t  CR;                /*!< (@ 0x00000010) Control register                                           */
  23.     __IOM uint32_t  IGEN;              /*!< (@ 0x00000014) Interrupt generate register                                */
  24.     __IM  uint32_t  CNT;               /*!< (@ 0x00000018) Counter register                                           */
  25. } IWDG_Type;

  26. /* =========================================================================================================================== */
  27. /* ================                                           FLASH                                           ================ */
  28. /* =========================================================================================================================== */

  29. /**
  30.   * [url=home.php?mod=space&uid=247401]@brief[/url] Embedded Flash (FLASH)
  31.   */

  32. typedef struct                         /*!< (@ 0x40022000) FLASH Structure                                            */
  33. {
  34.     __IOM uint32_t  ACR;               /*!< (@ 0x00000000) Flash access control register                              */
  35.     __OM  uint32_t  KEYR;              /*!< (@ 0x00000004) Flash key register                                         */
  36.     __OM  uint32_t  OPTKEYR;           /*!< (@ 0x00000008) Flash OPTKEY register                                      */
  37.     __IOM uint32_t  SR;                /*!< (@ 0x0000000C) Flash status register                                      */
  38.     __IOM uint32_t  CR;                /*!< (@ 0x00000010) Flash control register                                     */
  39.     __OM  uint32_t  AR;                /*!< (@ 0x00000014) Flash address register                                     */
  40.     __IM  uint32_t  RESERVED;
  41.     __IM  uint32_t  OBR;               /*!< (@ 0x0000001C) Option byte register                                       */
  42.     __IM  uint32_t  WRPR;              /*!< (@ 0x00000020) Write protection register                                  */
  43. } FLASH_Type;

  44. #define IWDG_BASE                         0x40003000UL
  45. #define FLASH_BASE                        0x40022000UL

  46. #define IWDG                              ((IWDG_Type *)IWDG_BASE)
  47. #define FLASH                             ((FLASH_Type *)FLASH_BASE)

  48. /* =========================================================================================================================== */
  49. /* ================                                           IWDG                                            ================ */
  50. /* =========================================================================================================================== */

  51. /* ==========================================================  KR  =========================================================== */
  52. #define IWDG_KR_KEY_Pos                   (0UL)       /*!< KEY (Bit 0)                                           */
  53. #define IWDG_KR_KEY_Msk                   (0xffffUL)  /*!< KEY (Bitfield-Mask: 0xffff)                           */
  54. /* ==========================================================  PR  =========================================================== */
  55. #define IWDG_PR_PR_Pos                    (0UL)       /*!< PR (Bit 0)                                            */
  56. #define IWDG_PR_PR_Msk                    (0x7UL)     /*!< PR (Bitfield-Mask: 0x07)                              */
  57. /* ==========================================================  RLR  ========================================================== */
  58. #define IWDG_RLR_RL_Pos                   (0UL)       /*!< RL (Bit 0)                                            */
  59. #define IWDG_RLR_RL_Msk                   (0xfffUL)   /*!< RL (Bitfield-Mask: 0xfff)                             */
  60. /* ==========================================================  SR  =========================================================== */
  61. #define IWDG_SR_PVU_Pos                   (0UL)       /*!< PVU (Bit 0)                                           */
  62. #define IWDG_SR_PVU_Msk                   (0x1UL)     /*!< PVU (Bitfield-Mask: 0x01)                             */
  63. #define IWDG_SR_RVU_Pos                   (1UL)       /*!< RVU (Bit 1)                                           */
  64. #define IWDG_SR_RVU_Msk                   (0x2UL)     /*!< RVU (Bitfield-Mask: 0x01)                             */
  65. #define IWDG_SR_IVU_Pos                   (2UL)       /*!< IVU (Bit 2)                                           */
  66. #define IWDG_SR_IVU_Msk                   (0x4UL)     /*!< IVU (Bitfield-Mask: 0x01)                             */
  67. #define IWDG_SR_UPDATE_Pos                (3UL)       /*!< UPDATE (Bit 3)                                        */
  68. #define IWDG_SR_UPDATE_Msk                (0x8UL)     /*!< UPDATE (Bitfield-Mask: 0x01)                          */
  69. /* ==========================================================  CR  =========================================================== */
  70. #define IWDG_CR_IRQ_SEL_Pos               (0UL)       /*!< IRQ_SEL (Bit 0)                                       */
  71. #define IWDG_CR_IRQ_SEL_Msk               (0x1UL)     /*!< IRQ_SEL (Bitfield-Mask: 0x01)                         */
  72. #define IWDG_CR_IRQ_CLR_Pos               (1UL)       /*!< IRQ_CLR (Bit 1)                                       */
  73. #define IWDG_CR_IRQ_CLR_Msk               (0x2UL)     /*!< IRQ_CLR (Bitfield-Mask: 0x01)                         */
  74. /* =========================================================  IGEN  ========================================================== */
  75. #define IWDG_IGEN_IGEN_Pos                (0UL)       /*!< IGEN (Bit 0)                                          */
  76. #define IWDG_IGEN_IGEN_Msk                (0xfffUL)   /*!< IGEN (Bitfield-Mask: 0xfff)                           */
  77. /* ==========================================================  CNT  ========================================================== */
  78. #define IWDG_CNT_IWDG_PS_Pos              (0UL)       /*!< IWDG_PS (Bit 0)                                       */
  79. #define IWDG_CNT_IWDG_PS_Msk              (0xffUL)    /*!< IWDG_PS (Bitfield-Mask: 0xff)                         */
  80. #define IWDG_CNT_IWDG_CNT_Pos             (8UL)       /*!< IWDG_CNT (Bit 8)                                      */
  81. #define IWDG_CNT_IWDG_CNT_Msk             (0x7ff00UL) /*!< IWDG_CNT (Bitfield-Mask: 0x7ff)                       */

  82. /* =========================================================================================================================== */
  83. /* ================                                           FLASH                                           ================ */
  84. /* =========================================================================================================================== */

  85. /* ==========================================================  ACR  ========================================================== */
  86. #define FLASH_ACR_LATENCY_Pos             (0UL)          /*!< LATENCY (Bit 0)                                       */
  87. #define FLASH_ACR_LATENCY_Msk             (0x7UL)        /*!< LATENCY (Bitfield-Mask: 0x07)                         */
  88. #define FLASH_ACR_PRFTBE_Pos              (4UL)          /*!< PRFTBE (Bit 4)                                        */
  89. #define FLASH_ACR_PRFTBE_Msk              (0x10UL)       /*!< PRFTBE (Bitfield-Mask: 0x01)                          */
  90. /* =========================================================  KEYR  ========================================================== */
  91. #define FLASH_KEYR_FKEYR_Pos              (0UL)          /*!< FKEYR (Bit 0)                                         */
  92. #define FLASH_KEYR_FKEYR_Msk              (0xffffffffUL) /*!< FKEYR (Bitfield-Mask: 0xffffffff)                     */
  93. /* ========================================================  OPTKEYR  ======================================================== */
  94. #define FLASH_OPTKEYR_OPTKEYR_Pos         (0UL)          /*!< OPTKEYR (Bit 0)                                       */
  95. #define FLASH_OPTKEYR_OPTKEYR_Msk         (0xffffffffUL) /*!< OPTKEYR (Bitfield-Mask: 0xffffffff)                   */
  96. /* ==========================================================  SR  =========================================================== */
  97. #define FLASH_SR_BSY_Pos                  (0UL)          /*!< BSY (Bit 0)                                           */
  98. #define FLASH_SR_BSY_Msk                  (0x1UL)        /*!< BSY (Bitfield-Mask: 0x01)                             */
  99. #define FLASH_SR_PGERR_Pos                (2UL)          /*!< PGERR (Bit 2)                                         */
  100. #define FLASH_SR_PGERR_Msk                (0x4UL)        /*!< PGERR (Bitfield-Mask: 0x01)                           */
  101. #define FLASH_SR_WRPRTERR_Pos             (4UL)          /*!< WRPRTERR (Bit 4)                                      */
  102. #define FLASH_SR_WRPRTERR_Msk             (0x10UL)       /*!< WRPRTERR (Bitfield-Mask: 0x01)                        */
  103. #define FLASH_SR_EOP_Pos                  (5UL)          /*!< EOP (Bit 5)                                           */
  104. #define FLASH_SR_EOP_Msk                  (0x20UL)       /*!< EOP (Bitfield-Mask: 0x01)                             */
  105. /* ==========================================================  CR  =========================================================== */
  106. #define FLASH_CR_PG_Pos                   (0UL)          /*!< PG (Bit 0)                                            */
  107. #define FLASH_CR_PG_Msk                   (0x1UL)        /*!< PG (Bitfield-Mask: 0x01)                              */
  108. #define FLASH_CR_PER_Pos                  (1UL)          /*!< PER (Bit 1)                                           */
  109. #define FLASH_CR_PER_Msk                  (0x2UL)        /*!< PER (Bitfield-Mask: 0x01)                             */
  110. #define FLASH_CR_MER_Pos                  (2UL)          /*!< MER (Bit 2)                                           */
  111. #define FLASH_CR_MER_Msk                  (0x4UL)        /*!< MER (Bitfield-Mask: 0x01)                             */
  112. #define FLASH_CR_OPTPG_Pos                (4UL)          /*!< OPTPG (Bit 4)                                         */
  113. #define FLASH_CR_OPTPG_Msk                (0x10UL)       /*!< OPTPG (Bitfield-Mask: 0x01)                           */
  114. #define FLASH_CR_OPTER_Pos                (5UL)          /*!< OPTER (Bit 5)                                         */
  115. #define FLASH_CR_OPTER_Msk                (0x20UL)       /*!< OPTER (Bitfield-Mask: 0x01)                           */
  116. #define FLASH_CR_STRT_Pos                 (6UL)          /*!< STRT (Bit 6)                                          */
  117. #define FLASH_CR_STRT_Msk                 (0x40UL)       /*!< STRT (Bitfield-Mask: 0x01)                            */
  118. #define FLASH_CR_LOCK_Pos                 (7UL)          /*!< LOCK (Bit 7)                                          */
  119. #define FLASH_CR_LOCK_Msk                 (0x80UL)       /*!< LOCK (Bitfield-Mask: 0x01)                            */
  120. #define FLASH_CR_OPTWRE_Pos               (9UL)          /*!< OPTWRE (Bit 9)                                        */
  121. #define FLASH_CR_OPTWRE_Msk               (0x200UL)      /*!< OPTWRE (Bitfield-Mask: 0x01)                          */
  122. #define FLASH_CR_ERRIE_Pos                (10UL)         /*!< ERRIE (Bit 10)                                        */
  123. #define FLASH_CR_ERRIE_Msk                (0x400UL)      /*!< ERRIE (Bitfield-Mask: 0x01)                           */
  124. #define FLASH_CR_EOPIE_Pos                (12UL)         /*!< EOPIE (Bit 12)                                        */
  125. #define FLASH_CR_EOPIE_Msk                (0x1000UL)     /*!< EOPIE (Bitfield-Mask: 0x01)                           */
  126. /* ==========================================================  AR  =========================================================== */
  127. #define FLASH_AR_FAR_Pos                  (0UL)          /*!< FAR (Bit 0)                                           */
  128. #define FLASH_AR_FAR_Msk                  (0xffffffffUL) /*!< FAR (Bitfield-Mask: 0xffffffff)                       */
  129. /* ==========================================================  OBR  ========================================================== */
  130. #define FLASH_OBR_OPTERR_Pos              (0UL)          /*!< OPTERR (Bit 0)                                        */
  131. #define FLASH_OBR_OPTERR_Msk              (0x1UL)        /*!< OPTERR (Bitfield-Mask: 0x01)                          */
  132. #define FLASH_OBR_RDPRT_Pos               (1UL)          /*!< RDPRT (Bit 1)                                         */
  133. #define FLASH_OBR_RDPRT_Msk               (0x2UL)        /*!< RDPRT (Bitfield-Mask: 0x01)                           */
  134. #define FLASH_OBR_WDG_SW_Pos              (2UL)          /*!< WDG_SW (Bit 2)                                        */
  135. #define FLASH_OBR_WDG_SW_Msk              (0x4UL)        /*!< WDG_SW (Bitfield-Mask: 0x01)                          */
  136. #define FLASH_OBR_nRST_STOP_Pos           (3UL)          /*!< nRST_STOP (Bit 3)                                     */
  137. #define FLASH_OBR_nRST_STOP_Msk           (0x8UL)        /*!< nRST_STOP (Bitfield-Mask: 0x01)                       */
  138. #define FLASH_OBR_Data0_Pos               (10UL)         /*!< Data0 (Bit 10)                                        */
  139. #define FLASH_OBR_Data0_Msk               (0x3fc00UL)    /*!< Data0 (Bitfield-Mask: 0xff)                           */
  140. #define FLASH_OBR_Data1_Pos               (18UL)         /*!< Data1 (Bit 18)                                        */
  141. #define FLASH_OBR_Data1_Msk               (0xfc0000UL)   /*!< Data1 (Bitfield-Mask: 0x3f)                           */
  142. /* =========================================================  WRPR  ========================================================== */
  143. #define FLASH_WRPR_WRP_Pos                (0UL)          /*!< WRP (Bit 0)                                           */
  144. #define FLASH_WRPR_WRP_Msk                (0xfUL)        /*!< WRP (Bitfield-Mask: 0x0f)                             */

  145. /*
  146.    Mandatory Flash Programming Functions (Called by FlashOS):
  147.                 int Init        (unsigned long adr,   // Initialize Flash
  148.                                  unsigned long clk,
  149.                                  unsigned long fnc);
  150.                 int UnInit      (unsigned long fnc);  // De-initialize Flash
  151.                 int EraseSector (unsigned long adr);  // Erase Sector Function
  152.                 int ProgramPage (unsigned long adr,   // Program Page Function
  153.                                  unsigned long sz,
  154.                                  unsigned char *buf);

  155.    Optional  Flash Programming Functions (Called by FlashOS):
  156.                 int BlankCheck  (unsigned long adr,   // Blank Check
  157.                                  unsigned long sz,
  158.                                  unsigned char pat);
  159.                 int EraseChip   (void);               // Erase complete Device
  160.       unsigned long Verify      (unsigned long adr,   // Verify Function
  161.                                  unsigned long sz,
  162.                                  unsigned char *buf);

  163.        - BlanckCheck  is necessary if Flash space is not mapped into CPU memory space
  164.        - Verify       is necessary if Flash space is not mapped into CPU memory space
  165.        - if EraseChip is not provided than EraseSector for all sectors is called
  166. */

  167. /*
  168. *  Initialize Flash Programming Functions
  169. *    Parameter:      adr:  Device Base Address
  170. *                    clk:  Clock Frequency (Hz)
  171. *                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
  172. *    Return Value:   0 - OK,  1 - Failed
  173. */
  174. int Init(unsigned long adr, unsigned long clk, unsigned long fnc)
  175. {
  176.     /* Add your Code */
  177.     FLASH->ACR  = 0x00000000;           // Zero Wait State

  178.     FLASH->KEYR = 0x45670123;           // Unlock Flash
  179.     FLASH->KEYR = 0xCDEF89AB;

  180.     // Test if IWDG is running (IWDG in HW mode)
  181.     if ((FLASH->OBR & FLASH_OBR_WDG_SW_Msk) == 0)
  182.     {
  183.         IWDG->KR  = 0x5555;            // Enable write access to IWDG_PR and IWDG_RLR
  184.         IWDG->PR  = 0x06;              // Set prescaler to 256
  185.         IWDG->RLR = 4095;              // Set reload value to 4095
  186.     }

  187.     return (0);                        // Finished without Errors
  188. }

  189. /*
  190. *  De-Initialize Flash Programming Functions
  191. *    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
  192. *    Return Value:   0 - OK,  1 - Failed
  193. */
  194. int UnInit(unsigned long fnc)
  195. {
  196.     /* Add your Code */
  197.     FLASH->CR |= FLASH_CR_LOCK_Msk;    // Lock Flash
  198.     return (0);                        // Finished without Errors
  199. }

  200. /*
  201. *  Erase complete Flash Memory
  202. *    Return Value:   0 - OK,  1 - Failed
  203. */
  204. int EraseChip(void)
  205. {
  206.     /* Add your Code */
  207.     FLASH->CR |= FLASH_CR_MER_Msk;     // Mass Erase Enable
  208.     FLASH->CR |= FLASH_CR_STRT_Msk;    // Start Erase

  209.     while (FLASH->SR & FLASH_SR_BSY_Msk)
  210.     {
  211.         IWDG->KR = 0xAAAA;             // Reload IWDG
  212.     }

  213.     FLASH->CR &= ~FLASH_CR_MER_Msk;    // Mass Erase Disable

  214.     return (0);                        // Finished without Errors
  215. }

  216. /*
  217. *  Erase Sector in Flash Memory
  218. *    Parameter:      adr:  Sector Address
  219. *    Return Value:   0 - OK,  1 - Failed
  220. */
  221. int EraseSector(unsigned long adr)
  222. {
  223.     /* Add your Code */
  224.     FLASH->CR |= FLASH_CR_PER_Msk;     // Page Erase Enable
  225.     FLASH->AR  = adr;                  // Page Address
  226.     FLASH->CR |= FLASH_CR_STRT_Msk;    // Start Erase

  227.     while (FLASH->SR & FLASH_SR_BSY_Msk)
  228.     {
  229.         IWDG->KR = 0xAAAA;             // Reload IWDG
  230.     }

  231.     FLASH->CR &= ~FLASH_CR_PER_Msk;    // Page Erase Disable

  232.     return (0);                        // Finished without Errors
  233. }

  234. /*
  235. *  Program Page in Flash Memory
  236. *    Parameter:      adr:  Page Start Address
  237. *                    sz:   Page Size
  238. *                    buf:  Page Data
  239. *    Return Value:   0 - OK,  1 - Failed
  240. */
  241. int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
  242. {
  243.     /* Add your Code */
  244.     sz = (sz + 1) & ~1;                         // Adjust size for Half Words

  245.     while (sz)
  246.     {
  247.         FLASH->CR |= FLASH_CR_PG_Msk;           // Programming Enable

  248.         M16(adr) = *((unsigned short *)buf);    // Program Half Word

  249.         while (FLASH->SR & FLASH_SR_BSY_Msk)
  250.         {
  251.             IWDG->KR = 0xAAAA;                  // Reload IWDG
  252.         }

  253.         FLASH->CR &= ~FLASH_CR_PG_Msk;          // Programming Disable

  254.         if (FLASH->SR & (FLASH_SR_PGERR_Msk | FLASH_SR_WRPRTERR_Msk))
  255.         {
  256.             FLASH->SR |= FLASH_SR_PGERR_Msk | FLASH_SR_WRPRTERR_Msk;
  257.             return (1);                         // Failed
  258.         }

  259.         // Go to next Half Word
  260.         adr += 2;
  261.         buf += 2;
  262.         sz  -= 2;
  263.     }

  264.     return (0);                                 // Finished without Errors
  265. }

此外就是下载算法的配置,在FlashDevice中,如下所示:
  1. #include "FlashOS.h"        // FlashOS Structures


  2. struct FlashDevice const FlashDevice  =  {
  3.    FLASH_DRV_VERS,             // Driver Version, do not modify!
  4.    "MM32G0001 16kB Flash",     // Device Name
  5.    ONCHIP,                     // Device Type
  6.    0x08000000,                 // Device Start Address
  7.    0x00004000,                 // Device Size in Bytes (16kB)
  8.    1024,                       // Programming Page Size
  9.    0,                          // Reserved, must be 0
  10.    0xFF,                       // Initial Content of Erased Memory
  11.    100,                        // Program Page Timeout 100 mSec
  12.    3000,                       // Erase Sector Timeout 3000 mSec

  13. // Specify Size and Address of Sectors
  14.    0x000400, 0x000000,         // Sector Size  1kB (n Sectors)
  15.    SECTOR_END
  16. };

其中定义了Device Name,这个是在Keil中选择下载算法时所显示的,其实需要配置的就是Device Start Address,这个是MCU Flash的起始地址;Device Size是MCU FLASH的容量,Programming Page Size定义了MCU FLASH写入Page的大小,最后就是Specify Size and Address of Sectors的设置。
8.png

在完成上述函数和配置修改之后,需要在工程的配置中,Output选项卡中,修改一下生成下载算法的文件名,如下所示:
7.png

最后编译整个工程,生成FLM下载算法文件。

4.Keil Pack
Keil Pack是帮助我们让Keil MDK-Arm集成开发环境认识我们MCU的一个支持包,这支持包里包含了SVD、下载算法、以及一个pdsc描述文件,这是最基础的Pack包组成部分,可以参考如下链接:https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/index.html熟悉更多的Pack包配置

在pdsc文件中,除了对MCU一些描述外,对指定SVD文件、FLM下载算法也做了描述,另外可以根据芯片数据手册中提供的Part number芯片型号,添加到pdsc描述中,这样我们在创建Keil工程的时候就可以选择相应的芯片型号了。

对于Keil Pack的pdsc文件,我们也是采用了自动生成的方式,一个数据源,二是Python自动化生成;

4.1.构建pdsc数据源
pdsc的数据源一方面是cpu.yml文件中提取的,包含了处理器、调试SVD、下载算法和整体芯片描述部分,另一文件就是参考芯片数据手册中的2.1订购表,在device.yml中添加芯片型号和属性,如下所示:
cpu.yml:
  1. Processor :
  2.   Dcore               : 'Cortex-M0'
  3.   DcoreVersion        : 'r0p0'
  4.   Dfpu                : '0'
  5.   Dmpu                : '0'
  6.   Dendian             : 'Little-endian'
  7.   Dclock              : '48000000'

  8. Debug :
  9.   SVD_PATH            : 'SVD/MM32G0001.svd'

  10. Algorithm :
  11.   FLM_PATH            : 'FLM/MM32G0001_16K.FLM'
  12.   ROM_BASE            : '0x08000000'
  13.   ROM_SIZE            : '0x4000'

  14. description :
  15.   description         : 'The MM32G0001 microcontrollers are based on Arm Cortex-M0 core. These devices
  16. have a maximum clocked frequency of 48MHz, built-in 16KB Flash storage, and contain
  17. an extensive range of peripherals and I/O ports. These devices contain 1x12-bit ADC,
  18. 1x16-bit advanced timer, 1x16-bit general purpose timer and 1x16-bit basic timer, as
  19. well as communication interfaces including 2xUSART, 1xSPI and 1xI2C.
  20. The operating voltage of this product series is 2.0V to 5.5V, and the operating temperature
  21. range (ambient temperature) includes -40°C to 85°C industrial tier and -40°C to 105°C
  22. extended industrial tier. Multiple sets of power-saving modes make the design of low-power
  23. applications possible.'

device.yml:
  1. MM32G0001A6T :
  2.   RAM_BASE  : '0x20000000'
  3.   RAM_SIZE  : '0x800'
  4.   ROM_BASE  : '0x08000000'
  5.   ROM_SIZE  : '0x4000'

  6. MM32G0001A6T1 :
  7.   RAM_BASE  : '0x20000000'
  8.   RAM_SIZE  : '0x800'
  9.   ROM_BASE  : '0x08000000'
  10.   ROM_SIZE  : '0x4000'

  11. MM32G0001A1T :
  12.   RAM_BASE  : '0x20000000'
  13.   RAM_SIZE  : '0x800'
  14.   ROM_BASE  : '0x08000000'
  15.   ROM_SIZE  : '0x4000'

  16. MM32G0001A1N :
  17.   RAM_BASE  : '0x20000000'
  18.   RAM_SIZE  : '0x800'
  19.   ROM_BASE  : '0x08000000'
  20.   ROM_SIZE  : '0x4000'

4.2.Python自动化生成pdsc文件
pdsc也是通过XML语言来描述的,分了不同的层级,我们通过对数据源的提取完成pdsc文件的创建,具体功能函数如下所示:
  1. def package_device(chip, pdsc_file):
  2.     with open(fr'D:\PyCharm\{chip}\device.yml', mode='r') as device_file:
  3.         device_data = yaml.safe_load(device_file)
  4.         if device_data is None:
  5.             print('device.yml is empty!')
  6.         else:
  7.             for device in device_data:
  8.                 pdsc_file.write(f'\t\t\t\t<device Dname="{device}">\n')
  9.                 pdsc_file.write(f'\t\t\t\t\t<memory id="IRAM1" '
  10.                                 f'start="{device_data[device]['RAM_BASE']}" '
  11.                                 f'size="{device_data[device]['RAM_SIZE']}" '
  12.                                 f'default="1" init="0"/>\n')
  13.                 pdsc_file.write(f'\t\t\t\t\t<memory id="IROM1" '
  14.                                 f'start="{device_data[device]['ROM_BASE']}" '
  15.                                 f'size="{device_data[device]['ROM_SIZE']}" '
  16.                                 f'default="1" startup="1"/>\n')
  17.                 pdsc_file.write(f'\t\t\t\t</device>\n')



  18. def package_family(chip, pdsc_file):
  19.     with open(fr'D:\PyCharm\{chip}\cpu.yml', mode='r') as cpu_file:
  20.         cpu_data = yaml.safe_load(cpu_file)
  21.         if cpu_data is None:
  22.             print('cpu.yml is empty!')
  23.         else:
  24.             pdsc_file.write(f'\t\t<family Dfamily="{chip} Series" Dvendor="MindMotion:132">\n')
  25.             pdsc_file.write(f'\t\t\t<processor Dcore="{cpu_data['Processor']['Dcore']}" '
  26.                             f'DcoreVersion="{cpu_data['Processor']['DcoreVersion']}"\n')
  27.             pdsc_file.write(f'\t\t\t           Dfpu="{cpu_data['Processor']['Dfpu']}" '
  28.                             f'Dmpu="{cpu_data['Processor']['Dmpu']}" '
  29.                             f'Dclock="{cpu_data['Processor']['Dclock']}"/>\n')
  30.             pdsc_file.write(f'\t\t\t<debug     svd="{cpu_data['Debug']['SVD_PATH']}"/>\n')
  31.             pdsc_file.write(f'\t\t\t<algorithm name="{cpu_data['Algorithm']['FLM_PATH']}" '
  32.                             f'start="{cpu_data['Algorithm']['ROM_BASE']}" '
  33.                             f'size="{cpu_data['Algorithm']['ROM_SIZE']}" default="1"/>\n')
  34.             pdsc_file.write(f'\t\t\t<description>\n')
  35.             pdsc_file.write(f'\t\t\t\t{cpu_data['description']['description']}\n')
  36.             pdsc_file.write(f'\t\t\t</description>\n')
  37.             pdsc_file.write(f'\t\t\t<subFamily DsubFamily="{chip}">\n')
  38.             package_device(chip, pdsc_file)
  39.             pdsc_file.write(f'\t\t\t</subFamily>\n')
  40.             pdsc_file.write(f'\t\t</family>\n')


  41. def package_devices(chip, pdsc_file):
  42.     pdsc_file.write(f'\t<devices>\n')
  43.     package_family(chip, pdsc_file)
  44.     pdsc_file.write(f'\t</devices>\n')


  45. def package_generate(chip, version):
  46.     if not os.path.exists(fr'D:\PyCharm\{chip}\device.yml'):
  47.         with open(fr'D:\PyCharm\{chip}\device.yml', mode='w') as device_file:
  48.             print('create device.yml')
  49.         device_file.close()

  50.     pdsc_path = fr'MindMotion.{chip}_DFP.{version}'
  51.     pdsc_name = fr'MindMotion.{chip}_DFP.{version}'

  52.     if not os.path.exists(fr'D:\PyCharm\{chip}\{pdsc_path}'):
  53.         os.mkdir(fr'D:\PyCharm\{chip}\{pdsc_path}')

  54.     if not os.path.exists(fr'D:\PyCharm\{chip}\{pdsc_path}\FLM'):
  55.         os.mkdir(fr'D:\PyCharm\{chip}\{pdsc_path}\FLM')

  56.     if not os.path.exists(fr'D:\PyCharm\{chip}\{pdsc_path}\SVD'):
  57.         os.mkdir(fr'D:\PyCharm\{chip}\{pdsc_path}\SVD')

  58.     with (open(fr'D:\PyCharm\{chip}\{pdsc_path}\{pdsc_name}.pdsc', mode='w') as pdsc_file):
  59.         pdsc_file.write('<?xml version="1.0" encoding="UTF-8"?>\n')
  60.         pdsc_file.write('<package schemaVersion="1.7.7" '
  61.                         'xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" '
  62.                         'xs:noNamespaceSchemaLocation="PACK.xsd">\n')
  63.         pdsc_file.write(f'\t<vendor>MindMotion</vendor>\n')
  64.         pdsc_file.write(f'\t<name>{chip}_DFP</name>\n')
  65.         pdsc_file.write(f'\t<description>MindMotion {chip} Series Keil Pack</description>\n')
  66.         pdsc_file.write(f'\t<url>https://www.mindmotion.com.cn/</url>\n')
  67.         pdsc_file.write(f'\t<releases>\n')
  68.         pdsc_file.write(f'\t\t<release version="{version}" date="{datetime.datetime.now().date()}">\n')
  69.         pdsc_file.write(f'\t\t</release>\n')
  70.         pdsc_file.write(f'\t</releases>\n')
  71.         package_devices(chip, pdsc_file)
  72.         pdsc_file.write(f'</package>\n')
  73.         pdsc_file.close()

4.3.生成pdsc文件
9.png

4.4.Keil Pack打包安装
在Python自动生成的目录结构中MindMotion.MM32G0001_DFP.0.0.1,我们将之前生成的SVD文件和FLM下载算法,添加到这个文件夹相应的目录下,然后将MindMotion.MM32G0001_DFP.0.0.1文件夹进行压缩:MindMotion.MM32G0001_DFP.0.0.1.zip,然后将zip后缀名修改为pack,就可以啦……然后我们双击这个Keil Pack支持包进行安装:
10.png 11.png

5.模板工程
一个工程的模板最主要的芯片头文件,我们已经通过SVD自动化生成了,接下来就是启动文件了;在CMSIS规范中“C:\Users\xld0932\AppData\Local\Arm\Packs\ARM\CMSIS\5.9.0\Device”包含了启动文件的示例范本,我们结合MM32G0001,来制作模板工程。因为MM32G0001芯片是基于Cortex-M0内核的,所以我们Copy刚刚目录下的ARM\ARMCM0中的所有文件夹及文件,其中Include文件夹中的ARMCM0.h就是芯片的头文件,我们使用刚刚生成的MM32G0001.h进行替换,然后将其它所有出现ARMCM0替换成MM32G0001。

接下来,我们基于官方的Mini-G0001开发板,来创建一个基础工程:
12.png

这边就是pdsc文件中描述的芯片型号和说明啦^^

因为我们本篇使用的是Keil MDK-Arm集成开发环境,在Source文件夹下包含了ARM、GCC、IAR这3个集成开发环境的启动文件,我们当前只操作ARM目录下的启动文件.s,在这个文件中,我们需要依据芯片用户手册中中断的描述,来完善中断向量表;需要将Source目录下的system_mm32g0001.c中完善System_Init函数,这个函数主要是实现系统时钟配置,这个我们可以后面再配置,当前可以使用芯片默认的时钟嘛……具体如下所示:
startup_mm32g0001.s
  1. ;/**************************************************************************//**
  2. ; * [url=home.php?mod=space&uid=288409]@file[/url]     startup_mm32g0001.s
  3. ; * [url=home.php?mod=space&uid=247401]@brief[/url]    CMSIS Core Device Startup File for
  4. ; *           MM32G0001 Device
  5. ; * [url=home.php?mod=space&uid=895143]@version[/url]  V1.0.1
  6. ; * [url=home.php?mod=space&uid=212281]@date[/url]     23. July 2019
  7. ; ******************************************************************************/
  8. ;/*
  9. ; * Copyright (c) 2009-2019 Arm Limited. All rights reserved.
  10. ; *
  11. ; * SPDX-License-Identifier: Apache-2.0
  12. ; *
  13. ; * Licensed under the Apache License, Version 2.0 (the License); you may
  14. ; * not use this file except in compliance with the License.
  15. ; * You may obtain a copy of the License at
  16. ; *
  17. ; * www.apache.org/licenses/LICENSE-2.0
  18. ; *
  19. ; * Unless required by applicable law or agreed to in writing, software
  20. ; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  21. ; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. ; * See the License for the specific language governing permissions and
  23. ; * limitations under the License.
  24. ; */

  25. ;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------


  26. ;<h> Stack Configuration
  27. ;  <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
  28. ;</h>

  29. Stack_Size      EQU      0x00000400

  30.                 AREA     STACK, NOINIT, READWRITE, ALIGN=3
  31. __stack_limit
  32. Stack_Mem       SPACE    Stack_Size
  33. __initial_sp


  34. ;<h> Heap Configuration
  35. ;  <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
  36. ;</h>

  37. Heap_Size       EQU      0x00000000

  38.                 IF       Heap_Size != 0                      ; Heap is provided
  39.                 AREA     HEAP, NOINIT, READWRITE, ALIGN=3
  40. __heap_base
  41. Heap_Mem        SPACE    Heap_Size
  42. __heap_limit
  43.                 ENDIF


  44.                 PRESERVE8
  45.                 THUMB


  46. ; Vector Table Mapped to Address 0 at Reset

  47.                 AREA     RESET, DATA, READONLY
  48.                 EXPORT   __Vectors
  49.                 EXPORT   __Vectors_End
  50.                 EXPORT   __Vectors_Size

  51. __Vectors       DCD      __initial_sp                        ;     Top of Stack
  52.                 DCD      Reset_Handler                       ;     Reset Handler
  53.                 DCD      NMI_Handler                         ; -14 NMI Handler
  54.                 DCD      HardFault_Handler                   ; -13 Hard Fault Handler
  55.                 DCD      0                                   ;     Reserved
  56.                 DCD      0                                   ;     Reserved
  57.                 DCD      0                                   ;     Reserved
  58.                 DCD      0                                   ;     Reserved
  59.                 DCD      0                                   ;     Reserved
  60.                 DCD      0                                   ;     Reserved
  61.                 DCD      0                                   ;     Reserved
  62.                 DCD      SVC_Handler                         ;  -5 SVCall Handler
  63.                 DCD      0                                   ;     Reserved
  64.                 DCD      0                                   ;     Reserved
  65.                 DCD      PendSV_Handler                      ;  -2 PendSV Handler
  66.                 DCD      SysTick_Handler                     ;  -1 SysTick Handler

  67.                 ; Interrupts
  68.                 DCD      IWDG_Handler                        ;0  IWDG Interrupt
  69.                 DCD      PVD_Handler                         ;1  PVD Interrupt
  70.                 DCD      0                                   ;2  Reserved
  71.                 DCD      FLASH_Handler                       ;3  Flash Global Interrupt
  72.                 DCD      RCC_Handler                         ;4  RCC Global Interrupt
  73.                 DCD      EXTI0_1_Handler                     ;5  EXTI Line[1:0] Interrupt
  74.                 DCD      EXTI2_3_Handler                     ;6  EXTI Line[3:2] Interrupt
  75.                 DCD      EXTI4_15_Handler                    ;7  EXTI Line[15:4] Interrupt
  76.                 DCD      0                                   ;8  Reserved
  77.                 DCD      0                                   ;9  Reserved
  78.                 DCD      0                                   ;10 Reserved
  79.                 DCD      0                                   ;11 Reserved
  80.                 DCD      ADC1_Handler                        ;12 ADC Global Interrupt
  81.                 DCD      TIM1_BRK_UP_TRG_COM_Handler         ;13 TIM1 Break Update Trigger COM Interrupt
  82.                 DCD      TIM1_CC_Handler                     ;14 TIM1 Capture Compare Interrupt
  83.                 DCD      0                                   ;15 Reserved
  84.                 DCD      TIM3_Handler                        ;16 TIM3 Global Interrupt
  85.                 DCD      0                                   ;17 Reserved
  86.                 DCD      0                                   ;18 Reserved
  87.                 DCD      TIM14_Handler                       ;19 TIM14 Global Interrupt
  88.                 DCD      0                                   ;20 Reserved
  89.                 DCD      0                                   ;21 Reserved
  90.                 DCD      0                                   ;22 Reserved
  91.                 DCD      I2C1_Handler                        ;23 I2C1 Global Interrupt
  92.                 DCD      0                                   ;24 Reserved
  93.                 DCD      SPI1_Handler                        ;25 SPI1 Global Interrupt
  94.                 DCD      0                                   ;26 Reserved
  95.                 DCD      USART1_Handler                      ;27 USART1 Global Interrupt
  96.                 DCD      USART2_Handler                      ;28 USART2 Global Interrupt
  97.                 DCD      0                                   ;29 Reserved
  98.                 DCD      0                                   ;30 Reserved
  99.                 DCD      0                                   ;31 Reserved

  100. __Vectors_End
  101. __Vectors_Size  EQU      __Vectors_End - __Vectors


  102.                 AREA     |.text|, CODE, READONLY

  103. ; Reset Handler

  104. Reset_Handler   PROC
  105.                 EXPORT   Reset_Handler             [WEAK]
  106.                 IMPORT   SystemInit
  107.                 IMPORT   __main

  108.                 LDR      R0, =SystemInit
  109.                 BLX      R0
  110.                 LDR      R0, =__main
  111.                 BX       R0
  112.                 ENDP

  113. ; The default macro is not used for HardFault_Handler
  114. ; because this results in a poor debug illusion.
  115. HardFault_Handler PROC
  116.                 EXPORT   HardFault_Handler         [WEAK]
  117.                 B        .
  118.                 ENDP

  119. ; Macro to define default exception/interrupt handlers.
  120. ; Default handler are weak symbols with an endless loop.
  121. ; They can be overwritten by real handlers.
  122.                 MACRO
  123.                 Set_Default_Handler  $Handler_Name
  124. $Handler_Name   PROC
  125.                 EXPORT   $Handler_Name             [WEAK]
  126.                 B        .
  127.                 ENDP
  128.                 MEND


  129. ; Default exception/interrupt handler

  130.                 Set_Default_Handler  NMI_Handler
  131.                 Set_Default_Handler  SVC_Handler
  132.                 Set_Default_Handler  PendSV_Handler
  133.                 Set_Default_Handler  SysTick_Handler

  134.                 Set_Default_Handler  IWDG_Handler
  135.                 Set_Default_Handler  PVD_Handler
  136.                 Set_Default_Handler  FLASH_Handler
  137.                 Set_Default_Handler  RCC_Handler
  138.                 Set_Default_Handler  EXTI0_1_Handler
  139.                 Set_Default_Handler  EXTI2_3_Handler
  140.                 Set_Default_Handler  EXTI4_15_Handler
  141.                 Set_Default_Handler  ADC1_Handler
  142.                 Set_Default_Handler  TIM1_BRK_UP_TRG_COM_Handler
  143.                 Set_Default_Handler  TIM1_CC_Handler
  144.                 Set_Default_Handler  TIM3_Handler
  145.                 Set_Default_Handler  TIM14_Handler
  146.                 Set_Default_Handler  I2C1_Handler
  147.                 Set_Default_Handler  SPI1_Handler
  148.                 Set_Default_Handler  USART1_Handler
  149.                 Set_Default_Handler  USART2_Handler


  150.                 ALIGN


  151. ; User setup Stack & Heap

  152.                 IF       :LNOT::DEF:__MICROLIB
  153.                 IMPORT   __use_two_region_memory
  154.                 ENDIF

  155.                 EXPORT   __stack_limit
  156.                 EXPORT   __initial_sp
  157.                 IF       Heap_Size != 0                      ; Heap is provided
  158.                 EXPORT   __heap_base
  159.                 EXPORT   __heap_limit
  160.                 ENDIF

  161.                 END

6.让LED灯闪烁
  1. int main(void)
  2. {
  3.     uint32_t i = 0;

  4.     /* PA15_LED1 */
  5.     RCC->AHBENR_b.mGPIOA = 1;

  6.     GPIOA->CRH_b.MODE15  = 1;
  7.     GPIOA->CRH_b.CNF15   = 0;

  8.     GPIOA->BSRR_b.BS15   = 1;

  9.     while(1)
  10.     {
  11.         GPIOA->BRR_b.BR15  = 1;

  12.         for (i = 0; i < 1000000; i++)
  13.         {
  14.             __NOP();
  15.         }

  16.         GPIOA->BSRR_b.BS15 = 1;

  17.         for (i = 0; i < 1000000; i++)
  18.         {
  19.             __NOP();
  20.         }
  21.     }
  22. }

程序编译无误后,有过Keil直接下载程序到开发板,通过观察Mini-G0001开发板的LED1,当前已经在间隔闪烁了!
13.png

7.附件
自定义MM32G0001 Keil Pack支持包: MindMotion.MM32G0001_DFP.0.0.1.pack.zip (22.45 KB, 下载次数: 9)
SVD生成的3种不同方式的头文件: MM32G0001-Header.zip (81.51 KB, 下载次数: 10)
MM32G0001数据源: MM32G0001数据源.zip (555.67 KB, 下载次数: 14)
Python自动化生成工具源代码: Python.zip (2.83 KB, 下载次数: 10)
下载算法工程源文件: 下载算法.zip (60.35 KB, 下载次数: 10)
工程模板及LED闪烁工程源代码: Project.zip (476.98 KB, 下载次数: 19)
  

打赏榜单

21小跑堂 打赏了 150.00 元 2024-03-07
理由:恭喜通过原创审核!期待您更多的原创作品~

评论

超级瞎折腾(手动狗头),详细介绍基于keil的从最开始一步步部署MM32开发环境 ,看起来感觉实在没必要但是却很有必要的一件事。在绝大多数工程师都在使用却不去开发的地方做详细探究。非常棒。  发表于 2024-3-7 13:59
www5911839 发表于 2024-3-6 18:32 | 显示全部楼层
大佬,太强了
怀揣少年梦 发表于 2024-3-8 08:54 | 显示全部楼层
牛啊,大佬
AProgrammer 发表于 2024-3-11 09:24 | 显示全部楼层
牛啊,大佬+1
[鑫森淼焱垚] 发表于 2024-4-16 19:54 | 显示全部楼层
牛啊,学习了
26823439952 发表于 2025-7-13 11:28 | 显示全部楼层
牛啊,学习了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:King.Xu

77

主题

3023

帖子

38

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