请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

最近用STM32来控制可编程电位器IIC模式,不成功,求帮助!

[复制链接]
胤幻1988 提问时间:2018-6-4 15:14 /
最近用STM32F103RET6控制MAX公司的可编程电位器DS3502不成功。不知道为何。模拟IIC代码,参考的原子的代码。
下面是IIC的具体代码,用的IIC2.
IIC2的C文件
  1. #include "myiic2.h"
  2. #include "delay.h"
  3.                                                                   
  4. //////////////////////////////////////////////////////////////////////////////////

  5. //初始化IIC2
  6. void IIC2_Init(void)
  7. {                                             
  8.         GPIO_InitTypeDef GPIO_InitStructure;
  9.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );        //使能GPIOB时钟
  10.           
  11.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
  12.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
  13.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  14.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  15.         GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);         //PB6,PB7 输出高
  16. }
  17. //产生IIC起始信号
  18. void IIC2_Start(void)
  19. {
  20.         SDA2_OUT();     //sda线输出
  21.         IIC2_SDA=1;                    
  22.         IIC2_SCL=1;
  23.         delay_us(4);
  24.         IIC2_SDA=0;//START:when CLK is high,DATA change form high to low
  25.         delay_us(4);
  26.         IIC2_SCL=0;//钳住I2C总线,准备发送或接收数据
  27. }          
  28. //产生IIC停止信号
  29. void IIC2_Stop(void)
  30. {
  31. //        SDA_OUT();//sda线输出
  32. //        IIC_SCL=0;
  33. //        IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  34. //         delay_us(4);
  35. //        IIC_SCL=1;
  36. //        IIC_SDA=1;//发送I2C总线结束信号
  37. //        delay_us(4);

  38.         SDA2_OUT();   //sda线输出
  39.         IIC2_SCL=0;
  40.         IIC2_SDA=0;   //STOP:when CLK is high DATA change form low to high
  41.                 delay_us(4);
  42.         IIC2_SCL=1;
  43.         delay_us(2);     //加入延时
  44.         IIC2_SDA=1;     //发送I2C总线结束信号
  45.         delay_us(4);        
  46. }
  47. //等待应答信号到来
  48. //返回值:1,接收应答失败
  49. //        0,接收应答成功
  50. u8 IIC2_Wait_Ack(void)
  51. {
  52.         u8 ucErrTime=0;
  53.         SDA2_IN();      //SDA设置为输入  
  54.         IIC2_SDA=1;delay_us(1);          
  55.         IIC2_SCL=1;delay_us(1);         
  56.         while(READ2_SDA)
  57.         {
  58.                 ucErrTime++;
  59.                 if(ucErrTime>250)
  60.                 {
  61.                         IIC2_Stop();
  62.                         return 1;
  63.                 }
  64.         }
  65.         IIC2_SCL=0;//时钟输出0           
  66.         return 0;  
  67. }
  68. //产生ACK应答
  69. void IIC2_Ack(void)
  70. {
  71.         IIC2_SCL=0;
  72.         SDA2_OUT();
  73.         IIC2_SDA=0;
  74.         delay_us(2);
  75.         IIC2_SCL=1;
  76.         delay_us(2);
  77.         IIC2_SCL=0;
  78. }
  79. //不产生ACK应答                    
  80. void IIC2_NAck(void)
  81. {
  82.         IIC2_SCL=0;
  83.         SDA2_OUT();
  84.         IIC2_SDA=1;
  85.         delay_us(2);
  86.         IIC2_SCL=1;
  87.         delay_us(2);
  88.         IIC2_SCL=0;
  89. }                                                                              
  90. //IIC发送一个字节
  91. //返回从机有无应答
  92. //1,有应答
  93. //0,无应答                          
  94. void IIC2_Send_Byte(u8 txd)
  95. {                        
  96.     u8 t;   
  97.         SDA2_OUT();             
  98.     IIC2_SCL=0;//拉低时钟开始数据传输
  99.     for(t=0;t<8;t++)
  100.     {              
  101.         //IIC_SDA=(txd&0x80)>>7;
  102.                 if((txd&0x80)>>7)
  103.                         IIC2_SDA=1;
  104.                 else
  105.                         IIC2_SDA=0;
  106.                 txd<<=1;           
  107.                 delay_us(2);   //对TEA5767这三个延时都是必须的
  108.                 IIC2_SCL=1;
  109.                 delay_us(2);
  110.                 IIC2_SCL=0;       
  111.                 delay_us(2);
  112.     }         
  113. }             
  114. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
  115. u8 IIC2_Read_Byte(unsigned char ack)
  116. {
  117.         unsigned char i,receive=0;
  118.         SDA2_IN();//SDA设置为输入
  119.     for(i=0;i<8;i++ )
  120.         {
  121.         IIC2_SCL=0;
  122.         delay_us(2);
  123.                 IIC2_SCL=1;
  124.         receive<<=1;
  125.         if(READ2_SDA)receive++;   
  126.                 delay_us(1);
  127.     }                                         
  128.     if (!ack)
  129.         IIC2_NAck();//发送nACK
  130.     else
  131.         IIC2_Ack(); //发送ACK   
  132.     return receive;
  133. }

复制代码
IIC的h文件:
  1. #ifndef __MYIIC2_H
  2. #define __MYIIC2_H
  3. #include "sys.h"


  4. //IO方向设置  PB11

  5. #define SDA2_IN()  {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=(u32)8<<12;}
  6. #define SDA2_OUT() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=(u32)3<<12;}

  7. //IO操作函数         
  8. #define IIC2_SCL    PBout(10) //SCL
  9. #define IIC2_SDA    PBout(11) //SDA         
  10. #define READ2_SDA   PBin(11)  //输入SDA

  11. //IIC所有操作函数
  12. void IIC2_Init(void);                //初始化IIC的IO口                                 
  13. void IIC2_Start(void);                                //发送IIC开始信号
  14. void IIC2_Stop(void);                                  //发送IIC停止信号
  15. void IIC2_Send_Byte(u8 txd);                        //IIC发送一个字节
  16. u8 IIC2_Read_Byte(unsigned char ack);//IIC读取一个字节
  17. u8 IIC2_Wait_Ack(void);                                 //IIC等待ACK信号
  18. void IIC2_Ack(void);                                        //IIC发送ACK信号
  19. void IIC2_NAck(void);                                //IIC不发送ACK信号

  20. void IIC2_Write_One_Byte(u8 daddr,u8 addr,u8 data);
  21. u8 IIC2_Read_One_Byte(u8 daddr,u8 addr);          
  22. #endif
复制代码
DS3502的c
  1. #include "DS3502.h"
  2. #include "delay.h"


  3. //硬件上A1,A0都是高电平
  4. //初始化IIC接口
  5. void DS3502_Init(void)
  6. {
  7.         IIC2_Init();
  8. }
  9. //DS3502定地址读出一个数据
  10. //ReadAddr:开始读数的地址  
  11. //返回值  :读到的数据
  12. u8 DS3502_ReadOneByte(u16 ReadAddr)
  13. {                                  
  14.         u8 temp=0;
  15.         //开始信号       
  16.   IIC2_Start();
  17.   //发送从机地址       
  18.         IIC2_Send_Byte(0X50+6);   //发送器件地址(不计算读写字BIT)A1,A0均为1,(110B)写数据          
  19.         IIC2_Wait_Ack();
  20.         //发送要读的寄存器地址
  21.   IIC2_Send_Byte(ReadAddr%256);   //发送低地址
  22.         IIC2_Wait_Ack();       
  23.   //重新开始信号       
  24.         IIC2_Start();
  25.   //发送计算写字的       
  26.         IIC2_Send_Byte(0X50+6+1);           //进入接收模式                          
  27.         IIC2_Wait_Ack();
  28.   //读取数据       
  29.   temp=IIC2_Read_Byte(0);                  
  30.   IIC2_Stop();//产生一个停止条件            
  31.         return temp;
  32. }
  33. //在DS3502指定地址写入一个数据
  34. //WriteAddr  :写入数据的目的地址   
  35. //DataToWrite:要写入的数据
  36. void DS3502_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
  37. {               
  38.         //开始信号       
  39.   IIC2_Start();
  40.   //发送从机地址  
  41.         IIC2_Send_Byte(0X50+6);   //发送器件地址(不计算读写字BIT)A1,A0均为1,(110B)写数据
  42.                  
  43.         IIC2_Wait_Ack();
  44.   //发送写入的寄存器地址       
  45.   IIC2_Send_Byte(WriteAddr%256);   //发送低地址
  46.         IIC2_Wait_Ack();
  47.   //发送要写入的数据       
  48.         IIC2_Send_Byte(DataToWrite);     //发送字节                                                          
  49.         IIC2_Wait_Ack();                                
  50.   IIC2_Stop();//产生一个停止条件
  51.         delay_ms(10);         
  52. }
复制代码
DS3502的h文件:
  1. #ifndef __DS3502_H
  2. #define __DS3502_H
  3. #include "myiic2.h"   

  4. u8 DS3502_ReadOneByte(u16 ReadAddr);                                                        //指定地址读取一个字节
  5. void DS3502_WriteOneByte(u16 WriteAddr,u8 DataToWrite);                //指定地址写入一个字节
  6. void DS3502_Init(void); //初始化IIC
复制代码
main 函数
  1. DS3502_WriteOneByte(0X00,43);//0~127
  2.         delay_ms(200);
  3.         CR_Value=DS3502_ReadOneByte(0X00);
  4.         delay_ms(200);
复制代码
反馈的数值一直为256。

硬件上连接



求大神帮忙看下!

QQ截图20180604151138.png

DS3502.pdf

下载

155.44 KB, 下载次数: 8, 下载积分: ST金币 -1

可编程电位器

收藏 评论3 发布时间:2018-6-4 15:14

举报

3个回答
废鱼 回答时间:2018-6-4 15:33:45
楼主,光从代码上分析不出什么太大问题,建议通过I2C总线波形进行一下判断。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

胤幻1988 回答时间:2018-6-4 15:49:43
安 发表于 2018-6-4 15:33
楼主,光从代码上分析不出什么太大问题,建议通过I2C总线波形进行一下判断。 ...

谢谢,已解决。代码没问题。硬件上,当时想着一个IO能否驱动8路,就加了个电流驱动增强的芯片。问题就出在它身上。拿掉,就好了。而且8路也能驱动成功!

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2 结帖奖励

查看全部评分

胤幻1988 回答时间:2018-6-4 15:50:47
已解决,结贴!

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版