搜索
bottom↓
回复: 16

STM32 SPI操作AD7705的问题!解决了

[复制链接]

出0入0汤圆

发表于 2013-5-24 18:12:10 | 显示全部楼层 |阅读模式
本帖最后由 icifan 于 2013-5-25 17:17 编辑

问题解决了!
在AD7705 Dout端接个22pf的电容终于OK
我也不知道为什么,就行了
OK~\(≧▽≦)/~啦啦啦

情况是这样的!此程序在51上模拟spi是可以的!移植过来时在第一块AD7705上测试是通过的!但后来烧了一块AD7705后!重新上一块AD7705后就读数出问题了!新的AD7705在51上测试是没问题的!真的是不知道哪里出问题了!读出的数据论七八糟的!都搞了了几天了!快疯了…………
真心求助!懂的伸个援助之手!小弟不胜感激…………

#include "spi.h"

/*        复用功能 SPI1_REMAP = 0
        SPI1_NSS                 PA4          CS               
        SPI1_SCK                  PA5         CLK       
        SPI1_MISO          PA6          DOUT       
        SPI1_MOSI          PA7          DIN               
                                PA8        DRDY                        */

#define CS_ADC_LOW()    GPIO_ResetBits(GPIOA,GPIO_Pin_4)        /*片选*/
#define CS_ADC_HIGH()   GPIO_SetBits(GPIOA,GPIO_Pin_4)

SPI_InitTypeDef  SPI_InitStructure;

void SPIx_Init(void)
{

        GPIO_InitTypeDef GPIO_InitStructure;
       
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1|RCC_APB2Periph_AFIO, ENABLE );       
  
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;// AdDrdy
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//PC8配置成上拉输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);               
        GPIO_SetBits(GPIOA,GPIO_Pin_8);
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4;//SPI CS DAC8554  AD7705
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);               
        GPIO_SetBits(GPIOA,GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4);

       

        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;  //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        SPI_Cmd(SPI1, DISABLE); //失能能SPI外设
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //选择了串行时钟的稳态:时钟悬空高
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //数据捕获于第二个时钟
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
        SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
  
        SPI_Cmd(SPI1, ENABLE); //使能SPI外设
       
        CS_ADC_LOW();       
        SPIx_ReadWriteByte(0xff);//启动传输                 
        CS_ADC_HIGH();
}   

//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPIx_ReadWriteByte(u8 TxData)
{               
        u8 retry=0;                                 

        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
        {
                retry++;
                if(retry>200)return 0;
        }                          

        SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
        retry=0;

        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //检查指定的SPI标志位设置与否:接受缓存非空标志位
        {
                retry++;
                if(retry>200)return 0;
        }                                                              

        return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据                                            
}

//写数据
void AD7705_WriteByte(u8 Dst_Addr)   
{   
           CS_ADC_LOW();//使能器件  
        delay_us(20);
        SPIx_ReadWriteByte(Dst_Addr);
        delay_us(100);
          CS_ADC_HIGH();//使能器件  
}



/********AD7705初始化函数***********/

void Init_AD7705(u8 chnanel)
{
    u8 i;
    for(i=0;i<100;i++)/* 多于连续32个 DIN=1 使串口复位 */
    {
                AD7705_WriteByte(0xff);//持续DIN高电平写操作,恢复AD7705接口
        }  
        delay_ms(1);
        switch(chnanel)
        {
                case 1:
                        AD7705_WriteByte(0x20); /* 写通讯寄存器选中ch1*/
                        AD7705_WriteByte(0x04); /* 1MHz时钟,200Hz数据更新速率 */
                        AD7705_WriteByte(0x10); /*选择设置寄存器,使用chnanel 1*/
                        AD7705_WriteByte(0x44); //写设置寄存器 ,设置成单极性、无缓冲、增益为1、滤波器工作、自校准
                break;
                case 2:
                        AD7705_WriteByte(0x21); /* 写通讯寄存器选中ch2 */
                        AD7705_WriteByte(0x04); /* 1MHz时钟,200Hz数据更新速率 */
                        AD7705_WriteByte(0x11); /*选择设置寄存器,使用chnane 2*/
                        AD7705_WriteByte(0x44); //写设置寄存器,设置成单极性、无缓冲、增益为1、滤波器工作、自校准
                break;
                default:       
                        break;
        }
}

/* 读AD7705转换数据 输入通道channel */
u16 GetData7705_CH1(void)
{
    u16 temp1 = 0;
        u16 DataL = 0;
    u16 DataH = 0;
        Init_AD7705(1);                        //初始化通道1
        delay_ms(1);
        AD7705_WriteByte(0x38);   //选中CH1数据寄存器读  
    while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1);  //待数据准备好AdDrdy=0  
        CS_ADC_LOW(); //使能器件  
        delay_us(20);
        DataH = SPIx_ReadWriteByte(0xff);
        DataL = SPIx_ReadWriteByte(0xff);
        delay_us(200);
    CS_ADC_HIGH();   //取消片选        
        DataH = DataH << 8;
    temp1  =  DataH | DataL;

    return temp1;
}

/* 读AD7705转换数据 输入通道channel */
u16 GetData7705_CH2(void)
{
    u16 temp2 = 0;
        u16 DataL = 0;
    u16 DataH = 0;
        Init_AD7705(2);                //初始化通道2
        delay_ms(1);
        AD7705_WriteByte(0x39);   //选中CH2数据寄存器读  
    while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1);  //待数据准备好AdDrdy=0  
        CS_ADC_LOW(); //使能器件  
        delay_us(20);
        DataH = SPIx_ReadWriteByte(0xff);
        DataL = SPIx_ReadWriteByte(0xff);
/        delay_us(100);
    CS_ADC_HIGH();   //取消片选        
        DataH = DataH << 8;
    temp2  =  DataH | DataL;

    return temp2;
}

//数据处理
void ADC_7705(void)
{         
        u8 num1[]={"0000.0mV"};
        u8 num2[]={"0000.0mV"};

        u16 RCH1_16bit,RCH2_16bit;
        u32 l_ncm1,l_ncm2;
               
        RCH1_16bit = GetData7705_CH1();
        l_ncm1        = (u32)(RCH1_16bit*(2500.0/65535)); //算出通道1电压
        RCH2_16bit = GetData7705_CH2();
        l_ncm2        = (u32)(RCH2_16bit*(2500.0/65535)); //算出通道2电压
       
        num1[0]        = l_ncm1/10000+'0';
        num1[1]        = (l_ncm1%10000)/1000+'0';
        num1[2]        = (l_ncm1%1000)/100+'0';
        num1[3]        = (l_ncm1%100)/10+'0';
        num1[5]        = l_ncm1%10+'0';
       
        num2[0]        = l_ncm2/10000+'0';
        num2[1]        = (l_ncm2%10000)/1000+'0';
        num2[2]        = (l_ncm2%1000)/100+'0';
        num2[3]        = (l_ncm2%100)/10+'0';
        num2[5]        = l_ncm2%10+'0';
       
        LCD_ShowString(140,40,num1);
        LCD_ShowString(140,60,num2);
}       

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2013-5-24 20:54:03 | 显示全部楼层
zeroXone 发表于 2013-5-24 19:50
你试着不用那个破延时保护看看   
   不用示波器和单步调试的话   你自己可以算下嘛  看那个时间内SPI发完 ...

您说的是这个么?while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1);

出0入0汤圆

 楼主| 发表于 2013-5-24 21:07:24 | 显示全部楼层
zeroXone 发表于 2013-5-24 19:37
前几天刚刚搞过STM32的SPI  也是遇到了各种问题
  只想说  LZ淡定点

情况是这样的!此程序在51上模拟spi是可以的!移植过来时在第一块AD7705上测试是通过的!但后来烧了一块AD7705后!重新上一块AD7705后就读数出问题了!新的AD7705在51上测试是没问题的!

出0入0汤圆

发表于 2013-5-24 21:18:47 | 显示全部楼层
STM32换一片试一下.

出0入0汤圆

 楼主| 发表于 2013-5-24 21:25:42 | 显示全部楼层
GUOHUDONG 发表于 2013-5-24 21:18
STM32换一片试一下.

换了!没用!

出0入0汤圆

 楼主| 发表于 2013-5-24 23:31:15 | 显示全部楼层
zeroXone 发表于 2013-5-24 21:36
你不是说读出来 乱七八糟吗单步调试  看读出来的是不是对的

试了!不对!

出0入4汤圆

发表于 2013-5-25 01:17:13 来自手机 | 显示全部楼层
注意几点
测ready频率可以知道7705的频率,能确定spi写操作成功没有
用示波器看读操作时spi的时序,特别是输出的16位,看输出数据与读到数据哪里不同

出0入4汤圆

发表于 2013-5-25 01:23:21 来自手机 | 显示全部楼层
你能确定第一次不是偶然成功,能就把原来那个还原,不能就老实从头找吧

出0入0汤圆

发表于 2013-5-29 16:47:38 | 显示全部楼层
楼主你好,我现在在做AD9959,楼主可否提供工程文件做参考。

出0入0汤圆

 楼主| 发表于 2013-5-29 19:18:33 | 显示全部楼层
asun1388 发表于 2013-5-29 16:47
楼主你好,我现在在做AD9959,楼主可否提供工程文件做参考。

这个我没做个哦

出0入0汤圆

发表于 2013-5-29 23:08:42 | 显示全部楼层
我只是想参考下你的做我的。。。。

出0入0汤圆

发表于 2013-5-30 02:17:20 | 显示全部楼层
这个做参考用

出0入0汤圆

发表于 2013-11-26 19:22:58 | 显示全部楼层
我现在用51做,只能读出0.明天再试试,做好了再用stm32,下次参考楼主的资料。

出0入0汤圆

发表于 2013-12-21 20:27:12 | 显示全部楼层
zeroXone 发表于 2013-5-24 19:50
你试着不用那个破延时保护看看   
   不用示波器和单步调试的话   你自己可以算下嘛  看那个时间内SPI发完 ...

您的意思是不是说的 上面的程序在发送的时候 ,并不晓得发送数据寄存器送入移位寄存器之后移位寄存器里面的内容是否发送完 ,如果没有发送完的把片选拉高的就会照成数据出错 ,请问是这样的么 ?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-23 15:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表