17221|26

259

帖子

5

TA的资源

一粒金砂(高级)

楼主
 

STM32f051驱动外接ADC芯片ADS1120问题 [复制链接]

 

       使用stm32f051c8t6的SPI1驱动ADS1120芯片,结果程序一直卡在等待nDRDY引脚变为低电平的代码段,于是在ADS1120初始化的函数配置寄存器结束后读取所有寄存器数据,用来检测配置是否正确,结果debug界面中显示的寄存器数据全是0xFF,,,之前一直使用的是HAL库,由于本次使用的板子需要兼容旧版程序因此需要使用固件库,初次使用,参考了不少代码,不知道是不是哪里配置错了,打算明天用示波器看看有关的四个引脚波形是否正确,,有用过ADS1120芯片的大侠给看看吧,多谢了!下面是相关代码:


====程序简述
开发环境:
        开发工具:keil V5.20  stm32f0_stdperiph_lib
        硬件设备:STM32F051C8T6, ADS1120


========SPI1配置及读写数据函数:
  1. SPI_InitTypeDef  SPI_InitStructure;

  2. void SPIx_Init(void)
  3. {
  4.         GPIO_InitTypeDef GPIO_InitStructure;
  5.   
  6.         RCC_AHBPeriphClockCmd(        RCC_AHBPeriph_GPIOA, ENABLE );
  7.         RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );       

  8.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  9.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  
  10.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  11.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  12.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  13.         GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);

  14.         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  
  15.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;               
  16.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;               
  17.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;               
  18.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;       
  19.         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;               
  20.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;               
  21.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;       
  22.         SPI_InitStructure.SPI_CRCPolynomial = 7;       
  23.         SPI_Init(SPI1, &SPI_InitStructure);  

  24.         SPI_Cmd(SPI1, ENABLE);
  25.        
  26.         SPIx_ReadWriteByte(0xff);                 
  27. }   
复制代码
  1. //SPI1写数据  
  2. void SPI1_WriteBytes(uint8_t *TxBuffer,uint16_t TxLenth)  
  3. {  
  4.     uint8_t i;  
  5.     while(TxLenth--){  
  6.         while( (SPI1->SR & SPI_SR_TXE) == 0 );  
  7.         SPI1->DR=*TxBuffer++;                  
  8.         while((SPI1->SR&SPI_SR_RXNE)==0);  
  9.         i=SPI1->DR;  
  10.     }  
  11.     i++;      
  12. }  

  13. //SPI1读数据  
  14. void SPI1_ReadBytes(uint8_t *RxBuffer,uint16_t RxLenth)  
  15. {  
  16.     while(RxLenth--){            
  17.         while((SPI1->SR&SPI_SR_TXE)==0);  
  18.         SPI1->DR=*RxBuffer;  
  19.         while((SPI1->SR&SPI_SR_RXNE)==0);  
  20.         *RxBuffer++=SPI1->DR;         
  21.     }  
  22. }  

  23. void ADC_WriteBytes(uint8_t *Cmd, uint16_t Count)
  24. {
  25.         SPI1_WriteBytes(Cmd,Count);
  26. }

  27. void ADC_ReadBytes(uint8_t *RxBuffer,uint16_t RxLenth)  
  28. {
  29.                 SPI1_ReadBytes(RxBuffer,RxLenth);
  30. }  

  31. void ADC_ReadWriteBytes(uint8_t *Cmd, uint8_t *Buffer,uint16_t Count)
  32. {
  33. //        uint8_t i;
  34. //        for(i=0; i<Count; i++)
  35. //        {
  36. //                *Buffer = SPIx_ReadWriteByte(*Cmd++);
  37. //                Buffer++;
  38. //        }
  39.         ADC_WriteBytes(Cmd,1);
  40.         ADC_ReadBytes(Buffer,Count);
  41. }
复制代码



====读写寄存器函数
  1. /**
  2.   * [url=home.php?mod=space&uid=159083]@brief[/url]  读取寄存器中的数据.
  3.   * @param        *Buffer:读取到的数据指针地址.
  4.         * @param        Length:需要读取的数据长度.
  5.   * @note   一次读取多个寄存器数据,从00寄存器开始读取.
  6.   * @retval None
  7.   */
  8. static void ADS1120_ReadReg(uint8_t *Buffer,uint8_t Length)  
  9. {  
  10.     uint8_t cmd;  
  11.     CS_L;
  12.                 cmd = ADC_CMD_RREG | 0x03;
  13.                 ADC_WriteBytes(&cmd,1);
  14.                 ADC_ReadBytes(Buffer,Length);
  15.     CS_H;  
  16. }

  17. /**
  18.   * @brief  写入数据到指定寄存器.
  19.   * @param  RegAddr: 指定寄存器地址.
  20.   * @param        *Buffer:需要写入的数据指针.
  21.         * @param        Length:写入数据长度.
  22.   * @note   None.
  23.   * @retval None
  24.   */
  25. static void ADS1120_WriteReg(uint8_t RegAddr,uint8_t *Buffer,uint8_t Length)  
  26. {  
  27.     uint8_t cmd;  
  28.     CS_L;
  29.                 cmd = ADC_CMD_WREG | (((RegAddr<<2) & 0x0c) |((Length-1)&0x03));
  30.                 ADC_WriteBytes(&cmd,1);  
  31.     ADC_WriteBytes(Buffer,Length);  
  32.     CS_H;  
  33. }

  34. /**
  35.   * @brief  忙状态判断.
  36.   * @param  None.
  37.   * @note   最长等待时间.
  38.   * @retval None
  39.   */
  40. static uint8_t ADS1120_WaitBusy()  
  41. {  
  42.     uint16_t i;  
  43.     CS_L;  
  44.     i=0;  
  45.     while(GPIO_ReadInputDataBit(ADS1120_DRDY_GPIO_PORT,ADS1120_DRDY_GPIO_PIN)){  // 等待就绪(等待DRDY为0)
  46.         Delay();  
  47.         i++; if(i>20000)return 1;  
  48.     }  
  49.     CS_H;  
  50.     return 0;  
  51. }  
复制代码



====ADS1120初始化函数
  1. /**
  2.   * @brief  ADS1120初始化.
  3.   * @param  None.
  4.   * @note   复位芯片及初始化寄存器 .
  5.   * @retval None
  6.         * @note         None
  7.   */
  8. void ADS1120_Init()  
  9. {  
  10.         uint8_t cmd;
  11.         uint8_t read[4],buf[4];
  12.        
  13.         ADS1120_WriteCmd(ADC_CMD_RESET);                                                                          // 复位设备至上电状态(不对SPI进行复位) 20psp需要0.6ms
  14.         Delay();  
  15.        
  16.         cmd = 0x28; // 差模输入正负端配置、增益配置
  17.         ADS1120_WriteReg(ADC_REG_00,&cmd,1);
  18.        
  19.         cmd = 0x00; // 数据率、操作模式、转换模式、温度传感器模式、烧毁电流检测
  20.         ADS1120_WriteReg(ADC_REG_01,&cmd,1);
  21.        
  22.         cmd = 0x07; // 内部2.048V参考电压、无滤波、低端电源开关总是开启(?)、恒流源电流1.5mA
  23.         ADS1120_WriteReg(ADC_REG_10,&cmd,1);
  24.        
  25.         cmd = 0x30; // IDAC1->AIN0,IDAC2->AIN3,nDRDY
  26.         ADS1120_WriteReg(ADC_REG_11,&cmd,1);
  27.        
  28.         // 读取寄存器
  29.         ADS1120_ReadReg(read,4);
  30.        
  31.         buf[0] = read[0];
  32.         buf[1] = read[1];
  33.         buf[2] = read[2];
  34.         buf[3] = read[3];
  35.          
  36. }
复制代码


====读取通道AD值函数
  1. /**
  2.   * @brief  获取指定通道的AD数据.
  3.   * @param  Ch:通道编号.
  4.   *          传入参数可为下述值:
  5.   *            @arg 0: RT0
  6.   *            @arg 1: RT1
  7.   *            @arg 2: RT2
  8.   * @note   None.
  9.   * @retval Data: AD数据
  10.   */
  11. int32_t ADS1120_GetChannelData(uint8_t Ch)
  12. {
  13.         int32_t result;
  14.         ADS1120_Change_Channel(Ch);       

  15.         ADS1120_Start();
  16.         ADS1120_WaitBusy();//16MS p73
  17.         result = ADS1120_Read();
  18.         ADS1120_Stop();
  19.         return result;
  20. }
复制代码


====读取AD数据函数
  1. /**
  2.   * @brief  读取ADS1120中的转换数据.
  3.   * @param  None.
  4.         * @note   None.
  5.   * @retval D:AD数值
  6.   */
  7. static int32_t ADS1120_Read(void)  
  8. {  
  9. //    uint8_t  Cmd[3]={ADC_CMD_RDATA,0x00,0x00};
  10.                 uint8_t  Cmd;
  11.     uint8_t  Buf[3];
  12.     int32_t D;  
  13.     CS_L;        
  14.                 ADC_ReadWriteBytes(&Cmd,Buf,3);
  15.     CS_H;  
  16.     D=Buf[0];
  17.                 D=D*256+Buf[1];
  18.                 D=D*256+Buf[2];
  19.                 D=D/256;
  20.     return D;  
  21. }
复制代码











此帖出自stm32/stm8论坛

最新回复

正在用这颗芯片,翻出老帖子,很不错的参考资料,谢谢!   详情 回复 发表于 2024-7-12 15:12
点赞 关注
 

回复
举报

4177

帖子

9

TA的资源

五彩晶圆(高级)

推荐
 
Tobey 发表于 2017-3-23 21:24
1、是的,规范的格式就应该是您说的那么写,欠考虑了,,因为当前就用SPI1测试一个功能,所以没怎么考虑 ...

关于模拟的事情,我想虽然不难,还是用本身自带的硬件spi较好。好好啃你的datasheet吧,多啃下,英文理解能力就慢慢上来了。做电子的,不啃这个不行的。
此帖出自stm32/stm8论坛
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

推荐
 
从你的程序看应该是spi与TI的ADS1120进行通讯,通过spi来操作ADS1120内部的寄存器来实现对ADS1120的一些功能。

1、从你刚开始的程序配置来看。GPIO初始化以后,在GPIO_Init后没有调用引脚复用函数。我记得我用F072的时候,是有引脚复用函数的。
  1. GPIO_PinAFConfig
复制代码



2、NSS即SPI使能引脚为什么没有在GPIO初始化中体现?


3、你的GPIO初始化之后,为什么把所有io的setbits也就是置位。不知道你要干嘛。。。。完全不用这句啊。
  1. GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
复制代码



4、关于SPI初始化,我说一下几点:
    a、设置SPI的数据大小,是16bit,还是8bit,这个要根据ADS1120的datasheet来看,我之前也用spi操作过tid的一个带寄存器的spi接口的片子。datasheet已经明确有指出是16bit的。所以我设置为16bit。这个一般都会在,芯片的datasheet的串行数据格式说明中,要么体现在图中,要么会明确说明。
  1. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;      
复制代码



   b、SPI_InitStructure.SPI_CPOL主要是设置时钟极性,设置串行同步时钟的空闲状态。这个要根据datasheet的时序图来看,如果SCLK的空闲状态为低电平就设置low;
   c、你的这个NSS既然设置的是如下:
  1. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
复制代码

为什么gpio不配置NSS引脚?
  d、SPI_InitStructure.SPI_FirstBit这个到底是MSB还是LSB。不要看着别人是MSB或者LSB就跟着设置。
这个的设置要看datasheet中,读写操作的时序图,有的时序图会明说MSB或LSB,有的只是给你给出数据格式。这个你要好好看的。
  e、SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; 既然选择是软件控制使能引脚,那么除了我上述中对nss引脚的提示之外。
建议,在SPI_Write_Byte和SPI_Read_Byte的函数中(即也就是你的SPI1_ReadBytes和SPI1_WriteBytes),NSS的处理如下:


  1. SPI1_ReadBytes(xx,xx)
  2. {
  3.    NSS =1;//打开nss
  4.    //SPI1_ReadBytes的语句体

  5.    NSS = 0;//读完,关闭nss
  6. }

  7. SPI1_WriteBytes(xx,xx)
  8. {
  9.    NSS =1;//打开nss
  10.    //SPI1_WriteBytes的语句体

  11.    NSS = 0;//写完,关闭nss
  12. }
复制代码



5、还有如果真要操作ADS1120.建议将寄存器操作封装为函数。你是学生,时间大把的有。
给你举个例子:

  1. ADS1120_Enable(void)
  2. {
  3. //寄存器使能
  4. }
复制代码






此帖出自stm32/stm8论坛

赞赏

3

查看全部赞赏

 
 

回复

259

帖子

5

TA的资源

一粒金砂(高级)

4
 
十分感谢您对上述代码提出的建议!
针对您提出的疑问,给出下面的回复:
1、GPIO初始化时未使用引脚复用函数
我想您指的是下面这种配置方式吧:
  1. GPIO_PinAFConfig(GPIOA, GPIO_PinSource5,  GPIO_AF_0);   
  2. GPIO_PinAFConfig(GPIOA, GPIO_PinSource6,  GPIO_AF_0);
  3. GPIO_PinAFConfig(GPIOA, GPIO_PinSource7,  GPIO_AF_0);
复制代码

之所以没用这种方式是因为我在配置引脚时选择了复用模式,
  1. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  2. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  //复用模式
  3. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  4. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  5. GPIO_Init(GPIOA, &GPIO_InitStructure);
复制代码

2、NSS未在GPIO初始化中体现
由于NSS被我归类到gpio配置文件中了,因此没在SPI配置文件中进行初始化配置       
3、这句确实是冗余的,,
4、SPI初始化
a、数据格式
根据图一来看是16bit的,我给设置成8bit,读的时候读取两次,,,这样的模式在之前编写的驱动是可以的,,

图1
b、CPOL及CPHA配置
这部分配置我是依据数据手册配置的,如图2所示:

图2
c、NSS引脚未配置
NSS引脚即上述CS引脚,在gpio配置文件中配置,采用CS_L,CS_H设置为低电平或高电平
d、数据传输是MSB开始还是LSB开始
这个从图1中可看出是MSB没问题
e、SPI数据读取前后的除能使能操作
当前的模式是在调用SPI_ReadBytes和SPI1_WriteBytes前打开nss,调用结束后关闭nss,现在按照您的建议进行修改,
5、封装寄存器操作
您说的是,测试通过就对其进行完善,多谢您提出的宝贵意见!






此帖出自stm32/stm8论坛

点评

1、“之所以没用这种方式是因为我在配置引脚时选择了复用模式,[/backcolor]”, -->GPIO在配置为复用模式后,还是需要调用引脚复用函数的。你的复用模式我早看到了。 这个其实与F103略有区别的。 2、数据传输  详情 回复 发表于 2017-3-22 18:42
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

5
 
Tobey 发表于 2017-3-22 11:06
十分感谢您对上述代码提出的建议!
针对您提出的疑问,给出下面的回复:
1、GPIO初始化时未使用引脚复用 ...

1、“之所以没用这种方式是因为我在配置引脚时选择了复用模式,”,
-->GPIO在配置为复用模式后,还是需要调用引脚复用函数的。你的复用模式我早看到了。
这个其实与F103略有区别的。

2、数据传输是MSB开始还是LSB开始。
--> 我知道你配置的是MSB,但是我的意思是说,你不要看别人配置的是MSB,你也跟风,配置成MSB。这个的确是要看datasheet的。

3、至于gpio初始化这里,我给你点建议,你这么配置不是不对。只是让人一下子看不出来你配置哪个引脚的。
如下我给你举个例子:
例如你的PA5是SPI的CS引脚,对吧。
建议直接宏定义为 :

  1. #define    CS_GPIO_Pin    GPIO_Pin_5

  2. #define   CS_GPIO_Port     GPIOA
复制代码


这样别人一看知道是cs引脚。对吧,我个人习惯这么写。因为看起来很容易看懂程序。

此帖出自stm32/stm8论坛

点评

1、是这样啊,,,我以为和f103的配置是一样的,, 重新修改了SPI配置: [mw_shl_code=applescript,true]void SPI1_Config(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructu  详情 回复 发表于 2017-3-22 20:37
 
 
 

回复

259

帖子

5

TA的资源

一粒金砂(高级)

6
 
huaiqiao 发表于 2017-3-22 18:42
1、“之所以没用这种方式是因为我在配置引脚时选择了复用模式,”,
-->GPIO在配置为复用模 ...

1、是这样啊,,,我以为和f103的配置是一样的,,
重新修改了SPI配置:
  1. void SPI1_Config(void)
  2. {
  3.         SPI_InitTypeDef  SPI_InitStructure;
  4.   GPIO_InitTypeDef GPIO_InitStructure;
  5.   
  6.   /* Enable the SPI1 periph */
  7.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

  8.    
  9.   /* SPI1 Pins configuration ************************************************/
  10.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource5,  GPIO_AF_0);   
  11.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource6,  GPIO_AF_0);
  12.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource7,  GPIO_AF_0);

  13.   /* Configure pins as AF pushpull */
  14.   GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5 |GPIO_Pin_6 | GPIO_Pin_7;
  15.   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  16.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  17.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  18.   GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  19.   GPIO_Init(GPIOA, &GPIO_InitStructure);  

  20.   
  21.   /* SPI1 configuration -------------------------------------------------------*/
  22.   SPI_I2S_DeInit(SPI1);
  23.   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  24.   SPI_InitStructure.SPI_DataSize  = SPI_DataSize_8b;
  25.   SPI_InitStructure.SPI_CPOL      = SPI_CPOL_Low;
  26.   SPI_InitStructure.SPI_CPHA      = SPI_CPHA_1Edge;
  27.   SPI_InitStructure.SPI_NSS       = SPI_NSS_Soft;
  28.   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  29.   SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  30.   SPI_InitStructure.SPI_CRCPolynomial = 7;
  31.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  32.   SPI_Init(SPI1, &SPI_InitStructure);
  33.   SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);
  34.   
  35.   /* Enable the SPI peripheral */
  36.   SPI_Cmd(SPI1, ENABLE);

  37.         SPI1_CS(Bit_SET);        
  38. }
复制代码

2、是的,我没什么经验,因此在编写驱动程序时都得先把datasheet看一遍,,,一天又过去了,然而并没有多大进展,当前能通过SPI发送数据也能读取数据,但是读出的数据总是0xFF,采用示波器测量,显示ADS1120数据输出引脚的确是高电平,,,于是给ADS1120发送两个字节(0x40、0x28),验证发送数据时序是否正确,(01000000,00101000)采用示波器测量没发现问题,如下图所示,,然而不管是读取寄存器数据还是读取AD转换结果,得到的数据都是0xFF,现在打算再梳理一遍程序逻辑,然后采用GPIO模拟SPI再试试、、、
3、明白您的意思了,其实我就是这么做的,,,只是觉得用CS_L、CS_H,看代码大概更易懂,所以给替换成了CS_L、CS_HL ,,,
  1. /* Private define ------------------------------------------------------------*/

  2. #define START_Pin GPIO_Pin_13
  3. #define START_GPIO_Port GPIOC
  4. #define ADS_CS_Pin GPIO_Pin_0
  5. #define ADS_CS_GPIO_Port GPIOA
  6. #define ADS_DRDY_Pin GPIO_Pin_1
  7. #define ADS_DRDY_GPIO_Port GPIOA
  8. #define PROTECT_Pin GPIO_Pin_2
  9. #define PROTECT_GPIO_Port GPIOA
  10. #define LINE_H_Pin GPIO_Pin_3
  11. #define LINE_H_GPIO_Port GPIOA
复制代码




此帖出自stm32/stm8论坛

点评

SPI的读写函数,我看过你的程序,这个我之前在网上看过,但是我也没有测试过到底好不好。spi的读写我建议你看下正点原子的F407的SPI好了,不用参数也可以。其实spi每次我如果没有记错的话,就是操作一个字节(我记得  详情 回复 发表于 2017-3-22 20:54
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

7
 
Tobey 发表于 2017-3-22 20:37
1、是这样啊,,,我以为和f103的配置是一样的,,
重新修改了SPI配置:
[mw_shl_code=applescript,tru ...

SPI的读写函数,我看过你的程序,这个我之前在网上看过,但是我也没有测试过到底好不好。spi的读写我建议你看下正点原子的F407的SPI好了,不用参数也可以。其实spi每次我如果没有记错的话,就是操作一个字节(我记得数据寄存器是一个字节的)
此帖出自stm32/stm8论坛

点评

好的,多谢指点!407的资料我倒是有,还没看过,就看过103的资料,昨天使用标准库建立keil项目就是参考的原子f103的资料,SPI一开始也是参考的原子f103中的资料,不过由于编程习惯不同,重新看了datasheet,自己重新  详情 回复 发表于 2017-3-22 21:41
 
 
 

回复

259

帖子

5

TA的资源

一粒金砂(高级)

8
 
huaiqiao 发表于 2017-3-22 20:54
SPI的读写函数,我看过你的程序,这个我之前在网上看过,但是我也没有测试过到底好不好。spi的读写我建议 ...

好的,多谢指点!407的资料我倒是有,还没看过,就看过103的资料,昨天使用标准库建立keil项目就是参考的原子f103的资料,SPI一开始也是参考的原子f103中的资料,不过由于编程习惯不同,重新看了datasheet,自己重新编写了SPI的读写函数:
1、SPI写数据函数依据datasheet中的时序图,SPI开启后就可以写数据了:


  1. /****************************************************************
  2.   * @brief  ADS1120_Write.
  3.   * @param  Byte
  4.   * @retval SPI_ReceiveData8
  5.   */
  6. uint8_t ADS1120_Write(uint8_t Byte)
  7. {
  8.         SPI1_CS(Bit_RESET);
  9.         while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET){};
  10.         SPI_SendData8(SPI1,Byte);
  11.         while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET){};
  12.         SPI1_CS(Bit_SET);
  13.         return(SPI_ReceiveData8(SPI1));       
  14. }
复制代码



2、SPI读数据函数依据datasheet中的时序图,在发送读取数据命令后,发送两个字节的0x00就能读出两个字节的AD转换数据了,由于读取寄存器是一个字节,因此通过变量RxLength来决定读取的数据长度,,不知道我是不是理解错了,,,得到的数据总是0xFF~~待会儿看看407的资料里是怎么写的,



  1. void ADS1120_WriteRead(uint8_t Byte, uint8_t *RxBuffer,uint16_t RxLength)
  2. {
  3.         int i;
  4.         ADS1120_Write(Byte);
  5.         for(i=0; i<RxLength; i++)
  6.         {
  7.                         *RxBuffer = ADS1120_Write(0x00);
  8.                         RxBuffer++;
  9.         }
  10. }
复制代码



此帖出自stm32/stm8论坛
 
 
 

回复

259

帖子

5

TA的资源

一粒金砂(高级)

9
 
使用GPIO模拟SPI读写,重新把datasheet中的读写时序看了遍,再对照示波器中显示的时序图,貌似找出了个问题,,,之前看时序图时看到下降沿就给标识为高亮,,,因此没发觉示波器中显示的波形有什么问题,,,现在看来,ADS1120的读写都是由SCLK的上升沿触发的,,而示波器中的波形显示的是SCLK下降沿触发,,,明天把备份项目修改下试试,但愿问题就是出在这里了,,,


此帖出自stm32/stm8论坛

点评

1、回复你7楼的内容。 --->a、你的这个函数ADS1120_Write,这个明显的就是个SPI的写函数。 我的建议是: 你的程序模块化,所谓模块化。SPI1.c/SPI1.h这个单独形成文件。ADS1120的寄存器封装的函数,单独形成ADS11  详情 回复 发表于 2017-3-22 23:19
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

10
 
本帖最后由 huaiqiao 于 2017-3-22 23:32 编辑
Tobey 发表于 2017-3-22 22:24
使用GPIO模拟SPI读写,重新把datasheet中的读写时序看了遍,再对照示波器中显示的时序图,貌似找出了个问题 ...

1、回复你7楼的内容。
--->a、你的这个函数ADS1120_Write,这个明显的就是个SPI的写函数。
我的建议是:
你的程序模块化,所谓模块化。SPI1.c/SPI1.h这个单独形成文件。ADS1120的寄存器封装的函数,单独形成ADS1120.c/ADS1120.h.  名字上不要混淆。
如果是我的话,这个ADS1120_Write这个函数我会写SPI1_Write函数,并且这个函数放在SPI1.c中,对吧。。。。
而在ADS1120.c中,如果ADS1120的寄存器操作需要封装成单独的函数的时候,如
  1. ADS1120_Enable(void)
  2. {
  3. //寄存器操作
  4. //调用SPI1相关的读或者写函数

  5. }
复制代码



可是我觉得你没必要在SPI1.c中单独写出SPI的读操作函数和写操作函数。如下的一个函数就既可以读字节,又可以写字节。
  1. /***********************************************************************************
  2. **函数名称:SPI1_ReadWriteByte(u8 TxData)
  3. **入口参数:TxData:要写入的字节
  4. **出口参数:读取到的字节
  5. **功能描述:
  6. **其    他:无
  7. **作    者:
  8. **版    本:Ver1.0
  9. *************************************************************************************/

  10. u8 SPI1_ReadWriteByte(u8 TxData)
  11. {   //SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
  12.     while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)== RESET){}//

  13.     SPI_I2S_SendData(SPI1,TxData);//通过外设spi1发送一个字节,因为我设置的DataSize是8b的

  14.     while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET){}//

  15.     return (SPI_I2S_ReceiveData(SPI1));//返回通过sp1接收到的数据
  16.    
  17. }
复制代码

如果你要操作两个字节,只需要将这里的u8 TxData 写成u16 TxData(可能F0的话需要写成uint16_t TxData),就可以的啊。没必要弄那么多函数出来。
还有如果你要改成u16 TxData的话,如下的配置,需要改成16bit的。
  1. SPI_InitTypeDef_Struct.SPI_DataSize             = SPI_DataSize_16b;
复制代码



2、回复你8楼内容
--->我觉得你在给自己增加工作量啊。为什么要用GPIO模拟呢?说实话,我都不会gpio模拟spi。真的,惭愧的。
到底是上升沿还是下降沿,你要好好通读datasheet,不要着急去配置,肯定datasheet某个章节会有体现的。好好理解相关章节的意思,这就是我们说的啃datasheet了。O(∩_∩)O哈哈~

3、还有我之所以说F0在引脚复用方面跟F103不同,是因为F103没有引脚复用函数,F103是只需要将IO配置成复用模式就可以(这个用户手册中能找到)。但是F0是不但要配置成复用模式,而且需要调用引脚复用函数(这点上,F0和F4相似)。








此帖出自stm32/stm8论坛

点评

1、是的,规范的格式就应该是您说的那么写,欠考虑了,,因为当前就用SPI1测试一个功能,所以没怎么考虑就直接作为ADS1120的专用函数了,, 2、GPIO模拟没想的那么难,,,就是将相关引脚设置为输入/输出,CS与之前  详情 回复 发表于 2017-3-23 21:24
 
 
 

回复

259

帖子

5

TA的资源

一粒金砂(高级)

11
 
huaiqiao 发表于 2017-3-22 23:19
1、回复你7楼的内容。
--->a、你的这个函数ADS1120_Write,这个明显的就是个SPI的写函数。
我的建议是 ...

1、是的,规范的格式就应该是您说的那么写,欠考虑了,,因为当前就用SPI1测试一个功能,所以没怎么考虑就直接作为ADS1120的专用函数了,,
2、GPIO模拟没想的那么难,,,就是将相关引脚设置为输入/输出,CS与之前的操作一致、不同点只是由之前的函数调用换作通过置高置低电平模拟时钟信号及MOSI数据信号发送数据,以及模拟时钟信号接收MISO发送过来的数据,,,一般情况下没必要采用GPIO模拟的,除非不小心引脚配置错了,或是找不到问题出处,采用GPIO模拟SPI通讯,排除SPI总线配置错误,,,
datasheet确实得好好啃,有时几个不懂的英文单词跳过了,问题就出来了,,,
3、受教了!配置的时候就没考虑过这个问题,,,
此帖出自stm32/stm8论坛

点评

关于模拟的事情,我想虽然不难,还是用本身自带的硬件spi较好。好好啃你的datasheet吧,多啃下,英文理解能力就慢慢上来了。做电子的,不啃这个不行的。  详情 回复 发表于 2017-3-23 23:14
 
 
 

回复

259

帖子

5

TA的资源

一粒金砂(高级)

12
 
问题已解决,,板子都快被示波器探针搓烂了,还好重新补焊后没什么影响怎么测都测不出SPI传输问题出在哪~~最后结果还是挺让人郁闷的:SPI1是ADS1220和字库芯片共用的、、由于字库芯片连接的CS初始化时被拉低了,导致ADS1220这边接收到的数据总是0xFF,测试时未接收到正确数据,便自认为是SPI时序出问题了,用GPIO模拟也无解,完全没考虑到外围芯片这个问题
不过这次倒是get到了新的调试技巧,折腾过程中下了两个驱动程序,其中一个是ti官网提供的ADS1220驱动程序,都传ee下载中心了,有需要的直接下载吧,不想花费积分的可以在下面链接中下载:
https://e2e.ti.com/support/data_ ... ds1220-example-code
这个板块不能编辑帖子,版主辛苦下给添个已解决之类的结贴吧,
此帖出自stm32/stm8论坛

点评

你解决了问题,下次能不你点下那个回复。让我也看到下呢,要不要我今天翻开看帖子,我都不知道你解决了呢。。。。。 说实话,你这个网站我第一看到,不过代码不用用户登录就能下载。 我大概看了下,这个ADS1120它  详情 回复 发表于 2017-3-29 23:07
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

13
 
Tobey 发表于 2017-3-26 21:55
问题已解决,,板子都快被示波器探针搓烂了,还好重新补焊后没什么影响怎么测都测不出SPI传输问题 ...

你解决了问题,下次能不你点下那个回复。让我也看到下呢,要不要我今天翻开看帖子,我都不知道你解决了呢。。。。。
说实话,你这个网站我第一看到,不过代码不用用户登录就能下载。
我大概看了下,这个ADS1120它封装的函数还不是太厉害,因为还是与ti的MCU相关。应该是ti的总部的工程师写的额。这个网站看来要经常上去看看了。

“SPI1是ADS1220和字库芯片共用的、、由于字库芯片连接的CS初始化时被拉低了”我觉得你的意思是三个芯片的CS你共用了一个引脚,所以spi和ADS1120的CS使能的时候,一并把你说的字库芯片也拉低了。而字库芯片的CS的可能不是这样的。

这个问题,你在一开始硬件设计的时候如果不好确认其时序的话,因为stm32和ADS1120是spi这个没得说。如果你不确定字库芯片的时序是否对SPI通讯影响的话,建议以后设计的时候,两个CS分开。

我为什么让你在如下的代码框架中这么写,也是为了防止CS出现误操作的情况(也就是防止CS出现错误的读写操作)
  1. SPI1_WriteBytes(xx,xx)
  2. {
  3.    NSS =1;//打开nss
  4.    //SPI1_WriteBytes的语句体

  5.    NSS = 0;//写完,关闭nss
  6. }
复制代码

此帖出自stm32/stm8论坛

点评

下回一定记得! 我原本是想编辑帖子,在标题上添上【已解决】的,,,不过这个版块我没找到编辑功能~~ 嗯,这是个参考驱动,实际使用还得根据实际需求修改才行,, ADS1120和字库芯片,这两个芯片  详情 回复 发表于 2017-3-30 22:19
 
 
 

回复

259

帖子

5

TA的资源

一粒金砂(高级)

14
 
huaiqiao 发表于 2017-3-29 23:07
你解决了问题,下次能不你点下那个回复。让我也看到下呢,要不要我今天翻开看帖子,我都不知道你解决了呢 ...

下回一定记得!
我原本是想编辑帖子,在标题上添上【已解决】的,,,不过这个版块我没找到编辑功能~~

嗯,这是个参考驱动,实际使用还得根据实际需求修改才行,,

ADS1120和字库芯片,这两个芯片有它们各自的CS片选引脚,不过它俩共用同一个SPI总线,其实这里是因为我偷懒造成的问题,,,由于是要实现一个测试用例,因此我把所有GPIO都放在一个文件下初始化了,结果在初始化结束后设置引脚电平时没注意,把字库芯片的CS引脚也给初始话为低电平了,,,因此造成了这一系列的问题,准确来说,读出的数据是持续波动的,用示波器测量会发现MISO引脚的波形既有高电平、低电平,还有一种介于二者之间的波形,,,后来把字库芯片的CS引脚初始化为高电平后,MISO的波形显示就正常了--》打印AD值发现数据接收正常了~~

此帖出自stm32/stm8论坛

点评

下次注意就好了,有了这次的经验下次想必同样的错误不会再犯了。加油  详情 回复 发表于 2017-3-30 23:31
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

15
 
Tobey 发表于 2017-3-30 22:19
下回一定记得!
我原本是想编辑帖子,在标题上添上【已解决】的,,,不过这个版块我没找到编 ...

下次注意就好了,有了这次的经验下次想必同样的错误不会再犯了。加油
此帖出自stm32/stm8论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(中级)

16
 
楼主你好,我也遇到这个问题了,写入寄存器后读到的都是FF,也就是MISO一直是高电平。但是我的CS、SLK、MOSI信号应该都是对的。现在不知道该去哪找问题了。楼主能否把你详细的代码、原理图分享一下,感激不尽!!!(如果在这里贴出来太繁琐,楼主可以直接发到我邮箱,学习一下 921159367@qq.com)再次感谢!!!
此帖出自stm32/stm8论坛

点评

这是我的测试用例,基于stm32f051的,你可以把底层SPI读写函数以及ADS1120的寄存器配置函数部分修改下试试,,  详情 回复 发表于 2017-4-6 15:03
 
 
 

回复

259

帖子

5

TA的资源

一粒金砂(高级)

17
 
zmh0 发表于 2017-4-5 22:59
楼主你好,我也遇到这个问题了,写入寄存器后读到的都是FF,也就是MISO一直是高电平。但是我的CS、SLK、MOS ...

这是我的测试用例,基于stm32f051的,你可以把底层SPI读写函数以及ADS1120的寄存器配置函数部分修改下试试,,

push_air20170322.rar

2.21 MB, 下载次数: 204

售价: 1 分芯积分  [记录]

此帖出自stm32/stm8论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(中级)

18
 
谢谢楼主,我今天终于找到问题了:被硬件给坑了,ADS1120接+5V的引脚中间加了一个0欧姆的电阻,然后这个电阻没给焊上去,所以导致ADS1120芯片根本没工作。。。(虽然没有用上,还是谢谢楼主的好意,祝楼主一切顺利~)
此帖出自stm32/stm8论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(中级)

19
 
Tobey 发表于 2017-4-6 15:03
这是我的测试用例,基于stm32f051的,你可以把底层SPI读写函数以及ADS1120的寄存器配置函数部分修改下试 ...


谢谢楼主,我今天终于找到问题了:被硬件给坑了,ADS1120接+5V的引脚中间加了一个0欧姆的电阻,然后这个电阻没给焊上去,所以导致ADS1120芯片根本没工作。。。(虽然没有用上,还是谢谢楼主的好意,祝楼主一切顺利~)
此帖出自stm32/stm8论坛

点评

问题解决了就好  详情 回复 发表于 2017-4-7 17:12
 
 
 

回复

259

帖子

5

TA的资源

一粒金砂(高级)

20
 
zmh0 发表于 2017-4-6 21:39
谢谢楼主,我今天终于找到问题了:被硬件给坑了,ADS1120接+5V的引脚中间加了一个0欧姆的电阻,然后这 ...

问题解决了就好
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表