在线时间234 小时
UID3301905
注册时间2017-1-8
NXP金币172
TA的每日心情 | 开心 2018-4-20 15:04 |
---|
签到天数: 8 天 连续签到: 1 天 [LV.3]偶尔看看II
金牌会员
 
- 积分
- 3265
- 最后登录
- 2023-7-24
|
【飞凌RT1052】双屏异显动态篇——基于ELCDIF-RGB彩屏界面的ADC波形抓取器
做这个小DEMO主要是为了归纳总结一下昨天调通的那几个外设,尝试使用ELCDIF-RGB彩屏界面去显示一些动态的折线,比如电压值等。像示波器这种专业仪器,它的理论基础就是ADC采集电压,只不过采集速率极快,精度极高,因此是使用外部ADC芯片加上高速串行通信总线实现的,像单片机的ADC,可以做个示波器的雏形,即简单的波形抓取器。这里我使用之前的10K电位器充当ADC电压信号输入的手段,用手拧动电位器以改变ADC输入电压。
做波形抓取器,核心部分不是ADC的代码,ADC代码直接套SDK用即可,不重要,重要的是液晶屏显示折线的算法,要做到显示美观、显示速率快,不是那么容易的。这里我使用了一个小小的显示算法,使用RGB屏进行折线显示的,因为RGB屏没有触摸的手段,因此只用来显示复杂的图案是最好的:
int over_back_color=0,over_point_color=0xffff,over_wrap_color=0x001f;
static int last_data=0;
void ELCDIF_RGB_fun(int x,int data)
{
ELCDIF_RGB_DrawVLine(x,32,240,over_back_color);
if(x==0)
{
last_data=0;
ELCDIF_RGB_DrawPixel(0,272-data,over_point_color);
}
else if(x>0)
{
if(data>last_data)
{
ELCDIF_RGB_DrawVLine(x,272-data,data-last_data,over_point_color);
}
else if(data<last_data)
{
ELCDIF_RGB_DrawVLine(x-1,272-last_data,last_data-data,over_point_color);
}
else
{
ELCDIF_RGB_DrawPixel(x,272-data,over_point_color);
ELCDIF_RGB_DrawPixel(x-1,272-data,over_point_color);
ELCDIF_RGB_DrawPixel(x+1,272-data,over_point_color);
}
}
ELCDIF_RGB_DrawPixel(x,72,over_wrap_color);
ELCDIF_RGB_DrawPixel(x,122,over_wrap_color);
ELCDIF_RGB_DrawPixel(x,172,over_wrap_color);
ELCDIF_RGB_DrawPixel(x,222,over_wrap_color);
if(x==100||x==200||x==300)
ELCDIF_RGB_DrawVLine(x,32,240,over_wrap_color);
last_data=data;
}
至于SPI液晶彩屏嘛,自然就是显示一些简单的动态数据,如温湿度等,详情看一会的效果图就行了,不再赘述。
在处理这种动态双屏异显的任务中,有一个很重要的点一定要注意,就是不同任务之间的优先级分配,比方说我的Demo里面,涉及到ADC电压采集、
RX8010日历时钟读取和DHT11温湿度传感器数据采集,在我们的认知中,ADC采集相对于DHT11采集是要快得多的,并且DHT11是阻塞读取,需要busy waiting,因此,不能被DHT11的阻塞等待时间影响了ADC电压的采集,常规的解决方法有两个,一个简单一个复杂,简单的方法就是让DHT11任务执行优先级降低,比如5秒/10秒才采集一次数据,而不是每个循环都采集;复杂的方法就是利用实时操作系统的时钟节拍,在DHT11读取状态为忙即必须阻塞等待的时候,CPU切换到ADC的采集任务,等DHT11忙等待完成再进行数据读取,此方法实现效果要好于上面那个简单的方法,但是实现起来太复杂了,开发者必须具备操作系统的基础知识,这个以后再研究,本DEMO我使用的是第一种简单的方法,详情看代码:
while (1)
{
ADC_SetChannelConfig(ADC1,0,&adcChannelConfigStruct);
while(0==ADC_GetChannelStatusFlags(ADC1,0));
result=ADC1->R[0]/16;
if(result<0)result=0;
else if(result>=230)result=230;
ELCDIF_RGB_fun(i,result);
i++;
if(i==480)
{
i=0;
}
j++;
if(j==1000)
{
j=0;
if(DHT11_Read_Data(&temper,&humi)==0)
{
SPILCD_Draw_ASCIIChar(74,44,temper/10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(90,44,temper%10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(74,84,humi/10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(90,84,humi%10+'0',0,CYAN,ZF32_NORMAL);
}
RX8010_Get_Time();
SPILCD_Draw_ASCIIChar(74,124,year/10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(90,124,year%10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(122,124,month/10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(138,124,month%10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(170,124,mdate/10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(186,124,mdate%10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(74,164,hour/10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(90,164,hour%10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(122,164,min/10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(138,164,min%10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(170,164,sec/10+'0',0,CYAN,ZF32_NORMAL);
SPILCD_Draw_ASCIIChar(186,164,sec%10+'0',0,CYAN,ZF32_NORMAL);
}
SPILCD_DrawString(74,204,"关",0,CYAN,ZF32_NORMAL);
}
看看效果,改变电位器值可看到折线变化:
循环读取温度日期时间:
上传工程文件:
工程文件.zip
(1.24 MB, 下载次数: 14)
|
|