搜索
bottom↓
回复: 2

PIC18F4580_CCSC_LCD12864_FFT

[复制链接]

出0入0汤圆

发表于 2013-8-14 06:32:49 | 显示全部楼层 |阅读模式
#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(;;)
        {

        }
}

出0入0汤圆

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

出0入0汤圆

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

PIC同系列的片子功能都差不多,看英文吃力,
就找个中文的资料看看好了,反正一般情况下,都是通用的
有问题了,再具体区看英文资料
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-6 01:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表