Danil
26.05.2017
17:44:27
Для-программиста
Для железо оно принимать нули может
И отправлять нули
Для программиста, на это кладется болт
Google
Danil
26.05.2017
17:45:59
Сказали правильно, но тебя это не касается
Serg
26.05.2017
17:46:10
SPI_I2S_SendData(SPIx, data);
// Зависнуть тут не может, потому что SPI всё равно отработает посылку
while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY));
// В силу особенностей организации SPI на STM32, нельзя только писать,
// после любой записи нужно прочитать, дополнительного времени это не требует
return SPI_I2S_ReceiveData(SPIx);
"В силу особенностей организации SPI на STM32, нельзя только писать, после любой записи нужно прочитать, дополнительного времени это не требует"
Danil
26.05.2017
17:46:45
Гонят
Serg
26.05.2017
17:46:46
если не читать, что будет?
Danil
26.05.2017
17:47:15
Флаг там нормально сбрасывается
Будет тоже самое что если не читать
Там два разных регистра, на отправку и приём
Serg
26.05.2017
17:48:31
А если надо только прочитать? SPI_SendData(SPIx, 0xFF) тоже не обязательно?
Danil
26.05.2017
17:48:45
Им друг на друга срать
Тоже не обязательно
Serg
26.05.2017
17:49:18
потому что SPI двухнаправленный
он когда пишет, одновременно и читает
Google
Serg
26.05.2017
17:49:18
поэтому входной буфер получает данные от слейва, даже если тот ничего писать не хочет
и буфер нужно зачистить, прочитав его.
Danil
26.05.2017
17:56:04
Там будет либо нуль либо число на приём
Они два разных, регистра, но запрос через один
То есть в программе DR а на деле их два
Если ты пишешь в DR то он в один регистр пишет, если читаешь в другой
Он-один раз нулем запишется и пока ты не прочитаешь, там будет ноль
Тебе и говорят, читай что там лежит, что бы данные не потерять
С каждым тактом уходит и приходит бит
Когда прошло 8 тактов, данные из отправки удаляются и флаг отправки поднимается, а данные из приёма если флаг приёма опущен копируются
И флаг приёма поднимается
И происходит прерывания для каждого флага
Тебе просто-надо забирать данные если флаг поднят на приём, и отправлять если спущен на отправку
Все остальное сделает железо
Сразу писать данные на флеш не стоит Кидай в буфер или из буфера
ОлегЪ
26.05.2017
18:27:24
как это понимать
Warning: D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.c(120): suspicious pointer conversion
ругается на это
while ((c = pgm_read_byte(progmem_s++)))
задефайнено так
#define pgm_read_byte(address) *((flash unsigned char *)(address))
использую
pgmspace.h
для вот этой функции
void i2c_lcd_pgmputs(const uint8_t *progmem_s)
{
register char c;
while ((c = pgm_read_byte(progmem_s++)))
{
i2c_lcd_putch(c);
}
}
сделал так
void i2c_lcd_pgmputs(const uint8_t *progmem_s)
{
register char c;
//while ((c = pgm_read_byte(progmem_s++)))
c = pgm_read_byte(progmem_s++);
while (c)
{
i2c_lcd_putch(c);
}
}
всеравно
Warning: D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.c(121): suspicious pointer conversion
Google
Danil
26.05.2017
18:28:59
Конст
Pgm read byte, кого принимает?
ОлегЪ
26.05.2017
18:30:24
должен принимать указатель на строку-константу во флеше
Danil
26.05.2017
18:32:41
А возвращает какой тип?
Так указатель на строку, а передаешь константа указатель на строку?
ОлегЪ
26.05.2017
18:35:34
не, ошибся. i2c_lcd_pgmputs принимает указатель на строку контанту во флеше
pgm_read_byte принимает указатель на контанту во флешее (по идее) и возвращает значение по этому указателю
#define pgm_read_byte(address) *((flash unsigned char *)(address))
но точно сказать не могу. т.к. в указателях не силен и примеров нигде найи не могу, потому и спрашиваю тут
Danil
26.05.2017
18:37:26
Вместо uint8_t char попрообуй
Unsigned char
ОлегЪ
26.05.2017
18:39:03
безрезультатно
Danil
26.05.2017
18:40:49
Char c в unsigned char
Ругается на c = Pgm_reade_byte
ОлегЪ
26.05.2017
18:42:17
пробовал char, signed char, unsigned char, ничего не меняется
Danil
26.05.2017
18:44:01
Если ее закоментить он же не ругается?
ОлегЪ
26.05.2017
18:44:40
не ругается, но тогда смысл функции теряется
Danil
26.05.2017
18:45:15
Тогда c тип unsigned char *
ОлегЪ
26.05.2017
18:45:18
Надо прочитать строку из флеша и отправить ее в дисплей
С как указатель обьявить?
Danil
26.05.2017
18:45:58
Не важно, :) мне же надо знать куда он ругается
Ага
Google
ОлегЪ
26.05.2017
18:49:16
Error: D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.c(122): a value of type 'flash unsigned char' can't be assigned to an entity of type 'unsigned char *'
Error: D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.c(125): function argument #1 of type 'unsigned char *' is incompatible with required parameter of type 'unsigned char'
Danil
26.05.2017
18:52:40
Окей, верни как было
c=(register char)Pgm_read_byte
ОлегЪ
26.05.2017
18:56:14
Error: D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.c(122): 'register' storage class not allowed in this context
если меняю на
void i2c_lcd_pgmputs(const uint8_t *progmem_s)
{
//register char c;
uint8_t c;
//while ((c = pgm_read_byte(progmem_s++)))
c = (uint8_t)pgm_read_byte(progmem_s++);
while (c)
{
i2c_lcd_putch(c);
}
}
, то
Warning: D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.c(122): suspicious pointer conversion
`
Danil
26.05.2017
18:57:48
Так а без с=
Просто пгм
Он жалуется на преобразование типов?
ОлегЪ
26.05.2017
18:59:37
void i2c_lcd_pgmputs(const uint8_t *progmem_s)
{
//register char c;
uint8_t c;
//while ((c = pgm_read_byte(progmem_s++)))
pgm_read_byte(progmem_s++);
while (c)
{
i2c_lcd_putch(c);
}
}
Warning: D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.c(122): suspicious pointer conversion
Warning: D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.c(123): local variable 'c' is used before its value is set
Warning: D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.c(125): local variable 'c' is used before its value is set
Danil
26.05.2017
19:00:09
Окей,
Значит это progremem_s не правильного типа
ОлегЪ
26.05.2017
19:02:03
но
void i2c_lcd_pgmputs(flash uint8_t *progmem_s)
или
void i2c_lcd_pgmputs(flash const uint8_t *progmem_s)
я написать не могу
Error: D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.c(117): function parameter #1 doesn't match its previous declaration from file: 'D:\Docs\Controllers\AVR\Projects\lcd_i2c\CodeVision\i2c_lcd.h', line: 106
а не,
void i2c_lcd_pgmputs(flash const uint8_t *progmem_s)
не ругается,
спс
Danil
26.05.2017
19:04:26
Методом тыка ::))
ОлегЪ
26.05.2017
19:04:42
ага, почти научного )
Danil
26.05.2017
19:06:36
Я думал он на с ругается
Ох уж эти преобразования типов
ОлегЪ
26.05.2017
19:07:58
я грешил на указатели. Все равно не пойму, зачем было делать три типа указателей в авр
metaclass
27.05.2017
11:52:25
посылать FF это типа принято, чтобы случайно слейву чушь лежащую в send-регистре не посылать при чтении.
Google
metaclass
27.05.2017
11:56:02
если мы что-нибудь послали слейву, а потом читаем
то если мы не перезапишем в регистр FF - то оно так и будет последнее значение слать вроде бы
LexsZero
27.05.2017
11:57:38
просто трансфер инициируется записью в регистр, если туда ничего не писать - то и слаться/приниматься ничего не будет.
Danil
27.05.2017
12:21:29
не байта, а указателя на байты.
да разобрались уже что указатель там. но мне такой код не кажется правильным т. к. никто не мешает иметь буфер в памяти с 0 адреса
metaclass
27.05.2017
12:21:59
это надо стандарт C смотреть
потому что идиома if(buffer) там везде
https://www.gnu.org/software/libc/manual/html_node/Null-Pointer-Constant.html
http://c-faq.com/null/ptrtest.html
Serg
28.05.2017
06:03:23
...Отсюда следует что SPI всегда работает в полнодуплексном режиме. А вот нужны ли нам данные, полученные от устройства при записи какого-либо параметра, это уже другой вопрос. Часто бывает что данные полученные от устройства при записи в него данных являются мусором, в таком случае их просто игнорируют, но мы их получим вне зависимости от нашего желания.
https://habrahabr.ru/post/123145/
Можно конечно попробовать перевести сначала в режим Rx, а потом Tx, но сложно угадать момент времени, Tx может переполниться
ОлегЪ
28.05.2017
06:11:11
Не пойму, в чем проблема? Не надо данных от слейва - игнорь их. Время на их прием и обработку всеравно не тратятся
Serg
28.05.2017
06:12:08
А потом, когда начну принимать данные от слейва, там же будет мусор в количестве байт, которые были отправлены
Так?
ОлегЪ
28.05.2017
06:16:37
Конкретно по стм32 не скажу, но у авр один регистр и для передачи и для приема. Прием происходит одновременно с передачей побитово, передали один бит, приняли и записали на его место, потом второй и тд. После передачи, если надо принятые данные, читаешь их и обрабатываешь. Если данные не надо, то в этот регистр просто пишешь следующий байт, который надо передать.
может быть в других устройствах для приема и передачи регистры разные, но это ничего собственно не меняет
Serg
28.05.2017
06:30:45
Но ведь регистры связанные, при отправке проталкиевается байт и на прием. И если другая сторона ничего не отправила - при приеме будет сначала мусор
Если я правильно понимаю