本帖最后由 校园故事 于 2012-10-26 09:51 编辑
院系:桂林电子科技大学 电子工程与自动化学院
我今年大三,可以说过去的两年多的时间,都是在实验室度过。
我和TI的故事,基本上就是我和MSP430的故事!
从大一刚进大学校园,就在在嵌入式系统训练基地里学习,大一上学期的努力,熟悉了51单片机,后来一个学长告诉我有一个型号的单片机,只要用几个水果就可以供电,而且可以运行很长的时间,它的低功耗和丰富强悍的片内资源让我着迷。那就是MSP430!!!而且,TI对于大学生有着优惠的支持,可以免费申请芯片!之后的一年多,一直在和MSP430打交道!
从msp430f149到MSP430F6638,从基本的IO到66系列的usb,越来越喜欢430!但是单片机只是一个平台,一个让我的代码运行的平台,在熟悉了430之后,使用430做过低功耗的超声波测距,430主控的简易信号发生器,430主控的循迹智能小车,430重力感应游戏机!!!
下面就说一说我的游戏机吧:
我的 重力感应游戏机(msp430主控,adxl345三轴加速度计, 大二的作品)
暑假没回家,琢磨着做点东西。恰好看到一个同样不回家的朋友在做03年的电子设计国赛题目,跷跷板爬坡小车。他用到了ADXL345重力感应加速度计,觉得不错,可以拿来玩玩,而且最近体感有关的也很热门,呵呵,做一个重力感应游戏机试试?
前前后后大概一个礼拜多的时间写出了第一版程序(直接用以前的430小班子加杜邦线加模块),直接控制adxl的角度(X/Y轴)划算成屏幕的坐标,后来发现这样不好,控制很不好。花了一个下午改成了只要x轴往左就屏幕的显示小人往左,往右就小人往右。但是又发现,控制很灵敏,太灵敏也不好。因为。。。即使传感器水平摆放,但是由于手的抖动,还是会不停的左移右移。后来加了阈值判断处理。嗯嗯,不错,然后加了难度控制,各种人物死法。。。
最让我喜欢的是整个作品的屏幕驱动。 使用的是常见的 nokia 5110屏幕,但是用过的人知道,他是不能很好直接控制某一个点,而是只能一次控制屏幕上的一页(纵向8个点)。后来想可以通过计算点的偏移量来控制具体的纵向一个点。
于是,我这样写:
void draw_point(unsigned char x,unsigned int y)//84列,6行,每行8个点
{
if(x > x_max)
x = x_max;
if(y > y_max)
y = y_max;
unsigned char hang = 0,yu = 0; // 列的增进量
hang = y / 8;
yu = (0x01 << (y % 8));
LCD_set_XY(x,hang);
LCD_write_byte(yu,1);
}
包括后来发现很多人,几乎大多数用5110屏幕的都会这样写。但是!!!
如果你这样做你就会发现,画竖线就悲剧了!
纵向的连续8个点(1 page)只能有一个点,因为其他的点都被后面的点的偏移量给偏移跑了!
So,我这样,
想到了以前学easyX图像编程的时候的帧缓存,先存在显存里(一个二维数组),再一起显示。这样就可以 运用C语言里面的 |= 或等于,使得后面的点的偏移量不影响之前画的点,同时还能够进行显示的叠加。所以~~可以看到我显示汉字或者别的图形,是可以做到类似于透明背景的效果!!!
程序是这样,先定义个缓存:
unsigned char dis_buf[6][84] = {
0x00
};
然后:
/*------------------------------------------
//画点的函数
直接在屏幕上画点来画图不可以
因为yu = (0x01 << (y % 8));这一句会导致把别的点
用空格覆盖掉,要想办法用 |=,所以,嘿嘿,缓存就可以了
------------------------------------------*/
void draw_point(unsigned char x,unsigned int y)//84列,6行,每行8个点
{
if(x > x_max)
x = x_max;
if(y > y_max)
y = y_max;
unsigned char hang = 0,yu = 0; // 列的增进量
hang = y / 8;
yu = (0x01 << (y % 8));
dis_buf[hang][x] |= yu;
}
对显示缓冲先修改。
到显示的时候这样用:
void buffer_clear();
//这里放你需要显示的东西比如
draw_point(44,12);
draw_circle(24,24,8);
buffer_show();
就可以啦!!
你会发现,现在显示任何东西都和以前使用ILI9320等彩屏之类的点阵屏幕一样正常了,
而且,那些画线啊,画圆函数啊都可以移植过来了。
/************************************************************
帧缓存 这里使用到了将改变的要显示的点先存储在数组(buffer)里面
下次显示再整幅画面一起刷新。
************************************************************/
void buffer_show() // 帧缓存 这里使用到了将改变的要显示的点先存储在数组(buffer)里面
{
unsigned char y,x;
LCD_set_XY(0,0);
for(y = 0;y < 6;y ++)
for(x = 0;x < 84; x++)
{
LCD_write_byte(dis_buf[y][x],1);
}
}
void buffer_clear()
{
unsigned char y,x;
for(y = 0;y < 6;y ++)
for(x = 0;x < 84; x++)
{
dis_buf[y][x] = 0X00;
}
}
很多人(像我这样的菜鸟)也许会这样说:
你显示东西要那么麻烦,还要多几句清除缓存,显示缓存,多麻烦!
但是,如果你做过图像处理,想要做到显示叠加,放大,缩小,移动,就要用到显存了。当然,像以前接触过的S3C2440等高级的ARM自带TFT处理能力的除外。。。
这个只限于使用一般的MCU控制LCD。思想是通用的嘛。呵呵。
大三了,头疼是考验还是继续在实验室呆着。。。O(︶︿︶)o 唉人生啊。 |