野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3070|回复: 1

瑞萨RA6M5之跑马灯

[复制链接]
发表于 2022-11-20 14:28:36 | 显示全部楼层 |阅读模式
      拿到启明6M5开发板,第一感觉比较精简,没有想象中那么大,但外部资源依旧很丰富,今天来开箱点个灯试试。
一、硬件实物


封装盒.png
尺寸大小.png
       如上图所示,长宽与6.5英寸手机相比略有偏差。这块板子有两个Type-C接口可做为供电接口,MCU为瑞萨的R7FA6M5BH3CFC。关于瑞萨产品的命名规则如下:
瑞萨产品命名规则.png
二、获取必备软件包
      开发之前,我们需要准备必要的开发工具,这里我们可以前往瑞萨的官网获取到。
      获取灵活配置软件包(FSP)的最新版V4_1_0,当然需要注册好瑞萨网站个人账户才能顺利下载。
FSP灵活配置软件包.png
      获取瑞萨官方提供的最新“setup_fsp_v4_1_0_e2s_v2022-10.exe”与“Renesas.RA_DFP.4.1.0.pack”可以通过访问https://github.com/renesas/fsp/releases获取到的。
fsp在github上的网址.png
资源链接.png
      如果我们不习惯使用官方提供的“e2 studio”,灵活配置工具FSP支持导出IAR、Keil工程,官方也提供了参考培训视频,使用方便快捷。
RA Smart Configurator.png
三、搭建开发环境
       安装下载后的必备软件工具,这里需注意的是,在安装“e2 studio”或“rasc”时,win10系统需要有"Microsoft Visual C++ 2015-2022"环境,如果没有则会安装失败,这里提供一下安装"Microsoft Visual C++ 2015-2022"的64位安装包。

VC_redist.x64.zip (24.05 MB, 下载次数: 3)
         傻瓜式安装完“e2 studio”与“rasc”后,还需要安装keil支持包“Renesas.RA_DFP.4.1.0.pack”。
安装Keil支持包.png
四、构建工程
      这里我们使用“rasc”工具,也就是“FSP Smart Configurator”来快速配置基于MDK的工程。双击打开“\fsp_v4_1_0_rasc\eclipse”目录下的“rasc.exe”,选择好对应的芯片型号,并勾选将要导出工程适用的IDE类型。
选CPU型号.png
选择对应的IDE.png
       接着一路默认选择即可,即所配置的工程“No-TrustZone”,不跑实时系统。
选No-TrustZone工程.png
选择不跑RTOS系统.png
       接着找到“Clocks”标签栏,将P212、P213管脚设置成外部时钟接口,其默认分频参数即可,即PLL 200MHz。
设置时钟分频.png
    由野火官方提供的SDK中,基于启明RA6M5板子的原理图“ebf410069_sch”有关于LED的管脚分布介绍。
ebf410069_sch.pdf (288.04 KB, 下载次数: 1)
LED原理图.png
       由上图可知,点亮LED1、LED2、LED3需要将P400、P403、P404输出低,因此选中对应管脚,配置成P400、P403、P404,并设置默认为输出高电平。
设置LED灯的管脚.png
       点击工具上“Generate Project Content”图标,即在“rasc”软件启动初始时设置的保存路径下生成了Keil工程。
生成代码工程.png
         接着使用Keil5打开工程,直接进行全编译,结果弹出如下界面,输入“0”,回车即可。
编译弹出对话框.png
         我们需要定义端口和引脚号的枚举类型, 用来表示某个要操控的某个管脚,这里将端口和管脚号分开出来单独定义。
在r_ioport.c源文件中添加部分代码
  1. /* 读引脚电平*/
  2. uint32_t IOPORT_PinRead(IO_Port_t port, IO_Pin_t pin)
  3. {
  4.         /*Read pin level.*/
  5.         return R_PFS->PORT[port >> 8].PIN[pin].PmnPFS_b.PIDR;
  6. }
  7. /* 写引脚电平*/
  8. void IOPORT_PinWrite(IO_Port_t port, IO_Pin_t pin, IO_Level_t level)
  9. {
  10.         uint32_t pfs_bits = R_PFS->PORT[port >> 8].PIN[pin].PmnPFS; //读寄存器PmnPFS
  11.         pfs_bits &= ~(uint32_t)0x1; //清零PODR 位
  12.         R_PFS->PORT[port >> 8].PIN[pin].PmnPFS = (pfs_bits | level);
  13. }
  14. /* 翻转引脚电平*/
  15. void IOPORT_PinToggle(IO_Port_t port, IO_Pin_t pin)
  16. {
  17.         uint32_t pfs_bits = R_PFS->PORT[port >> 8].PIN[pin].PmnPFS; //读寄存器PmnPFS
  18.         pfs_bits ^= (uint32_t)0x1; //取反PODR 位
  19.         R_PFS->PORT[port >> 8].PIN[pin].PmnPFS = pfs_bits;
  20. }
  21. /* 引脚访问使能*/
  22. void IOPORT_PinAccessEnable(void)
  23. {
  24.         R_PMISC->PWPR = 0; ///< Clear BOWI bit - writing to PFSWE bit enabled
  25.         R_PMISC->PWPR = 1U << 6U; ///< Set PFSWE bit - writing to PFS register enabled
  26. }
  27. /* 引脚访问禁止*/
  28. void IOPORT_PinAccessDisable(void)
  29. {
  30.         R_PMISC->PWPR = 0; ///< Clear PFSWE bit - writing to PFS register disabled
  31.         R_PMISC->PWPR = 1U << 7U; ///< Set BOWI bit - writing to PFSWE bit disabled
  32. }

  33. /* IOPORT 初始化函数*/
  34. void IOPORT_Init(IOPORT_Init_t *ioport_init)
  35. {
  36.         uint32_t pfs_bits = 0; //不读取寄存器PmnPFS
  37.         if(ioport_init->Mode == IO_MODE_GPIO) //如果引脚用作普通GPIO 功能
  38.         {
  39.                 if(ioport_init->Dir == IO_DIR_INPUT) /* 用作输入模式*/
  40.                 {
  41.                 pfs_bits |= (ioport_init->Pull) << 4; //设置输入上拉
  42.                 }
  43.                 else if(ioport_init->Dir == IO_DIR_OUTPUT) /* 用作输出模式*/
  44.                 {
  45.                 pfs_bits |= (ioport_init->Dir) << 2; //设置为输出
  46.                 pfs_bits |= (ioport_init->Level) << 0; //设置输出电平
  47.                 pfs_bits |= (ioport_init->Mode) << 6; //设置输出模式
  48.                 pfs_bits |= (ioport_init->Drive) << 10; //设置输出驱动能力
  49.                 }
  50.         }
  51.         else
  52.         {
  53.         }
  54.         /* 写入配置到寄存器PmnPFS */
  55.         R_PFS->PORT[ioport_init->Port >> 8].PIN[ioport_init->Pin].PmnPFS = pfs_bits;
  56. }
复制代码
在r_ioport.h头文件中添加部分代码
  1. /* IOPORT 端口定义*/
  2. typedef enum io_port
  3. {
  4. IO_PORT_00 = 0x0000, ///< IO port 0
  5. IO_PORT_01 = 0x0100, ///< IO port 1
  6. IO_PORT_02 = 0x0200, ///< IO port 2
  7. IO_PORT_03 = 0x0300, ///< IO port 3
  8. IO_PORT_04 = 0x0400, ///< IO port 4
  9. IO_PORT_05 = 0x0500, ///< IO port 5
  10. IO_PORT_06 = 0x0600, ///< IO port 6
  11. IO_PORT_07 = 0x0700, ///< IO port 7
  12. IO_PORT_08 = 0x0800, ///< IO port 8
  13. IO_PORT_09 = 0x0900, ///< IO port 9
  14. IO_PORT_10 = 0x0A00, ///< IO port 10
  15. IO_PORT_11 = 0x0B00, ///< IO port 11
  16. IO_PORT_12 = 0x0C00, ///< IO port 12
  17. IO_PORT_13 = 0x0D00, ///< IO port 13
  18. IO_PORT_14 = 0x0E00, ///< IO port 14
  19. } IO_Port_t;

  20. /* IOPORT 引脚定义*/
  21. typedef enum io_pin
  22. {
  23. IO_PIN_00 = 0x0000, ///< IO port 0 pin 0
  24. IO_PIN_01 = 0x0001, ///< IO port 0 pin 1
  25. IO_PIN_02 = 0x0002, ///< IO port 0 pin 2
  26. IO_PIN_03 = 0x0003, ///< IO port 0 pin 3
  27. IO_PIN_04 = 0x0004, ///< IO port 0 pin 4
  28. IO_PIN_05 = 0x0005, ///< IO port 0 pin 5
  29. IO_PIN_06 = 0x0006, ///< IO port 0 pin 6
  30. IO_PIN_07 = 0x0007, ///< IO port 0 pin 7
  31. IO_PIN_08 = 0x0008, ///< IO port 0 pin 8
  32. IO_PIN_09 = 0x0009, ///< IO port 0 pin 9
  33. IO_PIN_10 = 0x000A, ///< IO port 0 pin 10
  34. IO_PIN_11 = 0x000B, ///< IO port 0 pin 11
  35. IO_PIN_12 = 0x000C, ///< IO port 0 pin 12
  36. IO_PIN_13 = 0x000D, ///< IO port 0 pin 13
  37. IO_PIN_14 = 0x000E, ///< IO port 0 pin 14
  38. IO_PIN_15 = 0x000F, ///< IO port 0 pin 15
  39. } IO_Pin_t;

  40. /*IO引脚模式*/
  41. typedef enum
  42. {
  43. IO_MODE_GPIO = 0, /* 普通GPIO 功能*/
  44. IO_MODE_AF = 1, /* 复用功能*/
  45. IO_MODE_AN = 2 /* 模拟输入输出功能*/
  46. } IO_Mode_t;

  47. /*IO引脚方向*/
  48. typedef enum
  49. {
  50. IO_DIR_INPUT = 0, //引脚用作输入功能
  51. IO_DIR_OUTPUT = 1 //引脚用作输出功能
  52. } IO_Dir_t;

  53. /*IO引脚输出类型*/
  54. typedef enum
  55. {
  56. IO_OTYPE_PP = 0x00, /*!< 推挽模式*/
  57. IO_OTYPE_OD = 0x01 /*!< 开漏模式*/
  58. } IO_OType_t;

  59. /*IO引脚输出能力*/
  60. typedef enum
  61. {
  62. IO_DRIVE_LOW = 0, //Low drive
  63. IO_DRIVE_MIDDLE = 1, //Middle drive
  64. IO_DRIVE_HSHD = 2, //High-speed high-drive
  65. IO_DRIVE_HIGH = 3 //High drive
  66. } IO_DriveCapability_t;

  67. /*IO引脚输出电平*/
  68. typedef enum io_level
  69. {
  70. IO_LEVEL_LOW = 0, //< Low
  71. IO_LEVEL_HIGH //< High
  72. } IO_Level_t;

  73. /*IO引脚输入上下拉*/
  74. typedef enum
  75. {
  76. IO_NO_PULL = 0x00u, /* 浮空*/
  77. IO_PULL_UP = 0x01u, /* 上拉*/
  78. //IO_PULL_DOWN = 0x02u /* RA6M5 引脚没有下拉功能*/
  79. } IO_Pull_t;

  80. /*IOPORT初始化结构体类型定义*/
  81. typedef struct
  82. {
  83.         IO_Port_t Port;
  84.         IO_Pin_t Pin;
  85.         IO_Mode_t Mode;
  86.         IO_Dir_t Dir;
  87.         IO_OType_t OType;
  88.         IO_DriveCapability_t Drive;
  89.         IO_Level_t Level;
  90.         IO_Pull_t Pull;
  91. }IOPORT_Init_t;

  92. /*IO操作函数(调用一次只能操作一个IO 引脚)*/
  93. uint32_t IOPORT_PinRead (IO_Port_t port, IO_Pin_t pin);
  94. void IOPORT_PinWrite (IO_Port_t port, IO_Pin_t pin, IO_Level_t level);
  95. void IOPORT_PinToggle (IO_Port_t port, IO_Pin_t pin);
  96. void IOPORT_PinAccessEnable (void);
  97. void IOPORT_PinAccessDisable (void);
  98. /*IO初始化函数(调用一次只能初始化一个IO 引脚)*/
  99. void IOPORT_Init (IOPORT_Init_t *ioport_init);
复制代码
在hal_entry.c中的hal_entry()函数中添加调用IO口控制函数
  1. void hal_entry(void)
  2. {
  3.   /* TODO: add your own code here */

  4.         /* 调用取消写保护函数*/
  5.         IOPORT_PinAccessEnable();
  6.         /* 使用IOPORT 初始化结构体和调用初始化函数来配置PFS 寄存器*/
  7.         IOPORT_Init_t led_io_init;
  8.         led_io_init.Port = IO_PORT_04;
  9.         led_io_init.Pin = IO_PIN_00;
  10.         led_io_init.Mode = IO_MODE_GPIO; //普通GPIO 模式,而不是复用功能模式或其他的
  11.         led_io_init.Dir = IO_DIR_OUTPUT;
  12.         led_io_init.OType = IO_OTYPE_PP;
  13.         led_io_init.Drive = IO_DRIVE_LOW;
  14.         led_io_init.Level = IO_LEVEL_HIGH; //输出高电平(LED 熄灭)
  15.         IOPORT_Init(&led_io_init); //调用初始化函数,进行LED1 引脚初始化
  16.         led_io_init.Pin = IO_PIN_03; //更换引脚号
  17.         IOPORT_Init(&led_io_init); //结构体其他属性不变,再次调用初始化函数,进行LED引脚初始化
  18.         led_io_init.Pin = IO_PIN_04; //更换引脚号
  19.         IOPORT_Init(&led_io_init); //结构体其他属性不变,再次调用初始化函数,进行LED3引脚初始化
  20.         /** 此时3 个LED 灯的引脚默认输出的是高电平,所以3 个LED 灯都会默认不亮
  21.         * 我们先打开所有LED 灯,然后在while 循环里让LED1 闪烁:每秒钟翻转一次状态
  22.         */
  23.         IOPORT_PinWrite(IO_PORT_04, IO_PIN_00, IO_LEVEL_LOW); //点亮LED1
  24.         IOPORT_PinWrite(IO_PORT_04, IO_PIN_03, IO_LEVEL_LOW); //点亮LED2
  25.         IOPORT_PinWrite(IO_PORT_04, IO_PIN_04, IO_LEVEL_LOW); //点亮LED3
  26.         while(1)
  27.         {
  28.                 /*使用函数IOPORT_PinToggle 翻转LED1引脚电平*/
  29.                 IOPORT_PinToggle(IO_PORT_04, IO_PIN_00);
  30.                 R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);
  31.                 IOPORT_PinToggle(IO_PORT_04, IO_PIN_03);
  32.                 R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);
  33.                 IOPORT_PinToggle(IO_PORT_04, IO_PIN_04);
  34.                 R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);
  35.                 IOPORT_PinWrite(IO_PORT_04, IO_PIN_00, IO_LEVEL_HIGH);
  36.                 IOPORT_PinWrite(IO_PORT_04, IO_PIN_03, IO_LEVEL_HIGH);
  37.                 IOPORT_PinWrite(IO_PORT_04, IO_PIN_04, IO_LEVEL_HIGH);
  38.                 R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS);
  39.         }
  40. #if BSP_TZ_SECURE_BUILD
  41.     /* Enter non-secure code */
  42.     R_BSP_NonSecureEnter();
  43. #endif
  44. }
复制代码
五、编译下载        
编译完成后,使用Type-C接口的数据线给板卡上电,连接好JLink调试器。在Keil魔法棒下找JLink调试器,首次使用会弹出如下对话框。
提醒.png
          这里点击“确定”后,在接下来的对话框中,我们搜索M33,选择第一项即可。
选择M33内核.png
        此时开发板MCU识别到JLink调试器,选择SW方式。
选择J-LINK方式.png
识别到下载器.png
      接下来添加关于板卡的下载算法,这里必须添加如下三个算法,否则会下载失败。
下载算法.png
     下载完成后,板卡上的LED1、LED2、LED3按如下图频率被点亮。此次评测就告一段落了,如有不同见解,欢迎留言回复咱们后会有期。
点灯.gif
回复

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-4-27 05:28 , Processed in 0.038277 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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