如何使用EFM8微控制器在LCD上显示图像
出处:维库电子市场网 发布于:2025-02-20 17:29:39
当前的项目将这些功能融合在一起,以有效,方便地在LCD上显示128 x-128像素图像。目的是从任何标准的灰度.bmp映像文件开始,然后使用SCILAB对其进行处理,然后通过USB将其传输到EFM8微控制器,以便我们可以在128 x-128 x-128像素LCD上显示。该项目仅处理一个图像,但是此处介绍的技术很容易地显示出由一系列相似图像组成的简单动画。
该过程始于使用Paint.net 或其他一些图像编辑应用程序创建图像。该图像被加载到SCILAB中,并处理为与LCD兼容的格式,转换为像素数据的矩阵,并通过64个字节USB数据包传输到EFM8。然后,使用更新的SPI状态机将此像素数据(四行)传输到LCD模块。
端口I/O。
端口I/O配置与我们在上一篇文章中使用的配置相同。
外围设备和中断
外围和中断设置与我们在上一篇文章中使用的内容相同:SPI配置用于与LCD模块的通信,而Timer4用于短延迟。我们在此项目中不使用timer2,因为我们不需要帧速率。相反,当从PC接收像素数据包时,LCD会顺序更新。
固件
该项目的VCP配置与我们在上一个项目中使用的配置相同。但是,还有一些其他USB功能:以前EFM8仅从SCILAB接收数据,而现在EFM8也会传输数据。
void USBTxByte(unsigned char BytetoSend)
{
Block_Write(&BytetoSend, 1, &USBBytesTransmitted);}
正如上面的block_write()函数的名称所暗示的那样,vcpxpress库能够使用一个函数调用传输一个字节数组。但是,在此项目中,来自EFM8的USB传输仅用于流量控制:EFM8发送一个字节来通知Scilab,该是时候发送更多数据了。因此,usbtxbyte()函数只是使用block_write()传输单个字节的便利方法。
收到的USB数据包处理以下代码:
if (API_InterruptCode & RX_COMPLETE) // USB read complete{if(USBBytesReceived == 1 && USBRxPacket[0] == NEW_IMAGE_FLAG){CLEAR_LCD = TRUE;
NextLinetoWrite = 0;
//return the new image flag byte to the PC for flow controlUSBTxByte(NEW_IMAGE_FLAG);//continue with the next USB read procedureBlock_Read(USBRxPacket, USB_PACKET_SIZE, &USBBytesReceived);}
else if(USBBytesReceived == USB_PACKET_SIZE){/*this flag tells the while loop in ImagetoLCD_main.cto process a received USB pixel data packet*/USB_PACKET_RECEIVED = TRUE;//continue with the next USB read procedureBlock_Read(USBRxPacket, USB_PACKET_SIZE, &USBBytesReceived);}
}
当Scilab脚本完成将图像文件转换为LCD像素数据时,它将发送一个单字节数据包,其中具有Imagetolcd_defs.h中定义为new_image_flag中的值。因此,如果接收到的数据包长度是一个,并且单个字节具有new_image_flag的值,则微控制器知道新图像正在途中。它清除了LCD,将new_image_flag传输到PC,并将零加载到NextLineToWrite中,该变量是一个变量,当MicroController接收下一个像素数据包时,它保留了要更新的行地址。如果接收到的数据包长度为64个字节而不是一个字节,则数据包将带来实际的像素数据。在这种情况下,我们只是将USB_Packet_received标志设置为true; LCD更新完成后,流量控制字节将发送。
当Imagetolcd_main.c中的无限循环意识到USB_Packet_received已将其设置为true时,它调用ProcessususBrxPacket():
void ProcessUSBRxPacket()
{
unsigned char n = 0, row, column;
//copy the received pixel data to the LCD display data arrayfor(row = 0; row < LINES_PER_PACKET; row++){for(column = 0; column < NUM_LINE_DATA_BYTES; column++){LCDDisplayData[row][column] = USBRxPacket[n];n++;}
}
//wait until the SPI state variable indicates that the bus is available for a new transferwhile(LCDTxState != IDLE);UpdateLCDLines();
}
在这里,我们将像素数据传输到适当的二维阵列中。在此项目中,lcddisplaydata [] []是4行乘16列:我们仍然需要16列字节来容纳128位水平数据,但是我们只需要4行,因为像素数据是从64个字节数据包中的PC传输的,和64个字节除以16个字节等于4行。更新数组后,程序等待直到LCD通信接口为空闲,然后调用UpdatelCdlines()。
该项目需要对管理SPI转移到LCD的状态机器进行一些更改。以前,我们具有UpdateAlllCdlines()函数,该函数(您可能会从名称中猜到)启动一个过程,该过程更新一个SPI传输中的所有LCD线路。但是现在,我们在一个SPI传输期间仅更新四行,并且在该过程结束时执行了另外两个任务:
SCILAB脚本中的另一个主要部分是通过VCP连接将像素数据发送到EFM8的FO循环:
SCILAB脚本还调用TIC()和TOC()来测量和显示传输和显示一个图像所需的时间。在上面提到的相同的2.5 GHz Windows机器的情况下,该过程仅需约50毫秒,这意味着该系统应该能够舒适地维持每秒10张图像的动画帧速率。
上一篇:电容屏和触摸屏的区别
下一篇:接口七个片段显示到Arduino
版权与免责声明
凡本网注明“出处:维库电子市场网”的所有作品,版权均属于维库电子市场网,转载请必须注明维库电子市场网,https://www.dzsc.com,违反者本网将追究相关法律责任。
本网转载并注明自其它出处的作品,目的在于传递更多信息,并不代表本网赞同其观点或证实其内容的真实性,不承担此类作品侵权行为的直接责任及连带责任。其他媒体、网站或个人从本网转载时,必须保留本网注明的作品出处,并自负版权等法律责任。
如涉及作品内容、版权等问题,请在作品发表之日起一周内与本网联系,否则视为放弃相关权利。
- ILI9341的接口,你了解吗2025/3/11 17:45:47
- 什么是lcd12864?lcd12864的特性及其应用举例2025/3/6 17:47:27
- 光是一种电磁波,那么光的频率是多少?2025/3/5 17:55:48
- 如何与MCU接口16×2 LCD模块2025/3/3 17:32:07
- CCD图像传感器类型:全帧,交际转移和帧转移CCD2025/3/3 16:53:13