I2C STM32F103. Фигнякакаято с инкрементом в прерывании

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Alex-Elektron
Встал на лапы
Сообщения: 113
Зарегистрирован: Сб янв 11, 2014 21:25:55

I2C STM32F103. Фигнякакаято с инкрементом в прерывании

Сообщение Alex-Elektron »

Доброго времени суток! Написал простейшую конструкцию для проверки работы хардварного 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;
		}
	}
//----------------------------------------------------------------
}
Вложения
I2C_Глюк.png
(70.86 КБ) 135 скачиваний
Реклама
technik-1017
Открыл глаза
Сообщения: 42
Зарегистрирован: Вс сен 03, 2017 19:43:57
Контактная информация:

Re: I2C STM32F103. Фигнякакаято с инкрементом в прерывании

Сообщение technik-1017 »

переменные, используемые в прерывании, сделайте как volatile:
volatile int16_t i2c2_cnt;
Реклама
Alex-Elektron
Встал на лапы
Сообщения: 113
Зарегистрирован: Сб янв 11, 2014 21:25:55

Re: I2C STM32F103. Фигнякакаято с инкрементом в прерывании

Сообщение Alex-Elektron »

Никак не повлияло. Попробовал сделать

Код: Выделить всё

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;
	}
		
Ответить

Вернуться в «ARM»