#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]);
}
}
文章评论(0条评论)
登录后参与讨论