2021山东省赛光照值折线图【中职组】【完成一部分】
2021山东省赛光照值折线图(Bug版本)
原题目
NB-IoT 显示传感器检测值 选用一块 NB-IoT 模块,根据要求完成相关功能开发。
任务要求:
➢ 要求在 NB-IoT 模块上插上一个光照模块。
➢ NB-IoT 模块通电后,以 3 秒一次的频率读取光照值,并将最近 5 次读取 的光照值以折线图形式显示在 NB-IoT 模块板上(如效果图所示)并且 每个折线点上必须显示具体的光照值。液晶屏最高处表示光照值大于 等于 1000Lx,液晶屏最低处表示光照值小于等于 0Lx。
➢ 光照计算公式为:光照值 = (5/2.0)((电压值3300/(4096-1.0))/10.0) 。
➢ 编写完成后请将程序烧写到 NB-IoT 模块板中。
➢ 程序效果界面如下图所示:
题目分析:
-
很离谱的一个题
-
查了好多资料才勉强写了个差不多
-
资料一:
重要代码
-
资料二:
了解了屏幕原理[没看明白]
-
光照值获取依然是
#include "adc_reader.h"
里面的几个函数
因为这个屏幕横着按像素分[0-127],纵向按页分[0-7],一页有8个像素
代码:
引用头文件
#include "adc_reader.h"
#include "oledfont.h"
#include "hal_oled.h"
所定义的函数:
- 可能会补充有bug的函数 若有更好的解决方法可以留言交流
显示小文字
void ShowChar1(uint8_t x,uint8_t y,uint8_t chr)
{
unsigned char c=0,i=0;
c=chr-' ';
if(x>Max_Column-1){x=0;y=y+2;}
OLED_Set_Pos(x,y+1);
for(i=0;i<6;i++)
OLED_WR_Byte(F6x8[c][i],OLED_DATA);
}
在库中写死了16的大小
将不等于16的代码复制出来,定义上字库的头文件就可以显示小文字 或者将定义的SIZE 直接改成8大小
画点函数:根据资料1
void DrawPoint1(unsigned char x,unsigned char y)
{
static unsigned char data1;
data1=(unsigned char)(0x01<<((y%8)));
OLED_Set_Pos(x, (unsigned char)(y >> 3));
OLED_WR_Byte((unsigned char)(0xb0 + (y >> 3)),0);
OLED_WR_Byte((unsigned char)(((x & 0xf0) >> 4) | 0x10),0);
OLED_WR_Byte((unsigned char)((x & 0x0f) | 0x00),0);
OLED_WR_Byte(data1,1);
}
画线函数:
void Fill1(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2) //只可以花45°的线,会有点小bug但够用
{
while(1){
if(x1<x2)
x1 ++;
if(x1>x2)
x2 --;
if(y1<y2)
y1++;
if(y1>y2)
y1--;
DrawPoint1(x1,y1);
/* DrawPoint1(x1,y1-1);
DrawPoint1(x1-1,y1);*/ //加粗线条偶尔加粗
if(y1 == y2&&x1 == x2)break;
}
}
交点函数
void dot_D(uint8_t x,uint8_t y){ //偶尔有交点
DrawPoint1(x,y);
DrawPoint1(x+1,y);
DrawPoint1(x-1,y);
DrawPoint1(x,y+1);
DrawPoint1(x,y-1);
DrawPoint1(x+1,y+1);
DrawPoint1(x-1,y-1);
DrawPoint1(x-1,y+1);
DrawPoint1(x+1,y-1);
DrawPoint1(x+1,y+2);
DrawPoint1(x-1,y-2);
DrawPoint1(x-1,y+2);
DrawPoint1(x+1,y-2);
DrawPoint1(x+2,y+1);
DrawPoint1(x-2,y-1);
DrawPoint1(x-2,y+1);
DrawPoint1(x+2,y-1);
DrawPoint1(x+2,y);
DrawPoint1(x-2,y);
DrawPoint1(x,y+2);
DrawPoint1(x,y-2);
}
main函数
int main( void )
{
Init();
ADCS_Init();
OLED_Init();
OLED_Clear();
while( 1 )
{
//全在定时器
}
}
定时器文件
/* Includes ------------------------------------------------------------------*/
#include "timer_handles.h"
#include "key_scaner.h"
#include "adc_reader.h"
#include "oledfont.h"
#include "hal_oled.h"
void ShowChar1(uint8_t x,uint8_t y,uint8_t chr);
void DrawPoint1(unsigned char x,unsigned char y);
void Fill1(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2);
unsigned int t = 0;//计时
float light[7] ={0,0,0,0,0,0,0};//获取6次值
uint8_t i = 0 ,j = 0;
unsigned char arr[6][10] = {{000}};//数组
void dot_D(uint8_t x,uint8_t y){
DrawPoint1(x,y);
DrawPoint1(x+1,y);
DrawPoint1(x-1,y);
DrawPoint1(x,y+1);
DrawPoint1(x,y-1);
DrawPoint1(x+1,y+1);
DrawPoint1(x-1,y-1);
DrawPoint1(x-1,y+1);
DrawPoint1(x+1,y-1);
DrawPoint1(x+1,y+2);
DrawPoint1(x-1,y-2);
DrawPoint1(x-1,y+2);
DrawPoint1(x+1,y-2);
DrawPoint1(x+2,y+1);
DrawPoint1(x-2,y-1);
DrawPoint1(x-2,y+1);
DrawPoint1(x+2,y-1);
DrawPoint1(x+2,y);
DrawPoint1(x-2,y);
DrawPoint1(x,y+2);
DrawPoint1(x,y-2);
}
void ShowL(uint8_t x,uint8_t y,unsigned char a[]){
y-=2;
ShowChar1(x,y,a[0]);
ShowChar1(x+6,y,a[1]);
ShowChar1(x+12,y,a[2]); //显示数值
/*ShowChar1(x+32,y,arr[n][3]);
ShowChar1(x+48,y,arr[n][4]);
ShowChar1(x+72,y,arr[n][5]);*/
}
//画点连线
void ToPort(uint8_t begin,float high, uint8_t end,float e_high,uint8_t Zifu[]){
Fill1(begin,high,end,e_high);//连线函数
//dot_D(end,e_high); //画交点函数不写观感好一点
ShowL(begin,e_high/64*7-1,Zifu);//显示坐标上的值
}
void Time2Handler(){
keyScanner();
//t++;j++;
if(t == 200){i++;//1ms的定时器内部写的内容较多定时器不准 根据实际情况写检测周期
AdcScanChannel();//获取电压值
light[6] = (5/2.0)*(AdcReadCh0()*100);//转换值
if(i != 6)
light[i] = light[i+1];//存最近5次值
sprintf(arr[i],"%.2f",light[i]);
}
if(i == 6){i = 0;
OLED_Clear();
//画图
ToPort(0,(63-(light[0+1]/1000*64)),24,(63-(light[1+1]/1000)*64),arr[0+1]);
ToPort(24,(63-(light[1+1]/1000*64)),48,(63-(light[2+1]/1000)*64),arr[1+1]);
ToPort(48,(63-(light[2+1]/1000*64)),72,(63-(light[3+1]/1000)*64),arr[2+1]);
ToPort(72,(63-(light[3+1]/1000*64)),96,(63-(light[4+1]/1000)*64),arr[3+1]);
ToPort(96,(63-(light[4+1]/1000*64)),120,(63-(light[5+1]/1000)*64),arr[4+1]);
}
if(t == 600) {t = 0;}//清屏周期
}