这个是一路的程序(中断方式),SGADCON 赋每一路的值都没有问题,现在我想三路轮流采集就不行了。
#include "adc.h"
bit ADready; //24bit ADC转换完成标志位
unsigned long idata ADcode_pre;
void ADC_24bit_InIt() //24位ADC初始化
{
EIE &= 0xfb; //关闭SG ADC 中断
SGADCON = 0xc2; //1100 0010 开启ADC 正常工作 通道0 关闭64倍运放 输出速率 10HZ 通道1:0xd2 通道3:0xf2
SGADCON2 = 0x41; // 0100 0011 VCOM 输出电压控制位 输出1.5V
SGADCON3X = 0x99; //1001 1001 CCEN=1 1和2负输入不反 GCLK=8 ACLK=4 FCCH=1
SGADCON4X = 0x30; //0011 0000 不输出基准电流 开启内部BUF 开启BUF_LCAP属性 GREF不放大 关闭上下拉电流
SGADCON5X = 0x31; //0001 1101 滤波模式3 不丢弃
PD_CON = 0x66; //0110 0110 解锁P1.1 1.2 锁定P4.2 P4.3仅为输入模式 解锁写权限 开启内部LDO 同步休眠 开启温度模块
//EA = 1; //打开总中断(总中断在main函数中打开)
EIE |= 0x04; //打开SG ADC 中断
}
void data_receive() //从寄存器中获取ADC内码
{
union ADpattern idata temp;
//--ADcode_pre--赋值
temp.b[1] = SGADC3;
temp.b[2] = SGADC2;
temp.b[3] = SGADC1;
temp.b[0] = 0; //获取24位ADC数据内码
// temp.w ^= 0x800000; // 因为输出为双极性,+0x800000将负端平移上来
temp.w &= 0x00ffffff; //对25-32位清零
ADcode_pre = temp.w;
}
//内部 24bit SG ADC 中断,读取adc数据
static void sgadc_serve() interrupt 7
{
EIE &= 0xfb; //禁止中断
data_receive(); //读取 SDI0818 的 转换数据
ADready = 1;
EXIF &= 0xbf;
EIE |= 0x04; //打开中断
}
unsigned long Filter_ADdata() //读取adc转换数据,对其进行适当的平滑、滤波。
{
unsigned long d;
// -- 将 中断服务程序读取出的ADC原始信息 从 缓冲 Buffer 中取出 -----
EIE &= 0xfb; // 关闭adc中断,读取 ADC原始位信息 时 禁止 中断服务程序 改写
d = ADcode_pre;
ADready = 0; // 表示 ADC数据已被 处理程序 响应
EIE |= 0x04; // 打开中断
d >>= 2; // 将ADC数据右移两位,简单滤波
return d;
}
unsigned long Air_ADC_average() //气压传感器ADC通道
{
unsigned long ADC_code = 0;
unsigned char j;
unsigned long ADcode_filter_buff[10]; //用来求平均
while(~ADready); //等待AD转换完成标志
for(j=9;j>0;j--)
{
ADcode_filter_buff[j] = ADcode_filter_buff[j-1];
}
ADcode_filter_buff[0] =Filter_ADdata(); //获取最新ADC内码
for(j=0;j<10;j++)
{
ADC_code += ADcode_filter_buff[j]; //10次ADC内码相加
}
ADC_code /= 10; //求平均
return ADC_code;
}
下面是.H文件
#ifndef __ADC_H_
#define __ADC_H_
#include "SDI5229.h"
void ADC_24bit_InIt();
void data_receive();
unsigned long Filter_ADdata();
unsigned long Air_ADC_average();
union ADpattern //定义联合体,数据可以采用字节和字两种方式访问;
{
unsigned long w ;
unsigned char b[4];
};
#endif
----------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------
下面是我尝试用switch中切换通道,但没成功。
#include "adc.h"
float line0,line1,line2; //三通道结果
bit ADready; //24bit ADC转换完成标志位
unsigned long idata ADcode_pre;
void ADC_Setchannel(unsigned char channel)
{
switch(channel)
{
case 0: SGADCON &= 0xc2; break;
case 1: SGADCON &= 0xd2; break;
case 2: SGADCON &= 0xf2; break;
default:break;
}
}
void ADC_24bit_InIt(unsigned char channel) //24位ADC初始
{
EIE &= 0xfb; //关闭SG ADC 中断
SGADCON &= 0xcf; //清除ADC通道选择位
ADC_Setchannel(channel); //用此函数代替选通道寄存器
SGADCON2 = 0x41; // 0100 0011 VCOM 输出电压控制位 输出1.5V
SGADCON3X = 0x99; //1001 1001 CCEN=1 1和2负输入不反 GCLK=8 ACLK=4 FCCH=1
SGADCON4X = 0x30; //0011 0000 不输出基准电流 开启内部BUF 开启BUF_LCAP属性 GREF不放大 关闭上下接电流
SGADCON5X = 0x31; //0001 1101 滤波模式3 不丢弃
PD_CON = 0x66; //0110 0110 解锁P1.1 1.2 锁定P4.2 P4.3仅为输入模式 解锁写权限 开启内部LDO 同步休眠 开启温度模块
//EA = 1; //打开总中断 (main函数里打开)
EIE |= 0x04; //打开SG ADC 中断
}
void data_receive() //从寄存器中获取ADC内码
{
union ADpattern idata temp;
//--ADcode_pre--赋值
temp.b[1] = SGADC3;
temp.b[2] = SGADC2;
temp.b[3] = SGADC1;
temp.b[0] = 0; //获取24位ADC数据内码
// temp.w ^= 0x800000; // 因为输出为双极性,+0x800000将负端平移上来
temp.w &= 0x00ffffff; //对25-32位清零
ADcode_pre = temp.w;
}
//内部 24bit SG ADC 中断,读取adc数据
static void sgadc_serve() interrupt 7
{
EIE &= 0xfb; //禁止中断
data_receive(); //读取 SDI0818 的 转换数据
ADready = 1;
EXIF &= 0xbf;
EIE |= 0x04; //打开中断
}
unsigned long Filter_ADdata() //读取adc转换数据,对其进行适当的平滑、滤波。
{
unsigned long d;
// -- 将 中断服务程序读取出的ADC原始信息 从 缓冲 Buffer 中取出 -----
EIE &= 0xfb; // 关闭adc中断,读取 ADC原始位信息 时 禁止 中断服务程序 改写
d = ADcode_pre;
ADready = 0; // 表示 ADC数据已被 处理程序 响应
EIE |= 0x04; // 打开中断
d >>= 2; // 将ADC数据右移两位,简单滤波
return d;
}
unsigned long Air_ADC_average() //气压传感器ADC通道
{
unsigned long ADC_code = 0;
unsigned char j;
unsigned long ADcode_filter_buff[10]; //用来求平均
while(~ADready); //等待AD转换完成标志
for(j=9;j>0;j--)
{
ADcode_filter_buff[j] = ADcode_filter_buff[j-1];
}
ADcode_filter_buff[0] =Filter_ADdata(); //获取最新ADC内码
for(j=0;j<10;j++)
{
ADC_code += ADcode_filter_buff[j]; //10次ADC内码相加
}
ADC_code /= 10; //求平均
return ADC_code;
}
void ADC_channel(unsigned char channel)
{
switch(channel)
{
case 0: line0 = Air_ADC_average(); break; //通道0结果
case 1: line1 = Air_ADC_average(); break; //通道1结果
case 2: line2 = Air_ADC_average(); break; //通道2结果
default:break;
}
}
这是adc.h文件
#ifndef __ADC_H_
#define __ADC_H_
#include "SDI5229.h"
extern float line0;
extern float line1;
extern float line2;
void ADC_channel(unsigned char channel);
void ADC_Setchannel(unsigned char channel);
void ADC_24bit_InIt(unsigned char channel);
void data_receive();
unsigned long Filter_ADdata();
unsigned long Air_ADC_average();
union ADpattern //定义联合体,数据可以采用字节和字两种方式访问;
{
unsigned long w ;
unsigned char b[4];
};
#endif
main函数中调用
while(1)
{
if(ADCflag==1) //定时1S标志位 1S切换一个通道
{
ADCflag=0;
ADC_24bit_InIt(channel);
ADC_channel(channel);
channel++;
if(channel>2)
channel=0;
}
ADCBat = line0;
|