打印
[51单片机]

关于51单片机的实用问题

[复制链接]
1592|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我爱电子520|  楼主 | 2013-12-10 13:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我现在做一个水深测试工具,精度为1CM  采用ads1110 16位AD测量压力传感器。现在遇到问题是单片机采集回来的数据 不准确,跳变大  我发现问题是这样, 16位AD不是分高八位,低八位么。  现在就是低八位到了255要跳到高位了 但是高位必须是等到两个低八位才一个跳变  而且是直接增加两个变量   比如我采集的是高位是08
地位是255   之后线性增压后  地位又从0开始  但没给高位进数  之后第二次满后  高位才 变为10    我发现这高位寄存器只会显示双数   求大侠帮助!

相关帖子

沙发
我爱电子520|  楼主 | 2013-12-10 13:04 | 只看该作者
sbit  SDA=P1^4;   //数据端
sbit  SCL=P1^3;   //时钟端

uchar zf[10]="0123456789";
uchar temp;

uchar TMR;
uint j;
uchar ADCH=0;         //ADC转换结果的高8位
uchar ADCL=0;         //ADC转换结果的低8位

uint ADC=0;         //ADC结果
uint ADS_ADS;

void delaymm(void)   //延时函数
{
           _nop_();         _nop_();
        _nop_();        _nop_();
        _nop_();        _nop_();
        _nop_();        _nop_();
        _nop_();        _nop_();
        _nop_();        _nop_();

}
/*****************************************************************
//函数:void start(void)
//功能:开始
//说明:时钟线为高,数据线由主到低跳变
/*****************************************************************/
void start(void)
{
        SDA=0;
        delaymm();delaymm();
        SDA=1;
        delaymm();delaymm();
        SCL=1;
    delaymm(); delaymm();delaymm();
        SDA=0;
    delaymm();delaymm();delaymm();
        SCL=0;
        delaymm(); delaymm();

}
/*****************************************************************
//函数:void stop(void)
//功能:结束
//说明:时钟线为高,数据线由低到高跳变
/*****************************************************************/
void stop(void)
{
        SDA=0;
        delaymm();delaymm();
        SCL=1;
        delaymm();delaymm();delaymm();
        SDA=1;
        delaymm();delaymm();delaymm();
        SCL=0;
        delaymm(); delaymm();delaymm();
}
/*****************************************************************
//函数:void check(void)
//功能:检查应答信号
//说明:时钟线为低,数据据为高,当数据线为低时表示有应答,返回0否则返回1
/*****************************************************************/
uchar check(void)
{
    uchar ACK=0;  
        delaymm(); delaymm();delaymm();
        SCL=0;delaymm();delaymm();
        SCL=1;delaymm();delaymm();
        if(SDA)       
        {
                 ACK=1;
        }
        else
        {
                 ACK=0;
        }  
        SCL=0;          
        delaymm(); delaymm();delaymm();
        return(ACK);
}
/*****************************************************************
//函数:void sendBYTE(uchar data)
//功能:发送一个字节
//
/*****************************************************************/
void sendBYTE(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {
                if((dat&0x80)>0)
                {
                         SDA=1;
                }
                else
                {
                         SDA=0;
                }
                  delaymm();delaymm();
                SCL=1; delaymm();        delaymm();delaymm();delaymm();
                SCL=0;delaymm();delaymm();
                dat=dat<<1;
        }
        SDA=1;delaymm();

}
/*****************************************************************
//函数:uchar reciveBYTE(void)
//功能:接收一个字节
//
/*****************************************************************/
uchar reciveBYTE(void)
{
        uchar temp1=0;
        uchar j;
        for(j=0;j<8;j++)
        {
                 SCL=0;delaymm();
                SCL=1;delaymm();delaymm();delaymm();
                if(SDA)           //读1
                {
                         temp1=temp1|0x01;
                }
                else                //读0
                {
                         temp1=temp1&0xfe;
                }
                delaymm();delaymm();
                SCL=0;delaymm(); delaymm();
                temp1=temp1<<1;
    }
        return(temp1);       
}

/*****************************************************************
//函数:void  adk(void)
//功能:发送连续读信号
//
/*****************************************************************/
void  ack(void)
{
        SDA=0; delaymm();
        SCL=0; delaymm();
        SCL=1; delaymm();delaymm();delaymm();delaymm();delaymm();delaymm();
        SCL=0; delaymm();
        SDA=1; delaymm();       
}

/*****************************************************************
//函数:void nack(void)
//功能:发送不连续读信号
//
/*****************************************************************/
void nack(void)
{
        SDA=1; delaymm();
        SCL=0; delaymm();
        SCL=1; delaymm();delaymm();delaymm();delaymm();delaymm();
        SCL=0;        delaymm();
}

/*****************************************************************
//函数:void wrtoIIC(uchar dat)
//功能:写器件地址和配置字
//
/*****************************************************************/
void wrtoIIC(uchar dat)
{
        start();         //开始写
        sendBYTE(0x90);        //写器件地址

        while(check()); //
       
        sendBYTE(dat);
        while(check());
        stop();   //结束写

}               

/*****************************************************************
//函数:void rdfromIIC(void)
//功能:从ADS1110中读出数据
//
/*****************************************************************/
void rdfromIIC(void)
{
       
        start();
        sendBYTE(0x91);
        while(check());
        delaymm();
        ADCH=reciveBYTE();       
        ack();
        delaymm();
        ADCL=reciveBYTE();       
        ack();
        delaymm();
        TMR=reciveBYTE();       
        nack();
        stop();
        ADS_ADS=(int)ADCH*256+(int)ADCL;
}
void main()
{
wrtoIIC(0x8c);
rdfromIIC();

}

使用特权

评论回复
板凳
我爱电子520|  楼主 | 2013-12-10 13:06 | 只看该作者
问下ADCH高位      ADCL地位   为什么会这样  还是配置器设置有问题   晶振为12M

使用特权

评论回复
地板
ayb_ice| | 2013-12-10 13:38 | 只看该作者
多看手册,
严格按时序写

使用特权

评论回复
5
XZL| | 2013-12-10 14:38 | 只看该作者
没有硬件的程序啥都说明不了

使用特权

评论回复
6
我爱电子520|  楼主 | 2013-12-10 16:58 | 只看该作者
ayb_ice 发表于 2013-12-10 13:38
多看手册,
严格按时序写

已经按时序写了  值也出来了!但是不对

使用特权

评论回复
7
我爱电子520|  楼主 | 2013-12-10 16:59 | 只看该作者
XZL 发表于 2013-12-10 14:38
没有硬件的程序啥都说明不了

硬件是没问题的!

使用特权

评论回复
8
coody| | 2013-12-10 17:14 | 只看该作者
那你直接输入一个稳定的电压看看

使用特权

评论回复
9
dirtwillfly| | 2013-12-10 18:52 | 只看该作者
这是什么单片机?AD采样转换数值还不会自动进位?

使用特权

评论回复
10
ayb_ice| | 2013-12-11 08:17 | 只看该作者
首先:第9个时钟绝对不可以连续发(即使设备没有应答)
其次:主函数连个无限循环都没有
其它:没有继续看了

使用特权

评论回复
11
ayb_ice| | 2013-12-11 08:19 | 只看该作者
本帖最后由 ayb_ice 于 2013-12-11 08:20 编辑

这个函数严格按时序写了
那才怪了
时序可能对了,逻辑都错了
要先<<,再与或操作

uchar reciveBYTE(void)
{
        uchar temp1=0;
        uchar j;
        
        for(j=0;j<8;j++)
        {
                SCL=0;delaymm();
                SCL=1;delaymm();delaymm();delaymm();
                if(SDA)           //读1
                {
                        temp1=temp1|0x01;
                }
                else                //读0
                {
                        temp1=temp1&0xfe;
                }
                delaymm();delaymm();
                SCL=0;delaymm(); delaymm();
                temp1=temp1<<1;
        }
        return(temp1);
}

使用特权

评论回复
12
望断云山| | 2013-12-11 08:28 | 只看该作者
用asm搬砖的掩面路过 ......

使用特权

评论回复
13
lqw5222218| | 2014-3-22 09:55 | 只看该作者
我觉得你数据高位、低位,要分开用两个寄存器来存,对于你说的低位255,也就是存满,然后转高位,,这种情况,肯定会出错,你是不是转了后把低位清零了,举例一个数 高00000000 低11111111,你直存到对应的高位,低位寄存器不就成了,对不起我只会汇编语言,对c 不太熟。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

5

帖子

0

粉丝