在线时间0 小时
UID292279
注册时间2007-12-17
NXP金币0
该用户从未签到
新手上路

- 积分
- 130
- 最后登录
- 1970-1-1
|
发表于 2012-12-13 10:13:27
|
显示全部楼层
RE:哪位老师有ADC的驱动程序呀?能发给我一个吗??
/*********************************************************
Hardware : EVB9S08DZ60 Board
Author : WBR
Version : V1.0
Begin Time: 2011.5.30
**********************************************************/
#include /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "1302.h"
//#include "lcd.h"
//#include "mscan.h"
//#include "KEY.h"
/******************************************************
IO说明:
1:四路AD输入通道 ADP19(AD1) ADP11(AD2) ADP3(AD3) ADP4(AD4)
2:485通信 DE (PTE2) TXD1(PTE0) RXD1(PTE1)
3:四路光耦输入 DI1(PTG2) DI2 (PTE5) DI3 (PTE4) DI4(PTE3)
4 S1302 SCL(PTF2) SDA (PTF3) RST (PTG4)
5:继电器控制 PTA6 PTB5 PTA5 PTC4 PTB6
6:按键(输入) PTC0 PTB0 PTC1 PTA0 PTC2(SW1~SW5)
7:CAN TX(PTE6) RX(PTE7)
8 CD RW(PTG3) RS(PTF0) E(PTF1) RST(PTF7) 背光(PTG5) DATA(PTD0~PTD7)
************************************************************/
#define DI1 PTGD_PTGD2 //外触发1-----> G2
#define DI2 PTED_PTED5 //外触发2-----> E5
#define DI3 PTED_PTED4 //外触发3-----> E4
#define DI4 PTED_PTED3 //外触发4-----> E3
//********以上为输入IO********//
#define JDQ1 PTCD_PTCD4 //继电器1-----> C4
#define JDQ2 PTAD_PTAD5 //继电器2-----> A5
#define JDQ3 PTBD_PTBD5 //继电器3-----> B5
#define JDQ4 PTAD_PTAD6 //继电器4-----> A6
#define JDQ5 PTBD_PTBD6 //继电器5-----> B6
#define DE485 PTED_PTED2 //485 T R切换-----> E2
//#define ID_TX 0x0001 //自定义的CAN发送标识符
//#define ID_RX 0x0002 //自定义的CAN接收标识符
//Bool can_send_enable = FALSE; //CAN发送标志位,暂定RTC0.5秒发送一次
#define Baud 19200 //串口波特率9600
#define N 51
#define T 1800 //运算电量的时间单位1800是半个小时(1800秒)
#define Psum 21600 //总电量初值,满电量时
extern byte time_buf1[8]; //1302时钟寄存器
byte ReadTimeFlag = 0; //定时器每0.5秒读1302时间的标志位
byte ADSET = 0; //发送电流电压功率等数值到显示屏标志位
/*********************变量和函数定义****************************/
word ADCbuffer1[N] = 0; //AD转换缓冲
word ADC1,ADC2,ADC3,ADC4; //AD转换缓冲
byte ADC1L,ADC1H,ADC2L,ADC2H,ADC3L,ADC3H,ADC4L,ADC4H;
byte Buffer[15]; //串口接收缓冲
byte ADch_s; //AD通道选择
byte ADcount;
//byte Key_value=0; //按键
//byte CANbuffer[8]; //接收到的CAN内容缓冲区数组
word sum=0;
long P,P1,Premain;
//word Premain;
word PL,PH; //拆分P
byte P0L,P0H,P1L,P1H; //拆分PH,PL
byte RR = 1; //RR = 1;读屏的19号地址;RR = 2读屏的20号地址开始的时间;
byte PAGE7,PAGE8; //进入设置时间页面和电量页面设置计数;
byte T20;
word TENT;
byte WF,RF; //写读FLASH的标志位,同时也是计算电量的标志位
byte *p;
//================================
//中值滤波程序
//================================
void filter()
{
static byte count,i,j;
word value_buf[N];
word temp;
sum=0;
for(count=0;count16;
PL = P&0xffff;
P1H = PH>>8;
P1L = PH&255;
P0H = PL>>8;
P0L = PL&255;
P1 += P ;
i++;
if(i>T) //半小时候写一次FLASH,进行一次电量计算
{
i = 0;
WF = 1; //半小时置位读写FLASH,和计算电量标志
}
asm(nop);
ADch_s = 3;
ADCSC1=0x63;
}
if(ADcount == 3)
{
filter();
ADC3= (sum/(N-2));
ADC3H = (sum/(N-2))>>8;
ADC3L = (sum/(N-2))&255;
ADch_s = 4;
ADCSC1=0x64;
}
if(ADcount == 4)
{
filter();
ADC4= (sum/(N-2));
ADC4H = (sum/(N-2))>>8;
ADC4L = (sum/(N-2))&255;
ADch_s = 19;
ADCSC1=0x73;
}
if(RR ==2)
{
DE485 = 1;
Delay(2);
SCI1send (0x01); //站号
SCI1send (0x52); //读命令
SCI1send (0x14); //20号地址判断ENT键状态
SCI1send (0x01); //1个地址
SCI1send (0x68);
Delay(1); //必须加段延时确保数据发送出去
DE485 = 0; //485切换到接收状态
asm(nop);
}
if(RR ==3)
{
DE485 = 1;
Delay(2);
SCI1send (0x01); //站号
SCI1send (0x57); //写命令
SCI1send (0x14); //20号地址清零
SCI1send (0x01); //1个长度
SCI1send (0x00); //18号地址
SCI1send (0x00);
SCI1send (0x6D);
Delay(50);
RR =4;
}
if(RR ==4) //读时间
{
DE485 = 1;
Delay(5);
SCI1send (0x01); //站号
SCI1send (0x52); //读命令
SCI1send (0x0B); //11号地址
SCI1send (0x06); //6个地址
SCI1send (0x64);
Delay(1); //必须加段延时确保数据发送出去
DE485 = 0; //485切换到接收状态
//asm(nop);
}
}
if(WF)
{
WF = 0;
if(Pchange ==0) //如果是放电状态
{
if(!PowerL){
P1 = P1/T/2; //半个小时的实际电量
Premain = Premain -P1;
mw8 = Premain*100/Psum; //
if(mw8>8);
mw6L = ((aa&0xffff)&255);
p=( unsigned char *)(0x1400); //指定地址
*p=0x01;
FCMD=0X40; //擦除命令
FSTAT_FCBEF=1; //启动命令
asm{
NOP
NOP
NOP
NOP
}
while(FSTAT_FCCF==0); //等待完成
//*********************剩余电量的低8位(mw6L)写入 EEPROM 0X1400
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1400); //指定地址
*p = mw6L;
FCMD=0x20;
FSTAT_FCBEF=1;
Delay(2);
/*asm
{
NOP
NOP
NOP
NOP
} */
while(FSTAT_FCCF==0);
//*********************剩余电量的高8位(mw6H)写入 EEPROM 0X1401
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1401); //指定地址
*p = mw6H;
FCMD=0x20;
FSTAT_FCBEF=1;
Delay(2) ;
/*asm
{
NOP
NOP
NOP
NOP
}*/
while(FSTAT_FCCF==0);
asm(nop);
}
P1 = 0;
}
//******************************************************
if(Pchange ==0xff) //如果是充电状态
{
P1 = P1/T/2; //半个小时的实际电量
Premain = Premain +P1;
mw8 = Premain*100/Psum;
if(mw8>50) //
{
Failure = Failure&0xfb; //清电量过低标志
PowerL = 0; //
}
if(Premain>Psum)
{
Premain = Psum; //充到最大值了
}
aa = Premain;
mw6H = ((aa&0xffff)>>8);
//mw6H = aa;
//mw6L = 0;
mw6L = ((aa&0xffff)&255);
//**********************先擦除才能写************************
p=( unsigned char *)(0x1400); //指定地址
*p=0x01;
FCMD=0X40; //擦除命令
FSTAT_FCBEF=1; //启动命令
asm{
NOP
NOP
NOP
NOP
}
while(FSTAT_FCCF==0); //等待完成
//*********************剩余电量的低8位(mw6L)写入 EEPROM 0X1400
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1400); //指定地址
*p = mw6L;
FCMD=0x20;
FSTAT_FCBEF=1;
asm
{
NOP
NOP
NOP
NOP
}
while(FSTAT_FCCF==0);
//*********************剩余电量的高8位(mw6H)写入 EEPROM 0X1401
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1401); //指定地址
*p = mw6H;
FCMD=0x20;
FSTAT_FCBEF=1;
asm
{
NOP
NOP
NOP
NOP
}
while(FSTAT_FCCF==0);
asm(nop);
P1 = 0;
}
}
if(ReadTimeFlag)
{
ReadTimeFlag = 0;
if(RR ==1)
{
Delay(10);
DE485 = 1;
Ds1302_Read_Time();
asm(nop);
SCI1send (0x01); //站号
SCI1send (0x57); //写命令
SCI1send (0x00); //首地址
SCI1send (0x12); //18个地址
SCI1send (ADC1H); //MW0高位 电压
SCI1send (ADC1L); //MW0低位
SCI1send (0x00); //MW1
SCI1send (0x00);
SCI1send (ADC2H); //MW2 电流
SCI1send (ADC2L);
SCI1send (0x00); //MW3
SCI1send (0x00);
SCI1send (P0H); //MW4 功率
SCI1send (P0L);
SCI1send (P1H); //MW5
SCI1send (P1L);
SCI1send (mw6H); //MW6
SCI1send (mw6L);
SCI1send (0x00); //MW7
SCI1send (0x00);
SCI1send (0x00); //MW8
SCI1send (mw8);
SCI1send (0x00); //MW9
SCI1send (0x00);
SCI1send (0x00); //MW10
SCI1send (Pchange);
SCI1send (0x00);
SCI1send (time_buf1[1]);
SCI1send (0x00);
SCI1send (time_buf1[2]);
SCI1send (0x00);
SCI1send (time_buf1[3]);
SCI1send (0x00);
SCI1send (time_buf1[4]);
SCI1send (0x00);
SCI1send (time_buf1[5]);
SCI1send (0x00);
SCI1send (time_buf1[6]);
SCI1send (0x00); //MW17
SCI1send (Failure);
SCI1send (0x6a+Pchange+Failure+mw6L+mw6H+mw8+ADC1L+ADC1H+ADC2L+ADC2H+P0H+P0L+P1H+P1L+time_buf1[1]+time_buf1[2]+time_buf1[3]+time_buf1[4]+time_buf1[5]+time_buf1[6]);
asm(nop);
Delay(10);
SCI1send (0x01); //站号
SCI1send (0x52); //读命令
SCI1send (0x13); //19号地址判断在哪个页面
SCI1send (0x01); //1个地址
SCI1send (0x67);
Delay(1); //必须加段延时确保数据发送出去
DE485 = 0; //485切换到接收状态
asm(nop);
}
}
}
}
//==========================================
//定时器1中断函数 中断向量号11 250毫秒定时
//==========================================
void interrupt 11 TPM1_ISR(void)
{
static byte i,j,k;
if((TPM1SC & 0x80)==0x80)
{
TPM1SC_TOF=0;
ADSET = 1;
}
i++;
if(!PAGE7) //
{
j = 0;
}
else
{
j++;
if(j>PAGE7) //大于5秒
{
j = 0;
RR = 2; //转判断ENT键是否按下程序
PAGE7 = 0;
}
}
if(!TENT)
{
k = 0;
}
else
{
k++;
if(k>TENT)
{
k = 0;
T20 = 1; //如果ENT键1分钟内没有按下则跳转到2界面(显示电压,电流)
TENT = 0;
}
}
if(!PAGE8) //
{
k = 0;
}
else
{
k++;
if(k>PAGE8) //大于5秒
{
k = 0;
RR = 2; //转判断ENT键是否按下程序
PAGE7 = 0;
}
}
if(!TENT)
{
k = 0;
}
else
{
k++;
if(k>TENT)
{
k = 0;
T20 = 1; //如果ENT键1分钟内没有按下则跳转到2界面(显示电压,电流)
TENT = 0;
}
}
if(i>3)
{
i = 0;
ReadTimeFlag = 1;
}
}
//==========================================
//串口接收中断 VectorNumber_Vsci1rx 中断向量号17
//==========================================
interrupt VectorNumber_Vsci1rx void SCI_RE(void)
{
static byte j;
static byte i;
byte Rcv;
if(SCI1S1_RDRF) //串口接收中断标志位
{ //清标志位
SCI1S1_RDRF = 0; //接收数据送缓存
Rcv = SCI1D;
//*********************读页面数值*****************************
if(RR == 1)
{
if(Rcv == 0x13)
{
j = 1;
Buffer[0]=Rcv;
}
else
{
if(j < 5) //5个字节
{
Buffer[j] = Rcv;
j++;
}
}
if((Buffer[3]==0x07)&&(Buffer[4]==0x1c)) //如果检测到是第7页面则处理数据
{
PAGE7 =20; //如果停在7页面设置一个计数器,5秒时间内如果还在则认为在修改时间
TENT = 240; //2分钟内ENT键没有按下,则跳转到2页面;
}
if(Buffer[3]!=0x07) //如果跳转到别的界面,马上清零
{
PAGE7 = 0;
TENT = 0;
RR = 1; //回到正常状态
}
if((Buffer[3]==0x08)&&(Buffer[4]==0x1d)) //如果检测到是第8页面则处理数据
{
PAGE8 =20; //5秒中内停留 表示正在设置初始电量值;
//TENT = 100; //
}
}
//****************判断ENT键按下与否******************************* ENT键按下的话20站号变成1
if(RR ==2)
{
if(Rcv == 0x14)
{
j = 1;
Buffer[0]=Rcv;
}
else
{
if(j < 5) //5个字节
{
Buffer[j] = Rcv;
j++;
}
}
if((Buffer[3]==0x01)&&(Buffer[4]==0x17)) //ENT键已经按下
{
RR = 3;
}
}
//******************************读取要修改的时间*******************************
if(RR ==4) //此时ENT已经清零
{
Buffer[j]=Rcv;
if(!i)
{
if(Buffer[j]== 0x0b) //接收到11
{
Buffer[0] =0x0b;
j=1; //才开始类加
}
if(Buffer[1]== 0x06)
{
i = 1;
}
}
if(i)
{
if(j< 15)
{
Buffer[j] = Rcv;
j++;
}
}
if(j==15)
{
i = 0;
}
if(Buffer[14]==(Buffer[3]+Buffer[5]+Buffer[7]+Buffer[9]+Buffer[11]+Buffer[13]+0x12))
{
RR = 0;
time_buf1[1] = Buffer[3] ;
time_buf1[2] = Buffer[5] ;
time_buf1[3] = Buffer[7] ;
time_buf1[4] = Buffer[9] ;
time_buf1[5] = Buffer[11];
time_buf1[6] = Buffer[13];
}
}
if(1)
{
}
}
}
//==========================================
//ADC转换完成中断服务程序 VectorNumber_Vadc中断向量号23
//==========================================
interrupt VectorNumber_Vadc void ADC_ISR(void)
{
static byte count;
switch(ADch_s)
{
case 19:
ADCbuffer1[count]=ADCRL;
count++;
if (count > N-1){
count = 0;
ADCSC1=0x00;
ADcount = 1;
}
break;
case 11:
ADCbuffer1[count]=ADCRL;
count++;
if (count > N-1){
count = 0;
ADCSC1=0x00;
ADcount = 2;
}
break;
case 3:
ADCbuffer1[count]=ADCRL;
count++;
if (count > N-1){
count = 0;
ADCSC1=0x00;
ADcount = 3;
}
break;
case 4:
ADCbuffer1[count]=ADCRL;
count++;
if (count > N-1){
count = 0;
ADCSC1=0x00;
ADcount = 4;
}
break;
default:break;
}
asm(nop); //在此设置一个断点,观测ad_h和ad_l的变化
} |
|