ADC1采集电压并控制舵机,感觉各通道之间相互影响,并且采集数据不对,请指教问题在哪

jwy2014 2015-11-05 04:54:00
#include <C8051F020.h>
#include "stdio.h"
#include "intrins.h"
#include "math.h"
#include "string.h"

typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long ulong;
typedef unsigned short ushort;
sfr16 DP = 0x82; // data pointer
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 TMR3 = 0x94; // Timer3 counter
sfr16 ADC0 = 0xbe; // ADC0 data
sfr16 ADC0GT = 0xc4; // ADC0 greater than window
sfr16 ADC0LT = 0xc6; // ADC0 less than window
sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 T2 = 0xcc; // Timer2
sfr16 RCAP4 = 0xe4; // Timer4 capture/reload
sfr16 T4 = 0xf4; // Timer4
sfr16 DAC0 = 0xd2; // DAC0 data
sfr16 DAC1 = 0xd5; // DAC1 data
void UartSendStr(unsigned char *pStr);
void UartSendChar(unsigned char ch);
void UartCharPro(unsigned char ch);
void init_adc1(void);
void init_vref(void);
uint start_adc1(uchar channel);


void delay1ms(uint time);
#define CMD_LEN 75 // 命令长度
#define CMD_TAG 1 // 提示符长度
unsigned char g_ucLen = 0; // 命令长度
unsigned char g_ucCur = 1; // 光标位置
unsigned char xdata g_ucCmd[CMD_LEN + 1] = {0};
unsigned char xdata g_ucCmd1[CMD_LEN + 1] = {0};
uint adc1_result;
bit isnewdata;
unsigned short data temp;
uint xdata t[8];//存放电压检测数据,为8个数据
ushort xdata measurement[8];

#define SYSCLK 22118400 // SYSCLK frequency in Hz
#define VREF1 2430 // Mv
#define AV+ 2430 // Mv
void init_adc1(void) //系统时钟=12M
{
ADC1CF=0x81; //ADC1配置寄存器,设置转换时钟(SAR<=6M)和内部放大器增益,SAR转换时钟
//=系统时钟/(b7-b3)=2M,内部放大器增益=1(b1-b0);此时为系统时钟17分频,增益为1
AMX1SL=0x00; //模拟输入通道选择寄存器(b3-0)
ADC1CN=0x82; //ADC1控制寄存器,允许ADC(b7),向AD1BUSY写1启动ADC(b3-b1)
EIE2=0x08; //允许ADC0中断,EADC1=1,EIE2.3=1
}

void init_vref(void)
{
REF0CN = 0x0a; // ADC0电压取于DAC0,ADC1取于AV+,TEMPE关闭,内部偏压器工作,内部电压基准缓冲器关闭
}

void SYSCLK_Init()
{
int i;
OSCXCN=0X67; //0X67=0110,0111
for(i=0;i<256;i++); //等待>1ms
while(!(OSCXCN&0X80)); //等待XTLVLD变为1
OSCICN=0X88; //时钟失效监测器,选择外部时钟源作为系统时钟
}

void UART0_Init()
{
SCON0=0x50; //串口方式1
TMOD=0X20; //选用定时器1作为波特率发生器
TH1=0xF4;
TL1=0xF4;
PCON=0x80; //波特率设置为9600
TR1=1; //定时器启动
}
void Timer3_Init (int counts)
{
TMR3CN = 0x02; // Stop Timer3; Clear TF3;
// use SYSCLK as timebase
TMR3RL = -counts; // Init reload values
TMR3 = 0xffff; // set to reload immediately
EIE2 &= ~0x01; // disable Timer3 interrupts
TMR3CN |= 0x04; // start Timer3
}
uint start_adc1(uchar channel)
{

AMX1SL=channel;
ADC1CN|=0x10; //ADC1BUSY=0;
}

void config(void)
{

//WDTCN = 0x07; //看门狗禁止
WDTCN = 0xDE;
WDTCN = 0xAD;

XBR0 = 0x04; //交叉开关使能,但没有进行外围设备配置
XBR1 = 0x00;
XBR2 = 0x40;

OSCXCN = 0x00;
OSCICN = 0x84; //b7=1,使能时钟丢失检测器(时钟丢失时间大于100ms将触发复位),
//CLKSL(b3)=0,选择内部晶振,IOSCEN(B2)=1,内部振荡器使能
//IFCN1-0(B1-0)=00,内部振荡器典型频率为2MHz

P1=0x00; //逻辑高电平输出
P1MDOUT = 0x00; //P1口为开漏输出,引脚被配置为模拟输入
P1MDIN = 0x00;
}

void delay1ms(uint time){//延迟1ms
uint i;
uint j;
for (i=0;i<time;i++){
for(j=0;j<300;j++);
}
}



void UartSendStr(unsigned char *pStr)
{

while(*pStr != 0)

{

SBUF0 = *pStr++;
while(TI0==0);
TI0=0;
}
}

void UartSendChar(unsigned char ch)

{
SBUF0 = ch;
while(TI0==0);
TI0=0;
}

void UartCharPro(unsigned char ch)

{

//P0 = ~ch;
switch(ch)
{
case '\b': // 退格键
if(g_ucCur > CMD_TAG)
{

UartSendChar('\b');

UartSendChar(' ');

UartSendChar('\b');

if(g_ucLen)
{
g_ucLen--;
}

g_ucCur--;

}

break;

case '\r': // 回车键

UartSendChar('\r');

UartSendChar('\n');

g_ucCmd[g_ucLen] = 0;

UartSendStr(g_ucCmd);

UartSendChar('\r');

UartSendChar('\n');

UartSendChar('>');

g_ucLen = 0;

g_ucCur = 1;

break;

default: // 其它字符

UartSendChar(ch);

g_ucCur++;

if(g_ucLen < CMD_LEN)
{

g_ucCmd[g_ucLen++] = ch;

}

else
{

g_ucCmd[g_ucLen] = 0;

}
}
}
void main()
{
int i;
config();
SYSCLK_Init();
UART0_Init();
init_vref();
init_adc1();//ADC0初始化
Timer3_Init (SYSCLK/50000);
AD0EN=1;
delay1ms(20);
EA=1;
i=0;
while(1)
{
if(isnewdata)//由该位查询ADC1转化值是否更新
{

isnewdata=0;
TMR3CN&=0xFB;
for(i=0;i<8;i++)
{

measurement[i] = (ushort)t[i] * 2430.0 / 256.0 ;
sprintf(g_ucCmd1,"#%dP%luT10\r\n",i+1,(unsigned long)(measurement[i]*0.8+500.0));
UartSendStr(g_ucCmd1);
delay1ms(500);
}
i=0;//在此设断点,观察程序运行结果
TMR3CN|=0x04; //开定时器3

}
}
}

void ADC1_ISR() interrupt 17
{
//ADC1中断
static unsigned int channel = 0;
ADC1CN&=~0x20;
isnewdata=1;
t[channel] = ADC1;; // 读ADC值
channel++;
delay1ms(20);
AMX1SL = channel; // 设置mux到下个通道 // 改变通道
if (channel == 8)
{
channel = 0;
}
delay1ms(20);

}
...全文
345 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhujinqiang 2015-12-13
  • 打赏
  • 举报
回复
各个通道的电压是依次查询的?
mollyjh 2015-11-11
  • 打赏
  • 举报
回复
为什么要用那么多延时?

27,382

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧