OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5908|回复: 22

主时钟频率改变后,iic不能用了,

[复制链接]

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
发表于 2018-3-8 11:18:55 | 显示全部楼层 |阅读模式
5金钱
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
// #define SYSCLK_FREQ_24MHz  24000000
// #define SYSCLK_FREQ_36MHz  36000000
// #define SYSCLK_FREQ_48MHz  48000000
//#define SYSCLK_FREQ_56MHz  56000000
#define SYSCLK_FREQ_72MHz  72000000

在主程序中,这样设置72M的话,iic就能正常使用,应答信号等都正常,只要改成36M
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
// #define SYSCLK_FREQ_24MHz  24000000
#define SYSCLK_FREQ_36MHz  36000000
// #define SYSCLK_FREQ_48MHz  48000000
//#define SYSCLK_FREQ_56MHz  56000000
//#define SYSCLK_FREQ_72MHz  72000000

IIC就不能正常运行了,应答信号都不对,请问是什么原因,

最佳答案

查看完整内容[请看2#楼]

已经解决了,不是程序的问题,是iic上接的电阻问题,之前用的是10K,只能用72m,后来改成33K了,就能用24M了,不知道为什么会这样
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
 楼主| 发表于 2018-3-8 11:18:56 | 显示全部楼层
已经解决了,不是程序的问题,是iic上接的电阻问题,之前用的是10K,只能用72m,后来改成33K了,就能用24M了,不知道为什么会这样
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
 楼主| 发表于 2018-3-8 11:28:09 | 显示全部楼层
//初始化IIC
void IIC_Init(void)
{                                             
        GPIO_InitTypeDef GPIO_InitStructure;
        //RCC->APB2ENR|=1<<4;//先使能外设IO PORTB时钟
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );       
          
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);                                                  //PE.5 输出高

        IIC_SCL=1;
        IIC_SDA=1;

}
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
 楼主| 发表于 2018-3-8 11:29:29 | 显示全部楼层
//产生IIC起始信号
void IIC_Start(void)
{
        SDA_OUT();     //sda线输出
        IIC_SDA=1;                    
        IIC_SCL=1;
        delay_us(4);
        IIC_SDA=0;//START:when CLK is high,DATA change form high to low
        delay_us(4);
        IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}          
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答                          
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
        SDA_OUT();             
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1;           
                delay_us(2);   //对TEA5767这三个延时都是必须的
                IIC_SCL=1;
                delay_us(2);
                IIC_SCL=0;       
                delay_us(2);
    }         
}        
//读ADXL345寄存器
//addr:寄存器地址
//返回值:读到的值
u16 ADXL345_RD_Reg(u8 addr)                
{
        u16 temp=0;                 
        IIC_Start();                                   
        IIC_Send_Byte(ADXL_WRITE);        //发送写器件指令         
                        temp=IIC_Wait_Ack();       
                        printf("%d  ",temp);
  IIC_Send_Byte(addr);                   //发送寄存器地址
        temp=IIC_Wait_Ack();
        printf("%d  ",temp);
        IIC_Start();                                      //重新启动
        IIC_Send_Byte(ADXL_READ);        //发送读器件指令         
        temp=IIC_Wait_Ack();       
        printf("%d  ",temp);
    num1=IIC_Read_Byte(1);                //  读取两个字节。num1和unm2为FDC2214的地址。48*256+85=12373,即是:0X3055
                num2=IIC_Read_Byte(0);                //读取一个字节,不继续再读,发送NAK
       
    IIC_Stop();                                        //产生一个停止条件             
        return temp;                                //返回读到的值
}  
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2018-3-8 11:37:45 | 显示全部楼层
修改一下I2C里面调用的延时函数.
最好使用逻辑分析仪看一下时序图.比较保险.
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
 楼主| 发表于 2018-3-8 11:47:45 | 显示全部楼层
操作系统 发表于 2018-3-8 11:37
修改一下I2C里面调用的延时函数.
最好使用逻辑分析仪看一下时序图.比较保险.

原来是这样的:
void delay_init()         
{
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //选择外部时钟  HCLK/8
        fac_us=SystemCoreClock/8000000;        //为系统时钟的1/8  
        fac_ms=(u16)fac_us*1000;//非ucos下,代表每个ms需要的systick时钟数   
}                                                                    

我改成了
void delay_init()         
{
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //选择外部时钟  HCLK/8
        fac_us=SystemCoreClock/4000000;        //为系统时钟的1/8  
        fac_ms=(u16)fac_us*500;//非ucos下,代表每个ms需要的systick时钟数   
}                                                                    
但是还是不行
回复

使用道具 举报

1

主题

882

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3071
金钱
3071
注册时间
2018-2-7
在线时间
285 小时
发表于 2018-3-8 11:49:15 | 显示全部楼层
很可能是延时函数的延时时长变了,IIC总线的时序就乱了。
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
 楼主| 发表于 2018-3-8 11:54:04 | 显示全部楼层
HXYDJ 发表于 2018-3-8 11:49
很可能是延时函数的延时时长变了,IIC总线的时序就乱了。

中间的时序改成一样了,还是不行,
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2018-3-8 11:57:23 | 显示全部楼层
shmilyzgc 发表于 2018-3-8 11:47
原来是这样的:
void delay_init()         
{

最好看一下时序,是哪里不对了.这是解决问题的最好方法.
没有逻辑分析仪,去买一个.解决问题事半功倍.工欲善其事,必先利其器.
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2018-3-8 14:58:16 | 显示全部楼层
上拉电阻  默认是 4.7K的.太大了不太好吧.
回复

使用道具 举报

8

主题

569

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2363
金钱
2363
注册时间
2015-5-8
在线时间
320 小时
发表于 2018-3-8 14:59:14 | 显示全部楼层
之前是因为延时函数问题
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
 楼主| 发表于 2018-3-8 15:02:16 | 显示全部楼层
操作系统 发表于 2018-3-8 14:58
上拉电阻  默认是 4.7K的.太大了不太好吧.

4.7k不行啊关键是,也不知道为什么会这样。。。改成了30k之后才能用24m,也用不了8M。8m的话接收就不行了
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2018-3-8 15:05:04 | 显示全部楼层
应该是程序上的原因吧.
与电阻关系不会很大.
IO设置为开漏了没有呀.这是基本要求.
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
 楼主| 发表于 2018-3-8 15:09:06 | 显示全部楼层
操作系统 发表于 2018-3-8 15:05
应该是程序上的原因吧.
与电阻关系不会很大.
IO设置为开漏了没有呀.这是基本要求.

//初始化IIC
void IIC_Init(void)
{                                             
        GPIO_InitTypeDef GPIO_InitStructure;
        //RCC->APB2ENR|=1<<4;//先使能外设IO PORTB时钟
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );       
          
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);                                                  //PE.5 输出高

        IIC_SCL=1;
        IIC_SDA=1;

}
这个是跟原子的例程上一样的
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2018-3-8 15:13:28 | 显示全部楼层
本帖最后由 操作系统 于 2018-3-8 15:18 编辑
shmilyzgc 发表于 2018-3-8 15:09
//初始化IIC
void IIC_Init(void)
{                                             

原子哥的程序,不一定是对的呀.不是开漏的 I2C 通用性不强..易出怪问题.
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
 楼主| 发表于 2018-3-8 15:18:59 | 显示全部楼层
操作系统 发表于 2018-3-8 15:13
原子哥的程序,不一定是对的呀.

这个配置应该没问题吧?哪个引脚要开漏?我看到的都是推挽输出
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2018-3-8 15:22:34 | 显示全部楼层
shmilyzgc 发表于 2018-3-8 15:18
这个配置应该没问题吧?哪个引脚要开漏?我看到的都是推挽输出

你查一下STM8S的PDF.所有的型号I2C引脚内置默认开漏结构.
这也是为什么I2C总线的IO口.要求设置开漏的节凑.
你一定要设置 为推挽来操作..也是可以的.但是程序调试起来问题更多.注意的地方也多.
并且要经常修改IO的方向寄存器.开漏方式就没有这个缺点了.多上网查一查.
回复

使用道具 举报

头像被屏蔽

1

主题

65

帖子

0

精华

禁止访问

积分
1389
金钱
1389
注册时间
2018-3-8
在线时间
146 小时
发表于 2018-3-8 15:23:50 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
 楼主| 发表于 2018-3-8 15:28:03 | 显示全部楼层
操作系统 发表于 2018-3-8 15:22
你查一下STM8S的PDF.所有的型号I2C引脚内置默认开漏结构.
这也是为什么I2C总线的IO口.要求设置开漏的节 ...

也就是说我能直接更改为开漏吗?像这样改?
//初始化IIC
void IIC_Init(void)
{                                             
        GPIO_InitTypeDef GPIO_InitStructure;
        //RCC->APB2ENR|=1<<4;//先使能外设IO PORTB时钟
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );       
          
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
        //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_OD;//开漏输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);                                                  //PE.5 输出高

        IIC_SCL=1;
        IIC_SDA=1;

}
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-3-14
在线时间
12 小时
 楼主| 发表于 2018-3-8 15:29:57 | 显示全部楼层
操作系统 发表于 2018-3-8 15:22
你查一下STM8S的PDF.所有的型号I2C引脚内置默认开漏结构.
这也是为什么I2C总线的IO口.要求设置开漏的节 ...

改了,,测试还是一样,,24M的时候能工作,8M的时候就不行了。如果是10K的电阻的话就只能72M。。
回复

使用道具 举报

15

主题

50

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
322
金钱
322
注册时间
2014-10-29
在线时间
37 小时
发表于 2018-8-3 07:57:25 | 显示全部楼层
第一:电阻的数值,不是随便选的,由OD口的电流决定最小电阻值,最大值的确定比较复杂,受PCB布线、总线设备个数的影响,说到底是电阻、电容的关系会导致SCL时钟跳变的速度,我们有深究,有兴趣可以研究一下;可以研究一下IIC协议规范中“The&#8194;number&#8194;of&#8194;ICs&#8194;that&#8194;can&#8194;be&#8194;connected&#8194;to&#8194;the&#8194;same bus&#8194;is&#8194;limited&#8194;only&#8194;by&#8194;a&#8194;maximum&#8194;bus&#8194;capacitance&#8194;of&#8194;400&#8194;pF.&#8194;”
第二:IIC通信,就算它遇到再大的问题,只要你有一个差不多的示波器,或是逻辑分析仪,找到波形,对照协议的时序,药到病除;
第三:为什么你们都不用硬件IIC,尝试一下吧,不要被网上的说不好用,有bug而直接选择放弃,耳听为虚,手操为实;另外,在你理解STM32F系列的硬件IIC工作逻辑时,也是你深入理解IIC协议的良药;
回复

使用道具 举报

15

主题

50

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
322
金钱
322
注册时间
2014-10-29
在线时间
37 小时
发表于 2018-8-3 08:04:49 | 显示全部楼层
补充一下:看你的程序是操作adxl345芯片,那还要仔细分析该芯片的属性参数,来确定问题到底在哪里,不要想看从设备,因为主从要通信,必须合拍才可以!简单举例:常用的AT24CXX系列eeprom操作,如果你发送一帧数据后,stop;接着直接再去读,那是读不出来的,原因是eep内部有一个写存储阵列时间,详细自己研究datasheet;
回复

使用道具 举报

8

主题

34

帖子

0

精华

高级会员

Rank: 4

积分
834
金钱
834
注册时间
2014-4-9
在线时间
89 小时
发表于 2019-3-7 20:13:46 | 显示全部楼层
互利共赢 发表于 2018-8-3 07:57
第一:电阻的数值,不是随便选的,由OD口的电流决定最小电阻值,最大值的确定比较复杂,受PCB布线、总线设 ...

论“真学习”与“假学习”,您这是真的;
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-24 00:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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