麻烦各位大佬帮帮我,用stc89c52单片机和AD7702模块,以及电位器做虚拟电压表的时候,转动电位器是,上位机的电压值一直不变,想问问各位是不是程序单片机有问题,程序如下
#include<reg52.h>
#include<intrins.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit cs =P1^0;
sbit reset=P1^1;
sbit din =P1^2;
sbit sck =P1^3;
sbit dout =P1^4;
sbit ready=P1^5;
void delayms(unsigned int xms) //定义延时函数
{
unsigned int i,j;
for(i=0;i<xms;i++)
for(j=0;j<110;j++);
}
void usart_init(void){
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
SCON=0x50;
}
char putchar(char c){
SBUF=c;
while(!TI);
TI=0;
return (c);
}
//通讯寄存器字节定义
enum{
reg_com =0x00, //通讯寄存器
reg_setup=0x10, //设置寄存器
reg_clock=0x20, //时钟寄存器
reg_data =0x30, //数据寄存器
zero_ch1 =0x60, //ch1偏移寄存器
full_ch1 =0x70, //ch1满量程寄存器
zero_ch2 =0x61, //ch2偏移寄存器
full_ch2 =0x71, //ch2满量程寄存器
write =0x00,
read =0x08,
ch1=0,
ch2=1,
ch3=2,
ch4=3
};
//时钟寄存器字节定义
enum{
clk_enable =0x00,
clk_disable=0x10,
clk_4_9512M =0x08,
clk_2_4576M =0x00,
clk_1M =0x04,
clk_2M =0x0c,
fs_50hz =0x00,
fs_60hz =0x01,
fs_250hz =0x02,
fs_500hz =0x04,
zero_0 =0x00,
zero_1 =0x80
};
//校准寄存器字节定义
enum{
md_normal =(0<<6), //正常模式
md_calibself=(1<<6), //自校准模式
md_calibzero=(2<<6), //零刻度校准模式
md_calibfull=(3<<6), //满刻度校准模式
gain_001=(0<<3),
gain_002=(1<<3),
gain_004=(2<<3),
gain_008=(3<<3),
gain_016=(4<<3),
gain_032=(5<<3),
gain_064=(6<<3),
gain_128=(7<<3),
bipolar =(0<<2), //双极型输入
unipolar=(1<<2), //单机性输入
buff_no =(0<<1), //无输入缓冲
buff_yes=(1<<1), //有输入缓冲
fsync_0=0, //启用
fsunc_1=1 //不启用
};
//硬件复位
void ad7705_reset(){
reset=1;
delayms(1);
reset=0;
delayms(2);
reset=1;
delayms(1);
}
void spi_send8bits(unsigned char dat){
unsigned int i;
for(i=0;i<8;i++){
if(dat&0x80)
din=1;
else
din=0;
sck=0;
dat<<=1;
_nop_();
sck=1;
_nop_();
}
}
//同步spi接口的时序
void ad7705_spisync(){
cs=0;
spi_send8bits(0xff);
spi_send8bits(0xff);
spi_send8bits(0xff);
spi_send8bits(0xff);
cs=1;
}
//ad7705写数据
void ad7705_send1byte(unsigned char dat){
cs=0;
spi_send8bits(dat);
cs=1;
}
//自动校准某一通道
static void ad7705_waitready(){
unsigned long i;
for(i=0;i<8000;i++){
if(ready==0)
break;
}
if(i>8000){
printf("0");
ad7705_spisync();
delayms(5);
}
}
void ad7750_calibration(unsigned int channel){
if(channel==1){
ad7705_send1byte(reg_setup | write | ch1);
ad7705_send1byte(md_calibself | gain_001 | unipolar | buff_yes | fsync_0);
ad7705_waitready();
}
else if(channel==2){
ad7705_send1byte(reg_setup | write | ch2);
ad7705_send1byte(md_calibself | gain_001 | unipolar | buff_yes | fsync_0);
ad7705_waitready();
}
}
void ad7705_init(){
ad7705_reset();
delayms(5);
ad7705_send1byte(reg_clock | write | ch2); //写通讯寄存器
ad7705_send1byte(clk_enable | clk_4_9512M | fs_50hz); //写时间寄存器
ad7750_calibration(2);
delayms(5);
}
unsigned char spi_read8bits(){
unsigned int i;
unsigned char read=0;
for(i=0;i<8;i++){
sck=0;
_nop_();
read=read<<1;
if(dout!=0)
read++;
sck=1;
_nop_();
}
return read;
}
static unsigned short ad7705_read2byte(){
unsigned short read;
cs=0;
read=spi_read8bits();
read<<=8;
read+=spi_read8bits();
cs=1;
return read;
}
unsigned short ad7705_readvalue(unsigned int channel){
unsigned int i;
unsigned short read=0;
for(i=0;i<2;i++){
ad7705_waitready();
if(channel==1)
ad7705_send1byte(0x38);
else if(channel==2)
ad7705_send1byte(0x39);
read=ad7705_read2byte();
}
return read;
}
void ad770_choosegain(unsigned int channel,unsigned int gain){
switch(channel){
case 1:ad7705_send1byte(reg_setup | write | ch1);break;
case 2:ad7705_send1byte(reg_setup | write | ch2);break;
}
_nop_();
switch(gain){
case 1:ad7705_send1byte(md_calibself | gain_001 | unipolar | buff_yes | fsync_0);break;
case 2:ad7705_send1byte(md_calibself | gain_002 | unipolar | buff_yes | fsync_0);break;
case 4:ad7705_send1byte(md_calibself | gain_004 | unipolar | buff_yes | fsync_0);break;
case 8:ad7705_send1byte(md_calibself | gain_008 | unipolar | buff_yes | fsync_0);break;
case 16:ad7705_send1byte(md_calibself | gain_016 | unipolar | buff_yes | fsync_0);break;
case 32:ad7705_send1byte(md_calibself | gain_032 | unipolar | buff_yes | fsync_0);break;
case 64:ad7705_send1byte(md_calibself | gain_064 | unipolar | buff_yes | fsync_0);break;
case 128:ad7705_send1byte(md_calibself | gain_128 | unipolar | buff_yes | fsync_0);break;
}
ad7705_waitready();
}
void main(){
unsigned int flag,i;
unsigned short adc;
float value;
usart_init();
ad7705_init();
ad770_choosegain(2,1);
while(1){
value=0;
for(i=0;i<3;i++){
adc=ad7705_readvalue(2);
value+=(float)adc*5000/65535.0;
}
printf("%.3f\n",value/3);
flag=1*((2500<value)&&(value<=5000))+2*((1250<value)&&(value<=2500))+3*((40<value)&&(value<=1250))+4*((0<value)&&(value<=40));
switch(flag) //定义增益选择语句
{
case 1:ad770_choosegain(2,1);break;
case 2:ad770_choosegain(2,2);break;
case 3:ad770_choosegain(2,4);break;
case 4:ad770_choosegain(2,128);break;
}
}
}
|