呵呵~大家好,“Msp430f149驱动TFT显示”我以前发过,不过那时是用摄像头照的不清楚。现在为了参赛,就拍清楚点,写详细点。首先声明,我也是菜鸟,写得有不当的地方老鸟可千万别喷我呀~呵呵~
Msp430f149是一款片上资源很丰富的低功耗16位单片机。我就玩了一下它片上ADC、PWM、串口。其实想玩单片机很简单的(开发产品除外,因为你可能在硬件上遇到意想不到的问题。而且开发产品时程序都比较大。玩的话,程序就小多了,呵呵~当然DIY一个完整的作品,程序也不小。),基本上会C51的话其他的就比较容易上手了(ARM除外,主要我一直想学,但一直没入门,主要它涉及操作系统,俺是一点都不懂呀),前几天弄了一下AVR,感觉也还可以。不管AVR也好,MSP430也好它们和51单片机的区别就是它们有丰富的内部资源,这些资源的开放是通过内部的寄存器(可以看一下它们的技术手册)。我在弄Msp430驱动TFT时,就把它当做了一个简单的控制器来用,内部资源都没用(浪费呀~)。大家自学单片机,刚开始都很茫然,因为大家不了解它写程序编译烧录的流程和软件。其实只要有人把这些整理一下,大家跟着弄一遍就基本差不多。然后自己在写点小程序就,慢慢就觉得它不过如此。
我还是说Msp430吧,我们首先要知道它的编译环境。Msp430也有很多编译环境,我用的是IAR EW3.42A。这个环境带有硬件仿真(通过并口 Msp430 Jtag仿真器把程序下载到单片机里并可以一步一步在电脑上调试)。我用的液晶屏的型号是KLM256A01在网上找的资料是KGM256E3的,它们的引脚定义是一样的。本来比赛要求上电路图,但我的Protel Dxp有点问题,现在懒得弄,就一个最小系统上连一个液晶,下面我会将清楚的。反正就是一个交流。呵呵~
图1:这就是一个Msp430的最小系统,上面看着脏脏的东西是松香,主要是自己弄着玩,没必要弄阻焊剂(我也没弄过),所以涂了一层松香酒精溶液来抗氧化,不涂的话,现在大家看见的板应该都变黑了。这个最小系统上面就一个电源(两个1117,一个3.3伏的一个5伏的。单片机供电是3.3伏的,那个5伏纯粹是摆设,本来想用430的pwm来驱动舵机,由5V来给舵机供电,谁知道舵机电流大,舵机多了它带不起)。还有一个复位电路,就一个1M的电阻串一个104的电容。电阻上并了一个放电电的二极管(我感觉有没有都无所谓),电容上并的是复位按钮。耳机接口焊盘上焊了两个3.3V的稳压二极管是保护单片机的。
图2:最小系统的背面,那个耳机接口是来接串口的(模仿对讲机的),亮的那个是8M的晶振(Msp430f149支持最大的就是8M),黑的那个热缩了的是32K晶振。Msp430内部模块可由三种时钟源中的一种来提供(8M高速晶振,32k晶振,内部数控时钟源)。Msp430设置这么都晶振源的目的就是为了低功耗,这三种时钟源可有按生产需要随意搭配。(我一直都没用过它低功耗这个功能。因为我是在玩,等要干正事再说。呵呵~)我会把程序发上来,不过很乱,我画环,画正弦曲线,写字都是分开写的,要实现哪个就把其他的注释掉,呵呵~纯属娱乐,程序不是很规范,高手就给我指导指导哈,千万不要喷我呀~
图3:DIY的Jtag仿真器,网上找的图纸,芯片用的74ls244,做的单面板,技术不行,基本就剩飞线了,呵呵~
图4:两块板子用废硬盘数据线练在一起。
图5:画环
画环函数:
下面那个if后面跟的一长串就是计算圆的公式
void xie_huahuan(char r,char r1,char x,char y,char nv,char nan ,char hong) //r外圆半径,r1内圆半径,x,y坐标(圆心坐标) 绿蓝红(环的颜色)
{ // y=y*2;
int b,d;
for(d=0;d<y;d++)
{
for(b=0;b<176;b++) //我的液晶是220*176的分辨率,这个程序里的176就是这个屏的X轴的长度
{
if(b<x){
if((y-d)*(y-d)+(x-b)*(x-b)>r*r||(y-d)*(y-d)+(x-b)*(x-b)<r1*r1)
{
xie_d(0xff); //绿、蓝、红 一个像素是由三原色构成,
xie_d(0xff); //我这是在写一个像素点的数据,三个全
xie_d(0xff); // 写0xff是让这个点显示为白色
}
else{
xie_d(nv); //绿、蓝、红 这是在写环的颜色,改变他们的
xie_d(nan); //改变它们的值,环的颜色就会变化
xie_d(hong);}
}
else{
if((y-d)*(y-d)+(b-x)*(b-x)>r*r||(y-d)*(y-d)+(b-x)*(b-x)<r1*r1)
{
xie_d(0xff); //绿、蓝、红 同上面
xie_d(0xff);
xie_d(0xff);
}
else{
xie_d(nv); //绿、蓝、红
xie_d(nan);
xie_d(hong);;
}
}
}}
for(d=0;d<(220-y);d++)
{
for(b=0;b<176;b++)
{
if(b<x){
if(d*d+(x-b)*(x-b)>r*r||d*d+(x-b)*(x-b)<r1*r1)
{
xie_d(0xff); //绿、蓝、红
xie_d(0xff);
xie_d(0xff);
}
else{
xie_d(nv); //绿、蓝、红
xie_d(nan);
xie_d(hong);}
}
else{
if(d*d+(b-x)*(b-x)>r*r||d*d+(b-x)*(b-x)<r1*r1)
{
xie_d(0xff); //绿、蓝、红
xie_d(0xff);
xie_d(0xff);
}
else{
xie_d(nv); //绿、蓝、红
xie_d(nan);
xie_d(hong);;
}
}
}
}
}
我把一个环分解成4个份来画的,这个程序就是写来玩的,没有优化。
图6:画正弦曲线void xie_hua(char r,char x,char y,char w,char jx) //r幅值 x 曲线长度 y 曲线中心线 w线径 jx显示中心线的位置 照片上的那个白线就是中心线,位置可以上下调。
{ double jjk,jjh; // jjk,jjh变量都是自己随手定的,重要的是数据类型double
for(jjh=0;jjh<221;jjh++) //我以前就是这个数据类型搞错了,一直写不出来 {
for(jjk=0;jjk<176;jjk++){ if(r*sin((6.283185306*jjh)/x)+y<jjk||r*sin((6.283185306*jjh)/x)+y>jjk+w)
{ if(jjk==jx)
{xie_d(0xff); //绿、蓝、红 xie_d(0xff);
xie_d(0xff);} else{
xie_d(0); //绿、蓝、红 xie_d(0);
xie_d(0);} }
else {
xie_d(0xf0); //绿、蓝、红 xie_d(0xff);
xie_d(0); }
}
}}
图7:写汉字,这个有点难度,不过想明白了就没啥。这个我没写子函数,直接是写在主函数里的,我上面写了几个字,就用了几个这样的函数。我所这个难是因为我没找到彩色字模提取软件,而且用彩色字模提取软件提取的数据量也是很大的,假设是一个16*16的点阵,彩色字模的大小是:16*16*3Byte=768Byte,用普通的黑白液晶的字模的话 16*16/8=32Byte。最开始就是没有想明白在把这32Byte扩展成768Byte。现在这个问题解决了。注释在下面程序里。(这个程序还不完善,网友有兴趣可以自己完善,我就是玩。呵呵~)
xie_c(0x2a); // xie_dd(0); //
xie_dd(0x10); // xie_dd(0); //
xie_dd(0x77); // xie_c(0x2b); //
xie_dd(0); // xie_dd(0x10); //
xie_dd(0); // xie_dd(0x70); // 上面的这些语句是在对SPFD54126B进行操作,告诉它我要在什么位置写多大的一个字
xie_c(0x2c); 对SPFD54126B操作,写显示寄存器 for(kl=0;kl<1261;kl++) //这个字是由1261个点组成,就是那个大的“乐”
{ vb=hz2[kl]; //“乐”的单色字模存在数组hz2[]中,KL是for循环的参数,每循环一次KL加一,这条语句就是把数组中的第KL个元素给VB这个变量
for(bb=0;bb<8;bb++) {
cc=(vb&0x80)&&1; //VB与十六进制0x80位与,如果vb的最高位是1,cc就是1 xie_d(cc*0); //@ CC为“1”的点就点亮,cc为"0"的点就是黑色(我字的底色就是黑色,照片上周围那些雪花是因为我没有对那些显示寄存器操作)。
xie_d(cc*0xff);//@ xie_d(cc*0); //@ 带@的这数据就是在写三原色显示寄存器,为“0ff”那个原色就全开,显示出来的字就是这个颜色。
vb=vb<<1; }
}