打印
[N32G45x]

在N32G457VEL (n32g45xvl-stb)开发板上试验RT_Thread microPython

[复制链接]
732|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 catnull 于 2022-3-6 15:00 编辑

N32G457VEL n32g45xvl-stb)开发板上试验RT_Thread microPython

论坛上有一个RT_Thread 的比赛,也是基于N32G45xvl-stb板卡的,有一些关于RT-Thread操作系统下面制作的项目的**,感觉很高阶,也很好用,因为会把底层的细节包装起来,不用太费劲看手册就能完成一些基本的操作。安装了Rt-Thread ,也跑了一个Blink程序,估计可行。浏览了一下手册,RT-Thread 是嵌入式操作系统的乐高,很多丰富的组件和功能都已经移植好了。N32G45x也有板级支持包,于是决定入坑。题目就选择比较有意思的microPython. microPython适合做调试,很灵活,几个语句就可以完成很多工作。比如ADC,读个电压,用嵌入式得有库代码,还要安装工具链,然后找手册,调参数,学习曲线很弯曲。但是搞了一个microPython,这些都省了,然后连刷机都不用,就是弄一个串口连上就可以。有点遗憾的是开发板没有板载的flash扩展,板级支持包中没有flash存储和文件系统的实现,所以不能把代码存在板上。但是这个问题不影响核心。小时候玩的小霸王学习机(不是游戏机),里面敲了半天的计算正弦积分的FBASIC程序,不是掉了电之后就没有了么?小霸王学习机还费电视,家里黑白电视被搞坏了,母亲还特意去阿姨家借了一台旧电视回来。。。。。。好吧,回到正题,我们怎么搞定microPython?
[size=11.0000pt]一、初战失败,flash空间和内存都不够
一顿操作猛如虎,安装好RT-Thread 2.1.5,然后安装N32G45x 板级支持包,设置组件,设置一些参数,然后更新,编译。链接的时候晕了,空间不够,flashram 双双告急。
当时工程师姐姐特意支持发了顶配的457vel,有512kBflash ,还有144kb ram,不应该的。
想了半天明白了,是默认定义的问题。于是找资料,顺着目录看到board.h文件,内有定义。

1 修改board.c文件,适配N32G457VEL
从注释里面,发现编写RT-Thread支持库的大牛,开发的环境是N32G452XX,内存SRAM原先只有80kB , FLASH也少得很,不够microPython最小的200kB的身材。
当然得改好了,立马可以链接成功了,不再报错,稍微报点警告,不管。
2 编译的过程
二、初试microPython,感受神器的kiss之美,简单,简单,简单。Keep It Simple and Stupid.
下载到开发板上,一切安好。
先来一个putty.exe打开开发板的mp之门。
3 链接开发板使用 putty终端,用得顺手

可以跑个数学程序,问问开发板1+1=?,看看它是否工作正常。
图4 小试 1+1 microPython显神威
三、明确N32G45XVL-STB开发板的RT_Thread 引脚定义,使用microPython不迷糊
数学太烧脑,hello World一起搞。
接下来去点个灯。Blink走起。
但是板载的灯在PB5上,还有一个在PA8.
microPython已经把细节封装了,您只需要知道是第几个引脚就可以了。
实际上RT-RThread也封装了。看文件/Libraries/drivers/drv_gpio.h。原先是452,QF64封装,PB5对应的是57,恰好也能跑默认的闪灯。但是457vel比较阔气,有100引脚,所以修改一下引脚定义。
图5 修改引脚数为100,适配457vel
#if (N32F10X_PIN_NUMBERS == 100)
    __N32_PIN_DEFAULT,
    __N32_PIN(1, APB2, E, 2),
    __N32_PIN(2, APB2, E, 3),
    __N32_PIN(3, APB2, E, 4),
    __N32_PIN(4, APB2, E, 5),
    __N32_PIN(5, APB2, E, 6),
    __N32_PIN_DEFAULT,
    __N32_PIN(7, APB2, C, 13),
    __N32_PIN(8, APB2, C, 14),
    __N32_PIN(9, APB2, C, 15),
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN(15, APB2, C, 0),  //ADC1 PC0
    __N32_PIN(16, APB2, C, 1),
    __N32_PIN(17, APB2, C, 2),
    __N32_PIN(18, APB2, C, 3),
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN(23, APB2, A, 0),//SOFT I2C SCL
    __N32_PIN(24, APB2, A, 1),//SOFT I2C SDA
    __N32_PIN(25, APB2, A, 2),
    __N32_PIN(26, APB2, A, 3),
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN(29, APB2, A, 4),  // Key1 PA4
    __N32_PIN(30, APB2, A, 5),  //Key2  PA5
    __N32_PIN(31, APB2, A, 6),  //key3  PA6
    __N32_PIN(32, APB2, A, 7),
    __N32_PIN(33, APB2, C, 4),
    __N32_PIN(34, APB2, C, 5),
    __N32_PIN(35, APB2, B, 0),
    __N32_PIN(36, APB2, B, 1),
    __N32_PIN(37, APB2, B, 2),
    __N32_PIN(38, APB2, E, 7),
    __N32_PIN(39, APB2, E, 8),
    __N32_PIN(40, APB2, E, 9),
    __N32_PIN(41, APB2, E, 10),
    __N32_PIN(42, APB2, E, 11),
    __N32_PIN(43, APB2, E, 12),
    __N32_PIN(44, APB2, E, 13),
    __N32_PIN(45, APB2, E, 14),
    __N32_PIN(46, APB2, E, 15),
    __N32_PIN(47, APB2, B, 10),
    __N32_PIN(48, APB2, B, 11),
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN(51, APB2, B, 12),
    __N32_PIN(52, APB2, B, 13),
    __N32_PIN(53, APB2, B, 14),
    __N32_PIN(54, APB2, B, 15),
    __N32_PIN(55, APB2, D, 8),
    __N32_PIN(56, APB2, D, 9),
    __N32_PIN(57, APB2, D, 10),
    __N32_PIN(58, APB2, D, 11),
    __N32_PIN(59, APB2, D, 12),
    __N32_PIN(60, APB2, D, 13),
    __N32_PIN(61, APB2, D, 14),
    __N32_PIN(62, APB2, D, 15),
    __N32_PIN(63, APB2, C, 6),
    __N32_PIN(64, APB2, C, 7),
    __N32_PIN(65, APB2, C, 8),
    __N32_PIN(66, APB2, C, 9),
    __N32_PIN(67, APB2, A, 8),  //led1 PA8
    __N32_PIN(68, APB2, A, 9),
    __N32_PIN(69, APB2, A, 10),
    __N32_PIN(70, APB2, A, 11),
    __N32_PIN(71, APB2, A, 12),
    __N32_PIN(72, APB2, A, 13),
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
    __N32_PIN(76, APB2, A, 14),
    __N32_PIN(77, APB2, A, 15),
    __N32_PIN(78, APB2, C, 10),
    __N32_PIN(79, APB2, C, 11),
    __N32_PIN(80, APB2, C, 12),
    __N32_PIN(81, APB2, D, 0),
    __N32_PIN(82, APB2, D, 1),
    __N32_PIN(83, APB2, D, 2),
    __N32_PIN(84, APB2, D, 3),
    __N32_PIN(85, APB2, D, 4),
    __N32_PIN(86, APB2, D, 5),
    __N32_PIN(87, APB2, D, 6),
    __N32_PIN(88, APB2, D, 7),
    __N32_PIN(89, APB2, B, 3),
    __N32_PIN(90, APB2, B, 4),
    __N32_PIN(91, APB2, B, 5), //led0
    __N32_PIN(92, APB2, B, 6),
    __N32_PIN(93, APB2, B, 7),
    __N32_PIN_DEFAULT,
    __N32_PIN(95, APB2, B, 8),
    __N32_PIN(96, APB2, B, 9),
    __N32_PIN(97, APB2, E, 0),
    __N32_PIN(98, APB2, E, 1),
    __N32_PIN_DEFAULT,
    __N32_PIN_DEFAULT,
#endif
引脚定义是完成 mp 的引脚初始化的重要参考,例如板载的LED灯是接在PB5,那么就需要采用如下的测试程序:
microPython:
from machine import Pin
PIN_OUT = 91
PIN_IN  = 29
p_out = Pin(("PB15", PIN_OUT), Pin.OUT_PP)
p_out.value(1)                 # set io high
p_out.value(0)                 # set io low
p_in = Pin(("key_0", PIN_IN), Pin.IN, Pin.PULL_UP)
print(p_in.value() )           # get value, 0 or 1
点亮灯,使用按键,都是用一两句语句就完事了。
MicroPython的世界里,如何测量电压——ADC通道引脚的使用
2.1 找了10小时的bug,还是搞出来了。。。
数字引脚比较简单。但是ADC的调试比较费劲。本来也费劲,因为ADC的板级代码,逻辑很多,涉及GPIO模式设定为模拟输入,时钟设置和启用,DMA选项,触发,采样时间等等。microPython只是做最简单的ADC,但也比较费劲。
因为1.0.1的板级支持包,和1.0.0一样,在RT-ThreadFish命令行下面,都跑不通ADC。原来是代码里面有一些bug,忘记包含了一个<drivers/drv_adc.h>引起的。感觉应该改了就行了,但是还是郁闷,没反应。发现是傻瓜化配置生成的rtconfig.h的文件里面,会默认设置简单的
#define BSP_USING_ADC,
而只有再加上
#define BSP_USING_ADC1
#define BSP_USING_ADC2
#define BSP_USING_ADC3
才会触发drv_adc.c里面的关键代码的编译。可能452ADC 比较简单,默认就行。这个问题解决了之后,ADC就可以在mp里面工作了。

图6 RT_Thread傻瓜设置不灵活,手动修改解决
2.2 通道和引脚之间有一座暗桥,值得探索。
通道6 ADC1 ADC2 对应的引脚是PC0
通道7 ADC1 ADC2 对应的引脚是pC1

图7 ADC通道的配置

明确这个细节,可以比较好的使用microPython ADC读取模拟电压功能。
举例:
>>> from machine import ADC      # machine 导入 ADC
>>> adc = ADC(1, 6)             # 创建 ADC 对象,当前使用编号为 1 ADC 设备的  通道,就是以PC0引脚对应测试输入引脚
>>> adc.read()                   # 获取 ADC 对象采样值
4095
>>> adc.deinit()                 # 关闭 ADC 对象
>>> adc.init(6)                 # 开启并重新配置 ADC 对象
8 machine.ADC功能测试——前巅峰之作

五、致谢
2012年制作Arduino Atmega8控制板开始,入圈开源硬件很多年了。看着《无线电》杂志从stm32主打,到Arduino霸麦,如今我们在21ic.com继续追梦。感谢Nations公司的开发板,是从硬件到固件库几乎全部开源,也感谢制作RT-Thread操作系统的很多大师。作为天然的极客,可以说很菜,但很好玩。Just For Fun

附:代码包。
源代码太大,放在gitee.com
https://gitee.com/xiaohezyd/rt_-thread_micro-python_-n32-g457-vel_stb
附上bin文件做测试。 Debug.zip (1.35 MB)

使用特权

评论回复
沙发
guijial511| | 2022-3-7 08:11 | 只看该作者
学习了,谢谢分享。

使用特权

评论回复
板凳
两只袜子| | 2022-3-7 09:10 | 只看该作者
什么叫神器的kiss之美啊?感觉很神奇了

使用特权

评论回复
地板
WoodData| | 2022-3-7 09:24 | 只看该作者
学习了

使用特权

评论回复
5
单片小菜| | 2022-3-7 10:35 | 只看该作者
这个不错,或许可以尝试一下。

使用特权

评论回复
6
海滨消消| | 2022-3-8 16:49 | 只看该作者
有机会尝试一下

使用特权

评论回复
7
catnull|  楼主 | 2022-3-8 19:19 | 只看该作者
两只袜子 发表于 2022-3-7 09:10
什么叫神器的kiss之美啊?感觉很神奇了

各有各的好处。比如你做工业产品,那必须做到很精致,所以适合用keil MDK开发,追求极致。但是如果仅仅是快速的功能实现,那么用microPython作为一个中间件,或者一个平台,或者称之为虚拟机,那么就可以很简便,很灵活。比如你需要做一些数据处理,还有操作,只要写好相应的micropython的脚本,然后通过串口把这个脚本直接粘贴,就可以完成目标。
相比较于配置编译环境,设置连接器(J-Link),再把新编译的固件烧写过去,简直要简单许多。
当然,这仅仅适合于好玩,但是这又什么关系呢,你再也不用重复对着庞大臃肿的代码寻找关键的语句修改参数的。
其实还有更猛的东西,比如microBlocks,这个玩意儿都不用写代码,直接积木图形编程,就可以控制单片机完成一些常用的功能。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

39

帖子

1

粉丝