Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.88/25: Рейтинг темы: голосов - 25, средняя оценка - 4.88
max_sk
80 / 7 / 2
Регистрация: 11.04.2015
Сообщений: 441
1

Датчик температуры по I2C

15.09.2018, 14:06. Просмотров 4580. Ответов 78
Метки нет (Все метки)

Добрый день всем !

У меня есть датчик температуры, передающий инфу по I2C. Хочу связать его с Нуклео бордом.

Подскажите, где лучше всего почитать теорию по I2C ?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.09.2018, 14:06
Ответы с готовыми решениями:

Встроенный датчик температуры.
Приветствую! Задался целью разобраться со встроенным датчиком температуры. В программировании...

Динамическая индикация и датчик температуры
Здравствуйте. Делаю проект вывода температуры на семисегментные дисплеи при помощи динамической...

датчик температуры для К1816ВЕ31
подскажить какой датчик температуры нужно использовать для контроля за температурой в микроволновой...

STM32F107 и I2C
в даташит в статус регистре бизи флаг это бит 1. соответственно возникает желание сделать так...

I2C CMSIS
всем привет кто работал с модулем I2C на STM32F103 используя только CMSIS скиньте пример...

78
Voland_
1670 / 1015 / 97
Регистрация: 04.01.2010
Сообщений: 3,396
15.09.2018, 15:13 2
прямо отвечая на вопрос - вот. Но навряд ли что-то из этого документа вам пригодится на практике.
2
Radikal_78
42 / 42 / 2
Регистрация: 20.11.2016
Сообщений: 96
15.09.2018, 17:13 3
Можно прочитать в книге Евстифеева "Микроконтроллеры AVR Atmel семейств Tiny и Mega". Только этот интерфейс именуется там как TWI
1
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,944
16.09.2018, 07:06 4
Цитата Сообщение от max_sk Посмотреть сообщение
где лучше всего почитать теорию по I2C ?
вот по I2C http://www.gaw.ru/html.cgi/txt/interface/iic/index.htm
вот по микросхеме памяти с I2C http://www.gaw.ru/html.cgi/txt/doc/memory/seeprom/at24c128_256.htm
разжевано, по моему, буквально все
2
max_sk
80 / 7 / 2
Регистрация: 11.04.2015
Сообщений: 441
18.09.2018, 16:28  [ТС] 5
Я купил датчик температуры от Моторолы ТС74А7. Нужно ли ему подводить pull-up резисторы на Vdd на лапки SCL и SDA ? В даташит датчика этой инфы не нашел...
0
Humanoid
Почетный модератор
9982 / 3870 / 348
Регистрация: 12.06.2008
Сообщений: 11,402
18.09.2018, 19:43 6
Цитата Сообщение от max_sk Посмотреть сообщение
Я купил датчик температуры от Моторолы ТС74А7. Нужно ли ему подводить pull-up резисторы на Vdd на лапки SCL и SDA ? В даташит датчика этой инфы не нашел...
Там указано, что используется I2C. Значит нужна подтяжка.
1
Radikal_78
42 / 42 / 2
Регистрация: 20.11.2016
Сообщений: 96
18.09.2018, 21:14 7
что за датчик такой? Найти в инете не могу((
0
Humanoid
Почетный модератор
9982 / 3870 / 348
Регистрация: 12.06.2008
Сообщений: 11,402
18.09.2018, 21:55 8
Цитата Сообщение от Radikal_78 Посмотреть сообщение
что за датчик такой? Найти в инете не могу((
Просто max_sk там русские буквы использовал Если от руки написать с английскими буквами, то находит.

Добавлено через 6 минут
А вообще, нехорошо, когда человек просит помочь, а сам усложняет людям поиск информации по его вопросу.

Цитата Сообщение от max_sk Посмотреть сообщение
датчик температуры от Моторолы ТС74А7
Кстати, TC74A7 - это майкрочип.
1
max_sk
80 / 7 / 2
Регистрация: 11.04.2015
Сообщений: 441
19.09.2018, 13:48  [ТС] 9
Humanoid, спасибо за поправку. Кстати, а какие резисторы использовать для подтяжки ? 1кОм подойдет ? :?
0
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,944
19.09.2018, 13:50 10
Цитата Сообщение от max_sk Посмотреть сообщение
а какие резисторы использовать для подтяжки
В первой ссылке, что я дал, есть расчет резисторов
обычно ставят 10кОм на одну микросхему, я ставил 2.2 кОм при питании 3 Вольта
0
max_sk
80 / 7 / 2
Регистрация: 11.04.2015
Сообщений: 441
19.09.2018, 20:03  [ТС] 11
Покамест застрял на Start condition. Не могу понять, толи оно не генерируется, толи оно стирается после чтения I2C_SR1.

Вот отрывок из даташит :

Bit 0 SB: Start bit (Master mode)
0: No Start condition
1: Start condition generated.
– Set when a Start condition generated.
– Cleared by software by reading the SR1 register followed by writing the DR register, or by
hardware when PE=0

Вот отрывок кода, который я набросал :

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
int main(void)
{
  /* USER CODE BEGIN 1 */
uint8_t ReceiveVar=0;
char ReceiveNum[2]="";
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
  *I2C_CR1 &= ~(0x1U << 0); // peripheral disable
  *I2C_CR2 = 0x0020U; // input frequency = 32MHz, others = 0
  *I2C_CCR = 0x00A0U; // for ~ 100kHz
  *I2C_TRISE = 0x0020U; // rising time ~ 1000nsec
  *I2C_CR1 |= 0x1U; // Set PE - peripheral enable
  *I2C_CR1 |= (0x1U << 8); // Set START bit
  
  *I2C_DR = 0x009AU; // Slave address with 0 ( write condition )
  if( (*I2C_SR1 & 0x0001U )==0x0000U){ 
      HAL_UART_Transmit( &huart2, "No start condition generated\r\n", 30, 100);
  }
  if( (*I2C_SR1 & 0x0002U )==0x0002U){ 
      HAL_UART_Transmit( &huart2, "End of address transmition\r\n", 28, 100);
  }
  if( (*I2C_SR1 & 0x0004U )==0x0004U){ 
      HAL_UART_Transmit( &huart2, "Data byte transfer succeeded\r\n", 30, 100);
  }
  if( (*I2C_SR1 & 0x0008U )==0x0008U){ 
      HAL_UART_Transmit( &huart2, "Master has sent first address byte (header).\r\n", 48, 100);
  }
  if( (*I2C_SR1 & 0x0010U )==0x0010U){ 
      HAL_UART_Transmit( &huart2, "Stop condition detected\r\n", 25, 100);
  }
  if( (*I2C_SR1 & 0x0040U )==0x0040U){ 
      HAL_UART_Transmit( &huart2, "Data register not empty\r\n", 25, 100);
  }
  if( (*I2C_SR1 & 0x0080U )==0x0080U){ 
      HAL_UART_Transmit( &huart2, "Data register empty\r\n", 21, 100);
  }
  if( (*I2C_SR1 & 0x0100U )==0x0100U){ 
      HAL_UART_Transmit( &huart2, "BERR: Bus error\r\n", 17, 100);
  }
  if( (*I2C_SR1 & 0x0200U )==0x0200U){ 
      HAL_UART_Transmit( &huart2, "ARLO: Arbitration lost (master mode)\r\n", 38, 100);
  }
  if( (*I2C_SR1 & 0x0400U )==0x0400U){ 
      HAL_UART_Transmit( &huart2, "AF: Acknowledge failure\r\n", 25, 100);
  }
  if( (*I2C_SR1 & 0x0800U )==0x0800U){ 
      HAL_UART_Transmit( &huart2, "OVR: Overrun/Underrun\r\n", 23, 100);
  }
  if( (*I2C_SR1 & 0x1000U )==0x1000U){ 
      HAL_UART_Transmit( &huart2, "PECERR: PEC Error in reception\r\n", 32, 100);
  }
  if( (*I2C_SR1 & 0x4000U )==0x4000U){ 
      HAL_UART_Transmit( &huart2, "TIMEOUT: Timeout or Tlow error\r\n", 32, 100);
  }
  if( (*I2C_SR1 & 0x8000U )==0x8000U){ 
      HAL_UART_Transmit( &huart2, "SMBALERT: SMBus alert\r\n", 23, 100);
  }
    /*else{
      if( ((*I2C_SR2 & 0x0003U)==0x0003U) && ((*I2C_SR1 & 0x0002U )==0x0002U) ){ // Is Master Mode and bus is busy and ADDR=1 - address sent
          HAL_UART_Transmit( &huart2, "ADDR is sent\r\n", 14, 100);
      }
      *I2C_DR = 0x0000U; // Command to sensor to read temperature 
      if( (*I2C_SR1 & 0x0400U)==0x0400U){ // AF=1 - acknowledge failure
          HAL_UART_Transmit( &huart2, "AF error !!!\r\n", 14, 100);
      }
  }*/
  /* USER CODE END 2 */
Вот на всякий случай мой header-файл :

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef I2C_REGS_H_
#define I2C_REGS_H_
 
#define I2C_CR1   ((volatile unsigned *)0x40005400+0x00)    //I2C control register 1
#define I2C_CR2   ((volatile unsigned *)0x40005400+0x04)        //I2C control register 2
#define I2C_OAR1  ((volatile unsigned *)0x40005400+0x08)        //I2C Own address register 1
#define I2C_OAR2  ((volatile unsigned *)0x40005400+0x0C)        //I2C Own address register 2
#define I2C_DR    ((volatile unsigned *)0x40005400+0x10)        //I2C Data register
#define I2C_SR1   ((volatile unsigned *)0x40005400+0x14)        //I2C Status register 1
#define I2C_SR2   ((volatile unsigned *)0x40005400+0x18)        //I2C Status register 2
#define I2C_CCR   ((volatile unsigned *)0x40005400+0x1C)        //I2C Clock control register
#define I2C_TRISE ((volatile unsigned *)0x40005400+0x20)        //I2C TRISE register
 
#endif /*I2C_REGS_H_*/
Буду рад вашим подсказкам.

Добавлено через 8 минут
Я правильно понимаю, что адрес слейва должен быть при первом обращении быть 0х9А ? Вот отрывок даташит датчика :

3.1.2 SMBUS/I2C SLAVE ADDRESS
The TC74 is internally programmed to have a default
SMBus/I2C address value of 1001 101b. Seven other
addresses are available by custom order (contact
Microchip Technology Inc.

Добавлено через 8 минут
Сопротивления подтяжки поставил 5.1кОм, за неимением других. Я сейчас в отпуске, выйду на работу - попробую подобрать другие...

Добавлено через 7 минут
Вот этот отрывок кода :

C
1
2
3
4
5
6
*I2C_CR1 &= ~(0x1U << 0); // peripheral disable
  *I2C_CR2 = 0x0020U; // input frequency = 32MHz, others = 0
  *I2C_CCR = 0x00A0U; // for ~ 100kHz
  *I2C_TRISE = 0x0020U; // rising time ~ 1000nsec
  *I2C_CR1 |= 0x1U; // Set PE - peripheral enable
  *I2C_CR1 |= (0x1U << 8); // Set START bit

Писал по этому отрывку из даташит платы Nucleo-L152RE, которая есть у меня :

26.3.3 I2C master mode
In Master mode, the I2C interface initiates a data transfer and generates the clock signal. A serial data transfer always begins with a Start condition and ends with a Stop condition. Master mode is selected as soon as the Start condition is generated on the bus with a START bit.
The following is the required sequence in master mode.
• Program the peripheral input clock in I2C_CR2 Register in order to generate correct
timings
• Configure the clock control registers
• Configure the rise time register
• Program the I2C_CR1 register to enable the peripheral
• Set the START bit in the I2C_CR1 register to generate a Start condition
The peripheral input clock frequency must be at least:
• 2 MHz in Sm mode
• 4 MHz in Fm mode
0
ValeryS
Модератор
7372 / 5573 / 707
Регистрация: 14.02.2011
Сообщений: 18,944
19.09.2018, 20:55 12
Цитата Сообщение от max_sk Посмотреть сообщение
Я правильно понимаю, что адрес слейва должен быть при первом обращении быть 0х9А ?
нет
Цитата Сообщение от max_sk Посмотреть сообщение
MBus/I2C address value of 1001 101b.
адрес у тебя 0x4D
младший бит по спецификации шины, означает направление 0 запись( в микросхему) 1 чтение (из микросхемы)
для формирования запроса адреса адрес сдвигается влево (умножается на 2) и добавляется бит направления
следовательно
для записи 0x4D*2+0=0x9A
для чтения 0x4D*2+1=0x9B
1
max_sk
80 / 7 / 2
Регистрация: 11.04.2015
Сообщений: 441
21.09.2018, 16:33  [ТС] 13
Правильно ли я понимаю, что если в даташит указано :

The peripheral registers have to be accessed by half-words (16 bits) or words (32 bits).

То записывать или считывать надо целиком сразу весь регистр, и что побитовые операции запрещены ?

Добавлено через 16 минут
Как мне узнать, был ли отправлен Start , если в даташит указано следующее :

Bit 0 SB: Start bit (Master mode)
0: No Start condition
1: Start condition generated.
– Set when a Start condition generated.
Cleared by software by reading the SR1 register followed by writing the DR register, or by
hardware when PE=0
0
Radikal_78
42 / 42 / 2
Регистрация: 20.11.2016
Сообщений: 96
21.09.2018, 20:28 14
посмотрел свой код

while ((!((FLAGS=I2C1->SR1)& SB))&& TimeOut){} ; - пока не установится флаг SB, программа будет
виснуть в этом цикле до истечения таймаута.

файл main.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#define SB       0x00000001
volatile uint8_t TimeOut;
uint32_t FLAGS;
uint8_t  Pause=25; 
.............................................
 
int AddrDat (uint8_t Bit)  // отправка адреса, Bit- чтение/запись
 {
   
   I2C1->CR1 |= I2C_CR1_START;                  // send START
 
  TimeOut=Pause;
  while ((!((FLAGS=I2C1->SR1)& SB))&& TimeOut){} ;         // wait flag SB  
  
  if (!TimeOut)                 
      { ....
        LCD_out("No START");  // если время истекло, а флага SB до сих пор не было,
                                           //  то вывожу на свой индикатор сообщение об ошибке
      while (1);
      } 
 
  I2C1->DR= Addres<<1 | Bit;   //
 
  TimeOut=Pause;
  while ((!((FLAGS=I2C1->SR1)& ADDR))&& TimeOut){} ;         // wait flag ADDR
   
  if (!TimeOut) 
     {                                              // если нет подтверждения адреса от Slave, то посылаем STOP 
     I2C1->CR1 |= I2C_CR1_STOP;   // send STOP 
     return 0; 
     } 
  return 1;  // если все нормально, возвращаем true
  }
файл stm32f4xx_it.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
extern volatile uint8_t TimeOut;
...............................................
 
 
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
  if (TimeOut != 0x0)
  
    TimeOut--;
 
 
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  HAL_SYSTICK_IRQHandler();
  /* USER CODE BEGIN SysTick_IRQn 1 */
 
  /* USER CODE END SysTick_IRQn 1 */
}
1
max_sk
80 / 7 / 2
Регистрация: 11.04.2015
Сообщений: 441
21.09.2018, 20:41  [ТС] 15
Radikal_78, спасибо за пример кода, но разве согласно даташит САМО чтение не обнуляет старт-бит ? Я так понял это место в даташит... :|
0
Radikal_78
42 / 42 / 2
Регистрация: 20.11.2016
Сообщений: 96
21.09.2018, 20:53 16
max_sk, при обращении к регистру мы получим установленный бит SB , а после окончания чтения регистра SR1, этот флаг будет сброшен
1
max_sk
80 / 7 / 2
Регистрация: 11.04.2015
Сообщений: 441
22.09.2018, 14:13  [ТС] 17
Таки старт бит не появляется. Интересно, в чем может быть причина ? Наверное без осциллоскопа и авометра не обойтись...
0
Radikal_78
42 / 42 / 2
Регистрация: 20.11.2016
Сообщений: 96
22.09.2018, 14:56 18
Может уже пора приобрести себе такую штуку?

https://mysku.ru/blog/aliexpress/39911.html

Такая есть у меня. И не парюсь, над вопросами куда у меня пропадают биты?)))
1
max_sk
80 / 7 / 2
Регистрация: 11.04.2015
Сообщений: 441
22.09.2018, 16:22  [ТС] 19
Спасибо. Заказал на местном сайте аналогичную. Будет дороже, но зато качество проверенное. Большое спасибо еще раз.
0
Radikal_78
42 / 42 / 2
Регистрация: 20.11.2016
Сообщений: 96
22.09.2018, 16:49 20
кстати, че за среда программирования такая?

Я в IAR Workbench пишу, проекты через Куб создаю.

Кстати, в твоем коде не заметил установки бита ACK.

I2C1->CR1|=I2C_CR1_ACK;
Если его не установить, STM32 не будет выдавать этот сигнал ACK и протокол обмена информацией между МК и датчиком будет нарушен.
1
22.09.2018, 16:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.09.2018, 16:49

Вопросы по I2C
Пытаюсь соединить mpu6050 c stm32f4discovery по I2C. Датчик находится на плате gy-87, там было...

Работа с I2C
Помогите проверить корректность функций работы с модулем I2C. volatile I2C_regs_t* const m_regs;...

msp430g2553+ I2C
Доброго времени суток, нужна помощь сmsp430g2553+ I2C. Проблема в том что я не вижу посылки заливая...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru