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

2019-07-21 04:35发布

/* #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就不能正常运行了,应答信号都不对,请问是什么原因,

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
22条回答
shmilyzgc
1楼-- · 2019-07-21 09:40
 精彩回答 2  元偷偷看……
shmilyzgc
2楼-- · 2019-07-21 10:44
//初始化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;

}
shmilyzgc
3楼-- · 2019-07-21 11:02
//产生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;                                //返回读到的值
}  
操作系统
4楼-- · 2019-07-21 12:37
修改一下I2C里面调用的延时函数.
最好使用逻辑分析仪看一下时序图.比较保险.
shmilyzgc
5楼-- · 2019-07-21 18:21
操作系统 发表于 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时钟数   
}                                                                    
但是还是不行
HXYDJ
6楼-- · 2019-07-21 20:40
 精彩回答 2  元偷偷看……

一周热门 更多>