CSM32RV20配有RTC计时器,但该计时器应该是一个准计时器,并不能像常规RTC计时器那样进行RTC的时间进行设置与读取,也不具时间的进制转换性能。 其相关资料的介绍如下: RTC计时器有两个寄存器, mtime 和 mtimecmp。 Mtime寄存器用于反映当前计时器的计数值, mtimecmp 用于设置计时器比较值。在MCU 核中,采用 rtc_toggle 输入作为这个实时计数器。 rtc_toggle 可以通过在mtime 寄存器中确定实时计数器计数值来确定。 rtc_toggle 用于计时时,频率不需要很高。 rtc_toggle 必须严格地以上述公式描述的频率范围运行,即它必须严格地小于时钟频率的一半。此外, rtc_toggle 的频率必须保持不变,并且必须可以通过软件设置来修改这个频率。 为此,原计划用RTC计时器来实现电子时钟的想法就不便实现了。此外,若使用RTC计时器的计时功能来处理也不够便捷,故改为直接用系统提供的延时函数来模拟实现,这比使用定时器的方式也更简便些。 此外,为了进行可行性验证,也先不使用任何显示显示器件,只用系统的提供的串口输出功能来加以验证。 模拟RTC电子时钟的程序如下:
- uint8_t t,m=0,h=0,p;
- int main(void)
- {
- CLIC_Init(); //系统中断配置
- System_Clock_Init(); //系统时钟初始化
- GPIO_MODE_Init(GPIOA,PIN8,GPIO_MODE_OUTPUT); //GPIO 模式
- UART_Init_case1(UART1); //非中断模式
- ee_printf("n CSM32RV20 RTC TEST rn"); //115200bps
- GPIO_Write(GPIOA,PIN8,GPIO_RESET);
- t=0;
- p=0;
- while(1)
- {
- if(t!=p)
- {
- if(t>59)
- {
- t=0;
- m++;
- }
- if(m>59)
- {
- m=0;
- h++;
- }
- if(h>23)
- {
- h=0;
- }
- ee_printf("%d:%d:%drn",h,m,t);
- p=t;
- }
- Delay32M_ms(1000);
- t++;
- GPIO_Toggle(GPIOA,PIN8);
- }
- }
复制代码
经编译和下载,其运行结果如图1和图2所示。
图1 启动计时
图2 进制处理 由此可见,该模拟效果是可行性的。 有了前面的基础,就可以为它添加一个显示器件了,为了低能耗和尽量少地占用系统资源,这里是一款0.91寸的单色OLED屏为显示器件,且该器件是以I2C接口来工作,故只需2个GPIO口即可完成对它的驱动。 依使用的方便性,这里是使用扩展接口J2中的PB0和PB1来连接OLED屏,J2的引脚排列见图3所示。 SCLK ---- PB0 SDIN ---- PB1
图3 界面效果 在采用GPIO口来模拟I2C通讯的情况下,这2个引脚输出高低电平的语句定义为: #define OLED_SCLK_Set() GPIO_Write(GPIOB,PIN0,GPIO_SET) #define OLED_SCLK_Clr() GPIO_Write(GPIOB,PIN0,GPIO_RESET) #define OLED_SDIN_Set() GPIO_Write(GPIOB,PIN1,GPIO_SET) #define OLED_SDIN_Clr() GPIO_Write(GPIOB,PIN1,GPIO_RESET) 为实现显示效果,所使用的数值显示函数为:
- void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size2)
- {
- uint8_t t,temp;
- uint8_t enshow=0;
- for(t=0;t
- {
- temp=(num/oled_pow(10,len-t-1))%10;
- if(enshow==0&&t<(len-1))
- {
- if(temp==0)
- {
- OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
- continue;
- }
- else enshow=1;
- }
- OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
- }
- }
复制代码
所使用的字符串显示函数为:
- void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
- {
- unsigned char j=0;
- while (chr[j]!='\0')
- {
- OLED_ShowChar(x,y,chr[j],Char_Size);
- x+=8;
- if(x>120)
- {
- x=0;
- y+=2;
- }
- j++;
- }
- }
复制代码
其实现计时显示效果的主程序为:
- int main(void)
- {
- int16_t i;
- uint8_t t,m=0,h=0,p;
- CLIC_Init();
- System_Clock_Init();
- GPIO_MODE_Init(GPIOB,PIN0,GPIO_MODE_OUTPUT);
- GPIO_MODE_Init(GPIOB,PIN1,GPIO_MODE_OUTPUT);
- GPIO_MODE_Init(GPIOA,PIN8,GPIO_MODE_OUTPUT);
- GPIO_Write(GPIOB,PIN0,GPIO_SET);
- GPIO_Write(GPIOB,PIN1,GPIO_SET);
- GPIO_Write(GPIOA,PIN8,GPIO_SET);
- OLED_Init();
- OLED_Clear();
- OLED_ShowString(40,0,"CSM32RV20",16);
- OLED_ShowString(40,2,"RTC TEST",16);
- Delay32M_ms(2000);
- OLED_Clear();
- OLED_ShowString(40,0,"2022- 1-18",16);
- OLED_ShowString(40,2," : :",16);
- t=0;
- p=0;
- h=8;
- m=30;
- while(1)
- {
- if(t!=p)
- {
- if(t>59)
- {
- t=0;
- m++;
- }
- if(m>59)
- {
- m=0;
- h++;
- }
- if(h>23)
- {
- h=0;
- }
- OLED_ShowNum(56,2,h,2,16);
- OLED_ShowNum(80,2,m,2,16);
- OLED_ShowNum(104,2,t,2,16);
- p=t;
- }
- Delay32M_ms(1000);
- t++;
- GPIO_Toggle(GPIOA,PIN8);
- }
- }
复制代码
经程序的编译下载,其运行效果如图4和图5所示。
图4 界面效果
图5 计时效果 由于CSM32RV20开发板只是一款功能测评板,故扩展接口还有改进的空间,建议在后续推出开发板的时候为它配上一个Arduino接口,那样使用起来就更方便了,可以快速地插上OLED屏、传感器等器件来使用,并可以保障连接的可靠性。
|