前言:
在开发过程中,对于RICS-V架构的单片机了解甚少,参考了GD官网给出的资料,环境的搭建还是很容易的,这里不再赘述。本文着重在于对其外设使用点的一些小建议和注意细节。
OC&UART(输出比较和UART):
我把这两个功能集成在一起,这样可以通过上位机来控制定时器的OC功能,上位机控制很好的处理了数据交互和中断的实现细节,下面开始分析代码:【TIMER2的中断是1秒一次,由于RTC时钟的界面设计,TIMER2在RTC开启的情况下不会开启,在其他功能下开启】
在这里,首先开启串口对应的引脚(ps:所有外设的开启都遵循一个流程:开启始终,打开引脚,配置外设,外设使能),注意串口引脚的AF控制,TX和RX在AF时是不一样的,而在库函数使用手册里,GD官方没有解释这两个对应的是具体哪个通道,这对于定时器等多通道的很头疼,需要一个一个试。
然后配置串口的波特率,停止位,奇偶校验等参数,然后开启串口,设置eclic(类似于STM32 NVIC)设置优先级和开启全局中断,设置完以后才可以使用中断服务程序,但是测量出机器中断屏蔽时并不能屏蔽未达优先级的中断,很奇怪。
在中断服务程序,使用了串口接收传来的数据,然后给到OC的CCR寄存器来设置比较值。
在发送程序里:
使用了多个#ifdef #endif来预处理开启的部分,使用者可以在<DEFINE.h>头文件里开启和关闭#define来观察某个外设的工作状态而不要手动的去开启和关闭。
串口每隔一秒发送一次ADC采集到的温度值,ADC开启的是CPU的内部温度传感器的ADC值,由于没有找到典型值的位置,所以没法按照给定的数据来计算中世纪的温度值,但是使用打火机【有危险】烧单片机时,可以观察到ADC的值产生了下降,符合公式的相关关系。
这里的数据采用的取反来观察,一旦烧的时间久,会发生单片机重启的现象,所以不建议使用打火机烧芯片,不要把他放在超过其工作温度的地方运行,防止出现错误。
ADC采集内部电压:
在这里,首先开启内部ADC的时钟,时钟开启以后对ADC的规则组,对齐方式,通道,特殊模式进行一系列配置,详情见固件库使用手册。
注意的是需要关闭外部触发的功能,以为这个代码使用的是软件触发然后持续不断的采集数据,通过Get_Value()函数得到其寄存器采集到的数据,ADC支持8~12b的采集精度,所以可以很大程度上的得到数据的特点。
库函数写的十分的详细,在ADC的采集还是十分方便的,具体的实现细节可以参考代码,逻辑上没啥困难。
RTC实时时钟:
在这里,不得不吐槽一波了,这里没有外部低速时钟,所以得依靠内部的32kRCRC振荡器开提供时钟,外部高度时钟由于频率过高,无法分频到1Hz,所以不得不使用内部RC振荡器,由于RC振荡器受温度,芯片生产工艺的限制,无法做到真正的32kHz,所以用作看门狗这样对短时间,精度要求不高的外设是很有帮助的,但是,在RTC这样对时钟要求的外设,使用这个必然导致无法准确的得到1Hz,所以这个板子上的RTC就是个玩具,根本没用,32秒就已经产生了3秒的误差。我认为作为一款消费电子产品,不支持RTC的功能会导致这个板子根本没人用,不仅仅密钥更新不了,对时间的访问也丢失精度,即使做的再好,也是没用的。
对于RTC的访问,首先要做的是打开备份寄存器的读取写入权限,一定要先打开PMU的时钟,开启备份寄存器,再开启RTC时钟,顺序不能错否则会无法开启RTC,
然后按照代码顺序开启配置,配置不需要像STM32那样使用时间戳,支持日历写入还是很人性化的,在写入和读取的过程还是很方便的,使用结构体返回数据,在中断函数调用写函数
这个函数向屏幕写入数据,具体的刷写“:”等配置不再展示,因为很方便自定义配置。
这个是旧版函数,可以拿来做为参考(__RTC___是旧版 EVE_RTC(eventuall RTC)是最终版)
TRNG&CRC(真随机数和CEC校验):
CRC校验在检查数据和密钥传递有着重要的用途,网上有很多CRC的教程,原理分析的博客和视频,很方便去了解怎么算的,TRNG真随机数,不需要随机数种子,可以产生真随机数,不会重样,很强大的。
只需要开启对应的库函数外设时钟,还是很方便的
OLED显示函数粗解:
OLED显示屏存在以下诸多问题,包括但不限于第一次上电不显示,容易出现乱码(感觉是串扰),复位多次任然有乱码和花屏现象,在一般显示时是正常的,但是在多个函数整合一起可能会出现问题。OLED库函数取自于江科大STM32入门教学里的OLED显示代码,在此标出。
OLED出现在不同屏幕上不显示的情况,目前不知道是怎么回事,有的可以有的不行。
OLED的函数注释都在,可以参考,在main函数先调用OLED_Init函数初始化就可以使用了。
PWMI功能解释:
PWMI是检测外部的PWM信号的装置,内容很简单,难就难在如何开启主从模式,主从模式的配置属于事件的一种,是外设无需CPU干预即可完成一些既定工作,无需中断战用CPU时间,有利于CPU处理更多内容和减少频繁中断,是很有利于外设的运行。
在这里,主从模式是隶属于RCU_SYSCFG里的,所以需要打开函数“rcu_periph_clock_enable(RCU_SYSCFG);”来打开system config,这点需要注意,不开启时钟主从模式无法运行,无法自动把定时器复位,会出现读取到的CCR值一直递增变化,到达自动重装值重头再来,所以需要注意开启时钟,和STM32不一样,STM32没有这方面内容,这一点需要注意。
首先开启时钟,打开TIMER分频器的时钟,配置时基单元和开启定时器通道,配置通道引脚,配置IC功能的结构体,设置主从模式开始定时器,这个流程很常见,可以参考代码来理解含义。
最终按照读取到的值,可以做如下运算,得到计算的占空比和实际频率,由于预分频的值有点大,所以在非整数的情况下占空比和频率的计算值会和实际值有误差,属于正常情况,因为整数运算丢失精度导致的,所以可以把分频值改小一点,重装值改成65535,就可以实现精度的增加。
可以看到,在属于整数运算的情况下,计算值和信号发生器的值是一样的,这就很好的反映了PWMI的作用。【参数解释:Freq:频率;VOID:占空比;第三行:通道0读取数值,第四行:通道一读取数值;配置的分频和重装值和上面配置代码一样】
正交编码器:
正交编码器是很常见的运用,在电机驱动,串级PID都有运用,现在大部分采用了是霍尔或光栅编码器,在原理上三者差别不大,而且GD库函数贴心的准备了“void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode)”函数用来配置霍尔传感器,由于笔者手上没有编码电机和光栅,所以没有使用这个函数,使用提供的“void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity)”函数来配置正交编码器。
在这里,首先开启TIMER的时钟【注意:时钟的开启代表着你要使用这个外设,并不是配置TIMER的内部时钟源,这点需要注意】,然后配置通道引脚和时基单元,由于是使用外部编码器作为时钟的,所以无需配置内部时钟和计数方向,因为这两个是编码器对应的外设控制的,无需我们管。
通过开启定时器,设置通道的滤波器,极性,然后设置成编码器模式,在这里,需要尤其注意的是,需要开启主从模式,需设置从模式为编码器模式,模式几按照自己需求来,注意一定要开启主从,别忘了开启rcu_syscfg时钟,否则计数器会一直自增,没法开启外设!!!一定要开主从模式,配置成编码器模式,触发源无需配置,一定要注意,和STM32和GD32f103c8t6不一样,一定要注意!!!
正向计数模式
反向计数溢出现象,很方便。
通过这个函数获取编码器的数值,记住在一开始把Tim_valueq清零。
然后配置通道输入,配置成IC功能,用于开启两个通道,注意,只能使用通道0和通道1两个作为编码器接口,其他的通道不行(如手册说明其他通道,以手册为准)。
最后配置通道不反向然后开启定时器,通过读取Tim_value值得到当前编码器的状态,注意,首次开启编码器需要手动把Tim_value值清零,否则会产生初始值不是0的现象)
结尾:
到这里,笔者记录了大部分使用到的外设,配置等,但是主从模式其他触发暂时没有涉及到,半个月以来,从0入门了GD的官方库,了解了RISC-V架构单片机的组成,运行,和效率。由于笔者对RTOS了解甚少,所以WIFI和BLE就没有去测量,很抱歉。
在此,感谢ICEasy商城提供的免费样品,感谢JUST103实验室对的测评提供的支持,单片机测试和本文的编写者为zxyyl。
本套例程对外开源,希望对你们有帮助,谢谢。
由于笔者接下来要开始准备蓝桥杯比赛,请看到这篇测评并且觉得有帮助的人为笔者加油,谢谢你们的支持。

