yklstudent 发表于 2013-8-14 06:32:49

PIC18F4580_CCSC_LCD12864_FFT

#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 =
{
0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000,
};

comPlex x;

INT8U vis;

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);
}
else
{
    bak |= DEC_HEX_TAB;
}
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)) == 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.real*cos(2*PI*P/N)+x.img*sin(2*PI*P/N);
                                product.img = x.real*(-1)*sin(2*PI*P/N)+x.img*cos(2*PI*P/N);
                                x.real = x.real-product.real;
                                x.img = x.img-product.img;
                                x.real = x.real+product.real;
                                x.img = x.img+product.img;
                        }
                }
        }       
}

//初始化旋转因子
void Init_TW(void)
{
        INT16S i;
        for(i=0;i<N;i++)
        {
                vis = 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==0)
                {
                        tmp3 = x;
                        x = x;
                        x = tmp3;
                        vis = 1;
                        vis = 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.real = 3;
                x.img = 0;
        }
        for(ii=20;ii<128;ii++)
        {
                x.real = 0;
                x.img = 0;
        }
        Init_Tw();
        Bit_Reverse();
        FFT();
        for(ii=64;ii<128;ii++)
        {
                tmp = sqrt((x.real*x.real)+(x.img*x.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.real*x.real)+(x.img*x.img));
                y = 63-(INT16S)tmp;
                GUI_Point(ii+64,y,1);
                GUI_Display(ii+64,y);
        }
        for(;;)
        {

        }
}

craigtao 发表于 2014-9-10 10:20:07

前辈,你好,最近我也打算学习 PIC18F4580 这个芯片,好像没有中文的手册,挺麻烦的,E文看的很吃力

yklstudent 发表于 2014-9-10 10:53:31

craigtao 发表于 2014-9-10 10:20
前辈,你好,最近我也打算学习 PIC18F4580 这个芯片,好像没有中文的手册,挺麻烦的,E文看的很吃力 ...

PIC同系列的片子功能都差不多,看英文吃力,
就找个中文的资料看看好了,反正一般情况下,都是通用的
有问题了,再具体区看英文资料
页: [1]
查看完整版本: PIC18F4580_CCSC_LCD12864_FFT