打印
[51单片机]

51怎么用串口以外的I/O口读取16位串行AD的数据啊

[复制链接]
3235|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 黑小子mxx 于 2014-3-23 18:45 编辑

由于51的串口有他用,所以只能用别的I/O口读取16位串行AD的数据,不知道怎么实现啊?哪位大神给点儿提示,有源程序就更好了,谢谢了先~~~~

下面是我从网上找的程序,但是不全,前面蓝色部分是我自己加的,注释差不多也是,不知道我的理解对不对?
还有:标记红色的3行代码我看的不是很明白,希望各位帮忙分析一下。看要怎么改改才可行。
ad7705 数据采集处理源代码

#define SpiCS_0  P1^0 = 0
#define SpiCS_1  P1^0 = 1
#define SpiDo_0  P1^1 = 0
#define SpiDo_1  P1^1 = 1
#define SpiCL_0  P1^2 = 0
#define SpiCL_1  P1^2 = 1
#define RESET_0  P1^3 = 0
#define RESET_1  P1^3 = 1

sbit IN = P1^4;
sbit DRDY = P3^2;
#define spiDA_IN  IN & 0x01


void Press_Init(void)        //ad7705初始化测压channel 00
{
        SpiCS_0;//使能AD7705,低有效
        Delay(50);
        RESET_0;                //防止接口迷失,复位AD7705
        Delay(150);
        RESET_1;                //
        

        MSP430_WriteSPI0(0x20);        // 写0x21通信寄存器,测温channel 01 ,下一个写设置寄存器
        MSP430_WriteSPI0(0x04);        // 写0xc0时钟寄存器内部频率50HZ
        MSP430_WriteSPI0(0x10);        // 写0x11通信寄存器,测温channel 01 ,下一个写时钟寄存器
        MSP430_WriteSPI0(0x40);        // 写0x46设置寄存器,设置成单极性、无缓冲、增益为1、滤波器工作、自校准
}

void MSP430_WriteSPI0(char a) //向AD7705写入一个字节的函数
{
        char j,temp=0x80;
        
        for (j=0; j<8; j++)
        {   
                SpiCL_0;                //串行时钟为低电平时钟
                if (temp & a)
                {
                        SpiDo_1;        //向AD7705发送高电平
                }
                else
                {
                        SpiDo_0;        //向AD7705发送低电平
                }
               
                SpiCL_1;                //串行时钟为高电平
                temp = temp>>1;
        }
}

int Read7705(void)
{
        unsigned char i;
        unsigned char TempBit  = 0;
        int TempData = 0;
        
        SpiCL_0;                        //串行时钟为低电平
        spiDIR_IN;                        //输入模式????
        for (i=0; i<16; i++)
        {
                SpiCL_1;                //串行时钟为高电平
                if (SpiDA_IN == 0x01 )
                {
                        TempBit = 1;        //读取一个高电平
                }
                else
                {
                        TempBit = 0;        //读取一个低电平
                }
                SpiCL_0;                //串行时钟为低电平
                TempData = (TempData << 1) | TempBit;
        }
        spiDIR_OUT;                        //输出模式?????
        SpiDi_1;                        //??????
        
        return TempData;
}

int get_ad7705(char channel)        //读温度channel=0x01或差压数据 channel=0x00
{
        if(channel==0x00)
        {
                MSP430_WriteSPI0(0x38);//写通信寄存器设置读当前通道数据 0x38|channel=0x00
        }
        else
        {

                MSP430_WriteSPI0(0x39);//0x38|channel=0x01//8785413
        }
        
        while (DRDY==1);//DRDY为高不能进行读操作
        kb[30] = Read7705();//RXBUF0
        if(kb[30]<0)
                kb[30]=kb[30]+32768;
        else
                kb[30]=kb[30]-32767;
        return(kb[30]);                //接收到的数据为AD16bit
}

int adave(char n,char channel) //求n次A/D转换的平均值
{
        volatile char i,pit;
        
        for(ue=0;ue<n;ue++)
        {
                ADC_temp[ue]=get_ad7705(channel); //读走温度数据  
        }
        
        ADC_tem=0;
        for(pit=4;pit<n;pit++)
        {
                ADC_tem+=ADC_temp[pit]; //求和
        }
        
        max=ADC_temp[4];
        min=ADC_temp[4];
        for(i=4;i<n;i++)
        {
                if(ADC_temp>max)
                max=ADC_temp;
                if(ADC_temp<min)
                min=ADC_temp;
        }
        ADC_tem=(ADC_tem-max-min)/(n-6);//去掉最大最小值然后求平均值
        return ADC_tem;
}

相关帖子

沙发
df_flying| | 2014-3-22 19:47 | 只看该作者
本帖最后由 df_flying 于 2014-3-22 19:56 编辑

串口没用的话你可以用来接收16位啊?那就是说可以分开读喽?那用定时器(发送的话定一个定时器溢出就行了,需要接受就加个外部中断。)模拟一个串口就是啊。其实可以用一个外部中断和定时器共同模拟一个接受16位的串行数据的

使用特权

评论回复
板凳
coody| | 2014-3-22 20:14 | 只看该作者
16位串行AD是什么数据格式,你要先弄清楚

使用特权

评论回复
地板
天风立马| | 2014-3-22 20:33 | 只看该作者
先确定用哪种通信方式。比如I2C?SPI?UART?等等。确定好了,随便找几个(需要几个找几个)闲着的io口,对照时序图写程序即可。

使用特权

评论回复
5
黑小子mxx|  楼主 | 2014-3-22 23:12 | 只看该作者
coody 发表于 2014-3-22 20:14
16位串行AD是什么数据格式,你要先弄清楚

格式不是很清楚啊~不过AD用的是AD7705

使用特权

评论回复
6
黑小子mxx|  楼主 | 2014-3-22 23:13 | 只看该作者
天风立马 发表于 2014-3-22 20:33
先确定用哪种通信方式。比如I2C?SPI?UART?等等。确定好了,随便找几个(需要几个找几个)闲着的io口,对 ...

AD7705转换芯片还需要一个串行时钟,是不是用SPI通信方式好点啊?可是不知道怎么写啊、、、

使用特权

评论回复
7
黑小子mxx|  楼主 | 2014-3-22 23:29 | 只看该作者
本帖最后由 黑小子mxx 于 2014-3-22 23:31 编辑
天风立马 发表于 2014-3-22 20:33
先确定用哪种通信方式。比如I2C?SPI?UART?等等。确定好了,随便找几个(需要几个找几个)闲着的io口,对 ...


使用特权

评论回复
8
黑小子mxx|  楼主 | 2014-3-22 23:33 | 只看该作者
df_flying 发表于 2014-3-22 19:47
串口没用的话你可以用来接收16位啊?那就是说可以分开读喽?那用定时器(发送的话定一个定时器溢出就行了, ...

不知道大神有没有源程序额?这一点儿头绪都没有啊、、、

使用特权

评论回复
9
月影风| | 2014-3-22 23:46 | 只看该作者
按照通讯协议写,用几个线就几个io

使用特权

评论回复
10
xyz549040622| | 2014-3-23 07:59 | 只看该作者
先搞清楚数据是AD中的数据是如何出来的,如何给AD写命令再说

使用特权

评论回复
11
ayb_ice| | 2014-3-23 08:42 | 只看该作者
把时序看懂自然就明白了

使用特权

评论回复
12
lbc___| | 2014-3-23 09:52 | 只看该作者
一般这种的都是spi口吧

使用特权

评论回复
13
黑小子mxx|  楼主 | 2014-3-23 11:00 | 只看该作者
本帖最后由 黑小子mxx 于 2014-3-23 11:04 编辑
ayb_ice 发表于 2014-3-23 08:42
把时序看懂自然就明白了

前面两个我知道了,是为了防止接口迷失,于是将AD7705复位,可是后面三条语句我看了时序图还是不是很明白,大神能否给点儿提示?
下面是时序图:

使用特权

评论回复
14
黑小子mxx|  楼主 | 2014-3-23 11:05 | 只看该作者
lbc___ 发表于 2014-3-23 09:52
一般这种的都是spi口吧

嗯,已经确定用SPI,就是有几行语句看不懂

使用特权

评论回复
15
黑小子mxx|  楼主 | 2014-3-23 11:09 | 只看该作者
xyz549040622 发表于 2014-3-23 07:59
先搞清楚数据是AD中的数据是如何出来的,如何给AD写命令再说

AD7705的数据是高位在前、低位在后吧,写命令的话应该先写通信寄存器。我就知道这么多了、、、不知大神能否赐教一下?

使用特权

评论回复
16
天风立马| | 2014-3-23 11:46 | 只看该作者
黑小子mxx 发表于 2014-3-22 23:13
AD7705转换芯片还需要一个串行时钟,是不是用SPI通信方式好点啊?可是不知道怎么写啊、、、 ...

时序图让你干什么你干什么就行了。他让低你就低,让你高你就高,什么时候低,低多久,什么时候高,高多久。时序图上都会标的很清楚,就像你发的。看不懂动的话,去查怎么看时序图,看懂了,就无所谓哪种协议了,只要有时序图,都随意用。

使用特权

评论回复
17
ayb_ice| | 2014-3-23 13:42 | 只看该作者
这看不懂吗
比如,写时序
首先是CS拉低,其次时钟拉低,然后写数据,再将时钟拉高,1BIT完成...

使用特权

评论回复
18
黑小子mxx|  楼主 | 2014-3-23 14:40 | 只看该作者
ayb_ice 发表于 2014-3-23 13:42
这看不懂吗
比如,写时序
首先是CS拉低,其次时钟拉低,然后写数据,再将时钟拉高,1BIT完成... ...

这个道理我懂,可是上面三行红色的语句我不知道是用来干啥的。能否帮忙解释解释?

使用特权

评论回复
19
江枫渔火| | 2014-3-23 14:59 | 只看该作者
撸主,这个很简单的啊!
首先你发的代码是430的,这东西的端口控制跟51是不一样的啊。你所说的3个红色地方,只是用来切换端口状态的。

51的端口输入和输出不需要切换的,但其他单片机的端口都是需要设置模式的,如果你前面设置了端口为输出模式,而你不改一下端口模式,是不能接受输入的,这一点【在用惯51做端口模拟I2C和SPI的的童鞋都要注意的】

使用特权

评论回复
20
黑小子mxx|  楼主 | 2014-3-23 15:43 | 只看该作者
本帖最后由 黑小子mxx 于 2014-3-23 15:44 编辑
江枫渔火 发表于 2014-3-23 14:59
撸主,这个很简单的啊!
首先你发的代码是430的,这东西的端口控制跟51是不一样的啊。你所说的3个红色地方 ...

额额,对对对。听他们玩儿ARM得老是要设置端口模式,原来是这样。那如果用51的话上面三条语句是可以省略的是吗?是不是还需要在读写之前应该要对AD7705的通信寄存区写命令啊?

使用特权

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

本版积分规则

42

主题

307

帖子

2

粉丝