|
#include <18f4580.h>
#device ADC=10
#include <math.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,NOPUT,NODEBUG,NOLVP,NOBROWNOUT,NOCPD,NOPROTECT,NOWRT
typedef unsigned int8 INT8U;
typedef unsigned int16 INT16U;
typedef unsigned int32 INT32U;
typedef signed int8 INT8S;
typedef signed int16 INT16S;
typedef signed int32 INT32S;
typedef unsigned int8 BOOL;
typedef unsigned int16 WORD;
typedef unsigned int16 TCOLOR;
typedef unsigned int8 uint8;
typedef unsigned int16 uint16;
typedef unsigned int16 uint32;
//
#define _BV(N) (1<<N)
//
#define MOVE_RIGHT(NUM,BIT) (NUM>>BIT)
#define MOVE_LEFT(NUM,BIT) (NUM<<BIT)
#define GUI_LCD_XMAX 128
#define GUI_LCD_YMAX 64
#define GUI_LCM_XMAX 128
#define GUI_LCM_YMAX 64
#byte TRISE=0xF96
#byte TRISD=0xF95
#byte TRISC=0xF94
#byte TRISB=0xF93
#byte TRISA=0xF92
#byte LATE=0xF8D
#byte LATD=0xF8C
#byte LATC=0xF8B
#byte LATB=0xFBA
#byte LATA=0xF89
#byte PORTE=0xF84
#byte PORTD=0xF83
#byte PORTC=0xF82
#byte PORTB=0xF81
#byte PORTA=0xF80
typedef struct
{
INT16S real;
INT16S img;
}complex;
#define N 128
void Init_Port(void)
{
set_tris_c(0x00);
set_tris_e(0x00);
bit_clear(PORTE,0);
}
const TCOLOR DEC_HEX_TAB[16] =
{
0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000,
};
comPlex x[N];
INT8U vis[N];
void delay_ms(WORD ms)
{
BOOL i;
do
{
for(i=110;i>0;i--);
}while(--ms);
}
/***********************************************
作者:kl.yao
时间:2013年05月30日星期四
函数描述:
LCD液晶引脚初始化配置!
***********************************************/
void LCD_Port_Init(void)
{
output_a(0xff);
set_tris_a(0x00);
output_d(0xff);
set_tris_d(0x00);
}
//LCD检测判断忙
void LCD_CheckBusy(void)
{
BOOL count = 0;
set_tris_d(0xff); //输入模式
do
{
output_low(PIN_A0);
output_high(PIN_A1);
output_high(PIN_A2);
if(++count>=10)
{
break;
}
}while((PORTD&0x80)==0x80); //while(input(PIN_D7));
set_tris_d(0x00); //输出模式
}
//LCD写指令
void LCD_Write_Com(BOOL com)
{
LCD_CheckBusy();
output_low(PIN_A0);
output_low(PIN_A1);
output_high(PIN_A2);
output_d(com);
output_low(PIN_A2);
}
//LCD写数据
void LCD_Write_Data(BOOL dat)
{
LCD_CheckBusy();
output_high(PIN_A0);
output_low(PIN_A1);
output_high(PIN_A2);
output_d(dat);
output_low(PIN_A2);
}
//LCD读数据
BOOL LCD_Read_Data(void)
{
BOOL rev_data;
LCD_CheckBusy();
set_tris_d(0xFF); //输入模式
output_high(PIN_A0);
output_high(PIN_A1); //0-W,1-R
output_high(PIN_A2);
rev_data = input_d();
output_low(PIN_A2);
set_tris_d(0x00); //输出模式
return (rev_data);
}
//LCD写字数据
void LCD_WriteWord(BOOL x,BOOL y,TCOLOR wrdata)
{
x &= 0x0F;
y &= 0x1F;
LCD_Write_Com(0x36);
LCD_Write_Com(0x80|y);
LCD_Write_Com(0x80|x);
LCD_Write_Data((BOOL)(wrdata>>8));
LCD_Write_Data((BOOL)(wrdata>>0));
}
//LCD度字数据
TCOLOR LCD_ReadWord(BOOL x,BOOL y)
{
TCOLOR rev_data = 0;
x &= 0x0F;
y &= 0x1F;
LCD_Write_Com(0x36);
LCD_Write_Com(0x80|y);
LCD_Write_Com(0x80|x);
LCD_Read_Data(); //第一次读取数据部准确,舍弃!
rev_data |= LCD_Read_Data();
rev_data <<= 8;
rev_data |= LCD_Read_Data();
return (rev_data);
}
//LCD填充函数
void LCD_DispFill(TCOLOR filldata)
{
BOOL i,j;
LCD_Write_Com(0x34);
for(i=0;i<(GUI_LCD_YMAX/2);i++)
{
for(j=0;j<(GUI_LCD_XMAX/8);j++)
{
LCD_Write_Com(0x80|i);
LCD_Write_Com(0x80|j);
LCD_Write_Data((BOOL)(filldata>>8));
LCD_Write_Data((BOOL)(filldata>>0));
}
}
LCD_Write_Com(0x36);
LCD_Write_Com(0x30);
}
//LCD图形模式填充函数
void GUI_FillSCR(TCOLOR dat)
{
LCD_DispFill(dat);
}
//LCD打点函数
void GUI_Point(BOOL x,BOOL y,TCOLOR color)
{
TCOLOR bak;
BOOL i,j;
if(x>=GUI_LCD_XMAX)
return;
if(y>=GUI_LCD_YMAX)
return;
i = x>>4;
j = 15-(x&0x0F);
if(y>=0x20)
{
y -= 0x20;
i += 0x08;
}
bak = LCD_ReadWord(i,y);
if(0==color)
{
bak &= (~DEC_HEX_TAB[j]);
}
else
{
bak |= DEC_HEX_TAB[j];
}
LCD_WriteWord(i,y,bak);
}
//LCD读点函数
void GUI_ReadPoint(BOOL x,BOOL y,TCOLOR *ret)
{
TCOLOR bak;
BOOL i,j;
if(x>=GUI_LCD_XMAX)
return;
if(y>=GUI_LCD_YMAX)
return;
i = x>>4;
j = 15-(x&0x0F);
if(y>=0x20)
{
y -= 0x20;
i += 0x08;
}
bak = LCD_ReadWord(i,y);
if( (bak & (DEC_HEX_TAB[j])) == 0)
*ret = 0x0000;
else
*ret = 0x0001;
}
//LCD画水平线函数
void GUI_HLine(BOOL x0,BOOL y0,BOOL x1,TCOLOR color)
{
TCOLOR bak,wr_dat;
BOOL i,j,k;
BOOL temp;
if(x0>x1)
{
temp = x1;
x1 = x0;
x0 = temp;
}
if(y0>=0x20)
{
y0 -= 0x20;
k = 0x08;
}
else
{
k = 0x00;
}
do
{
j = x0 & 0x0F;
i = (x0>>4)+k;
bak = LCD_ReadWord(i,y0);
if((x0>>4)!=(x1>>4))
{
wr_dat = 0xFFFF >> (j);
if(color)
{
wr_dat = bak | wr_dat;
}
else
{
wr_dat = ~wr_dat;
wr_dat = bak & wr_dat;
}
LCD_WriteWord(i,y0,wr_dat);
x0 = (x0+16) & 0xF0;
}
else
{
wr_dat = 0xFFFF >> (j);
temp = (15- (x1&0x0F));
wr_dat &= ( 0xFFFF << (temp) );
if(color)
{
wr_dat = bak | wr_dat;
}
else
{
wr_dat = ~wr_dat;
wr_dat = bak & wr_dat;
}
LCD_WriteWord(i,y0,wr_dat);
return;
}
}while(x1>=x0);
}
//LCD写竖直线函数
void GUI_RLine(BOOL x0,BOOL y0,BOOL y1,TCOLOR color)
{
BOOL bak;
if(y0>y1)
{
bak = y1;
y1 = y0;
y0 = bak;
}
do
{
GUI_Point(x0,y0,color);
y0 ++;
}while(y1>y0);
}
void LCD_Init(void)
{
output_high(PIN_A3);
output_high(PIN_A4);
output_low(PIN_A4); //LCD复位
delay_ms(10);
output_high(PIN_A4);
delay_ms(2);
LCD_Write_Com(0x30);
delay_ms(2);
LCD_Write_Com(0x30);
delay_ms(2);
LCD_Write_Com(0x01);
delay_ms(2);
LCD_Write_Com(0x06);
delay_ms(2);
LCD_Write_Com(0x0C);
delay_ms(2);
LCD_Write_Com(0x36);
delay_ms(2);
}
/*************************************
作者:kl.yao
时间:2013年05月07日星期二
功能描述:
LCD显示位置定位函数!
*************************************/
void LCD_GoToXY(BOOL x,BOOL y)
{
x &= 0x0F;
y &= 0x03;
switch(y)
{
case 0:
{
LCD_Write_Com(0x80|x);
break;
}
case 1:
{
LCD_Write_Com(0x90|x);
break;
}
case 2:
{
LCD_Write_Com(0x88|x);
break;
}
case 3:
{
LCD_Write_Com(0x98|x);
break;
}
default:
{
break;
}
}
}
/*************************************
作者:kl.yao
时间:2013年05月07日星期二
功能描述:
LCD输出显示函数!
*************************************/
void LCD_Print(BOOL x,BOOL y,BOOL *DataStr)
{
LCD_GoToXY(x,y);
while(*DataStr!='\0')
{
LCD_Write_Data(*DataStr++);
}
}
/*************************************
作者:kl.yao
时间:2013年05月07日星期二
功能描述:
LCD内部寄存器初始化配置函数!
*************************************/
void LCD_Hz_Init(void)
{
output_high(PIN_A3);
output_high(PIN_A4);
output_low(PIN_A4); //LCD复位
delay_ms(10);
output_high(PIN_A4);
LCD_Write_Com(0x38);
delay_ms(2);
LCD_Write_Com(0x38);
delay_ms(2);
LCD_Write_Com(0x38);
delay_ms(2);
LCD_Write_Com(0x01); //清屏
delay_ms(2);
LCD_Write_Com(0x06);
delay_ms(2);
LCD_Write_Com(0x0c);
delay_ms(2);
//LCD_Write_Com(0x30); //基本指令
}
//横轴
void AXIS_X(BOOL y)
{
BOOL i;
for(i=0;i<127;i++)
{
GUI_Point(i,y,1);
}
}
//数轴
void AXIS_Y(BOOL x)
{
BOOL i;
for(i=0;i<63;i++)
{
GUI_Point(x,i,1);
}
}
void FFT(void)
{
INT16S i,j,k,t,P,B;
complex product;
for(i=0;i<7;i++)
{
B = _BV(i);
for(j=0;j<B;j++)
{
t = _BV((6-i));
P = t*j;
for(k=j;k<N;k+=2*B)
{
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);
x[k+B].real = x[k].real-product.real;
x[k+B].img = x[k].img-product.img;
x[k].real = x[k].real+product.real;
x[k].img = x[k].img+product.img;
}
}
}
}
//初始化旋转因子
void Init_TW(void)
{
INT16S i;
for(i=0;i<N;i++)
{
vis[i] = 0;
}
}
//比特反转
void Bit_Reverse(void)
{
INT16S i,j = 0;
complex tmp3;
for(i=0;i<N;i++)
{
INT16S tmp=i,tmp2=0,j;
for(j=0;j<7;j++)
{
tmp2 += ((tmp>>j)&1)*(_BV((6-j)));
}
if (vis[i]==0)
{
tmp3 = x[i];
x[i] = x[tmp2];
x[tmp2] = tmp3;
vis[i] = 1;
vis[tmp2] = 1;
}
}
}
/******************************************
函数名称:GUI_Display
输入参数:x,y
函数功能:数轴打点
输出参数:无
******************************************/
void GUI_Display(BOOL x,BOOL y)
{
BOOL i;
for(i=63;i>=y;i--)
{
GUI_Point(x,i,1);
}
}
void main(void)
{
BOOL ii,y;
float tmp;
Init_Port();
LCD_Port_Init();
LCD_Init();
LCD_Hz_Init();
GUI_FillSCR(0x0000);
AXIS_X(0);
AXIS_X(63);
AXIS_Y(0);
AXIS_Y(127);
for(ii=0;ii<20;ii++)
{
x[ii].real = 3;
x[ii].img = 0;
}
for(ii=20;ii<128;ii++)
{
x[ii].real = 0;
x[ii].img = 0;
}
Init_Tw();
Bit_Reverse();
FFT();
for(ii=64;ii<128;ii++)
{
tmp = sqrt((x[ii].real*x[ii].real)+(x[ii].img*x[ii].img));
y = 63-(INT16S)tmp;
GUI_Point(ii-64,y,1);
GUI_Display(ii-64,y);
}
for(ii=0;ii<64;ii++)
{
tmp = sqrt((x[ii].real*x[ii].real)+(x[ii].img*x[ii].img));
y = 63-(INT16S)tmp;
GUI_Point(ii+64,y,1);
GUI_Display(ii+64,y);
}
for(;;)
{
}
}
|
|