mr_Gish 0 19 декабря, 2014 Опубликовано 19 декабря, 2014 (изменено) · Жалоба Доброго времени суток! Возникла задача, необходимо связать stm32 связать с мультиплексорной платой ADG728, который связывается при помощи I2C, код написан, но на осциллографе я вижу только подъем с нуля на единицу, никаких импульсов не вижу #include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_tim.h" #include "stm32f10x_usart.h" //---------------- #include "stm32f10x_i2c.h" GPIO_InitTypeDef gpio; I2C_InitTypeDef i2c; #define TIMER_PRESCALER 720 #define EXT_TIM_PULSE 150 #define TIM_PULSE 50 uint16_t previousState; GPIO_InitTypeDef port; TIM_TimeBaseInitTypeDef timer; TIM_OCInitTypeDef timerPWM; uint16_t buttonPreviousState; GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; void I2C_init() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); I2C_StructInit(&I2C_InitStructure); I2C_InitStructure.I2C_ClockSpeed = 100000; I2C_InitStructure.I2C_OwnAddress1 = 1; I2C_InitStructure.I2C_Ack = I2C_Ack_Disable;//Enable I2C_Init(I2C1, &I2C_InitStructure); I2C_Cmd(I2C1, ENABLE); I2C_AcknowledgeConfig(I2C1, ENABLE); } void I2C_single_write(uint8_t HW_address, uint8_t addr, uint8_t data) { I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, HW_address, I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, addr); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1, data); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C1, ENABLE); while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); } uint8_t I2C_single_read(uint8_t HW_address, uint8_t addr) { uint8_t data; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, HW_address, I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, addr); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, HW_address, I2C_Direction_Receiver); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)); data = I2C_ReceiveData(I2C1); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_GenerateSTOP(I2C1, ENABLE); while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); return data; } void delay(int a) { int i = 0; int f = 0; while(f < a) { while(i<60) {i++;} f++; } } int main() { uint8_t single_data_read = 0; I2C_init(); delay(500); I2C_StretchClockCmd(I2C1, ENABLE); I2C_single_write(0xA0, 0x00, 0x15); delay(500); single_data_read = I2C_single_read(0xA0, 0x03); while(1); } Будьте добры, дайте советов, проект горит, спасибо Изменено 19 декабря, 2014 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 19 декабря, 2014 Опубликовано 19 декабря, 2014 · Жалоба Будьте добры, дайте советов, проект горит, спасибо Если проект горит, я бы не связывался с аппаратным I2C у STM32 - это очень странный зверь. Лучше сделайте ногодрыгом - это проще и надёжнее. Примеров кода в тырнетах масса: i2c bit banging code. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mr_Gish 0 19 декабря, 2014 Опубликовано 19 декабря, 2014 · Жалоба Если проект горит, я бы не связывался с аппаратным I2C у STM32 - это очень странный зверь. Лучше сделайте ногодрыгом - это проще и надёжнее. Примеров кода в тырнетах масса: i2c bit banging code. Данный мультиплексор работает ведь только с i2c Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axel 1 19 декабря, 2014 Опубликовано 19 декабря, 2014 · Жалоба Если проект горит, я бы не связывался с аппаратным I2C у STM32 - это очень странный зверь. Кривоватый конечно, но работает. Если может помочь код, не использующий либы, могу поделиться работающим примером для EEPROM (STM32F103) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 19 декабря, 2014 Опубликовано 19 декабря, 2014 · Жалоба Данный мультиплексор работает ведь только с i2c Неужели вы не в курсе, что такое "i2c через ногодрыг". Лучше почитайте про это, в вашей ситуации это будет очень полезное знание, ИМХО. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mr_Gish 0 19 декабря, 2014 Опубликовано 19 декабря, 2014 · Жалоба Кривоватый конечно, но работает. Если может помочь код, не использующий либы, могу поделиться работающим примером для EEPROM (STM32F103) было бы замечательно, спасибо Неужели вы не в курсе, что такое "i2c через ногодрыг". Лучше почитайте про это, в вашей ситуации это будет очень полезное знание, ИМХО. Спасибо, обязательно почитаю, новичок еще в этом деле Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axel 1 19 декабря, 2014 Опубликовано 19 декабря, 2014 · Жалоба было бы замечательно, спасибо Обманул, для 103-го дома не оказалось. Есть только для F4xx и для F030, но они вроде очень похожи. Посмотрите... f030_i2c.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 20 декабря, 2014 Опубликовано 20 декабря, 2014 · Жалоба Доброго времени суток! Возникла задача, необходимо связать stm32 связать с мультиплексорной платой ADG728, который связывается при помощи I2C, код написан, но на осциллографе я вижу только подъем с нуля на единицу, никаких импульсов не вижу GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOB, &GPIO_InitStructure); Для i2c необходимо сконфигурировать пины в режиме "альтернативная функция, открытый сток", ни в коем случае не пушпулл, а то i2c не будет управлять пинами. Кстати, в мануале в разделе 9.1.11 написано, как следует конфигурировать GPIO для каждой функции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MSprut 0 20 декабря, 2014 Опубликовано 20 декабря, 2014 · Жалоба Вот инициализация для 103-го камня, кривовато, но может поможет: void i2c_init(void) { GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); /* I2C1 SDA and SCL configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_Init(GPIOB, &GPIO_InitStructure); /* I2C1 configuration */ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 400000;//ClockSpeed; I2C_Cmd(I2C1, ENABLE); I2C_Init(I2C1, &I2C_InitStructure); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mr_Gish 0 22 декабря, 2014 Опубликовано 22 декабря, 2014 · Жалоба Для i2c необходимо сконфигурировать пины в режиме "альтернативная функция, открытый сток", ни в коем случае не пушпулл, а то i2c не будет управлять пинами. Кстати, в мануале в разделе 9.1.11 написано, как следует конфигурировать GPIO для каждой функции. Все равно никакого эффека Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mr_Gish 0 23 декабря, 2014 Опубликовано 23 декабря, 2014 · Жалоба Кто нибудь реализовал i2c через i2c bit banging code? Не могли бы скинуть примеры Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 23 декабря, 2014 Опубликовано 23 декабря, 2014 · Жалоба Кто нибудь реализовал i2c через i2c bit banging code? Не могли бы скинуть примеры Вот тут нечто похожее на вменяемый код. И протестировано должно быть, раз называется примером. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Easyrider 0 23 декабря, 2014 Опубликовано 23 декабря, 2014 (изменено) · Жалоба Ногодрыгом делать i2c это моветон. Я делал как полингом, так и по прерыванию. unsigned char I2c_Start (I2C_TypeDef* I2Cx) { u16 cnt = maxcnt; if (I2Cx->SR2&I2C_SR2_BUSY) return I2C_BUS_BUSY; I2Cx->CR1 |= I2C_CR1_START; while ((I2Cx->SR1 & I2C_SR1_SB) == 0) { cnt--; if (cnt == 0) return I2C_BUS_BUSY; } return 0; } void I2c_ReStart (I2C_TypeDef* I2Cx) { I2Cx->CR1 |= I2C_CR1_START; while (!(I2Cx->SR1 & I2C_SR1_SB)); } unsigned char I2c_WriteAddress (I2C_TypeDef* I2Cx, unsigned char i2c_address) { u16 cnt = maxcnt; I2Cx->DR = i2c_address; while (!(I2Cx->SR1 & (I2C_SR1_ADDR|I2C_SR1_ARLO|I2C_SR1_AF)))//stuck here sometimes { cnt--; if (cnt == 0) return I2C_NOACK; } if (I2Cx->SR1&(I2C_SR1_ARLO|I2C_SR1_AF)) return I2C_NOACK; (void) I2Cx->SR1; (void) I2Cx->SR2; if (i2c_address&1) while (!(I2Cx->SR1 & I2C_SR1_RXNE)); return 0; } void I2c_WriteByte (I2C_TypeDef* I2Cx, unsigned char data) { I2Cx->DR = data; while (!(I2Cx->SR1 & I2C_SR1_BTF)); } unsigned char I2c_ReadByte (I2C_TypeDef* I2Cx) { while((I2Cx->SR1 & I2C_SR1_RXNE)==0); // wait data I2Cx->SR1; I2Cx->SR2; return I2Cx->DR; } unsigned char I2c_Stop (I2C_TypeDef* I2Cx) { I2Cx->CR1 |= I2C_CR1_STOP; while (I2Cx->SR2&I2C_SR2_BUSY); return I2C_OK; } void I2c_ACK (I2C_TypeDef* I2Cx) { I2Cx->CR1 |= I2C_CR1_ACK; } void I2c_NACK (I2C_TypeDef* I2Cx) { I2Cx->CR1 &= ~I2C_CR1_ACK; } /* Reads Page with 1-byte pointer */ unsigned char I2c_Read_Page (I2C_TypeDef* I2Cx, unsigned char I2c_Address, unsigned char Reg, unsigned char * buffer, unsigned char Len) { I2c_ACK(I2Cx); if (I2c_Start(I2Cx)) return I2C_BUS_BUSY; if (I2c_WriteAddress(I2Cx, I2c_Address)) return I2C_NOACK; I2c_WriteByte(I2Cx, Reg); I2c_ReStart(I2Cx); I2c_WriteAddress(I2Cx, I2c_Address|1); while (Len>1) { I2c_ACK(I2Cx); * buffer++ = I2c_ReadByte(I2Cx); Len--; } I2Cx->CR1&=~I2C_CR1_POS; I2Cx->CR1 |= I2C_CR1_STOP; * buffer++ = I2c_ReadByte(I2Cx); //I2Cx->CR1 |= I2C_CR1_STOP; I2c_NACK(I2Cx); return I2C_OK; } unsigned char I2c_Write_Page (I2C_TypeDef* I2Cx, unsigned char I2c_Address, unsigned char Reg, unsigned char * buffer, unsigned char Len) { I2c_ACK(I2Cx); if (I2c_Start(I2Cx)) return I2C_BUS_BUSY; if (I2c_WriteAddress(I2Cx, I2c_Address)) return I2C_NOACK; I2c_WriteByte(I2Cx, Reg); while (Len--) I2c_WriteByte(I2Cx, * buffer++); I2c_Stop(I2Cx); return I2C_OK; } unsigned char I2c_Write_Register (I2C_TypeDef* I2Cx, unsigned char I2c_Address, unsigned char Reg, unsigned char data) { if (I2c_Start(I2Cx)) return I2C_BUS_BUSY; if (I2c_WriteAddress(I2Cx, I2c_Address)) return I2C_NOACK; I2c_WriteByte(I2Cx, Reg); I2c_WriteByte(I2Cx, data); I2c_Stop(I2Cx); return I2C_OK; } I2C_RESULT CheckI2C (I2C_TypeDef* I2Cx) { if (I2Cx->SR2&I2C_SR2_BUSY) return I2C_BUS_BUSY; return I2C_OK; } Изменено 24 декабря, 2014 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 24 декабря, 2014 Опубликовано 24 декабря, 2014 · Жалоба Ногодрыгом делать i2c это моветон. Не надо говорить ерунды. Находиться в плену предрассудков - вот это точно моветон. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axel 1 24 декабря, 2014 Опубликовано 24 декабря, 2014 · Жалоба Ногодрыгом делать i2c это моветон. Ну почему же, вполне себе вариант в определенных обстоятельствах. В данном же случае - интерфейс работающий, не без нюансов, но "...всю Одессу удовлетворяет..."© Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться