金牌会员
- 积分
- 1823
- 金钱
- 1823
- 注册时间
- 2014-8-5
- 在线时间
- 211 小时
|
一时来兴趣,想在OLED上运行STemwin,手上正好有个OLED板子。移植主要是参考这个帖子 http://bbs.armfly.com/read.php?tid=1678
这个帖子讲的还是非常详细的,我也是通过这个一步步然后自己慢慢测试完成的
移植遇到的问题及解决办法:
1、OLED内部没有显存,需要自己在单片机内部通过SRAM来实现显存
2、STemwin移植主要是实现画点、读点这两个函数,但由于OLED的打点我们是直接写bit 1到单片机内部SRAM显存,所以在显存写1的同时还需要把这个显存对应的数据写入OLED中,
实现单片机内部显存与OLED显示同步。读点函数则通过单片机内部显存返回该坐标数据。
[mw_shl_code=c,true]/*
*********************************************************************************************************
* 函 数 名: OLED_PutPixel
* 功能说明: 画1个像素
* 形 参:
* _usX,_usY : 像素坐标
* _ucColor :像素颜色
* 返 回 值: 无
*********************************************************************************************************
*/
void OLED_PutPixel(uint16_t _usX, uint16_t _usY, uint8_t _ucColor)
{
uint8_t ucValue;
uint8_t ucPageAddr;
uint8_t ucColAddr;
const uint8_t aOrTab[8] = {0x01, 0x02, 0x04, 0x08,0x10,0x20,0x40,0x80};
const uint8_t aAndTab[8] = {0xFE, 0xFD, 0xFB, 0xF7,0xEF,0xDF,0xBF,0x7F};
ucPageAddr = _usY / 8;
ucColAddr = _usX;
ucValue = s_ucGRAM[ucPageAddr][ucColAddr];
if (_ucColor == 0)
{
ucValue &= aAndTab[_usY % 8];
}
else
{
ucValue |= aOrTab[_usY % 8];
}
s_ucGRAM[ucPageAddr][ucColAddr] = ucValue;
if (s_ucUpdateEn == 1)
{
OLED_WriteCmd (0xB0 + ucPageAddr); /* 设置页地址(0~7) */
OLED_WriteCmd (0x00 + (ucColAddr & 0x0F)); /* 设置列地址的低地址 */
OLED_WriteCmd (0x10 + ((ucColAddr >> 4) & 0x0F)); /* 设置列地址的高地址 */
OLED_WriteData(ucValue);
}
/*
*********************************************************************************************************
* 函 数 名: OLED_GetPixel
* 功能说明: 读取1个像素
* 形 参:
* _usX,_usY : 像素坐标
* 返 回 值: 颜色值 (0, 1)
*********************************************************************************************************
*/
uint8_t OLED_GetPixel(uint16_t _usX, uint16_t _usY)
{
uint8_t ucValue;
uint8_t ucPageAddr;
uint8_t ucColAddr;
ucPageAddr = _usY / 8;
ucColAddr = _usX;
ucValue = s_ucGRAM[ucPageAddr][ucColAddr];
if (ucValue & (_usY % 8))
{
return 1;
}
else
{
return 0;
}
}
}[/mw_shl_code]
此驱动代码全是参考上面那个帖子里面的工程
3、此函数需要修改,我们采用的单色显示屏
[mw_shl_code=applescript,true]/*********************************************************************
*
* _GetDevData
*/
static void * _GetDevData(GUI_DEVICE * pDevice, int Index) {
GUI_USE_PARA(pDevice);
#if GUI_SUPPORT_MEMDEV
switch (Index) {
case LCD_DEVDATA_MEMDEV:
return (void *)&GUI_MEMDEV_DEVICE_1; // TBD: Has to be adapted to the right memory device depending on the used color depth!
}
#else
GUI_USE_PARA(Index);
#endif
return NULL;
}
[/mw_shl_code]
4、最最重要的一点!void LCD_X_Config(void)函数修改
#define XSIZE_PHYS 128 //给定层可见区的X尺寸 (单位:像素)
#define YSIZE_PHYS 64 //给定层可见区的Y尺寸 (单位:像素)
#define VXSIZE_PHYS 128 //给定层虚拟区的X尺寸 (单位:像素)
#define VYSIZE_PHYS 64 //给定层虚拟区的Y尺寸 (单位:像素)
[mw_shl_code=applescript,true]/*********************************************************************
*
* LCD_X_Config
*
* Function description:
* Called during the initialization process in order to set up the
* display driver configuration.
*
*/
void LCD_X_Config(void) {
// Set display driver and color conversion
//
// GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_1, 0, 0); //之前因为此语句 进入硬件中断
GUI_DEVICE_CreateAndLink(GUIDRV_TEMPLATE, GUICC_1, 0, 0);//改成这样成功解决
LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);
LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
}
[/mw_shl_code]
之前就是因为这个没有修改,结果在执行GUI_Init()函数后,进入硬件中断,跟踪发现调用的三个函数都没有出问题。当把这个函数修改好后成功解决,有兴趣的
朋友可以看下宏GUIDRV_FLEXCOLOR与宏GUIDRV_TEMPLAT两个的定义。
5、OLED的STemwin不需要太大内存,我这边开10K,暂时测试没有出现因为内存大小的问题
6、成功移植STemwin后,之前测试发现不能显示窗口,通过修改堆栈大小成功解决。大小都设置成0X800。
[mw_shl_code=applescript,true]Stack_Size EQU 0x800
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x800
AREA HEAP, NOINIT, READWRITE, ALIGN=3[/mw_shl_code]
7、由于F103C8T6 FLASH太小,当移植完STemwin后本想加入FreeRTOS,但是加入操作系统后,FLASH几乎就满了,所有没有移植。
8、STemwin 从V5.28版本开始,自动开启换肤功能,由于采用单色屏,当使用换肤后就没有层次感,所以需要手动把小工具的皮肤换成经典皮肤。
最后附上工程代码:
|
|