Форум РадиоКот https://radiokot.ru/forum/ |
|
I2C STM32F103. Фигнякакаято с инкрементом в прерывании https://radiokot.ru/forum/viewtopic.php?f=59&t=151850 |
Страница 1 из 1 |
Автор: | Alex-Elektron [ Пт янв 19, 2018 12:57:48 ] | ||
Заголовок сообщения: | I2C STM32F103. Фигнякакаято с инкрементом в прерывании | ||
Доброго времени суток! Написал простейшую конструкцию для проверки работы хардварного I2C. Программка просто циклически посылает массив с циферками на анализатор. Фигня в том, что массив она посылает почему-то не с нулевого элемента, а с первого. Можно решить задачу через костыль, но это грубо. Что я упускаю? Код простейший, логи прикрепил: Код: #include "stm32f10x.h"
#define OLED_ADDR 0x78 uint8_t i2c2_data[512]={1,2,3,4}; int16_t i2c2_cnt; void I2C2_INIT(){ RCC->APB1ENR |= RCC_APB1ENR_I2C2EN; RCC->APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN; GPIOB->CRH |= GPIO_CRH_CNF10 | GPIO_CRH_MODE10 | GPIO_CRH_CNF11 | GPIO_CRH_MODE11; //PB10, PB11 - OD, AF I2C2->CR1 |= I2C_CR1_SWRST; I2C2->CR1 &= ~I2C_CR1_SWRST; I2C2->CR2 = 36 | I2C_CR2_ITEVTEN; I2C2->CCR = I2C_CCR_FS | 30; I2C2->TRISE = 25; I2C2->CR1 |= I2C_CR1_PE; NVIC_EnableIRQ(I2C2_EV_IRQn); } void I2C_Write_massive(){ I2C2->CR1 |= I2C_CR1_START; } int main(void){ I2C2_INIT(); while(1) { I2C_Write_massive(3); for(uint32_t i=0; i<360000; i++); } } void I2C2_EV_IRQHandler(){ volatile uint32_t sr1 = I2C2->SR1, sr2 = I2C2->SR2; if(sr1 & I2C_SR1_SB ){ I2C2->DR = OLED_ADDR; } //---------- передача данных------------------------------- if((sr1 & I2C_SR1_TXE)){ if(i2c2_cnt < 4){ I2C2->DR = i2c2_data[i2c2_cnt++]; } else{ i2c2_cnt = 0; I2C2->CR1 |= I2C_CR1_STOP; } } //---------- }
|
Автор: | technik-1017 [ Пт янв 19, 2018 13:09:32 ] |
Заголовок сообщения: | Re: I2C STM32F103. Фигнякакаято с инкрементом в прерывании |
переменные, используемые в прерывании, сделайте как volatile: volatile int16_t i2c2_cnt; |
Автор: | Alex-Elektron [ Пт янв 19, 2018 13:26:03 ] |
Заголовок сообщения: | Re: I2C STM32F103. Фигнякакаято с инкрементом в прерывании |
Никак не повлияло. Попробовал сделать Код: i2c2_data[512]={0x78,1,2,3,4}; то есть, в нулевой элемент массива вкатил адрес устройства, и в обработчике сделал так, чтобы адрес читался из нулевого элемента массива Код: if(sr1 & I2C_SR1_SB ){ I2C2->DR = i2c2_data[0]; } Вот эта ерундовина отправляет то, что я хочу увидеть, но я не хочу записывать адрес в массив. Добавлено after 8 minutes 56 seconds: Проблему решил. Если кому пригодится, то в тело условия проверки флага старта добавил обнуление переменной i2c2_cnt = 0; Код: if(sr1 & I2C_SR1_SB ){
i2c2_cnt = 0; I2C2->DR = OLED_ADDR; } |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |