开发板:Tiny6410
显示屏:S70
交叉编译: gcc-3.4.5-glibc-2.3.6
标准c库以及数学函数库:arm-uclibc-3.4.6
GUI: ucgui
github:
https://github.com/felixwangithub/non-os/tree/master/19.ucguiLCD_S70驱动:#include "lcd_s70.h"
// 初始化LCD
void LCD_S70_Init(void)
{
// 配置GPIO用于LCD相关的功能
GPICON = 0xAAAAAAAA;
GPJCON = 0x00AAAAAA;
// normal mode
MIFPCON &= ~(1<<3);
// RGB I/F
SPCON = (SPCON & ~(0x3)) | 1;
// 配置VIDCONx,设置接口类型、时钟、极性和使能LCD控制器等
// 16位
VIDCON0 = (0<<26)|(0<<17)|(0<<16)|(0<<6)|(0<<5)|(1<<4)|(0<<2)|(3<<0);
// HSYNC VSYNC 反转
VIDCON1 |= 1<<5 | 1<<6;
// 配置VIDTCONx,设置时序和长宽等
// 设置时序
VIDTCON0 = VBPD<<16 | VFPD<<8 | VSPW<<0;
VIDTCON1 = HBPD<<16 | HFPD<<8 | HSPW<<0;
// 设置长宽
VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);
// 配置WINCON0,设置window0的数据格式
// 配置RGB位数: 24BPP
WINCON0 |= 1<<0;
WINCON0 &= ~(0xf << 2);
//WINCON0 |= 0x5<<2;
//WINCON0 |= 0x1<<16;//当字体颠倒
WINCON0 |= 0xB<<2;
// 配置VIDOSD0A/B/C,设置window0的坐标系
#define LeftTopX 0
#define LeftTopY 0
#define RightBotX 799
#define RightBotY 479
VIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);
VIDOSD0B = (RightBotX<<11) | (RightBotY << 0);
VIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1);
// 置VIDW00ADD0B0和VIDW00ADD1B0,设置framebuffer的地址
VIDW00ADD0B0 = FRAME_BUFFER;
VIDW00ADD1B0 = (((HOZVAL + 1)*4 + 0) * (LINEVAL + 1)) & (0xffffff);
}
void LCD_SetPixel(unsigned int x, unsigned int y, unsigned int Color)
{
unsigned long * pixel = (unsigned long *)FRAME_BUFFER;
*(pixel + y * COL + x) = Color;
}
unsigned int LCD_GetPixel(unsigned int x, unsigned int y)
{
unsigned long * pixel = (unsigned long *)FRAME_BUFFER;
return *(pixel + y * COL + x);
}
void LCD_ClearScreen(unsigned int Color)
{
int i, j;
for (i = 0; i < ROW; i++)
for (j = 0; j < COL; j++)
LCD_SetPixel(j, i, Color);
}
修改LCDTemplate.c:/*********************************************************************
*
* LCD_L0_SetPixelIndex
*
* Purpose:
* Sets the index of the given pixel. The upper layers
* calling this routine make sure that the coordinates are in range, so
* that no check on the parameters needs to be performed.
*/
void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {
GUI_USE_PARA(x);
GUI_USE_PARA(y);
GUI_USE_PARA(PixelIndex);
/* Convert logical into physical coordinates (Dep. on LCDConf.h) */
#if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
int xPhys = LOG2PHYS_X(x, y);
int yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
/* Write into hardware ... Adapt to your system */
{
LCD_SetPixel(x,y,PixelIndex);
}
}
/*********************************************************************
*
* LCD_L0_GetPixelIndex
*
* Purpose:
* Returns the index of the given pixel. The upper layers
* calling this routine make sure that the coordinates are in range, so
* that no check on the parameters needs to be performed.
*/
unsigned int LCD_L0_GetPixelIndex(int x, int y) {
LCD_PIXELINDEX PixelIndex;
GUI_USE_PARA(x);
GUI_USE_PARA(y);
/* Convert logical into physical coordinates (Dep. on LCDConf.h) */
#if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
int xPhys = LOG2PHYS_X(x, y);
int yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
/* Read from hardware ... Adapt to your system */
{
PixelIndex = (LCD_PIXELINDEX)(LCD_GetPixel(x, y));
}
return PixelIndex;
}
使用Timer0定时中断,在中断服务函数中更新OS_TimeMS:extern volatile int OS_TimeMS;
void irq_init(void)
{
/* 在中断控制器里使能timer0中断 */
VIC0INTENABLE |= (1<<23);
}
// timer0中断的中断处理函数
void do_irq(void)
{
OS_TimeMS++;
printf("OS_TimeMS=%d\r\n",OS_TimeMS);
//清timer0的中断状态寄存器
TINT_CSTAT |= 1<<5;
}
// 初始化timer
void timer_init(unsigned long ms)
{
// PCLK = 66MHz
// 定时器的输入时钟 = PCLK / ( {prescaler value + 1} ) / {divider value} = PCLK/(65+1)/1=1Mhz(0.001ms)
//设置预分频系数为65
TCFG0 |= 65;
// 1分频, 定时器时钟为1Mhz(0.001ms)
TCFG1 = 0;
// 1s = 1Mhz, 1ms = 1000Hz, 1ns = 1Hz
TCNTB0 = (ms*1000);
TCMPB0 = 0;
// 手动更新
TCON |= 1<<1;
// 清手动更新位
TCON &= ~(1<<1);
// 自动加载和启动timer0
TCON |= (1<<0)|(1<<3);
// 使能timer0中断
TINT_CSTAT |= 0x1;
}
[ 此帖被flygo在2018-12-20 01:20重新编辑 ]