Вс июл 11, 2021 18:56:02
Вс июл 11, 2021 19:05:52
Пн июл 12, 2021 02:52:36
Пн июл 12, 2021 08:22:44
#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;
}
}
Пн июл 12, 2021 11:37:37
Пн июл 12, 2021 12:28:18
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();
}
}
У меня и с DMA есть, правда только передача на mcp4725, и режим FAST_MODE 1МГц.Eddy_Em писал(а):Т.е. прием-передача через DMA
Пн июл 12, 2021 19:45:29