Метценгерштейн
Jan 30 2013, 15:25
В своей программе в терминалке получаю ответ от визнета 0x12, но осциллом вижу, что визнет выдает мне число 0х13, значит я не корректно его обрабатываю. Из даташита по визнету по SPI понятно, что данные выставляются, когда sck период только начался и он еще в лог.0. Так же и на картинке осцилла. Т.е. возможные комбинации выставлены как положено.
Код
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
тогда почему мой STM32 не хочет видеть число 0x13 ?


здесь D4- MISO, т.е. вход STM32
перепробовал все полярности в STM32- ничего не улучшилось.
замыкал напрямую в STM32 MISO на MOSI- принимаю то, что отправляю. Если разъединяю перемычку, принимаю 0xFF, а с соединенной, именно то, что отправил.
Что еще можно предпринять?
Метценгерштейн
Jan 31 2013, 13:40
новая вводная:
замкнуты напрямую MISO на MOSI.
инициализация SPI
Код
// SPI1
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; //Тактирование модуля SPI1
SPI1->CR1 = 0
| SPI_CR1_BR_2 | SPI_CR1_BR_0 //Baud rate = Fpclk/64
| 0 * SPI_CR1_CPOL //Полярность тактового сигнала
| 0 * SPI_CR1_CPHA //Фаза тактового сигнала
| 0 * SPI_CR1_DFF //8 бит данных
| 0 * SPI_CR1_LSBFIRST //MSB передается первым
| 1 * SPI_CR1_SSM //Программный режим NSS
| 1 * SPI_CR1_SSI //Аналогично состоянию, когда на входе NSS высокий уровень
| 1 * SPI_CR1_MSTR //Режим Master
| 1 * SPI_CR1_SPE; //Включаем SPI1
;
SPI1->CR2 = SPI_CR2_SSOE; //Вывод NSS - выход управления slave select
а вот, что делаю в проге
Код
void WIZnet_main (void)
{
WIZ_SPIInit();
uint8_t temp=0;
uint8_t data;
Delay_ms(1);
for (data=0; data < 0xff; data ++)
{
on (TestPin);
Usart1_Send_Byte_HEX (data);
Usart1_Send_String ("->");
while(!(SPI1->SR & SPI_SR_TXE))
;
SPI1->DR = data;
while(!(SPI1->SR & SPI_SR_RXNE));
temp = SPI1->DR;
off (TestPin);
Usart1_Send_Byte_HEX (temp);
Usart1_Send_String ("\r\n");
}
}
и при этом выводится следующее:
Код
00->01
01->00
02->03
03->02
04->05
05->04
06->07
07->06
08->09
09->08
0A->0B
0B->0A
0C->0D
0D->0C
0E->0F
0F->0E
10->11
11->10
12->13
13->12
14->15
15->14
16->17
17->16
18->19
19->18
...
а почему?
AHTOXA
Jan 31 2013, 16:17
Покажите настройки ног SPI.
Метценгерштейн
Jan 31 2013, 16:43
Код
void WIZ_SPIInit()
{
// настройка SCS вывода (GPIOB, GPIO_Pin_8)
GPIOB->MODER |= GPIO_MODER_MODER8_0; //output
GPIOB->OTYPER &= ~GPIO_OTYPER_OT_8; //Output push-pull
GPIOB->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR8; //40 MHz
GPIOB->PUPDR &=~GPIO_PUPDR_PUPDR8; //No pull-up, pull-down
// настройка TestPin выхода (GPIOB, GPIO_Pin_7)
GPIOB->MODER |= GPIO_MODER_MODER7_0; //output
GPIOB->OTYPER &= ~GPIO_OTYPER_OT_7; //Output push-pull
GPIOB->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR7; //40 MHz
GPIOB->PUPDR &=~GPIO_PUPDR_PUPDR7; //No pull-up, pull-down
// настрока вывода Reset (GPIOB, GPIO_Pin_5)
GPIOB->MODER |= GPIO_MODER_MODER5_0; //output
GPIOB->OTYPER &= ~GPIO_OTYPER_OT_5; //Output push-pull
GPIOB->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR5; //40 MHz
GPIOB->PUPDR &=~GPIO_PUPDR_PUPDR5; //No pull-up, pull-down
// Линини SPI1 (Master) настройка SCLK, MISO и MOSI
// PA12(MOSI), PA11(MISO), PA5(SCK), PA4(NSS) - AF, Push-Pull, AF5(SPI1)
GPIOA->MODER |= GPIO_MODER_MODER12_1 | GPIO_MODER_MODER11_1 | GPIO_MODER_MODER5_1; //Alternate function
GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_12 | GPIO_OTYPER_OT_11 | GPIO_OTYPER_OT_5); //Push-Pull
GPIOA->AFR[1] |= (5<<16 | 5<<12); //PA12 = AF5, PA11 = AF5
GPIOA->AFR[0] |= (5<<20 | 5<<16); //PA5 = AF5, PA4 = AF5
// настройка внешнего прерывания на PB3
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI3_PB; // Connect EXTI line 3 to PB
EXTI->IMR |= EXTI_IMR_MR3; // какую линию выбираем из 23-х (у нас 3-я)
EXTI->FTSR |= EXTI_FTSR_TR3; // настройка фронта-среза на акт. 0
NVIC_EnableIRQ(EXTI3_IRQn); // NVIC_DisableIRQ(EXTI0_IRQn);
NVIC_SetPriority(EXTI3_IRQn, 1); //приоритет
// SPI1
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; //Тактирование модуля SPI1
SPI1->CR1 = 0
| SPI_CR1_BR_2 | SPI_CR1_BR_0 //Baud rate = Fpclk/64
| 0 * SPI_CR1_CPOL //Полярность тактового сигнала
| 0 * SPI_CR1_CPHA //Фаза тактового сигнала
| 0 * SPI_CR1_DFF //8 бит данных
| 0 * SPI_CR1_LSBFIRST //MSB передается первым
| 1 * SPI_CR1_SSM //Программный режим NSS
| 1 * SPI_CR1_SSI //Аналогично состоянию, когда на входе NSS высокий уровень
| 1 * SPI_CR1_MSTR //Режим Master
| 1 * SPI_CR1_SPE; //Включаем SPI1
;
SPI1->CR2 = SPI_CR2_SSOE; //Вывод NSS - выход управления slave select
}
AHTOXA
Jan 31 2013, 17:58
А зачем у вас включается альтернативная функция для NSS? (Причём направление его не задано, то есть, оставлен на вход, по умолчанию.)
Остальное вроде нормально.
Попробуйте сделать NSS простым GPIO (и уберите SPI_CR2_SSOE из SPI1->CR2)
Метценгерштейн
Jan 31 2013, 18:39
исправил.
инициализация портов
Код
void WIZ_SPIInit()
{
// настройка SCS вывода (GPIOB, GPIO_Pin_8)
GPIOB->MODER |= GPIO_MODER_MODER8_0; //output
GPIOB->OTYPER &= ~GPIO_OTYPER_OT_8; //Output push-pull
GPIOB->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR8; //40 MHz
GPIOB->PUPDR &=~GPIO_PUPDR_PUPDR8; //No pull-up, pull-down
// настройка TestPin выхода (GPIOB, GPIO_Pin_7)
GPIOB->MODER |= GPIO_MODER_MODER7_0; //output
GPIOB->OTYPER &= ~GPIO_OTYPER_OT_7; //Output push-pull
GPIOB->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR7; //40 MHz
GPIOB->PUPDR &=~GPIO_PUPDR_PUPDR7; //No pull-up, pull-down
// настрока вывода Reset (GPIOB, GPIO_Pin_5)
GPIOB->MODER |= GPIO_MODER_MODER5_0; //output
GPIOB->OTYPER &= ~GPIO_OTYPER_OT_5; //Output push-pull
GPIOB->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR5; //40 MHz
GPIOB->PUPDR &=~GPIO_PUPDR_PUPDR5; //No pull-up, pull-down
// Линини SPI1 (Master) настройка SCLK, MISO и MOSI
// PA12(MOSI), PA11(MISO), PA5(SCK), Push-Pull, AF5(SPI1)
GPIOA->MODER |= GPIO_MODER_MODER12_1 | GPIO_MODER_MODER11_1 | GPIO_MODER_MODER5_1; //Alternate function
GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_12 | GPIO_OTYPER_OT_11 | GPIO_OTYPER_OT_5); //Push-Pull
GPIOA->AFR[1] |= (5<<16 | 5<<12); //PA12 = AF5, PA11 = AF5
GPIOA->AFR[0] |= (5<<20); //PA5 = AF5
// настройка внешнего прерывания на PB3
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI3_PB; // Connect EXTI line 3 to PB
EXTI->IMR |= EXTI_IMR_MR3; // какую линию выбираем из 23-х (у нас 3-я)
EXTI->FTSR |= EXTI_FTSR_TR3; // настройка фронта-среза на акт. 0
NVIC_EnableIRQ(EXTI3_IRQn); // NVIC_DisableIRQ(EXTI0_IRQn);
NVIC_SetPriority(EXTI3_IRQn, 1); //приоритет
// SPI1
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; //Тактирование модуля SPI1
SPI1->CR1 = 0
| SPI_CR1_BR_2 | SPI_CR1_BR_0 //Baud rate = Fpclk/64
| 0 * SPI_CR1_CPOL //Полярность тактового сигнала
| 0 * SPI_CR1_CPHA //Фаза тактового сигнала
| 0 * SPI_CR1_DFF //8 бит данных
| 0 * SPI_CR1_LSBFIRST //MSB передается первым
| 1 * SPI_CR1_SSM //Программный режим NSS
| 1 * SPI_CR1_SSI //Аналогично состоянию, когда на входе NSS высокий уровень
| 1 * SPI_CR1_MSTR //Режим Master
| 1 * SPI_CR1_SPE; //Включаем SPI1
;
//SPI1->CR2 = SPI_CR2_SSOE; //Вывод NSS - выход управления slave select
}
сама ф-я
Код
void WIZnet_main (void)
{
WIZ_SPIInit();
uint8_t temp=0;
uint8_t data;
for (data=0; data < 10; data ++)
{
Usart1_Send_Byte_HEX (data);
Usart1_Send_String ("->");
while(!(SPI1->SR & SPI_SR_TXE))
;
SPI1->DR = data; //Пишем в буфер передатчика SPI1. После этого стартует обмен данными
while(!(SPI1->SR & SPI_SR_RXNE)); //Ожидаем окончания приема данных модулем SPI1 (RXNE =1 - приемный буфер содержит данные)
temp = SPI1->DR;//Считываем данные из приемного буфера SPI1. При этой операции происходит очистка буфера и сброс флага RXNE
Usart1_Send_Byte_HEX (temp);
Usart1_Send_String ("\r\n");
Delay_ms(20);
}
}
и то, что вывелось
Код
01->00
02->03
03->02
04->05
05->04
06->07
07->06
08->09
09->08
напомню, MISO на MOSI напрямую замкнуты
AHTOXA
Jan 31 2013, 18:52
А, вот ещё что. MISO нужно настроить как вход, а не как выход!
(Альтернативный конечно, можно с подтяжкой).
Метценгерштейн
Jan 31 2013, 19:26
похоже, что не надо. т.к. в одном
GPIOA->MODER
я ставлю или вход или выход или альтернатива.
тут-то я и выбираю альтернативу.
а она уже жестко привязана к ноге MISO.
тут еще что-то сидит.
Окей. Попробуйте ещё не полагаться на значения по умолчанию для регистров.
То есть, вместо
Код
GPIOA->MODER |= GPIO_MODER_MODER12_1;
пишите
Код
GPIOA->MODER &= ~GPIO_MODER_MODER12;
GPIOA->MODER |= GPIO_MODER_MODER12_1;
И ещё. Добавьте строчки
Код
SPI1->I2SCFGR &= ~SPI_I2SCFGR_I2SMOD;
SPI1->CR2 = 0;
_перед_
Код
SPI1->CR1 = ...
ЗЫ. А плата у вас случайно не F4DISCOVERY?
Метценгерштейн
Feb 1 2013, 08:15
попробую все проделать.
плата
STM32L152RBT6
такаятоже самое все. разве что у меня нет регистра
SPI1->I2SCFGR &= ~SPI_I2SCFGR_I2SMOD;
не обнулял его.
проверяю еще идею и пойду ассемблер смотреть
Метценгерштейн
Feb 1 2013, 12:20
причесал чужой код под свой проц. в отдельном проекте. И, он работает!
у меня тоже самое, тот же код, те же ф-ии, и не работает. Как так?
Гляньте, кому не сложно. Может глаз замылился и не вижу очевидного?
http://files.mail.ru/CA973E3E6B124F4688677F583F8C721Fэто рабочий проект
вывод:
Код
01->01
02->02
03->03
04->04
05->05
06->06
07->07
08->08
09->09
http://files.mail.ru/201299FB61304FBF979B8A7805554D6Fвторой проект, кот. не работает.
в нем из main() я сразу иду в файл
WIZnet_5100 в ф-ю
WIZnet_main();
и дальше делаю все тоже самое.
но результат
Код
JþÖ˜ffË>03
03->02
04->05
05->04
06->07
07->06
08->09
09->08
так в чем же разница?
нашел причину:
как только в рабочий проект добавляю к проекту файл
startup_stm32l1xx_md.s из папки IAR, так сразу получаю ту же хрень.
и что тут делать?
Метценгерштейн
Feb 2 2013, 20:53
Продолжение исследования:
удаляя файл startup_stm32l1xx_md.s, я вынуждаю перейти проц на тактирование MSI 2,097 МГц.
Если файлом system_stm32l1xx.c, сгенерированным прогой, задана частота 32 МГц, хоть от кварца, хоть от RC, то и получается эта хрень с выводом.
Если тактирование 2,097 МГц, то все ОК.
А почему?
Удаляя файл startup_stm32l1xx_md.s, вы удаляете таблицу векторов (и вектор сброса в том числе). Без вектора сброса программа не может работать в принципе. Возможно у вас в проекте два конфликтующих файла стартапа?
Метценгерштейн
Feb 3 2013, 07:56
нет, один файл стартапа.
проблема не в нем- проблема в том, что на 32 МГц не хочет работать ни в какую.
Цитата(Метценгерштейн @ Feb 3 2013, 13:56)

нет, один файл стартапа.
Тогда как же вы его удаляете? Что остаётся вместо стартапа, когда вы удаляете startup_stm32l1xx_md.s?
Метценгерштейн
Feb 3 2013, 15:41
не знаю, что остается) Мусор какой-то. И благодаря ему, работать начинает только от генератора MSI на 2 МГц.
в общем, факт налицо. от 32 МГц не хочет работать.
Цитата(Метценгерштейн @ Feb 3 2013, 21:41)

не знаю, что остается) Мусор какой-то.
Ага, и этот мусор случайно прыгает на __iar_program_start()? Так не бывает. Ищите, где у вас другой стартап.
Цитата(Метценгерштейн @ Feb 3 2013, 21:41)

И благодаря ему, работать начинает только от генератора MSI на 2 МГц.
То есть, скорость SPI у вас меняется, но UART при этом работает на оной и той же скорости? (Вы же выводите в UART переданный и принятый байты).
Метценгерштейн
Feb 3 2013, 19:04
UART использует стандартные библиотеки, где в зависимости от частоты шины - они сами подгоняют скорости как надо. Вроде так было.
Скачайте проект, найдите там еще один файл инициализации. Обычно начало старта и есть нулевой адрес флеша. Просто пока попадает на него.
Дело в том, что ваша функция main() вызывается из функции __iar_program_start(). Которая, в свою очередь, вызывается из стартапа (после SystemInit). То есть, выкинув стартап, вы не просто отменяете вызов инициализации (SystemInit()), а совсем исключаете возможность выполнения программы.
Проект я качал, там действительно только один стартап. Но, может быть, другой стартап лежит в другой папке, и поэтому не попал в архив? Или этот один стартап включён дважды.
(У меня нет IAR-а, я не могу проверить ваш проект.)
Метценгерштейн
Feb 4 2013, 08:36
этот файл включен только в проект. больше нигде его нет. в коде программы я его не использую. Тут, в общем, какой-то глюк. Как с SPI, так и с работой без этого стартапа.
Метценгерштейн
Feb 9 2013, 19:18
в общем, пришел к такому выводу:
при настройке в утилите тактовой частоты PCLK2 на 8 МГц через делитель APB2 prescaler, при этом сама частота шины = 32 МГц, вне зависимости от кварца или RC, то все работает.
Так же поднимал частоту системную до 12 МГц- все работало.
Получается, что наш SPI не хочет тактироваться от частот выше 12 МГц (а при частоте шины 32 МГц больше 8 МГц и не выставить)
А где в даташите это сказано?
Golikov A.
Feb 15 2013, 15:27
Сейчас у меня нет под рукой СТМ и ИАР не могу проверить, потому извиняюсь могу глупостей наговорить

1. у СТМ32 есть настройка максимальной частоты выходных ножек. По умолчанию там минимум стоит, поглядите может для СПИ эта настройка тоже имеет смысл...
2. У иар в среде есть свой мини стартап, то есть без стартап файла он сам добавить в вектор прерывание переход на маин, это может и быть вашим вторым стартапом, так проект и работает.
Еще раз оговорюсь могу обмануть, я уже пересел с ИАР на кеил, но что-то смутно помнится, что дело было так...
Golikov A.
Feb 18 2013, 15:33
В теме откуда я пришел, эта проблема решилась выставлением максимальной частоты работы порта, так что для СПИ эта настройка тоже имеет смысл.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.