原创 877 12864

2009-9-22 16:51 1628 7 7 分类: MCU/ 嵌入式
 



#include "pic.h"
__CONFIG(0X3F31);
unsigned int    pl[2];   //频率头一次和第二次的值,相减就是本次的频率值
unsigned int    plpl;   //频率算出来的值放在这里了
unsigned char   plbit;   //两次总要有个计数的值吧
bank2 unsigned int    plad[35]; //计算电压值,中断一到过一ms采一次,直到下个中断来为止
bank2 unsigned char   pladbit; //上面的数组总要有个数来增减吧
bank2 bit    timer0ad; //CCP中断来时开始计时,1ms到后值位他,开始采AD,采完后又清0
bank2 bit   adtimer; //通过这个位来控制AD0和别的AD的采集,因为采集太快别的也会显示0通道的值
bank2 unsigned int   advpp; //计算AD的峰值
bank2 unsigned int    max;
bank2 unsigned int    mix;
bank2 unsigned int    big;
///////////////////*********************************************************************************************************************************************
#define RST RB4   //复位信号
#define RS_CS   RB7   //命令/数据选择,串口片选
#define RW_SID RB6 //读/写选择 串口 RW_SID
#define E_CLK RB5   //使能信号   串口 E_CLK


union adres
{
int DD;
unsigned char data[2];
}
union adres current_v;      //当前电压
union adad
{
int ff;
unsigned char addata[2];
}
union adad current_a;      //当前电压
union adad current_b;      //当前电压
union adad current_c;      //当前电压
union adad current_d;      //当前电压
union adad current_e;      //当前电压
union adad current_f;      //当前电压
union adad current_g;      //当前电压


/****************************************************************              
              发送一个字节
*****************************************************************/
void SendByte(unsigned char Dbyte)
{
     unsigned char i;
     for(i=0;i<8;i++)
     {
   E_CLK = 0;
   Dbyte="Dbyte"<<1;      //左移一位
   RW_SID = CARRY;      //移出的位给RW_SID
   E_CLK = 1;
   E_CLK = 0;
}
     }
/****************************************************
void sort(int array[],int n)
{
int i,j,k,t;
for(i=0;i<n-1;i++)
{k=i;
for(j=i+1;j<n;j++)
   if(array[j]<array[k])k=j;
t=array[k];array[k]=array;array=t;
}
}
/**********************************************************
              接收一个字节
***********************************************************/
unsigned char ReceiveByte(void)
{
     unsigned char i,temp1,temp2;
     temp1 = 0;
     temp2 = 0;
     for(i=0;i<8;i++)
     {
           temp1=temp1<<1;
           E_CLK = 0;
           E_CLK = 1;           
           E_CLK = 0;
           if(RW_SID) temp1++;
     }
     for(i=0;i<8;i++)
     {
           temp2=temp2<<1;
           E_CLK = 0;
           E_CLK = 1;
           E_CLK = 0;
           if(RW_SID) temp2++;
     }
     return ((0xf0&temp1)+(0x0f&temp2));
}
/****************************************************************
                      检查忙状态
******************************************************************/
void CheckBusy( void )
{
     do   SendByte(0xfc);         //11111,RW(1),RS(0),0
     while(0x80&ReceiveByte());     //BF(.7)=1 Busy
}
/******************************************************************
                写指令
*******************************************************************/
void WriteCommand(unsigned char Cbyte )
{
     RS_CS = 1;
     CheckBusy();
     SendByte(0xf8);            //11111,RW(0),RS(0),0
     SendByte(0xf0&Cbyte);      //高四位
     SendByte(0xf0&Cbyte<<4);   //低四位(先执行<<)
     RS_CS = 0;
}
/*************************************************************
                 写数据
**************************************************************/
void WriteData(unsigned char Dbyte )
{
     RS_CS = 1;
     CheckBusy();
     SendByte(0xfa);            //11111,RW(0),RS(1),0
     SendByte(0xf0&Dbyte);      //高四位
     SendByte(0xf0&(Dbyte<<4));   //低四位(先执行<<)
     RS_CS = 0;
}
/*********************** read data **************************/
unsigned char ReadData( void )
{
     CheckBusy();
     SendByte(0xfe);            //11111,RW(1),RS(1),0
     return ReceiveByte();
}
/******************* delay ********************/
void delay_10us(unsigned char x)
{
while(x--);
}
/******************* delay ********************/
void delay_ms(unsigned char cnt)
{
    unsigned char i;
do {
i = 4;
do {
   delay_10us(39);
} while(--i);
} while(--cnt);
}
//**************************流水灯******************************
void led_test()
{
PORTD=0XFF;
delay_ms(50);
PORTD=0Xfe;//11111110
delay_ms(50);
PORTD=0Xfd;//11111101
delay_ms(50);
PORTD=0Xfb;//11111011
delay_ms(50);
PORTD=0Xf7;//11110111
delay_ms(50);
PORTD=0Xef;//11101111
delay_ms(50);
PORTD=0Xdf;//11011111
delay_ms(50);
PORTD=0Xbf;//10111111
delay_ms(50);
PORTD=0X7f;//01111111
delay_ms(50);
PORTD=0xff;
}
/////*******************************************************
void initial_LCD(void)
{  
//**************************初始化**********************
//   PSB="0";
RST=0;//Reset.
   NOP();
   NOP();
   RST="1";
   NOP();
   delay_10us(10);
   WriteCommand(0x30);    //30H--基本指令操作
   delay_10us(4);
   WriteCommand(0x0c);    //开显示,关光标,不闪烁。
   delay_10us(10);
   WriteCommand(0x01);    //清除显示
   delay_ms(10);
   //WriteCommand(0x06);    //指定在资料写入或读取时,光标的移动方向,DDRAM的地址计数器(AC)加1。
}
/*****************************************************/
void display(unsigned char x,unsigned int zhi)
{unsigned char qian,bai,shi,ge;
unsigned int temp;
temp=zhi;
qian=temp/0x3e8+48;   //千位显示的代码
WriteCommand(x);    //页地址
//WriteData(0xA3);
WriteData(qian);
/*if(xiaoshudian = 3)
   {
   WriteData(0xA3);
   WriteData(0xAE);
   }*/
bai=(temp%0x3e8)/0x64+48;      //百位显示的代码
//WriteData(0xA3);
WriteData(bai);
shi=((temp%0x3e8)%0x64)/0xa+48; //十位显示的代码
//WriteData(0xA3);
WriteData(shi);
ge=((temp%0x3e8)%0x64)%0xa+48;   //个位显示的代码---176
//WriteData(0xA3);
WriteData(ge);
delay_ms(10);//100
//WriteCommand(0x0C);
}
/******************************************************/
void lcd_display(void)
{
WriteCommand(0x01);
//WriteCommand(0x34);
//WriteCommand(0x30); //清屏
delay_ms(1);
//WriteCommand(0x80);   //页地址
//WriteData(0xB5);   //电
//WriteData(0xE7);
//WriteData(0xD1);   //压
//WriteData(0xB9);
}
/*******************************************/
void ddi(void)
{
di();        //全局中断关
PEIE=0;        //所有外设中断
}
/*******************************************/
void eei(void)
{
ei();        //全局中断开
PEIE=1;        //所有外设中断
}
/*****************************************/
void do_ad_no_int(unsigned char adcc)
{
ADCON1 = 0b10000000;        // ;VDDVSS为参考源 结果右对齐 ADFM ADCS2 ! ! PCFG3 PCFG2 PCFG1 PCFG0
ADCON0 = adcc;          // AN1     ADCON0 ADFM VCFG CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
delay_ms(10);//10
ADIF=0;        //清除AD转换中断标志 BANK0
ADGO=1;        //开始转换
while(ADIF=0);{}     //等待结果
ADCON1 = 0b10000110;        //一定要设回数字口,不然全乱套了,妈的!
}
/***********************************************************************************************************************************************************/
//中断子程序
void interrupt IRQ(void)
{unsigned int i;
unsigned int j;
if(CCP1IF)
{TMR1ON=1;
if(adtimer)
T0IE=1;     //Tiemr0中断允许
   pl[plbit]=CCPR1H;
   pl[plbit]=(pl[plbit]<<8)+CCPR1L;
   CCP1IF=0;
   plbit++;
   if(plbit==2)
   { T0IE=0;     //Tiemr0中断允许
   adtimer="0";
   max=(plad[15]+plad[16]+plad[17])/3;   //29-30-31
   mix=(plad[6]+plad[7]+plad[8])/3;   //11-12-13
   j="max-mix";
   advpp="max-mix";
   advpp=(j*34+advpp*5/10)/100*128/100;
plbit=0;
CCPR1H=0;
CCPR1L=0;
pl[1]=pl[1]-pl[0];
     plpl="1000000/pl"[1];
   pladbit="0";
}
    //CCP1中断服务子程序
}
if(T0IF)
{TMR0=0x06;
RB1=!RB1;
    T0IF=0;
ADCON1 = 0b10000000;
ADCON0=0x01;          // AN0     ADCON0 ADFM VCFG CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
for(i=0;i<20;i++)
{;}
ADIF=0;         //清除AD转换中断标志 BANK0
ADGO=1;         //开始转换
while(ADIF=0);{}      //等待结果
ADCON1 = 0b10000110;     //一定要设回数字口,不然全乱套了,妈的!
   current_v.data[0]=ADRESL;
   current_v.data[1]=ADRESH;
   plad[pladbit]=current_v.DD;   //送入数组
   big="current"_v.DD;
   pladbit++;       //加1
}
}


//***********定时器1-2初始化设置子程序********************/
void fun_timerset()
{
TMR1H=TMR1L=0x00;
TMR1ON=0;
CCP1IF=0;     //清除CCP1的中断标志,以免中断一打开就进入
       //Timer0初始化设置
PSA=0;      //Timer0 使用预分频器
       //Timer0选择分频率为1:4
PS0=1;PS1=0;PS2=0;
       //内部时钟定时方式,定时时间:1000uS,误差:0uS
T0CS=0;
TMR0=0x06;
T0IF=0;
T0IE=0;     //Tiemr0中断允许
}


//****************CCP初始化设置子程序********************/
void fun_ccpset()
{
//CCP1模块设置
CCP1CON=0X05;//0101
CCP1IE=1;//CCP1中断允许
}
/*/********************************************/
void init()
{
TRISA=0B11101111;    //打开必要的端口
TRISB=0B00000000;    //打开必要的端口
TRISC=0B00000100;    //打开必要的端口--CCP1
TRISE=0B11111111;    //打开必要的端口
TRISD=0B00000000;    //打开必要的端口   
PORTD=0;
ADCON1=0b10000000;        //设AN0-AN7全为模似量输入
STATUS=0x00;     //IRP(1) RP1(1) RP0 TO PD Z DC C
OPTION=0B10001110;    //RB不用上拉,分频器给WDT,1/64 分频 分频比1:256 BANK1
}
/********************主*******************************/
void main(void)
{
init();
led_test();
initial_LCD();
lcd_display();
/***********************////
fun_timerset();   //定时器1-2初始化设置子程序
fun_ccpset();    //CCP初始化设置子程序
ei();
PEIE=1;
GIE=1;
/*******************//////
while(1)
{
   display(0x80,advpp);
   WriteData(0x56);//V
   led_test();


   if(adtimer==0)
   {
   ddi();
   do_ad_no_int(0x09);     //AN1-00001001
   current_a.addata[0]=ADRESL;
   current_a.addata[1]=ADRESH;
   display(0x90,current_a.ff);
   delay_ms(50);


   do_ad_no_int(0x11);     //AN2-00010001
   current_b.addata[0]=ADRESL;
   current_b.addata[1]=ADRESH;
   display(0x94,current_b.ff);
   delay_ms(50);


   do_ad_no_int(0x19);     //AN3-00011001
   current_c.addata[0]=ADRESL;
   current_c.addata[1]=ADRESH;
   display(0x88,current_c.ff);
   delay_ms(50);


   do_ad_no_int(0x21);     //AN4-00100001
   current_d.addata[0]=ADRESL;
   current_d.addata[1]=ADRESH;
   display(0x8c,current_d.ff);
   delay_ms(50);


   do_ad_no_int(0x29);     //AN5-00101001
   current_e.addata[0]=ADRESL;
   current_e.addata[1]=ADRESH;
   display(0x98,current_e.ff);
   delay_ms(50);


   do_ad_no_int(0x31);     //AN6-00110001
   current_f.addata[0]=ADRESL;
   current_f.addata[1]=ADRESH;
   display(0x9c,current_f.ff);
   delay_ms(50);


   /*do_ad_no_int(0x39);     //AN7-00111001
   current_g.addata[0]=ADRESL;
   current_g.addata[1]=ADRESH;
   display(0x84,current_g.ff);
   delay_ms(50);*/
   display(0x84,plpl);
   WriteData(0x48);//H
   WriteData(0x5a);//Z
   eei();
   adtimer="1";       //这里的AD都采集完后才开始采AD0
   }



//display(0x9c,plad[12]);
//display(0x98,plad[30]);
}

}

转载自:http://hi.baidu.com/bailsfi/blog/item/ae939282f4bfaeba6d81195d.html
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
7
关闭 站长推荐上一条 /3 下一条