06.09.2016, 19:21
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
AT24C32 + STM32F030F4
Добрый день. Пробую подключить епром к МК. Нашел готовую либу. Не компилит из-за двух строк. Немогу понять что нужно?
PHP код:
|
UserSource\main.c(606): error: #167: argument of type "unsigned int" is incompatible with parameter of type "uint8_t *"
|
вот кусок весь
PHP код:
|
uint8_t I2C_Temp=25,I2C_Read=0;
#define I2C_BUS I2C1
// Вспомогательные переменные
typedef enum _I2C_Direction {I2C_Transmitter=0, I2C_Receiver=1} I2C_Direction;
/*
Битовые смещения для настройки разных регистров
Чтобы не использовать в коде магические числа, и код был читаемым
Например:
I2C-›CR2 |= 1‹‹I2C_OFFSET_CR2_NBYTES; // Здесь понятно, что передаётся 1 байт
I2C-›CR2 |= 1‹‹16; // Здесь возникает путаница, то ли 1 байт, то ли 16
*/
#define I2C_OFFSET_TIMINGR_SCLL 0
#define I2C_OFFSET_TIMINGR_SCLH 8
#define I2C_OFFSET_TIMINGR_SDADEL 16
#define I2C_OFFSET_TIMINGR_SCLDEL 20
#define I2C_OFFSET_TIMINGR_PRESC 28
#define I2C_OFFSET_CR2_NBYTES 16
/*
Выполняет первичную настройку шины.
Настраивает порты, альтернативные функции.
Настраивает тайминги для работы шины.
*/
void I2C_Initialization (void)
{
// Тактирование GPIO не включаю, т.к. оно уже включено в начале программы
RCC-›APB1ENR |= RCC_APB1ENR_I2C1EN; // Включаю тактирование I2C
// Настройка ног PB6, PB7
GPIOB-›MODER |= GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1; // Режим альтернативной функции
GPIOB-›OTYPER |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7; // Открытый коллектор
GPIOB-›OSPEEDR |= GPIO_OSPEEDR_OSPEEDR6 | GPIO_OSPEEDR_OSPEEDR7; // Максимальная скорость
// Выбор альтернативной функции
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1); // I2C1_SCL
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1); // I2C1_SDA
I2C_BUS-›CR1 &= ~I2C_CR1_PE; // Отключаю I2C
while (I2C_BUS-›CR1 & I2C_CR1_PE) {}; // Жду пока отключится
// Частота тактирования модуля I2C = 48 МГц
// Частота шины I2C = 100 kHz
// Настраиваю тайминги
I2C_BUS-›TIMINGR |= \
(0xB ‹‹ I2C_OFFSET_TIMINGR_PRESC)|\
(0x13 ‹‹ I2C_OFFSET_TIMINGR_SCLL)|\
(0xF ‹‹ I2C_OFFSET_TIMINGR_SCLH)|\
(0x4 ‹‹ I2C_OFFSET_TIMINGR_SCLDEL)|\
(0x2 ‹‹ I2C_OFFSET_TIMINGR_SDADEL);
I2C_BUS-›CR1 |= I2C_CR1_PE; // Включаю I2C
while ((I2C_BUS-›CR1 & I2C_CR1_PE)==0) {}; // Жду пока включится
}
/*
Это служебная функция, использовать её не нужно.
Устанавливает направление данных - приём или передача.
Задаёт объём пересылаемых данных.
Задаёт адрес ведомого устройства.
Выдаёт старт на шину.
Параметры:
Direction - направление (0-отправка, 1-приём)
Adress - адрес ведомого устройства
Size - размер данных (от 1 до 255 байт)
*/
void I2C_Start_Direction_Adress_Size (I2C_Direction Direction, uint8_t Adress, uint8_t Size)
{
//I2C_BUS-›CR2 &= ~I2C_CR2_AUTOEND; // Выдавать стоп вручную
//I2C_BUS-›CR2 &= ~I2C_CR2_RELOAD; // Не использовать режим перезагрузки
if (Direction) I2C_BUS-›CR2 |= I2C_CR2_RD_WRN; // Режим приёма
else I2C_BUS-›CR2 &= ~I2C_CR2_RD_WRN; // Режим передачи
I2C_BUS-›CR2 &= ~I2C_CR2_NBYTES; // Очистить размер данных
I2C_BUS-›CR2 |= Size‹‹I2C_OFFSET_CR2_NBYTES; // Установить размер данных
I2C_BUS-›CR2 &= ~I2C_CR2_SADD; // Очистить адрес ведомого устройства
I2C_BUS-›CR2 |= Adress; // Установить адрес ведомого устройства
I2C_BUS-›CR2 |= I2C_CR2_START; // Выдать старт на шину
while ((I2C_BUS-›ISR & I2C_ISR_BUSY)==0) {}; // Ожидать выдачу старта
}
/*
Это служебная функция, использовать её не нужно.
Выдаёт стоп на шину.
Очищает флаги.
Проверяет наличие ошибок, очищает флаги ошибок.
*/
void I2C_Stop (void)
{
I2C_BUS-›CR2 |= I2C_CR2_STOP; // Выдать стоп на шину
while (I2C_BUS-›ISR & I2C_ISR_BUSY) {}; // Ожидать выдачу стопа
// Очищаю флаги - необходимо для дальнейшей работы шины
I2C_BUS-›ICR |= I2C_ICR_STOPCF; // STOP флаг
I2C_BUS-›ICR |= I2C_ICR_NACKCF; // NACK флаг
// Если есть ошибки на шине - очищаю флаги
if (I2C_BUS-›ISR & (I2C_ISR_ARLO | I2C_ISR_BERR))
{
I2C_BUS-›ICR |= I2C_ICR_ARLOCF;
I2C_BUS-›ICR |= I2C_ICR_BERRCF;
}
}
/*
Выполняет транзакцию записи Size байт в регистр Register по адресу Adress.
Параметры:
Adress - адрес ведомого устройства
Register - регистр, в который хотим передать данные
Data - указывает откуда брать данные для передачи
Size - сколько байт хотим передать (от 1 до 254)
Возвращает:
1 - если данные успешно переданы
0 - если произошла ошибка
*/
uint8_t I2C_Write_Transaction (uint8_t Adress, uint8_t Register, uint8_t *Data, uint8_t Size)
{
uint8_t Count=0; // Счётчик успешно переданных байт
// Старт
I2C_Start_Direction_Adress_Size (I2C_Transmitter, Adress, 1+Size);
// Сейчас либо I2C запросит первый байт для отправки,
// Либо взлетит NACK-флаг, говорящий о том, что микросхема не отвечает.
// Если взлетит NACK-флаг, отправку прекращаем.
while ((((I2C_BUS-›ISR & I2C_ISR_TXIS)==0) && ((I2C_BUS-›ISR & I2C_ISR_NACKF)==0)) && (I2C_BUS-›ISR & I2C_ISR_BUSY)) {};
if (I2C_BUS-›ISR & I2C_ISR_TXIS) I2C_BUS-›TXDR=Register; // Отправляю адрес регистра
// Отправляем байты до тех пор, пока не взлетит TC-флаг.
// Если взлетит NACK-флаг, отправку прекращаем.
while ((((I2C_BUS-›ISR & I2C_ISR_TC)==0) && ((I2C_BUS-›ISR & I2C_ISR_NACKF)==0)) && (I2C_BUS-›ISR & I2C_ISR_BUSY))
{
if (I2C_BUS-›ISR & I2C_ISR_TXIS) I2C_BUS-›TXDR=*(Data+Count++); // Отправляю данные
}
I2C_Stop();
if (Count == Size) return 1; return 0;
}
/*
Выполняет транзакцию чтения Size байт из регистра Register по адресу Adress.
Параметры:
Adress - адрес ведомого устройства
Register - регистр, из которого хотим принять данные
Data - указывает куда складывать принятые данные
Size - сколько байт хотим принять (от 1 до 255)
Возвращает:
1 - если данные успешно приняты
0 - если произошла ошибка
*/
uint8_t I2C_Read_Transaction (uint8_t Adress, uint8_t Register, uint8_t *Data, uint8_t Size)
{
uint8_t Count=0; // Счётчик успешно принятых байт
// Старт
I2C_Start_Direction_Adress_Size (I2C_Transmitter, Adress, 1);
// Сейчас либо I2C запросит первый байт для отправки,
// Либо взлетит NACK-флаг, говорящий о том, что микросхема не отвечает.
// Если взлетит NACK-флаг, отправку прекращаем.
while ((((I2C_BUS-›ISR & I2C_ISR_TC)==0) && ((I2C_BUS-›ISR & I2C_ISR_NACKF)==0)) && (I2C_BUS-›ISR & I2C_ISR_BUSY))
{
if (I2C_BUS-›ISR & I2C_ISR_TXIS) I2C_BUS-›TXDR = Register; // Отправляю адрес регистра
}
// Повторный старт
I2C_Start_Direction_Adress_Size (I2C_Receiver, Adress, Size);
// Принимаем байты до тех пор, пока не взлетит TC-флаг.
// Если взлетит NACK-флаг, приём прекращаем.
while ((((I2C_BUS-›ISR & I2C_ISR_TC)==0) && ((I2C_BUS-›ISR & I2C_ISR_NACKF)==0)) && (I2C_BUS-›ISR & I2C_ISR_BUSY))
{
if (I2C_BUS-›ISR & I2C_ISR_RXNE) *(Data+Count++) = I2C_BUS-›RXDR; // Принимаю данные
}
I2C_Stop();
if (Count == Size) return 1; return 0;
}
int main(void)
{
RCC_DeInit();
PLL52();
RCC_AdjustHSICalibrationValue(19);
Init_PORT();
InitTimer3();
ADC_continious_ini();
while (1)
{
I2C_Write_Transaction( 0xA0, 2, I2C_Temp, 1);//ОШИБКА
I2C_Read = I2C_Read_Transaction (0xA0, 2, I2C_Read, 1);//ОШИБКА
}
}
|
Подскажите что сделать чтобы ошибка ушла?
|
|
|
|
06.09.2016, 19:50
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.02.2008
Сообщений: 1,772
Сказал спасибо: 123
Сказали Спасибо 599 раз(а) в 416 сообщении(ях)
|
Re: AT24C32 + STM32F030F4
Для начала перевести сообщение. Оно говорит, что аргумент с типом "unsigned int" не совместим с типом параметра "uint8_t *". То есть с указателем. В I2C_Read_Transaction и в I2C_Write_Transaction Вы передаете функции саму переменную, а надо указатель на нее. Это сами переменные, а надо создать указатели на них, то есть на их адреса. Так я считаю.
|
|
|
|
06.09.2016, 20:19
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: AT24C32 + STM32F030F4
andries5, напишите плиз строчку с примером... Я с указателями еще не подружился...
|
|
|
|
06.09.2016, 20:52
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: AT24C32 + STM32F030F4
Сообщение от AR_Favorit
|
А про указатели лучше узнавать в любом учебнике или разъяснялке по С, их море в сети)
|
читал, но так и не понял. Надо только на примере. С указателем чуток разобрался. Поставил знак & перед переменной. Ошибка ушла. Но в ините я исправил еще ножки портов. Не те стояли.
Теперь зацикливается тут I2C_Write_Transaction
PHP код:
|
// Отправляем байты до тех пор, пока не взлетит TC-флаг.
// Если взлетит NACK-флаг, отправку прекращаем.
while ((((I2C_BUS-›ISR & I2C_ISR_TC)==0) && ((I2C_BUS-›ISR & I2C_ISR_NACKF)==0)) && (I2C_BUS-›ISR & I2C_ISR_BUSY))
{
if (I2C_BUS-›ISR & I2C_ISR_TXIS) I2C_BUS-›TXDR=*(Data+Count++); // Отправляю данные
}
|
Почему может быть зацикливание...? Как то на атмеге с первого раза заработало ))
|
|
|
|
06.09.2016, 20:54
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,901
Сказал спасибо: 499
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: AT24C32 + STM32F030F4
Я в том посте ошибся - не увидел, что есть операции инкремента указателя в теле функций (при которых ни использовать имя массива как указатель нельзя, ни передавать адрес переменной вместо указателя на нее).
Так что можно только так:
Код:
|
uint8_t I2C_Temp=25;
uint8_t I2C_Read=0;
uint8_t* pI2C_Temp=&I2C_Temp; //Указатель, которому присвоено значение адреса I2C_Temp
uint8_t* pI2C_Read=&I2C_Read; //Указатель, которому присвоено значение адреса I2C_Read |
В функции передаете pI2C_Temp и pI2C_Read вместо I2C_Temp и I2C_Read соответственно.
Если захочется передавать и принимать за один вызов функции больше одного байта - I2C_Temp и I2C_Read должны быть объявлены массивами, и присвоение адреса указателю будет выглядеть даже проще:
Код:
|
uint8_t I2C_Temp[10];
uint8_t I2C_Read[10];
uint8_t* pI2C_Temp=I2C_Temp; //Указатель, которому присвоено значение адреса I2C_Temp
uint8_t* pI2C_Read=I2C_Read; //Указатель, которому присвоено значение адреса I2C_Read |
Последний раз редактировалось AR_Favorit; 06.09.2016 в 20:57.
|
|
|
|
06.09.2016, 20:59
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: AT24C32 + STM32F030F4
может у кого есть примеры на SPL по шине I2C дайте плиз чтобы разобраться.....?
|
|
|
|
06.09.2016, 21:03
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,901
Сказал спасибо: 499
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: AT24C32 + STM32F030F4
Стопудово на сайте ST в примерах к платам Discovery найдутся)
Хм. Нету((
Последний раз редактировалось AR_Favorit; 06.09.2016 в 21:09.
|
|
|
|
06.09.2016, 22:22
|
|
Заблокирован
Регистрация: 22.04.2014
Сообщений: 0
Сказал спасибо: 15
Сказали Спасибо 366 раз(а) в 284 сообщении(ях)
|
Re: AT24C32 + STM32F030F4
|
|
|
|
06.09.2016, 22:35
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: AT24C32 + STM32F030F4
STM32F0, зачем мне StdPeriph??? Я уже столько тем создавал по F030 и что до сих пор не скачал это думаете?? )))) Сейчас скачал апноут для расчета TIMINGR регистра. Без оскорблений оно вижу не уродилося.....
|
|
|
|
06.09.2016, 23:44
|
|
Заблокирован
Регистрация: 22.04.2014
Сообщений: 0
Сказал спасибо: 15
Сказали Спасибо 366 раз(а) в 284 сообщении(ях)
|
Re: AT24C32 + STM32F030F4
Тупые халявщики и невконякормщики.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 18:29.
|
|