Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
19.12.2022, 17:34
|
|
Модератор
Регистрация: 04.08.2010
Адрес: Москва СЗАО
Сообщений: 11,246
Сказал спасибо: 11,165
Сказали Спасибо 3,854 раз(а) в 2,925 сообщении(ях)
|
Re: Акселерометр LIS302DL и atmega16a
Ostroukhovio, ЕМНИП там две скорости - 100kHz и 400kHz (DR=0 и DR=1), смотрите DS на сайте ST…
__________________
rtfm forever должно быть основой для каждого. Альтернатива грустна, поскольку метод слепого щенка успешно работает при весьма малом числе вариантов…
|
|
|
|
19.12.2022, 18:13
|
|
Частый гость
Регистрация: 19.12.2022
Сообщений: 12
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Акселерометр LIS302DL и atmega16a
На сотке тоже не фурычит.
На текущий момент такой код:
Настройка TWI под 100кГц:
Код:
|
TWBR = 0x20;//TWBR_VALUE;
TWSR = 0x00; |
Настройка акселя:
Код:
|
void ACEL_Config(void){
uint8_t CTRL_REG1 = 0x47;
ACEL_Write(0x20, CTRL_REG1);
} |
Чтение показаний акселя (регистр оси Z):
Код:
|
if(ACEL_Read(0x2d)›127){
fLED_Driver(1,3,1);
}else{
fLED_Driver(1,3,0);
} |
Функции TWI:
Код:
|
uint8_t ACEL_Write(uint8_t addr, uint8_t data){
I2C_Start(I2C_device_w);
I2C_Write(addr);
I2C_Write(data);
I2C_Stop();
}
uint8_t ACEL_Read(uint8_t addr){
uint8_t InData;
I2C_Start(I2C_device_w);
I2C_Write(addr);
I2C_Repeated_Start(I2C_device_r);
InData = I2C_Read_Nack();
//
I2C_Stop();
return InData;
}
uint8_t I2C_Start(char write_address)/* I2C start function */
{
uint8_t status; /* Declare variable */
TWCR=(1‹‹TWSTA)|(1‹‹TWEN)|(1‹‹TWINT); /* Enable TWI, generate START */
while(!(TWCR&(1‹‹TWINT))); /* Wait until TWI finish its current job */
TWDR=write_address; /* Write SLA+W in TWI data register */
TWCR=(1‹‹TWEN)|(1‹‹TWINT); /* Enable TWI & clear interrupt flag */
while(!(TWCR&(1‹‹TWINT))); /* Wait until TWI finish its current job */
}
uint8_t I2C_Repeated_Start(char read_address) /* I2C repeated start function */
{
uint8_t status; /* Declare variable */
//TWCR=(1‹‹TWSTA)|(1‹‹TWEN)|(1‹‹TWINT);/* Enable TWI, generate start */
//while(!(TWCR&(1‹‹TWINT))); /* Wait until TWI finish its current job */
/* Return 0 for repeated start condition fail */
TWDR=read_address; /* Write SLA+R in TWI data register */
TWCR=(1‹‹TWEN)|(1‹‹TWINT); /* Enable TWI and clear interrupt flag */
while(!(TWCR&(1‹‹TWINT))); /* Wait until TWI finish its current job */
}
uint8_t I2C_Write(char data) /* I2C write function */
{
uint8_t status; /* Declare variable */
TWDR=data; /* Copy data in TWI data register */
TWCR=(1‹‹TWEN)|(1‹‹TWINT); /* Enable TWI and clear interrupt flag */
while(!(TWCR&(1‹‹TWINT))); /* Wait until TWI finish its current job */
}
char I2C_Read_Ack(void) /* I2C read ack function */
{
TWCR=(1‹‹TWEN)|(1‹‹TWINT)|(1‹‹TWEA); /* Enable TWI, generation of ack */
while(!(TWCR&(1‹‹TWINT))); /* Wait until TWI finish its current job */
return TWDR; /* Return received data */
}
char I2C_Read_Nack(void) /* I2C read nack function */
{
TWCR=(1‹‹TWEN)|(1‹‹TWINT); /* Enable TWI and clear interrupt flag */
while(!(TWCR&(1‹‹TWINT))); /* Wait until TWI finish its current job */
return TWDR; /* Return received data */
}
void I2C_Stop(void) /* I2C stop function */
{
TWCR=(1‹‹TWSTO)|(1‹‹TWINT)|(1‹‹TWEN);/* Enable TWI, generate stop */
while(TWCR&(1‹‹TWSTO)); /* Wait until stop condition execution */
} |
Либо неверный код I2c записи данных в аксель, либо что-то не то с самими настройками акселя.
Последний раз редактировалось Ostroukhovio; 19.12.2022 в 18:20.
|
|
|
|
19.12.2022, 18:26
|
|
Модератор
Регистрация: 04.08.2010
Адрес: Москва СЗАО
Сообщений: 11,246
Сказал спасибо: 11,165
Сказали Спасибо 3,854 раз(а) в 2,925 сообщении(ях)
|
Re: Акселерометр LIS302DL и atmega16a
Ostroukhovio, таки на Вашем месте я бы взял Raspberry PI или что-то похожее и провел обкатку обмена с чипом в требуемом объеме, а дальше уже весь найденный обмен перенес на целевое устройство с пошаговым приближением к требуемому результату…
В такой конфигурации можно и обмен МК настроить по I2C…
Сейчас у Вас разрозненный набор уравнений с несвязанными неизвестными на столе - нужно найти решение для его приведения к системе и дальше все уже встанет на свои места… - заставить работать обмен по I2C на 100kHz (или 400kHz при необходимости и возможности у МК)
- обеспечить корректную инициализацию акселерометра
- добиться установки уровней отслеживания и получить прерывания
- добиться получения корректных данных об ускорениях по осям
- преобразовать полученные данные по ускорениям в требуемое для задачи значение
- …
PS Особо учтите - акселерометр сыпет достаточно мусора по осям и нужен алгоритм по обработке считанного для получения уверенной корреляции с физическими флюктуациями объекта в реальном мире… Как пример - вполне уверенная работа акселерометра, как акустического датчика для шумов выше порога его разрешения…
PPS Если что, страница LIS320DL на сайте ST https://www.st.com/en/mems-and-sensors/lis302dl.html
Там есть все нужные материалы…
Ну и прочитать материалы по работе I2C у выбранного МК на сайте microchip тоже не помешает - https://www.microchip.com/en-us/product/ATMEGA16A
Эта работа ведет к созданию структурированного представления…
__________________
rtfm forever должно быть основой для каждого. Альтернатива грустна, поскольку метод слепого щенка успешно работает при весьма малом числе вариантов…
Последний раз редактировалось mike-y-k; 19.12.2022 в 18:41.
|
|
|
|
19.12.2022, 23:17
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 6,789
Сказал спасибо: 2,912
Сказали Спасибо 3,120 раз(а) в 2,111 сообщении(ях)
|
Re: Акселерометр LIS302DL и atmega16a
Сообщение от mike-y-k
|
заставить работать обмен по I2C на 100kHz (или 400kHz при необходимости и возможности у МК)
|
С обменом - всё в порядке (верный ответ по адресу Who_Am_I):
Сообщение от Ostroukhovio
|
На данный момент считывается только имя акселя 0х3b
|
Не получается запустить преобразование и/или верно вычитать данные из OutZ:
Сообщение от Ostroukhovio
|
Но у меня судя по коду регистр всегда возвращает значение меньше 127.
|
Ostroukhovio, пляшите вокруг CTRL_REG1. Запишите в него нужное значение (например 0x47) с обязательным получением Ack от акселерометра после I2C_Write() (раздел 5.1.1).
Сообщение от ForcePoint
|
Кстати, алгоритм линеен и не учитывает, например, отсутствие ACK от ведомого после "***_Start(I2C_device_*)".
|
__________________
Экзорцист 40-го уровня.
Последний раз редактировалось ForcePoint; 19.12.2022 в 23:27.
|
|
|
Сказали "Спасибо" ForcePoint
|
|
|
19.12.2022, 23:49
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.10.2007
Сообщений: 2,760
Сказал спасибо: 1,106
Сказали Спасибо 1,037 раз(а) в 569 сообщении(ях)
|
Re: Акселерометр LIS302DL и atmega16a
Я правильно понимаю, что тс отлаживает интерфейс без логического анализатора и даже двухлучевого осциллографа?
или где картинки?
|
|
|
|
20.12.2022, 00:13
|
|
Модератор
Регистрация: 04.08.2010
Адрес: Москва СЗАО
Сообщений: 11,246
Сказал спасибо: 11,165
Сказали Спасибо 3,854 раз(а) в 2,925 сообщении(ях)
|
Re: Акселерометр LIS302DL и atmega16a
makakus, поскольку про приборы так ничего и не появилось - сильно похоже на то
Хотя было про pullup сопротивления и фронты, но это можно и одноканальным увидеть поочередно…
ForcePoint, на тему обмена в порядке - без подтверждений ЛА с анализом квитирования и расшифровкой такое имеет место быть и при проблемах с обменом…
__________________
rtfm forever должно быть основой для каждого. Альтернатива грустна, поскольку метод слепого щенка успешно работает при весьма малом числе вариантов…
|
|
|
|
20.12.2022, 08:41
|
|
Частый гость
Регистрация: 19.12.2022
Сообщений: 12
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Акселерометр LIS302DL и atmega16a
Всем привет. Из оборудования только китайский осцилл на 100Мгц. По нему собственно и смотрел на форнты сигнала.
Правильно я понимаю, что если я всеже получаю 0х3b то это значит что я читаю аксель верно, но не факт что функция записи в аксель верная?
Цитата:
|
Ostroukhovio, пляшите вокруг CTRL_REG1. Запишите в него нужное значение (например 0x47) с обязательным получением Ack от акселерометра после I2C_Write() (раздел 5.1.1).
|
Функция I2C_Read_Ack()? Про нее речь? Вызывать после каждого вызова функции I2C_Write?
Последний раз редактировалось Ostroukhovio; 20.12.2022 в 08:49.
|
|
|
|
20.12.2022, 11:45
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.02.2005
Адрес: Минск, Беларусь
Сообщений: 7,765
Сказал спасибо: 2,667
Сказали Спасибо 2,635 раз(а) в 1,948 сообщении(ях)
|
Re: Акселерометр LIS302DL и atmega16a
Ostroukhovio, а можно фото конструкции? На предмет длины этой самой шины I2C - или уверены, что с ней всё в порядке (включая блокировочные конд-ры по питанию)
И уменьшите подтягивающие резисторы на шине до около 2 кОм на всякий случай.
|
|
|
|
20.12.2022, 12:53
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 6,789
Сказал спасибо: 2,912
Сказали Спасибо 3,120 раз(а) в 2,111 сообщении(ях)
|
Re: Акселерометр LIS302DL и atmega16a
Сообщение от Ostroukhovio
|
Функция I2C_Read_Ack()? Про нее речь?
|
Нет, конечно. Код с тырнета что ли?
Должно быть примерно так:
Код:
|
uint8_t I2C_Write(char data) /* I2C write function */
{
uint8_t status; /* Declare variable */
TWDR=data; /* Copy data in TWI data register */
TWCR=(1‹‹TWEN)|(1‹‹TWINT); /* Enable TWI and clear interrupt flag */
while(!(TWCR&(1‹‹TWINT))); /* Wait until TWI finish its current job */
status = TWSR & 0xF8;
if((status & 0x20) | (status & 0x30) | (status & 0x38)) { // Ошибка при передаче
// Что-то сделать для корректировки
}
} |
См. "Table 20-2. Status Codes for Master Transmitter Mode" в документации на ATmega16.
__________________
Экзорцист 40-го уровня.
Последний раз редактировалось ForcePoint; 20.12.2022 в 15:52.
Причина: Добавил использование переменной status и её маскирование 0xF8.
|
|
|
|
20.12.2022, 20:44
|
|
Частый гость
Регистрация: 19.12.2022
Сообщений: 12
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Акселерометр LIS302DL и atmega16a
В параллель с вашим ответом сделал тоже самое. Но как оказалось дурнина вообще была в другом)) не тот адрес акселя стоял)) Поправил - данные с оси Z побежали.
Но вот почему-то в режиме кликов работать не хочет:
Код:
|
void ACEL_Config(void){
uint8_t CTRL_REG1 = 0b0100111;
ACEL_Write(0x20, CTRL_REG1);
uint8_t CTRL_REG2 = 0b0000000;
ACEL_Write(0x21, CTRL_REG2);
uint8_t CTRL_REG3 = 0b10111111;
ACEL_Write(0x22, CTRL_REG3);
uint8_t CLICK_CFG = 0b01111111;
ACEL_Write(0x38, CLICK_CFG);
uint8_t CLICK_THSXY = 0xAA;
ACEL_Write(0x3B, CLICK_THSXY);
uint8_t CLICK_THSZ = 0x0A;
ACEL_Write(0x3C, CLICK_THSZ);
//uint8_t FF_WU_CFG_1 = 0x4C;
//ACEL_Write(0x30, FF_WU_CFG_1);
uint8_t CLICK_TimeLimit = 0x03;
ACEL_Write(0x3D, CLICK_TimeLimit);
uint8_t CLICK_Latency = 0x7F;
ACEL_Write(0x3E, CLICK_Latency);
uint8_t CLICK_Window = 0x7F;
ACEL_Write(0x3F, CLICK_Window);
ACEL_Read(0x23);
ACEL_Read(0x27);
ACEL_Read(0x39);
} |
Хотя аксель настроен выдавать прерывания низкого уровня с push-pull на выводах.
Последний раз редактировалось Ostroukhovio; 20.12.2022 в 21:21.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 00:15.
|
|