微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > FFT算法在单片机中的使用&&LCD12864驱动

FFT算法在单片机中的使用&&LCD12864驱动

时间:11-30 来源:互联网 点击:

再次进行功能设定;

7. 延时37us;

8. 显示开关控制;

9. 延时100us以上;

10. 清除显示;

11. 延时10ms以上;

12. 进入点设置;

13. 初始化结束;

LCD液晶屏初始化过程如图所示为:

打点函数

打点函数是创建GUI的基础,打点函数的书写分为以下几个步骤:

1. 进入扩展模式

2. 写入打点地址

3. 读取该地址的数据

4. 修改该地址的数据

5. 将修改后的数据输入LCD中

6. 进入普通模式

GDRAM地址分布情况,需要注意的是横纵坐标的起始地址都是0x80,还有上下半屏的横坐标是不一样的,下半屏的横坐标要加上0x08,而纵坐标跟对应的上半屏的纵坐标是一样的。GDRAM地址分布图,如图所示。

下面的函数是12864与FFT算法的一个结合,里面设置了一个门函数,12864上显示的结果则是一个sinc函数,证明结果是正确的。

#include

#include

#include

#define N 128

#define PI 3.141592653589

#define uchar unsigned char

#define uint unsigned int

#define RS (1<4)

#define RW (1<5)

#define EN (1<6)

//

typedef struct

{

int real;

int img;

}complex;

void initw(); //初始化旋转因子

void bitReverse(); //比特反转

void FFT();

complex x[N];

uchar vis[N];

void delayms(uint ms)

{

uint i,j;

for(i=0;i{

for(j=0;j<3;j++);

}

}

//此处定义字符串

//写数据

void WriteDataLCM(unsigned char WDLCM) //写数据函数

{

// ReadStatusLCM(); //检测忙

delayms(1);

PORTA|=RS; //RS=1

delayms(1);

PORTA&=~RW; //RW=0

delayms(1);

PORTA|=EN; //EN=1

delayms(1);

PORTB=WDLCM; //输出数据

delayms(1);

PORTA&=~EN; //EN=0

delayms(1);

}

//写指令

void WriteCommandLCM(unsigned char WCLCM) //写命令函数

{

// ReadStatusLCM(); //根据需要检测忙

delayms(1);

PORTA&=~RS; //RS=0

delayms(1);

PORTA&=~RW; //RW=0

delayms(1);

PORTA|=EN; //EN=1

delayms(1);

PORTB=WCLCM; //输出指令

delayms(1);

PORTA&=~EN; //EN=0

delayms(1);

}

//读状态:检测忙

void ReadStatusLCM() //读状态函数

{

uchar temp;

uchar flag = 1;

while(flag==1)

{

PORTB=0xff;

delayms(1);

DDRB=0x00; //端口B改为输入

delayms(1);

PORTA&=~RS; //RS=0

delayms(1);

PORTA|=RW; //RW=1

delayms(1);

PORTA|=EN; //EN=1

delayms(10);

temp = PINB; //读端口B

delayms(10);

DDRB=0xff; //端口B改为

delayms(10);

PORTA&=~EN; //EN=0

delayms(1);

if(temp>>7==0)

flag = 0;

}

}

uchar read_data() //读数据函数

{

uchar lcd_data;

PORTB=0xff;

DDRB=0x00;

PORTA|=RW;

PORTA|=RS;

delayms(10);

PORTA|=EN;

delayms(10);

lcd_data=PINB;

delayms(10);

PORTA&=~EN;

DDRB=0xff;

return(lcd_data) ;

}

void point(uchar x,uchar y) //打点函数,最重要的函数,GUI的基础

{

uchar x_Dyte,x_byte;

uchar y_Dyte,y_byte;

uchar GDRAM_hbit,GDRAM_lbit;

WriteCommandLCM(0x36);

x_Dyte=x/16;

x_byte=x&0x0f;

y_Dyte=y/32;

y_byte=y&0x1f;

WriteCommandLCM(0x80+y_byte);

WriteCommandLCM(0x80+x_Dyte+8*y_Dyte);

read_data();

GDRAM_hbit=read_data();

GDRAM_lbit=read_data();

delayms(10);

WriteCommandLCM(0x80+y_byte);

WriteCommandLCM(0x80+x_Dyte+8*y_Dyte);

delayms(10);

if(x_byte<8)

{

WriteDataLCM(GDRAM_hbit|(0x01<(7-x_byte)));

WriteDataLCM(GDRAM_lbit);

}

else

{

WriteDataLCM(GDRAM_hbit);

WriteDataLCM(GDRAM_lbit|(0x01<(15-x_byte)));

}

WriteCommandLCM(0x30);

}

//LCM初始化

void LCMInit(void)

{

WriteCommandLCM(0x30); //三次显示模式设置,不检测忙信号

delayms(10);

WriteCommandLCM(0x30);

delayms(10);

WriteCommandLCM(0x30);

delayms(10);

WriteCommandLCM(0x30); //显示模式设置,开始要求每次检测忙信号

WriteCommandLCM(0x08); //关闭显示

WriteCommandLCM(0x01); //显示清屏

WriteCommandLCM(0x06); //显示光标移动设置

WriteCommandLCM(0x0C); //显示开及光标设置

}

void clear(uchar dat) //清屏函数

{

uchar i,j,k;

uchar addr=0x80;

for(i=0;i<2;i++)

{

for(j=0;j<32;j++)

{

for(k=0;k<8;k++)

{

WriteCommandLCM(0x36);

WriteCommandLCM(0x80+j);

WriteCommandLCM(addr+k);

WriteDataLCM(dat);

WriteDataLCM(dat);

}

}

addr=0x88;

}

WriteCommandLCM(0x36);

WriteCommandLCM(0x30);

}

void heng(uchar a)

{

uchar i;

for(i=0;i<127;i++)

point(i,a);

}

void su(uchar a)

{

uchar i;

for(i=0;i<63;i++)

point(a,i);

}

void FFT()

{

int i,j,k,t,P,B,m;

complex up,down,product;

for (i=0;i<7;i++)

{

B=1for (j=0;j{

t=1<(6-i);

P=t*j;

for (k=j;k{

complex product;

product.real=x[k+B].real*cos(2*PI*P/N)+x[k+B].img*sin(2*PI*P/N);

product.img=x[k+B].real*(-1)* sin(2*PI*P/N)+x[k+B].img*cos(2*PI*P/N);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top