STM32F030F4p6 i2c

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Аватара пользователя
vdv22
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт июн 08, 2017 17:52:33

STM32F030F4p6 i2c

Сообщение vdv22 »

здравствуйте .есть необходимость связать данный контроллер но шине I2C .написал код -все по мануалу (пока это отправка ) d keil .Прошли контроллер но на линии тишина... - бьюсь уже несколько дней но пока никак .Заранее спасибо за помощь!!

#define adress 0x7e

void i2c_init (void)
{

SET_BIT(RCC->AHBENR,RCC_AHBENR_GPIOAEN);


GPIOA->MODER |=GPIO_MODER_MODER9_1;
GPIOA->OSPEEDR|=GPIO_OSPEEDER_OSPEEDR9; //альтернативная функция AF4 для PA9
GPIOA->AFR[1]|=(4<<4);

GPIOA->MODER|=GPIO_MODER_MODER10_1;
GPIOA->OSPEEDR|=GPIO_OSPEEDER_OSPEEDR10; // //альтернативная функция AF4 для PA10
GPIOA->AFR[1]|=(4<<8);

RCC->APB1ENR |=RCC_APB1ENR_I2C1EN; // включаем тактирование
RCC->CFGR3|=RCC_CFGR3_I2C1SW; //источник тактирования
I2C1->TIMINGR=0X10420F13; // настройка таймингов при частоте 8 MHz
I2C1->CR1|=I2C_CR1_PE; // включаем модуль

}


void write_i2c (unsigned char adr,unsigned char data) //функция передачи
{
I2C1->CR2=I2C_CR2_AUTOEND|(2<<16)|I2C_CR2_START|(adress<<1); // передаем адрес ведомого , автостоп , условие старта.
while ((I2C1->ISR&I2C_ISR_TXE)!= I2C_ISR_TXE); //ждем передачи адреса
I2C1->TXDR=adr; //посылаем адрес ячейки в который хотим писать данные
while ((I2C1->ISR&I2C_ISR_TXIS)!= I2C_ISR_TXIS); //ждем окончания посылки
I2C1->TXDR=data; //отправляем данные
while ((I2C1->ISR&I2C_ISR_BUSY)==I2C_ISR_BUSY); //ждем освобождения шины

}
Реклама
ST7FOX
Мучитель микросхем
Сообщения: 402
Зарегистрирован: Сб июл 10, 2021 19:33:25

Re: STM32F030F4p6 i2c

Сообщение ST7FOX »

Странный у Вас мануал.
В RM0360 Reference manual STM32F030x4/x6/x8/xC and STM32F070x6/xB advanced ARM®-based 32-bit MCUs
написано первым действием в инициализации: Clear PE bit in I2C_CR1

Возможно, Вы и дальше всё "упростили"?
Реклама
Аватара пользователя
vdv22
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт июн 08, 2017 17:52:33

Re: STM32F030F4p6 i2c

Сообщение vdv22 »

делал я и с отключенным модулем вначале и без этот -результата нет . Вот и спрашиваю что в моем коде не так .
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: STM32F030F4p6 i2c

Сообщение Dimon456 »

Не блокирующая реализация для STM32F030F4p6 i2c
Спойлер

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

#define I2C_BUS I2C1

// Вспомогательные переменные
typedef enum _I2C_Direction {I2C_Transmitter=0, I2C_Receiver=1} I2C_Direction;

void init_I2C1(void)
{
	RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);	// I2C Clock Mux - HSI

	// Включаем тактирование нужных модулей
	RCC->AHBENR |= RCC_AHBENR_GPIOAEN;

	// Включаю тактирование I2C
	RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;		
	// Настройка ног PA9, PA10
	GPIOA->MODER |= GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1;			// Режим альтернативной функции
	GPIOA->OTYPER |= GPIO_OTYPER_OT_9 | GPIO_OTYPER_OT_10;				// Открытый коллектор
	GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9 | GPIO_OSPEEDER_OSPEEDR10;	// Максимальная скорость						GPIO_OSPEEDER_OSPEEDR9
	// Выбор альтернативной функции
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_4);	// I2C1_SCL
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_4);	// I2C1_SDA

	I2C_BUS->CR1 &= ~I2C_CR1_PE;			// Отключаю I2C
	while (I2C_BUS->CR1 & I2C_CR1_PE) {};	// Жду пока отключится

	// Настраиваю тайминги
	I2C_BUS->TIMINGR = (uint32_t)0x00905E82;	// 48MHz 0x10400CDB-100kHz 0x00905E82-200kHz

	I2C_BUS->CR1 |= I2C_CR1_PE;					// Включаю I2C
	while ((I2C_BUS->CR1 & I2C_CR1_PE)==0) {};	// Жду пока включится
}

void I2C_Write_Transaction (uint8_t Adress, uint8_t Data)
{
	// Старт
	I2C_Start_Direction_Adress_Size (I2C_Transmitter, Adress, 1);

	// Сейчас либо I2C запросит первый байт для отправки,
	// Либо взлетит NACK-флаг, говорящий о том, что микросхема не отвечает.
	// Если взлетит NACK-флаг, отправку прекращаем.
	while ((((I2C_BUS->ISR & I2C_ISR_TXIS)==0) && ((I2C_BUS->ISR & I2C_ISR_NACKF)==0)) && (I2C_BUS->ISR & I2C_ISR_BUSY)) {};
	if (I2C_BUS->ISR & I2C_ISR_TXIS) I2C_BUS->TXDR=Data;	// Отправляю данные

	I2C_Stop();
}

void I2C_Start_Direction_Adress_Size (I2C_Direction Direction, uint8_t Adress, uint8_t Size)
{
	//I2C_BUS->CR2 &= ~I2C_CR2_AUTOEND;				// Выдавать стоп вручную
	//I2C_BUS->CR2 &= ~I2C_CR2_RELOAD;				// Не использовать режим перезагрузки
	if (Direction) I2C_BUS->CR2 |= I2C_CR2_RD_WRN;	// Режим приёма
	else I2C_BUS->CR2 &= ~I2C_CR2_RD_WRN;			// Режим передачи
	I2C_BUS->CR2 &= ~I2C_CR2_NBYTES;				// Очистить размер данных
	I2C_BUS->CR2 |= Size<<I2C_OFFSET_CR2_NBYTES;	// Установить размер данных
	I2C_BUS->CR2 &= ~I2C_CR2_SADD;	// Очистить адрес ведомого устройства
	I2C_BUS->CR2 |= (Adress << 1);			// Установить адрес ведомого устройства
	I2C_BUS->CR2 |= I2C_CR2_START;					// Выдать старт на шину
	while ((I2C_BUS->ISR & I2C_ISR_BUSY)==0) {};	// Ожидать выдачу старта
}

void I2C_Stop (void)
{
	I2C_BUS->CR2 |= I2C_CR2_STOP;				// Выдать стоп на шину
	while (I2C_BUS->ISR & I2C_ISR_BUSY) {};		// Ожидать выдачу стопа
	// Очищаю флаги - необходимо для дальнейшей работы шины
	I2C_BUS->ICR |= I2C_ICR_STOPCF;		// STOP флаг
	I2C_BUS->ICR |= I2C_ICR_NACKCF;		// NACK флаг
	// Если есть ошибки на шине - очищаю флаги
	if (I2C_BUS->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR))
	{
		I2C_BUS->ICR |= I2C_ICR_ARLOCF;
		I2C_BUS->ICR |= I2C_ICR_BERRCF;
	}
}
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: STM32F030F4p6 i2c

Сообщение Eddy_Em »

Dimon456, здесь "не" лишнее. Неблокирующая — это когда нет блокировки. Т.е. прием-передача через DMA или хотя бы на прерываниях.
А блокирующую и я могу предложить.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Реклама
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: STM32F030F4p6 i2c

Сообщение Dimon456 »

Eddy_Em вот сканер
Спойлер

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

uint8_t adress_as[127];
void skaner(void)
{ 
	for(uint8_t address = 8; address < 127; address++ ) {

		I2C_Start_Direction_Adress_Size (I2C_Transmitter, address, 1);

		// Сейчас либо I2C запросит первый байт для отправки,
	    // Либо взлетит NACK-флаг, говорящий о том, что микросхема не отвечает.
	    // Если взлетит NACK-флаг, отправку прекращаем.
	    while ((((I2C_BUS->ISR & I2C_ISR_TXIS)==0) && ((I2C_BUS->ISR & I2C_ISR_NACKF)==0)) && (I2C_BUS->ISR & I2C_ISR_BUSY)) {};
	    if (I2C_BUS->ISR & I2C_ISR_TXIS) {
	    	adress_as[address]=address;  // 
	    	I2C_BUS->TXDR=0x00;	// Отправляю хоть что-то, иначе виснет
	    }

		I2C_Stop();
	}
}
Eddy_Em писал(а):Т.е. прием-передача через DMA
У меня и с DMA есть, правда только передача на mcp4725, и режим FAST_MODE 1МГц.
Реклама
Novice user
Мудрый кот
Сообщения: 1704
Зарегистрирован: Вт янв 05, 2016 10:14:25
Откуда: поселок Мелеуз

Re: STM32F030F4p6 i2c

Сообщение Novice user »

У меня была подобная проблема,оказалось что была включена собака и программа просто не успевала доходить до участка исходника где отправка по I2C,поставил так и все завелось http://forumupload.ru/uploads/0000/25/b8/385/392026.png
Ответить

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