/* * LPLD_I2C_Init * I2C通用初始化函数 * * 参数: * i2cx--选择I2C模块号 * |__I2C0 --I2C0号模块 * |__I2C1 --I2C1号模块 * port--通道端口位选择 * |__0 --I2C0(PTB2-I2C0_SCL PTB3-I2C0_SDA) * | --I2C1(PTE0-I2C1_SDA PTE1-I2C1_SCL) * |__1 --I2C0(PTD8-I2C0_SCL PTD9-I2C0_SDA) * | --I2C1(PTC10-I2C1_SCL PTC11-I2C1_SDA) * scl_frq--选择IIC SCL频率 * |__I2C_SCL_50KHZ --50khz * |__I2C_SCL_100KHZ --100khz * |__I2C_SCL_150KHZ --150khz * |__I2C_SCL_200KHZ --200khz * |__I2C_SCL_250KHZ --250khz * |__I2C_SCL_300KHZ --300khz * 输出: * 0--配置错误 * 1--配置成功 */ uint8 LPLD_I2C_Init(I2Cx i2cx, uint8 port, uint8 scl_frq) { uint8 ps; //参数检查 ASSERT( i2cx <= I2C1); //判断I2Cx模块号 ASSERT( scl_frq <= I2C_SCL_300KHZ); //判断SCL频率 ASSERT( port <= 1); //判断端口选择 //总线频率50mhz //scl_frq=50mhz/(mul * scl div) if(scl_frq == I2C_SCL_50KHZ) { ps=0x33; } else if(scl_frq == I2C_SCL_100KHZ) { ps=0x2B; } else if(scl_frq == I2C_SCL_150KHZ) { ps=0x28; } else if(scl_frq == I2C_SCL_200KHZ) { ps=0x23; } else if(scl_frq == I2C_SCL_250KHZ) { ps=0x21; } else if(scl_frq == I2C_SCL_300KHZ) { ps=0x20; } else return 0; if(i2cx==I2C0) { if(!port) { /* configure GPIO for I2C0 function */ PORTB_PCR2 = PORT_PCR_MUX(2); PORTB_PCR3 = PORT_PCR_MUX(2); } else if(port==1) { /* configure GPIO for I2C0 function */ PORTD_PCR8 = PORT_PCR_MUX(2); PORTD_PCR9 = PORT_PCR_MUX(2); } else return 0; SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK; //开启I2C0时钟 } else if(i2cx==I2C1) { if(!port) { /* configure GPIO for I2C0 function */ PORTE_PCR0 = PORT_PCR_MUX(6); PORTE_PCR1 = PORT_PCR_MUX(6); } else if(port==1) { /* configure GPIO for I2C0 function */ PORTC_PCR10 = PORT_PCR_MUX(2); PORTC_PCR11 = PORT_PCR_MUX(2); } else return 0; SIM_SCGC4 |= SIM_SCGC4_I2C1_MASK; //开启IIC1时钟 } else return 0; I2C_F_REG(I2Cx_Ptr[i2cx]) = ps; I2C_C1_REG(I2Cx_Ptr[i2cx]) = I2C_C1_IICEN_MASK; //使能I2Cx return 1; }
/*! * @brief I2C初始化,设置波特率 * @param I2Cn_e I2C模块(I2C0、I2C1) * @param baud 期待的波特率 * @return 实际的波特率 * @since v5.0 * Sample usage: i2c_init(I2C0,400*1000); // 初始化I2C0,期待的波特率为400k */ uint32 i2c_init(I2Cn_e i2cn, uint32 baud) { if(i2cn == I2C0) { /* 开启时钟 */ #if defined(MK60DZ10) SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK; //开启 I2C0时钟 #elif defined( MK60F15) SIM_SCGC4 |= SIM_SCGC4_IIC0_MASK; //开启 I2C0时钟 #endif /* 配置 I2C0功能的 GPIO 接口 */ if(I2C0_SCL == PTB0) port_init (PTB0, ALT2 | ODO | PULLUP ); else if(I2C0_SCL == PTB2) port_init (PTB2, ALT2 | ODO | PULLUP ); else if(I2C0_SCL == PTD8) port_init (PTD8, ALT2 | ODO | PULLUP ); else ASSERT(0); //上诉条件都不满足,直接断言失败了,设置管脚有误? if(I2C0_SDA == PTB1) port_init (PTB1, ALT2 | ODO | PULLUP ); else if(I2C0_SDA == PTB3) port_init (PTB3, ALT2 | ODO | PULLUP ); else if(I2C0_SDA == PTD9) port_init (PTD9, ALT2 | ODO | PULLUP ); else ASSERT(0); //上诉条件都不满足,直接断言失败了,设置管脚有误? } else { /* 开启时钟 */ #if defined(MK60DZ10) SIM_SCGC4 |= SIM_SCGC4_I2C1_MASK; //开启 I2C1时钟 #elif defined(MK60F15) SIM_SCGC4 |= SIM_SCGC4_IIC1_MASK; //开启 I2C1时钟 #endif /* 配置 I2C1功能的 GPIO 接口 */ if(I2C1_SCL == PTE1) port_init (PTE1, ALT6 | ODO | PULLUP ); else if(I2C1_SCL == PTC10) port_init (PTC10, ALT2 | ODO | PULLUP ); else ASSERT(0); //上诉条件都不满足,直接断言失败了,设置管脚有误? if(I2C1_SDA == PTE0) port_init (PTE0, ALT6 | ODO | PULLUP ); else if (I2C1_SDA == PTC11) port_init (PTC11, ALT2 | ODO | PULLUP ); else ASSERT(0); //上诉条件都不满足,直接断言失败了,设置管脚有误? } /* 设置频率 */ // I2C baud rate = bus speed (Hz)/(mul × SCL divider) 即这里 50MHz/(1 ×128)=390.625kHz // SDA hold time = bus period (s) × mul × SDA hold value // SCL start hold time = bus period (s) × mul × SCL start hold value // SCL stop hold time = bus period (s) × mul × SCL stop hold value //查表 ICR 对应的 SCL_divider ,见 《K60P144M100SF2RM.pdf》第1468页的 I2C Divider and Hold Values uint16 ICR_2_SCL_divider[0x40] = { 20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 36, 40, 44, 48, 56, 68, 48, 56, 64, 72, 80, 88, 104, 128, 80, 96, 112, 128, 144, 160, 192, 240, 160, 192, 224, 256, 288, 320, 384, 480, 320, 384, 448, 512, 576, 640, 768, 960, 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840 }; uint8 mult; if(bus_clk_khz <= 50000)mult = 0; //bus 一分频 else if(bus_clk_khz <= 100000)mult = 1; //bus 二分频 else mult = 2; //bus 四分频 uint16 scldiv = bus_clk_khz * 1000 / ( (mult + 1) * baud ); //最佳的分频系数 //需要从 ICR_2_SCL_divider 里找到 与最佳分频系数scldiv最相近的 分频系数 uint8 icr, n = 0x40; uint16 min_Dvalue = ~0, Dvalue; while(n) //循环里逐个扫描,找出最接近的 分频系数 { n--; Dvalue = abs(scldiv - ICR_2_SCL_divider[n]); if(Dvalue == 0) { icr = n; break; //退出while循环 } if(Dvalue < min_Dvalue) { icr = n; min_Dvalue = Dvalue; } } I2C_F_REG(I2CN[i2cn]) = ( 0 // I2C Frequency Divider register (I2Cx_F) I2C分频寄存器 I2C最大波特率为 400k | I2C_F_MULT(mult) // 乘数因子 mul = MULT + 1 | I2C_F_ICR(icr) // 时钟速率 = ICR_2_SCL_divider[ICR] ,查表获得 ICR 与 SCL_divider 映射关系 ); /* 使能 IIC1 */ I2C_C1_REG(I2CN[i2cn]) = ( 0 | I2C_C1_IICEN_MASK //使能I2C //| I2C_C1_IICIE_MASK //使能中断 ); return ( bus_clk_khz * 1000 / ( (mult + 1) * ICR_2_SCL_divider[icr]) ); }