Например TDA7294

Форум РадиоКот • Просмотр темы - Работа с EEPROM под FreeRTOS
Форум РадиоКот
Здесь можно немножко помяукать :)



Текущее время: Ср июл 17, 2019 21:14:10

Часовой пояс: UTC + 3 часа [ Летнее время ]


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Работа с EEPROM под FreeRTOS
СообщениеДобавлено: Пт апр 26, 2019 14:21:27 
Открыл глаза

Зарегистрирован: Чт мар 22, 2012 21:28:49
Сообщений: 67
Рейтинг сообщения: 0
Всем привет! Может кто сталкивался... Короче, работаю с МК STM32F103C8, кроме всего прочего прикрутил к нему микросхему EEPROM M24C08 (работает по I2C). Написал под неё две функции на запись и чтение по произвольному адресу. Потестировал - работает. Попробовал использовать данные функции в программе под FreeRTOS и тут-то очень удивился - программа зависает уже на этапе отправки старт бита на I2C. Т.е. если подробнее: внутри тела одного из тасков вызываю функцию, например, чтения одного байта из EEPROM. Функция начинает работать, отправляет старт бит на I2C и ждет выставления флага перехода в режим Master, но дождаться его не может. Интересный факт: если в режиме отладки остановить выполнение программы и выполнять функцию пошагово, то все работает. Если вызвать те же функции НЕ в теле таска, тоже все работает на УРА.

Пробовал поиграться с частотой системных тиков - не помогло. Функция чтения ниже.

void Recieve_from_I2C(char* bufer, int address, int byte_count)
{
char addr;

for(int i=0; i<byte_count; i++)
{
do{
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

addr = 0xA0 | ((address & 0x300) >> 7);

I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter);
delay_us(90);}
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

addr = address;

I2C_SendData(I2C1, i+addr);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

addr = 0xA0 | ((address & 0x300) >> 7);

I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
*(bufer+i) = I2C_ReceiveData(I2C1);

I2C_GenerateSTOP(I2C1, ENABLE);
}

}

Таск:
void Led_Task(void *pvParameters)
{
char a=0;

Send_to_I2C(&a, 0x00, 1);
Recieve_from_I2C(bufer, 0x10, 11);

while(1)
{
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
vTaskDelay(2000);
GPIO_SetBits(GPIOC, GPIO_Pin_13);
vTaskDelay(2000);
}
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с EEPROM под FreeRTOS
СообщениеДобавлено: Вс апр 28, 2019 17:16:46 
Открыл глаза
Аватар пользователя

Карма: 5
Рейтинг сообщений: 15
Зарегистрирован: Пн июл 04, 2016 17:51:22
Сообщений: 72
Откуда: Россия, Омск
Рейтинг сообщения: 0
1. И самое важное. Есть блок [code] [/code], в который принято вставлять код проекта, чтобы его не ломало парсером.

2. Вызывают ли разные потоки одни и те же функции доступа к микросхеме памяти? Может ли это происходить одновременно? Происходит ли хоть один успешный доступ к внешней памяти при работе RTOS?

3. На каком моменте зависает при запуске из-под RTOS?


Вернуться наверх
 
JLCPCB, всего $2 за прототип печатной платы! Цвет - любой!

Отличное качество, подтвержденное более чем 600,000 пользователей! Более 10,000 заказов в день.

Зарегистрируйтесь и получите два купона по 5$ каждый:https://jlcpcb.com/quote

Не в сети
 Заголовок сообщения: Re: Работа с EEPROM под FreeRTOS
СообщениеДобавлено: Пн апр 29, 2019 13:35:59 
Открыл глаза

Зарегистрирован: Чт мар 22, 2012 21:28:49
Сообщений: 67
Рейтинг сообщения: 0
AlanDrakes писал(а):
2. Вызывают ли разные потоки одни и те же функции доступа к микросхеме памяти? Может ли это происходить одновременно? Происходит ли хоть один успешный доступ к внешней памяти при работе RTOS?


Нет - не вызывают. Не одного успешного доступа не происходит.

AlanDrakes писал(а):
3. На каком моменте зависает при запуске из-под RTOS?

При первом же обращении к памяти

Код:
void Recieve_from_I2C(char* bufer, int address, int byte_count)
{
char addr;

for(int i=0; i<byte_count; i++)
{
do{
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

addr = 0xA0 | ((address & 0x300) >> 7);

I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter);
delay_us(90);}
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

addr = address;

I2C_SendData(I2C1, i+addr);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

addr = 0xA0 | ((address & 0x300) >> 7);

I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
*(bufer+i) = I2C_ReceiveData(I2C1);

I2C_GenerateSTOP(I2C1, ENABLE);
}

}

Таск:
void Led_Task(void *pvParameters)
{
char a=0;

Send_to_I2C(&a, 0x00, 1);
Recieve_from_I2C(bufer, 0x10, 11);

while(1)
{
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
vTaskDelay(2000);
GPIO_SetBits(GPIOC, GPIO_Pin_13);
vTaskDelay(2000);
}
}


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $88 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay
Не в сети
 Заголовок сообщения: Re: Работа с EEPROM под FreeRTOS
СообщениеДобавлено: Пн апр 29, 2019 14:23:07 
Модератор
Аватар пользователя

Карма: 77
Рейтинг сообщений: 782
Зарегистрирован: Пт мар 19, 2010 00:09:57
Сообщений: 4038
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Стека для задачи нормально выделили ?

_________________
Я мненью вашему вращенье придавал, а осью был - мой детородный орган.


Вернуться наверх
 
Плавкие предохранители LittelFuse. Грамотный подбор

Выбор оптимального плавкого предохранителя требует учета многих параметров. Для упрощения выбора оптимального предохранителя и автоматизации расчетов Littelfuse предлагает онлайн-утилиту. Подробнее>>
Не в сети
 Заголовок сообщения: Re: Работа с EEPROM под FreeRTOS
СообщениеДобавлено: Пн апр 29, 2019 17:37:12 
Открыл глаза
Аватар пользователя

Карма: 5
Рейтинг сообщений: 15
Зарегистрирован: Пн июл 04, 2016 17:51:22
Сообщений: 72
Откуда: Россия, Омск
Рейтинг сообщения: 0
Нет - не вызывают. Не одного успешного доступа не происходит.

AlanDrakes писал(а):
3. На каком моменте зависает при запуске из-под RTOS?

При первом же обращении к памяти


Уже хорошо. Но всё же, хотелось бы увидеть, на какой именно инструкции происходит останов.

У меня из предположений сейчас:
1. Проблема с запуском шины из-за неправильного начального состояния (нед единиц на проводах SDA/SCL при генерации START).
2. Нет ответа от устройства, но ожидается байт
3. Нет начала работы модуля (не инициализирован модуль I2C)
4. Не инициализирован GPIO порт (аналогично, будет висеть на START)

Кстати, это весь код проекта? Инициализацию периферии производите ДО запуска RTOS?


Вернуться наверх
 
Немногим дороже дискретного решения: новое поколение импульсных стабилизаторов Mornsun

Практически во всех радиоэлектронных устройствах массово применяются линейные понижающие стабилизаторы напряжения типа КРЕН в корпусе TO220 (другое обозначение – 78хх) и им подобные для формирования основного напряжения питания схемы.
Данные стабилизаторы позволяют без особых затрат получить нужное для каскада или узла схемы напряжение, если устройство питается от внешнего источника с более высоким напряжением. Для этого требуются… Подробнее>>
Не в сети
 Заголовок сообщения: Re: Работа с EEPROM под FreeRTOS
СообщениеДобавлено: Вт апр 30, 2019 11:38:11 
Открыл глаза

Зарегистрирован: Чт мар 22, 2012 21:28:49
Сообщений: 67
Рейтинг сообщения: 0
AlanDrakes писал(а):
Уже хорошо. Но всё же, хотелось бы увидеть, на какой именно инструкции происходит останов.

I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

Вот из цикла while не выходит. Но если остановить выполнение и в отладочном режиме ручками пошагово выполнить, то выходит и нормально отрабатывает вся функция шаг за шагом. Как только опять пускаешь на выполнение останавливается.

AlanDrakes писал(а):
2. Нет ответа от устройства, но ожидается байт


Возможно, но почему это проявляется именно под FreeRTOS. Я же говорю, в обычном коде ТЕ же функции отрабатывают на УРА. Остальные пункты проверял. Все нормально, опять же не работает именно под RTOS. Тайминги какие-то что ли нарушаются....

Инициализацию периферии провожу до запуска шедуллера.

Добавлено after 3 minutes 34 seconds:
Стека для задачи нормально выделили ?


Ды пробовал уже увеличивать - ни фига не помогло :(


Вернуться наверх
 


Не в сети
 Заголовок сообщения: Re: Работа с EEPROM под FreeRTOS
СообщениеДобавлено: Чт май 02, 2019 19:21:29 
Открыл глаза
Аватар пользователя

Карма: 5
Рейтинг сообщений: 15
Зарегистрирован: Пн июл 04, 2016 17:51:22
Сообщений: 72
Откуда: Россия, Омск
Рейтинг сообщения: 0
Если код ломается при добавлении RTOS - значит код имеет проблемы.

Не люблю я этот ваш HAL.. Попробуйте на регистрах вот так:
Код:
uint8_t I2C_Read8(uint8_t DevAddr, uint8_t RegAddr) {
   uint8_t value;
   (void) (I2C1->ISR);
   I2C1->TXDR = RegAddr;
   I2C1->ICR = I2C_ICR_STOPCF;
   I2C1->CR2 = (I2C_CR2_AUTOEND | DevAddr | (1<<16) | I2C_CR2_START);
   while (!(I2C1->ISR & (I2C_ISR_TXE | I2C_ISR_NACKF))) {};
   if (I2C1->ISR & I2C_ISR_NACKF) {
      I2C1->ICR = I2C_ICR_STOPCF | I2C_ICR_NACKCF;
      vTaskDelay(1); // Время на завершение работы порта (обычно не требуется, но это перестраховка)
      return -1;
   };
   I2C1->ICR = 0x3F38;
   I2C1->CR2 = (I2C_CR2_AUTOEND | DevAddr | I2C_CR2_RD_WRN | (1<<16) | I2C_CR2_START);
   while (!(I2C1->ISR & I2C_ISR_RXNE)) {};
   value = (I2C1->RXDR);
   return value;
};
void I2C_Write8(uint8_t DevAddr, uint8_t RegAddr, uint8_t RegValue) {
   I2C1->TXDR = RegAddr;
   I2C1->ICR = 0x3F38;
   I2C1->CR2 = (DevAddr | (2<<16) | I2C_CR2_START);
   while (!(I2C1->ISR & I2C_ISR_TXE)) {};
   I2C1->TXDR = RegValue;
   while (!(I2C1->ISR & I2C_ISR_TXE)) {};
   I2C1->CR2 = I2C_CR2_STOP;
};

Здесь у меня процедуры чтения регистра и записи регистра. Оба варианта - 8-ми битные. В условиях RTOS не сбоят. Во всяком случае, у меня.
Если не заработает - проверяйте остальное - не теряется ли тактирование, правильная ли подтяжка на порту.
Да в конце концов, возьмите самый дешёвый китайский логический анализатор с Али (logic analyzer). Он действительно помогает разобраться с проблемой.


Вернуться наверх
 


Не в сети
 Заголовок сообщения: Re: Работа с EEPROM под FreeRTOS
СообщениеДобавлено: Пн май 06, 2019 15:45:27 
Открыл глаза

Зарегистрирован: Чт мар 22, 2012 21:28:49
Сообщений: 67
Рейтинг сообщения: 0
Спасибо за ответы!!!! Попробую разобраться


Вернуться наверх
 
Prist.ru предлагает скидку всем частным лицам при покупке приборов АКИП, GW Instek, APPA (кроме осциллографов АКИП-4115/1А, GDS-71102)!

Интересные новинки уже на складе:

Осциллограф АКИП-4126Е

Многоканальные источники питания серии GPP

Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на форуме

Сейчас этот форум просматривают: А. Г. Лукашенко., maks740, ozzy и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y