static void mx_i2c1_init(void)
{
hi2c1.instance = i2c1; \\ 设置i2c实体
hi2c1.init.clockspeed = 100000; \\ 设置clk速率,从而设置trise,ccr,duty等寄存器
hi2c1.init.dutycycle = i2c_dutycycle_2; \\ 设置占空比t low /t high = 2 (ccr寄存器14位)
hi2c1.init.ownaddress1 = 100; \\ 设置地址a0,8位地址
hi2c1.init.addressingmode = i2c_addressingmode_7bit; \\ 设置为7位地址模式
hi2c1.init.dualaddressmode = i2c_dualaddress_disable; \\ 禁止双地址
hi2c1.init.ownaddress2 = 0; \\ 第2地址
hi2c1.init.generalcallmode = i2c_generalcall_disable; \\禁止广播
hi2c1.init.nostretchmode = i2c_nostretch_disable; \\禁止时钟拉伸
if (hal_i2c_init(&hi2c1) != hal_ok)
{
error_handler();
}
}
mx_i2c1_init调用库函数hal_i2c_init()(在stm32f1xx_hal_i2c.c中定义)来初始化i2c接口,需要初始化的数据已经在mx_i2c1_init中定义了
hal_statustypedef hal_i2c_init(i2c_handletypedef *hi2c)
{
uint32_t freqrange = 0;
uint32_t pclk1 = 0;
/* check the i2c handle allocation */
if(hi2c == null)
{
return hal_error;
}
/* check the parameters */
assert_param(is_i2c_all_instance(hi2c->instance));
assert_param(is_i2c_clock_speed(hi2c->init.clockspeed));
assert_param(is_i2c_duty_cycle(hi2c->init.dutycycle));
assert_param(is_i2c_own_address1(hi2c->init.ownaddress1));
assert_param(is_i2c_addressing_mode(hi2c->init.addressingmode));
assert_param(is_i2c_dual_address(hi2c->init.dualaddressmode));
assert_param(is_i2c_own_address2(hi2c->init.ownaddress2));
assert_param(is_i2c_general_call(hi2c->init.generalcallmode));
assert_param(is_i2c_no_stretch(hi2c->init.nostretchmode));
if(hi2c->state == hal_i2c_state_reset)
{
/* allocate lock resource and initialize it */
hi2c->lock = hal_unlocked;
/*配置相关硬件: gpio, clock, nvic */
hal_i2c_mspinit(hi2c);
}
hi2c->state = hal_i2c_state_busy;
/* disable the selected i2c peripheral */
__hal_i2c_disable(hi2c);
/* get pclk1 frequency */
pclk1 = hal_rcc_getpclk1freq();
/* calculate frequency range */
freqrange = i2c_freq_range(pclk1);
/*---------------------------- i2cx cr2 configuration i2c模块时钟频率 ----------------------*/
/* configure i2cx: frequency range */
hi2c->instance->cr2 = freqrange;
/*---------------------------- i2cx trise configuration --------------------*/
/* configure i2cx: rise time */
hi2c->instance->trise = i2c_rise_time(freqrange, hi2c->init.clockspeed);
/*---------------------------- i2cx ccr configuration ----------------------*/
/* configure i2cx: speed */
hi2c->instance->ccr = i2c_configure_speed(hi2c, pclk1);
/*---------------------------- i2cx cr1 configuration ----------------------*/
/* configure i2cx: generalcall and nostretch mode */
hi2c->instance->cr1 = (hi2c->init.generalcallmode | hi2c->init.nostretchmode);
/*---------------------------- i2cx oar1 configuration ---------------------*/
/* configure i2cx: own address1 and addressing mode */
hi2c->instance->oar1 = (hi2c->init.addressingmode | hi2c->init.ownaddress1);
/*---------------------------- i2cx oar2 configuration ---------------------*/
/* configure i2cx: dual mode and own address2 */
hi2c->instance->oar2 = (hi2c->init.dualaddressmode | hi2c->init.ownaddress2);
/* enable the selected i2c peripheral */
__hal_i2c_enable(hi2c);
/* 设置句柄相关状态位*/
hi2c->errorcode = hal_i2c_error_none;
hi2c->state = hal_i2c_state_ready;
hi2c->mode = hal_i2c_mode_none;
return hal_ok;
}
库函数hal_i2c_init()检查句柄的参数是否有效,然后再调用hal_i2c_mspinit()(在stm32f1xx_hal_msp.c中定义)进行相关gpio,时钟,中断方面的设置,然后才根据句柄所带的参数对i2c模块的寄存器进行配置。
void hal_i2c_mspinit(i2c_handletypedef* hi2c)
{
gpio_inittypedef gpio_initstruct;
if(hi2c->instance==i2c1)
{
/**i2c1 gpio configuration
pb6 ------> i2c1_scl
pb7 ------> i2c1_sda
*/
gpio_initstruct.pin = gpio_pin_6|gpio_pin_7;
gpio_initstruct.mode = gpio_mode_af_od;
gpio_initstruct.pull = gpio_pullup;
gpio_initstruct.speed = gpio_speed_freq_high;
hal_gpio_init(gpiob, &gpio_initstruct);
/* peripheral clock enable */
__hal_rcc_i2c1_clk_enable();
/* peripheral interrupt init 此处设置了开启i2c事件中断*/
hal_nvic_setpriority(i2c1_ev_irqn, 0, 0);
hal_nvic_enableirq(i2c1_ev_irqn);
/* user code begin i2c1_mspinit 1 */
/* user code end i2c1_mspinit 1 */
}
}
到此i2c的模块已经初始化已经完成,如果有中断发生就会调用中断处理函数i2c1_ev_irqhandler(void) (在stm32f1xx_it.c中定义),然而调用真正的中断服务函数hal_i2c_ev_irqhandler(&hi2c1)(stm32f1xx_hal_i2c.c中定义)
void i2c1_ev_irqhandler(void)
{
/* user code begin i2c1_ev_irqn 0 */
/* user code end i2c1_ev_irqn 0 */
hal_i2c_ev_irqhandler(&hi2c1);
/* user code begin i2c1_ev_irqn 1 */
/* user code end i2c1_ev_irqn 1 */
}
void hal_i2c_ev_irqhandler(i2c_handletypedef *hi2c)
{
uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
/* master or memory mode selected */
if((hi2c->mode == hal_i2c_mode_master) || \
(hi2c->mode == hal_i2c_mode_mem))
{
/* i2c in mode transmitter -----------------------------------------------*/
if(__hal_i2c_get_flag(hi2c, i2c_flag_tra) == set)
{
tmp1 = __hal_i2c_get_flag(hi2c, i2c_flag_txe);
tmp2 = __hal_i2c_get_it_source(hi2c, i2c_it_buf);
tmp3 = __hal_i2c_get_flag(hi2c, i2c_flag_btf);
tmp4 = __hal_i2c_get_it_source(hi2c, i2c_it_evt);
/* txe set and btf reset -----------------------------------------------*/
if((tmp1 == set) && (tmp2 == set) && (tmp3 == reset))
{
i2c_mastertransmit_txe(hi2c);
}
/* btf set -------------------------------------------------------------*/
else if((tmp3 == set) && (tmp4 == set))
{
i2c_mastertransmit_btf(hi2c);
}
}
/* i2c in mode receiver --------------------------------------------------*/
else
{
tmp1 = __hal_i2c_get_flag(hi2c, i2c_flag_rxne);
tmp2 = __hal_i2c_get_it_source(hi2c, i2c_it_buf);
tmp3 = __hal_i2c_get_flag(hi2c, i2c_flag_btf);
tmp4 = __hal_i2c_get_it_source(hi2c, i2c_it_evt);
/* rxne set and btf reset -----------------------------------------------*/
if((tmp1 == set) && (tmp2 == set) && (tmp3 == reset))
{
i2c_masterreceive_rxne(hi2c);
}
/* btf set -------------------------------------------------------------*/
else if((tmp3 == set) && (tmp4 == set))
{
i2c_masterreceive_btf(hi2c);
}
}
}
/* slave mode selected */
else
{
tmp1 = __hal_i2c_get_flag(hi2c, i2c_flag_addr);
tmp2 = __hal_i2c_get_it_source(hi2c, (i2c_it_evt));
tmp3 = __hal_i2c_get_flag(hi2c, i2c_flag_stopf);
tmp4 = __hal_i2c_get_flag(hi2c, i2c_flag_tra);
/* addr set --------------------------------------------------------------*/
if((tmp1 == set) && (tmp2 == set))
{
i2c_slave_addr(hi2c);
}
/* stopf set --------------------------------------------------------------*/
else if((tmp3 == set) && (tmp2 == set))
{
i2c_slave_stopf(hi2c);
}
/* i2c in mode transmitter -----------------------------------------------*/
else if(tmp4 == set)
{
tmp1 = __hal_i2c_get_flag(hi2c, i2c_flag_txe);
tmp2 = __hal_i2c_get_it_source(hi2c, i2c_it_buf);
tmp3 = __hal_i2c_get_flag(hi2c, i2c_flag_btf);
tmp4 = __hal_i2c_get_it_source(hi2c, i2c_it_evt);
/* txe set and btf reset -----------------------------------------------*/
if((tmp1 == set) && (tmp2 == set) && (tmp3 == reset))
{
i2c_slavetransmit_txe(hi2c);
}
/* btf set -------------------------------------------------------------*/
else if((tmp3 == set) && (tmp4 == set))
{
i2c_slavetransmit_btf(hi2c);
}
}
/* i2c in mode receiver --------------------------------------------------*/
else
{
tmp1 = __hal_i2c_get_flag(hi2c, i2c_flag_rxne);
tmp2 = __hal_i2c_get_it_source(hi2c, i2c_it_buf);
tmp3 = __hal_i2c_get_flag(hi2c, i2c_flag_btf);
tmp4 = __hal_i2c_get_it_source(hi2c, i2c_it_evt);
/* rxne set and btf reset ----------------------------------------------*/
if((tmp1 == set) && (tmp2 == set) && (tmp3 == reset))
{
i2c_slavereceive_rxne(hi2c);
}
/* btf set -------------------------------------------------------------*/
else if((tmp3 == set) && (tmp4 == set))
{
i2c_slavereceive_btf(hi2c);
}
}
}
}
lw
变频器应该如何配备制动电阻呢?
苹果都得看他脸色 OLED被一家日本小企业扼住咽喉
陶瓷扬声器系统的放大器设计的解决方案
安兔兔公布2019年10月份Android手机性能榜单 前10名清一色为骁龙855Plus
高通骁龙730处理器性能曝光 实现强大性能和持久续航的完美平衡
STM32 HAL库 I2C 学习
三大运营商2017年底或彻底取消长途漫游费
当销量爆棚的小米Note2撞上坑爹队友,结果就是停产
动态平板DRF在精神病专科医院的应用
2023年60%的私有小型基站RFFE仍依赖GAAS平台
华为荣耀v9和华为荣耀9相差近千元,详细对比看看具体相差在哪里?
夏普新上市LED阵列具有色温可调功能
Vivado工程模式和非工程模式的比较
未来式的存储器会是怎样的
arm处理器异常模式有哪些
PL2586 USB2.0高速4端口集线器控制器概述及特点
距领奖台仅一步之遥,远景电动方程式车队摩纳哥站斩获双积分
下一代通用内存会是ULTRARAM吗?
如何使用近场探头?
力科44Xi示波器可以开机,但进不了系统-安泰维修