lcd.c源码:
#define GPECON (*((volatile unsigned long *)0x7F008080))
#define GPEDAT (*((volatile unsigned long *)0x7F008084))
#define GPFCON (*((volatile unsigned long *)0x7F0080A0))
#define GPFDAT (*((volatile unsigned long *)0x7F0080A4))
#define GPICON (*((volatile unsigned long *)0x7F008100))
#define GPJCON (*((volatile unsigned long *)0x7F008120))
// display controller
#define MIFPCON (*((volatile unsigned long *)0x7410800C))
#define SPCON (*((volatile unsigned long *)0x7F0081A0))
#define VIDCON0 (*((volatile unsigned long *)0x77100000))
#define VIDCON1 (*((volatile unsigned long *)0x77100004))
#define VIDTCON0 (*((volatile unsigned long *)0x77100010))
#define VIDTCON1 (*((volatile unsigned long *)0x77100014))
#define VIDTCON2 (*((volatile unsigned long *)0x77100018))
#define WINCON0 (*((volatile unsigned long *)0x77100020))
#define VIDOSD0A (*((volatile unsigned long *)0x77100040))
#define VIDOSD0B (*((volatile unsigned long *)0x77100044))
#define VIDOSD0C (*((volatile unsigned long *)0x77100048))
#define VIDW00ADD0B0 (*((volatile unsigned long *)0x771000A0))
#define VIDW00ADD1B0 (*((volatile unsigned long *)0x771000D0))
#define VIDW00ADD2 (*((volatile unsigned long *)0x77100100))
#define WPALCON (*((volatile unsigned long *)0x771001A0))
#define WIN0_PALENTRY0 0x77100400
#define VSPW 9
#define VBPD 1
#define LINEVAL 271
#define VFPD 1
#define HSPW 40
#define HBPD 1
#define HOZVAL 479
#define HFPD 1
#define LeftTopX 0
#define LeftTopY 0
#define RightBotX 479
#define RightBotY 271
#define FRAME_BUFFER 0x54000000
unsigned int fb_base_addr;
unsigned int bpp;
unsigned int xsize;
unsigned int ysize;
void palette_init(void)
{
int i;
volatile unsigned long *p = (volatile unsigned long *)WIN0_PALENTRY0; //调色板地址
WPALCON |= (1<<9); // 允许CPU修改调色板
WPALCON &= ~(0x7);
WPALCON |= 1; // 调色板的数据格式: 24-bit ( 8:8:8 )
p[0] = 0x000000; //只初始化了调色板的前五格的颜色值
p[1] = 0x00ff00;
p[2] = 0xff0000;
p[3] = 0x0000ff;
p[4] = 0xffffff;
for (i = 0; i <256; i++) //用调色板以后显存的bpp=8,8最大能表示256个地址,也就是调色板最大有256项
{
//p[i] = ;
}
WPALCON &= ~(1<<9); // 禁止CPU访问调色板
}
void clean_screem(void)
{
int x;
int y;
int cnt = 0;
volatile unsigned char *p = (volatile unsigned char *)fb_base_addr;
for (x = 0; x <=HOZVAL; x++)
for (y = 0; y <= LINEVAL; y++)
p[cnt++] = 0;
}
void lcd_init(void)
{
// 1. 设置相关GPIO引脚用于LCD
GPICON = 0xaaaaaaaa; // gpi0~gpi15用作lcd_vd[0~15]
GPJCON = 0xaaaaaaa; // gpj0~gpi11用作lcd
//GPFCON &= ~(0x3<<28);
//GPFCON |= (1<<28); // GPF14用作背光使能信号
GPECON &= ~(0xf);
GPECON |= (0x1); // GPE0用作LCD的on/off信号
// 2. 初始化6410的display controller
// 2.1 hsync,vsync,vclk,vden的极性和时间参数
// 2.2 行数、列数(分辨率),象素颜色的格式
// 2.3 分配显存(frame buffer),写入display controller
MIFPCON &= ~(1<<3); // Normal mode
SPCON &= ~(0x3);
SPCON |= 0x1; // RGB I/F style
#if 0
VIDCON0 &= ~((3<<26) | (3<<17) | (0xff<<6)); // RGB I/F, RGB Parallel format,
// vclk== 27MHz Ext Clock input / (CLKVAL+1) = 27/3 = 9MHz
VIDCON0 |= ((2<<6) | (1<<4) | (0x3<<2));
#else
VIDCON0 &= ~((3<<26) | (3<<17) | (0xff<<6) | (3<<2)); // RGB I/F, RGB Parallel format,
VIDCON0 |= ((14<<6) | (1<<4) ); // vclk== HCLK / (CLKVAL+1) = 133/15 = 9MHz
#endif
VIDCON1 &= ~(1<<7); // 在vclk的下降沿获取数据
VIDCON1 |= ((1<<6) | (1<<5)); // HSYNC高电平有效, VSYNC高电平有效,
VIDTCON0 = (VBPD << 16) | (VFPD << 8) | (VSPW << 0);
VIDTCON1 = (HBPD << 16) | (HFPD << 8) | (HSPW << 0);
VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);
WINCON0 &= ~(0xf << 2);
WINCON0 |= (0x3<<2) | (1<<17); // 8 BPP (palletized), byte swap
VIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);
VIDOSD0B = (RightBotX<<11) | (RightBotY << 0);
VIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1) / 4;
VIDW00ADD0B0 = FRAME_BUFFER;
VIDW00ADD1B0 = (((HOZVAL + 1)*1 + 0) * (LINEVAL + 1)) & (0xffffff);
// VBASEL = VBASEU + (LINEWIDTH+OFFSIZE) x (LINEVAL+1)
// = 0 + (480*1 + 0) * 272
// =
//VIDW00ADD2 = HOZVAL + 1;
// 设置调色板
palette_init();
pwm_set(2);
fb_base_addr = FRAME_BUFFER;
xsize = HOZVAL + 1;
ysize = LINEVAL + 1;
bpp = 8;
clean_screem();
}
void backlight_enable(void)
{
//GPFDAT |= (1<<14);
}
void backlight_disable(void)
{
//GPFDAT &= ~(1<<14);
}
void lcd_on(void)
{
GPEDAT |= (1<<0);
// 等待10 frame
}
void lcd_off(void)
{
GPEDAT &= ~(1<<0);
}
void displaycon_on(void)
{
VIDCON0 |= 0x3;
WINCON0 |= 1; //6410的lcd控制器有多个窗口,这里只使能了一个窗口
}
void displaycon_off(void)
{
VIDCON0 &= ~0x3;
WINCON0 &= ~1; //6410的lcd控制器有多个窗口,这里只使能了一个窗口
}
void lcd_enable(void)
{
// 使能LCD本身
lcd_on();
// 打开背光
//backlight_enable();
pwm_start();
// 使能display controller
displaycon_on();
}
void lcd_disable(void)
{
// 关闭背光
// 关闭LCD本身
// 关闭display controller
}
void draw_line(void)
{
//不用调色板的时候画线传入的是24位颜色值,用调色板以后传入的是在调色板中的颜色索引值
DrawLine(0,0, 0,271, 0);
DrawLine(0,0, 479,0, 1);
DrawLine(0,0, 479,271, 2);
DrawLine(0,271, 479,0, 3);
DrawLine(0,271, 479,271, 1);
DrawLine(479,271, 479,0, 2);
DrawLine(0,136, 479,136, 3);
DrawLine(240,0, 240,271, 1);
}
void display_red(void)
{
volatile unsigned char *p = (volatile unsigned char *)FRAME_BUFFER;
int x, y;
int cnt = 0;
unsigned char colors[] = {0, 1, 2, 3};
static int color_idx = 0;
for (y = 0; y <= LINEVAL; y++)
{
for (x = 0; x <= HOZVAL; x++)
{
p[cnt++] =colors[color_idx] ; // red
}
}
color_idx++;
if (color_idx == 5)
color_idx = 0;
}
void lcd_test(void)
{
unsigned char c;
static int lcdon = 0;
static int blon = 0;
static int dispon = 0;
lcd_init();
while (1)
{
printf("********LCD TEST MENU********\n\r");
printf("[L] enable/disable LCD\n\r");
printf("[B] enable/disable back light\n\r");
printf("[C] enable/disable s3c6410 display controller\n\r");
printf("[D] display color\n\r");
printf("[I] draw line\n\r");
printf("[Q] quit\n\r");
do {
c = getc();
if (c == '\n' || c == '\r')
{
printf("\n\r");
}
else
{
putc(c);
}
} while (c == '\n' || c == '\r');
switch (c) {
case 'l':
case 'L':
{
if (lcdon)
{
lcd_off();
printf("LCD off\n\r");
}
else
{
lcd_on();
printf("LCD on\n\r");
}
lcdon = !lcdon;
break;
}
case 'b':
case 'B':
{
pwm_menu();
break;
}
case 'c':
case 'C':
{
if (dispon)
{
displaycon_off();
printf("Display controller off\n\r");
}
else
{
displaycon_on();
printf("Display controller on\n\r");
}
blon = !blon;
break;
}
case 'd':
case 'D':
{
display_red();
break;
}
case 'i':
case 'I':
{
draw_line();
break;
}
case 'q':
case 'Q':
{
return ;
break;
}
}
}
}
=====================================================================
framebuffer.c源码:
// FILE: framebuffer.c
// 实现在framebuffer上画点、画线、画同心圆、清屏的函数
#include "types.h"
#include "framebuffer.h"
extern unsigned int fb_base_addr;
extern unsigned int bpp;
extern unsigned int xsize;
extern unsigned int ysize;
//typedef UINT32 FB_24BPP[272][480];
// 画点
// 输入参数:
// x、y : 象素坐标
// color: 颜色值
// 对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),
// 需要转换为5:6:5格式
// 对于8BPP: color为调色板中的索引值,
// 其颜色取决于调色板中的数值
void PutPixel(UINT32 x, UINT32 y, UINT32 color)
{
UINT8 red,green,blue;
switch (bpp){
case 24:
{
//bpp=24位,但是为了对齐会浪费一个字节,一共4字节32位
UINT32 *addr = (UINT32 *)fb_base_addr + (y * xsize + x);
*addr = color;
break;
}
case 16:
{
UINT16 *addr = (UINT16 *)fb_base_addr + (y * xsize + x);
red = (color >> 19) & 0x1f;
green = (color >> 10) & 0x3f;
blue = (color >> 3) & 0x1f;
color = (red << 11) | (green << 5) | blue; // 格式5:6:5
*addr = (UINT16) color;
break;
}
case 8:
{
UINT8 *addr = (UINT8 *)fb_base_addr + (y * xsize + x);
*addr = (UINT8) color; // 调色板的索引值
break;
}
default:
break;
}
}
// 画线
// 输入参数:
// x1、y1 : 起点坐标
// x2、y2 : 终点坐标
// color : 颜色值
// 对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),
// 需要转换为5:6:5格式
// 对于8BPP: color为调色板中的索引值,
// 其颜色取决于调色板中的数值
void DrawLine(int x1,int y1,int x2,int y2,int color)
{
int dx,dy,e;
dx=x2-x1;
dy=y2-y1;
if(dx>=0)
{
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 1/8 octant
{
e=dy-dx/2;
while(x1<=x2)
{
PutPixel(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1+=1;
e+=dy;
}
}
else // 2/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
PutPixel(x1,y1,color);
if(e>0){x1+=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else // dy<0
{
dy=-dy; // dy=abs(dy)
if(dx>=dy) // 8/8 octant
{
e=dy-dx/2;
while(x1<=x2)
{
PutPixel(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1+=1;
e+=dy;
}
}
else // 7/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
PutPixel(x1,y1,color);
if(e>0){x1+=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
else //dx<0
{
dx=-dx; //dx=abs(dx)
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 4/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
PutPixel(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else // 3/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
PutPixel(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else // dy<0
{
dy=-dy; // dy=abs(dy)
if(dx>=dy) // 5/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
PutPixel(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else // 6/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
PutPixel(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
}
// 绘制同心圆
void Mire(void)
{
UINT32 x,y;
UINT32 color;
UINT8 red,green,blue,alpha;
for (y = 0; y < ysize; y++)
for (x = 0; x < xsize; x++){
color = ((x-xsize/2)*(x-xsize/2) + (y-ysize/2)*(y-ysize/2))/64;
red = (color/8) % 256;
green = (color/4) % 256;
blue = (color/2) % 256;
alpha = (color*2) % 256;
color |= ((UINT32)alpha << 24);
color |= ((UINT32)red << 16);
color |= ((UINT32)green << 8 );
color |= ((UINT32)blue );
PutPixel(x,y,color);
}
}
// 将屏幕清成单色
// 输入参数:
// color: 颜色值
// 对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),
// 需要转换为5:6:5格式
// 对于8BPP: color为调色板中的索引值,
// 其颜色取决于调色板中的数值
void ClearScr(UINT32 color)
{
UINT32 x,y;
for (y = 0; y < ysize; y++)
for (x = 0; x < xsize; x++)
PutPixel(x, y, color);
}
#define FONTDATAMAX 2048
extern const unsigned char fontdata_8x8[FONTDATAMAX];
void lcd_putc(unsigned char c)
{
static int x = 0;
static int y = 0;
int i,j;
unsigned char line_dots;
// 获得字模
unsigned char *char_dots = fontdata_8x8 + c * 8;
// 在framebuffer里描点
if (c == '\n')
{
//y = (y + 8) % 272;
y += 8;
if (y > 272)
y = 0;
return ;
}
else if (c == '\r')
{
x = 0;
return;
}
for (i = 0; i < 8; i++)
{
line_dots = char_dots[i];
for (j = 0; j < 8; j++)
{
if (line_dots & (0x80 >> j))
{
PutPixel(x+j, y+i, 1); // 调色板里面第1个条目的颜色值
}
else
{
PutPixel(x+j, y+i, 0); // 调色板里面第0个条目的颜色值
}
}
}
//x = (x + 8) % 480;
x += 8;
if (x > 480)
x = 0;
if (x == 0)
{
//y = (y + 8) % 272;
y += 8;
if (y > 272)
y = 0;
}
}
上一篇:自己写bootloader之OK6410
下一篇:OK6410裸机之LCD显
推荐阅读
史海拾趣
随着国内市场的稳定发展,佰宏公司开始积极拓展海外市场。他们的产品被多个海外电商平台上架,受到了国际客户的青睐。这一举措不仅提升了公司的国际化水平,也为公司的长期发展注入了新的动力。
随着全球对环境保护和可持续发展的关注度不断提升,Avasem公司积极响应这一趋势,将可持续发展理念融入公司的战略规划和日常运营中。公司采用环保材料和工艺生产电子产品,降低生产过程中的能源消耗和废弃物排放。同时,Avasem公司还积极参与社会公益事业,支持教育、环保等领域的项目。这些举措不仅提升了公司的社会形象,还为其赢得了更多消费者的支持和信任。
请注意,以上故事均为虚构内容,旨在展示一个电子行业公司可能的发展路径和策略。在实际情况下,一个公司的成长会受到多种因素的影响,包括市场环境、技术发展趋势、公司战略选择等。因此,这些故事并不能完全代表任何真实存在的电子行业公司的发展历程。
背景:1966年,在贵州凯里白午山区,国营新云器材厂(后更名为振华新云)正式成立,标志着公司的诞生。
内容:成立初期,公司面临着技术落后、设备陈旧等困难。然而,在老一辈员工的艰苦奋斗下,公司逐渐摸索出适合自身的发展道路。通过引进新技术、优化生产流程,不断提高产品质量和生产效率。
成果:经过几年的努力,振华新云逐渐在电子元器件行业崭露头角,为后续的快速发展奠定了坚实基础。
经过数年的技术积累和市场拓展,诚芯微在2013年注册了自主品牌CXW,标志着其品牌战略的正式启动。同年,公司推出了一系列具有竞争力的电源芯片产品,凭借其卓越的性能和稳定的品质,逐渐在市场中获得了认可。此外,诚芯微还加强了与上游晶圆制造、封装企业的合作,确保了产品的质量和良率。
在2020年,诚芯微与BYD、小米、公牛等知名企业建立了战略合作伙伴关系,共同推动电源芯片在汽车电子、智能家居等领域的应用。通过与这些行业巨头的合作,诚芯微不仅拓展了市场渠道,还提升了品牌影响力。同时,公司还加大了对新能源汽车电源管理芯片的研发力度,为新能源汽车产业的发展提供了有力支持。
芯茂微电子始终坚持以创新驱动发展,不断投入研发资源,推动技术创新和产品升级。同时,公司积极寻求与国内外知名企业和研究机构的合作,共同开展技术研发和市场拓展。通过与合作伙伴的紧密合作,芯茂微电子在集成电路设计、制造工艺、封装测试等方面取得了重要进展,进一步提升了公司的核心竞争力和市场地位。
1、汽车电子产品概述 近年来,越来越严格的安全、环保技术法规和用户苛刻的个性化使用要求使得制造商不得不依赖电子技术不断改进其产品的性能,可以说汽车技术所取得的每一项进步都离不开电子技术在汽车上的应用。电子技术的应用几乎已经深入到汽 ...… 查看全部问答∨ |
|
好久没来这里啦,大家好哇。 最近调试一个东东,老大说要预留内存给这个驱动,以前是HalAllocateCommonBuffer动态申请连续内存空间的。 我想问下,这个预留的好处在哪里呢? 能节约内存空间吗? 谢谢啦… 查看全部问答∨ |
我整理一份比较表格,方便大家参考. RampageII vs GENE照片如下. Extreme-Vcore GENE-Vcore Extreme-IO GENE-IO PCB Layer compare … 查看全部问答∨ |
设计资源 培训 开发板 精华推荐
- 遇见春天,“愚”你同乐 快来与keysight一起学习 光通信测试测量解决方案 下载赢好礼!
- Arrow&allegro有奖直播:下一代磁感应解决方案:XtremeSense™ TMR 技术如何促进高效应用
- 直播已结束|TI 嵌入式直播周带您直击工业应用
- 免费申请评测:欧时电子(RS Components)树莓派3来袭,待你玩耍带你飞
- 12月6日上午10:00有奖直播:如何使用Microchip安全方案为IoT设备保驾护航
- 创新驱动变革,R&S示波器助力功率电子测试
- 《开关电源的早期历史》终结篇:烛古鉴今,如何解决问题?
- 有奖下载 |《设计无线通信系统时需考虑的天线因素》
- 申请ufun学习板,入门&深度学习模拟,工程技能