@ru_electronics

Страница 299 из 718
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
вот это вот if(tbuf) {} else {}
tbuf указатель. Если нечего передавать (мы передали NULL) - то передаются FF

посылать 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
Но ведь регистры связанные, при отправке проталкиевается байт и на прием. И если другая сторона ничего не отправила - при приеме будет сначала мусор

Если я правильно понимаю

Страница 299 из 718