高级会员

- 积分
- 738
- 金钱
- 738
- 注册时间
- 2016-1-20
- 在线时间
- 188 小时
|
50金钱
本帖最后由 CCXX 于 2022-5-25 16:05 编辑
使用STM32F401的I2C3做smbus slave,I2C3不接host的时候一切正常。当I2C host以100KHz每500ms发一包数据,slave接收中断后导致操作系统不能调度,debug发现是systick不能进中断了,我试过把I2C3的优先级调到最低也是这样。i2c3使用PA8和PB4,初始化和中断函数如下,麻烦大家帮忙分一下,谢谢。
- void pcie_smbus_init(void)
- {
- RCC->AHB1ENR |= 0xff;
- GPIOA->MODER &= ~(0x3 << (8 * 2));
- GPIOA->MODER |= (0x2 << (8 * 2));
- GPIOA->OTYPER |= 1 << 8;
- GPIOA->PUPDR &= ~(0x3 << (8 * 2));
- GPIOA->PUPDR |= (0x1 << (8 * 2));
- GPIOA->AFR[1] = 4;
- GPIOB->MODER &= ~(0x3 << (4 * 2));
- GPIOB->MODER |= (0x2 << (4 * 2));
- GPIOB->OTYPER |= 1 << 4;
- GPIOB->PUPDR &= ~(0x3 << (4 * 2));
- GPIOB->PUPDR |= (0x1 << (4 * 2));
- GPIOB->AFR[0] = 9 << (4 * 4);
- RCC->APB1ENR |= 1 << 23;
- I2C3->CR1 = 0;
- I2C3->CR2 |= 1 << 10;
- I2C3->CR2 |= 1 << 9;
- I2C3->CR2 |= 1 << 8;
- I2C3->CR2 |= 42;
- I2C3->OAR1 = 0xa0;
- I2C3->OAR2 = 0x50 | 0x01;
- I2C3->SR1 = 0;
- I2C3->SR2 = 0;
- I2C3->CCR = 210;
- I2C3->TRISE = 0x2b;
- I2C3->CR1 |= 1 << 1;
- I2C3->CR1 |= 1 << 0;
- I2C3->CR1 |= 1 << 10;
- NVIC->IP[I2C3_EV_IRQn] = 0 << 4;
- NVIC->ISER[I2C3_EV_IRQn / 32] |= (1 << (I2C3_EV_IRQn % 32));
- NVIC->IP[I2C3_ER_IRQn] = 0 << 4;
- NVIC->ISER[I2C3_ER_IRQn / 32] |= (1 << (I2C3_ER_IRQn % 32));
- }
复制代码
- unsigned char g_smbus_buffer[256] = {0};
- unsigned int g_count = 0;
- void I2C3_EV_IRQHandler(void)
- {
- volatile unsigned short sr1 = 0;
- volatile unsigned short sr2 = 0;
- sr1 = I2C3->SR1;
- sr2 = I2C3->SR2;
- if((sr2 & 0x0005) == 0x0000)
- {
- if((sr1 & (1 << 0)) == (1 << 0))//start
- {
- }
- if((sr1 & (1 << 1)) == (1 << 1))//addr matched
- {
- g_count = 0;
- memset(g_smbus_buffer, 0, sizeof(g_smbus_buffer));
- }
- if((sr1 & (1 << 2)) == (1 << 2))//byte finished
- {
- }
- if((sr1 & (1 << 4)) == (1 << 4))//stop
- {
- }
- if((sr1 & (1 << 6)) == (1 << 6))//recv data
- {
- g_smbus_buffer[g_count++] = I2C3->DR;
- }
- }
- }
- void I2C3_ER_IRQHandler(void)
- {
- volatile unsigned short sr1 = 0;
- sr1 = I2C3->SR1;
- if((sr1 & (1 << 11)) == (1 << 11))//OVR
- {
- I2C3->CR1 &= ~(1 << 11);
- }
- if((sr1 & (1 << 10)) == (1 << 10))//AF
- {
- I2C3->CR1 &= ~(1 << 10);
- }
- if((sr1 & (1 << 9)) == (1 << 9))//ARLO
- {
- I2C3->CR1 &= ~(1 << 9);
- }
- if((sr1 & (1 << 8)) == (1 << 8))//BERR
- {
- I2C3->CR1 &= ~(1 << 8);
- }
- }
复制代码
|
|