stm32f1 + i2c1 help!

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Yorlik
Родился
Сообщения: 3
Зарегистрирован: Пн апр 01, 2019 13:59:02

stm32f1 + i2c1 help!

Сообщение Yorlik »

Помогите разобраться. Пытаюсь запустить i2c на портах 6 и 7 на stm32f103c8t6, все работает регистры статусов меняются, ошибок BERR не выдает, но и ничего не передает на самом деле.

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

#include "stm32f103xb.h"

int main() {

	// restart afio
	RCC->APB2RSTR |= RCC_APB2RSTR_AFIORST;
	// turn on b-pins
	RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
	// turn on afio
	RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
		// turn on I2C1
	RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
	// turn on pins 6, 7
	// AF and open-drain and 50MHz
	GPIOB->CRL |= 0xFF << 24;
	// set i2c1 freq
	I2C1->CR2 |= 2;
	// set ack
	I2C1->CR1 |= I2C_CR1_ACK;
	// set Pause
	I2C1->CCR |= 100;
	// trise
	I2C1->TRISE |= 9;
	// on i2c
	I2C1->CR1 |= I2C_CR1_PE;

	// start signal
	I2C1->CR1 |= I2C_CR1_START;
	while (!(I2C1->SR1 & I2C_SR1_SB));
	(void) I2C1->SR1;

	I2C1->DR |= 0x27 << 1;
	while (!(I2C1->SR1 & (I2C_SR1_ADDR)));
	(void) I2C1->SR1;
	(void) I2C1->SR2;

	I2C1->DR |= ('a' & 0xF0) | 0x08 | 0x04 | 0x01;
	while (!(I2C1->SR1 & (I2C_SR1_BTF)));
	(void) I2C1->SR1;
	(void) I2C1->SR2;

	I2C1->DR |= ('a' & 0xF0) | 0x08 | 0x00 | 0x01;
	while (!(I2C1->SR1 & (I2C_SR1_BTF)));
	(void) I2C1->SR1;
	(void) I2C1->SR2;

	I2C1->DR |= (('a' & 0x0F) << 4) | 0x08 | 0x04 | 0x01;
	while (!(I2C1->SR1 & (I2C_SR1_BTF)));
	(void) I2C1->SR1;
	(void) I2C1->SR2;

	I2C1->DR |= (('a' & 0x0F) << 4) | 0x08 | 0x00 | 0x01;
	while (!(I2C1->SR1 & (I2C_SR1_BTF)));
	(void) I2C1->SR1;
	(void) I2C1->SR2;

	I2C1->CR1 |= I2C_CR1_STOP;

	while (1);

	return 0;
}
Реклама
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: stm32f1 + i2c1 help!

Сообщение VladislavS »

RCC_APB2RSTR_AFIORST если нажал, то отпускать надо. Дальше не смотрел.
Реклама
Frogfot
Мучитель микросхем
Сообщения: 443
Зарегистрирован: Ср окт 19, 2011 08:48:27
Откуда: Мать городов русских

Re: stm32f1 + i2c1 help!

Сообщение Frogfot »

2 Yorlik Что за девайс висит на I2C? По идее он должен отвечать Ack - и STM32 ждёт пока не будет ответ.
Хорошему коту и в декабре - март :)
Yorlik
Родился
Сообщения: 3
Зарегистрирован: Пн апр 01, 2019 13:59:02

Re: stm32f1 + i2c1 help!

Сообщение Yorlik »

В том то и дело, устройство отвечает, но остальные байты не передаются, кроме адреса
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: stm32f1 + i2c1 help!

Сообщение VladislavS »

Посмотри пример. I2C не терпит суеты и лишних телодвижений.

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

bool EE_24C::WriteByte(uint16_t adr, uint8_t data)
{  
  pI2C->CR1 = I2C_CR1_PE | I2C_CR1_START;
  while(!(pI2C->SR1 & I2C_SR1_SB));
  pI2C->DR = w_adr;
  while(!(pI2C->SR1 & I2C_SR1_ADDR))
  {
    if(pI2C->SR1 & I2C_SR1_AF)
    {
      pI2C->CR1 = I2C_CR1_PE | I2C_CR1_STOP;
      return false;
    }
  };
  pI2C->SR2;
  while(!(pI2C->SR1 & I2C_SR1_TXE));
  pI2C->DR = adr>>8;
  while(!(pI2C->SR1 & I2C_SR1_TXE));
  pI2C->DR = adr;
  while(!(pI2C->SR1 & I2C_SR1_TXE));
  pI2C->DR = data;    
  while(!((pI2C->SR1 & I2C_SR1_TXE) && (pI2C->SR1 & I2C_SR1_BTF)));   
  pI2C->CR1 = I2C_CR1_PE | I2C_CR1_STOP;
  
  return true;
}
Реклама
Yorlik
Родился
Сообщения: 3
Зарегистрирован: Пн апр 01, 2019 13:59:02

Re: stm32f1 + i2c1 help!

Сообщение Yorlik »

Спасибо! Этот код работает. Странный конечно у stm32 i2c ведь я вроде тоже самое делаю)

Добавлено after 35 minutes 54 seconds:
Проблема в том, что регистр I2C1->DR сам не отчищается, хотя должен как написано в rm, и поэтому I2C1->DR |= data такая запись отправляла смесь предыдущего байта и этого, решение простое использовать I2C1->DR = data
Реклама
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: stm32f1 + i2c1 help!

Сообщение VladislavS »

Остановите Землю, я сойду.
Ответить

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