自己在做项目的过程中需要使用一个很小的显示屏来实时显示一组来自传感器的数据,然而当我选定了OLED,并且信心满满地写好所有驱动程序第一次上电测试时,却发现怎么都显示不了小数,什么情况?于是习惯性地打开了CSDN,搜索STM32 OLED 显示浮点数,但是~,试了好几种方法,都不怎么好用,不是显示位数不准确,就是补一大堆0。总而言之,都是通过数据类型转换来实现的。本着学习是我快乐的心态,我还真得到了精华,So 那就自己动手写一个函数来实现。
看自己手上有的,不一定要和笔者一样,看具体情况而定。
OLED_IIC-C8T6演示视频
这里先看看有缺陷的写法,不建议直接使用;问题是当后续传入参数长度发生变化时,不能灵活地对应显示到OLED上,也就是会造成小数点后位数被挤掉的问题发生,有能力者自行试验 。
/******************有缺陷,不会自动处理位数变化*******************
* void OLED_ShowFNum() 显示任意浮点数,参考中景园OLED_ShowNum()函数
* x , y : 起点坐标
* Fnum : 要显示的浮点数
* size1 : 字体大小
* mode : 0,反色显示;1,正常显示
***************************************************************/
void OLED_ShowFNum(u8 x,u8 y,float Fnum,u8 size1,u8 mode)
{
unsigned int i,flen;
unsigned char Data[sizeof(Fnum)]; //数据位数由sizeof(Fnum) 来判断,灵活创建数组大小
sprintf(Data,"%.3f",Fnum); //保留小数点后3位小数,打印到Data数组中
flen = sizeof(Data)+1; //判断浮点数长度,方便后期打印输出
// printf("转后:%c",*Data); //测试用
for(i=0;i<flen;i++){ //根据转后字符长度打印输出
x+=8; //每个字符占8位,向后占位
OLED_ShowChar(x,y,Data[i],size1,mode); //调用oled字符显示函数,在OLED屏上逐个显示
}
}
下面时最终的解决方案,若有问题 还望大佬指正
通过前面的折腾,发现转来转去,根本原因时数据类型问题,于是乎在开始参数传进来的地方想办法,发现sprintf()函数的强大已足够,不需要再做多余的数据格式转换了,至于显示有问题还是自己太菜了,这里利用字符串显示函数 :
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode);
那我为什么还要用字符显示函数呢, 直接调用不就完了 ;参考整数显示方法,通过调用字符串显示函数,实现最终目标!
/****************************************************************
* void OLED_ShowFNum() 显示任意浮点数,参考中景园OLED_ShowNum()函数
* x , y : 起点坐标
* Fnum : 要显示的浮点数
* size1 : 字体大小
* mode : 0,反色显示;1,正常显示
* @作 者 : Guard_Byte
***************************************************************/
void OLED_ShowFNum(u8 x,u8 y,float Fnum,u8 size1,u8 mode)
{
uint8_t Data[]= " "; //创建目标数组,用来存放转换后的字符数据
sprintf(Data,"%.3f",Fnum); //保留小数点后3位小数,打印到Data数组中
OLED_ShowString(x,y,Data,size1,mode); //调用OLED字符串显示函数,在OLED屏上显示
}
/* 这里只看浮点数自增片段 */
float num = 0.00;
//TIM3的中断服务函数
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //在STM32中RESET=0,SET=!RESET
{
LED1=!LED1;
if(num <100000) num+=0.501;
else num = 0.00; //清零
printf("定时器中断!\r\n");
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIM3更新中断标志
}
}
/************************************************
* 在定时器实验基础上
* 增加IIC OLED动态浮点数显示
* STM32F103C8T6核心板
* @ 作 者 :Guard_Byte
************************************************/
#include "sys.h"
#include "delay.h"
#include "usart1.h"
//#include "exti.h"
#include "oled.h"
#include "led.h"
#include "timer.h"
int main(void)
{
extern float num ; //在定时器3中 每隔一秒加一次
delay_init();
OLED_Init();
OLED_ColorTurn(0); //0正常显示,1 反色显示
OLED_DisplayTurn(0); //0正常显示 1 屏幕翻转显示
NVIC_Group2; //设置NVIC中断分组2;2位抢占优先级,2位响应优先级
USART1_Init(115200); //串口1初始化为115200
TIM3_Inits(9999,7199); //通用定时器3初始化,参数1:预装载值;参数2:预分频系数值
// EXTIX_Init(); //外部中断初始化
delay_init();
LED_Init(); //LED端口初始化
LED1=1;
OLED_ShowString(26,0,"FS-TAST",16,1); //固定位置不变
while(1)
{
// OLED_ShowNum(0,24,num,5,16,1); //显示位置,内容,数字位数,格式大小
OLED_ShowFNum(24,34,num,16,1); //调用显示函数 浮点型数据测试
OLED_Refresh(); //将上面的内容更新到OLED显存,刷新屏幕
delay_ms(1000); //1s刷新一次显示数据
// OLED_Clear(); //清屏函数,注意若要清屏,必须加入延时,否则还没看到就清掉了
}
}