Alhen 0 23 января, 2012 Опубликовано 23 января, 2012 (изменено) · Жалоба Второй день пытаюсь вызвать к жизни SPI1 или 2 на STM32VLDISCOVERY. Перерыл интернет и даташит до тошноты. Не пойму что не так: RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // Разрешить тактирование порта B. RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Тактирование альтернативных функций GPIO. //Настройки GPIO GPIOB->CRH |= GPIO_CRH_MODE15_1; // Выход MOSI PB.15 GPIOB->CRH &= ~GPIO_CRH_MODE15_0; // 2MHz GPIOB->CRH &= ~GPIO_CRH_CNF15; // Push-Pull GPIOB->CRH &= ~GPIO_CRH_MODE14; // Вход MISO PB.14 GPIOB->CRH &= ~GPIO_CRH_CNF14_0; // GPIOB->CRH |= GPIO_CRH_CNF14_1; // Pull-Up GPIOB->ODR |= GPIO_ODR_ODR14; // GPIOB->CRH |= GPIO_CRH_MODE13_1; // Выход SCK PB.13 GPIOB->CRH &= ~GPIO_CRH_MODE13_0; // 2MHz GPIOB->CRH &= ~GPIO_CRH_CNF13; // Push-Pull GPIOB->CRH &= ~GPIO_CRH_MODE12; // Вход NSS PB.12 GPIOB->CRH &= ~GPIO_CRH_CNF12_0; // GPIOB->CRH |= GPIO_CRH_CNF12_1; // Pull-Up GPIOB->ODR |= GPIO_ODR_ODR12; //Настройки SPI2 RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; //Разрешаем тактирование SPI2 SPI2->CR1 &= ~SPI_CR1_SPE; //Отключаем SPI перед изменением настроек SPI2->CR1 |= SPI_CR1_BR_0; //Задаем скорость SPI2->CR1 |= SPI_CR1_BR_1; // SPI2->CR1 |= SPI_CR1_CPOL; //Задаем режим SPI2->CR1 |= SPI_CR1_CPHA; // SPI2->CR1 &= ~SPI_CR1_DFF; //Формат данных 8 бит SPI2->CR1 &= ~SPI_CR1_CRCEN; //Запрет CRC SPI2->CR1 &= ~SPI_CR1_CRCNEXT; //Отключение передачи CRC SPI2->CR1 &= ~SPI_CR1_RXONLY; //и прочих не fullduplex настроек SPI2->CR1 &= ~SPI_CR1_SSM; //на всякий случай.. SPI2->CR1 &= ~SPI_CR1_SSI; // SPI2->CR1 &= ~SPI_CR1_LSBFIRST; //MSB вперед SPI2->CR1 |= SPI_CR1_MSTR; //В режиме Мастер SPI2->CR1 &= ~SPI_CR1_BIDIMODE;// SPI2->CR1 &= ~SPI_CR1_BIDIOE; // SPI2->CR2 &= ~SPI_CR2_SSOE; // Запретить выход SS // (на входе задан высокий уровень) SPI2->CR1 |= SPI_CR1_SPE; // Включаем SPI ..... //Пробная прием-передача u8 temp; while (SPI2->SR & SPI_SR_BSY); while (!(SPI2->SR & SPI_SR_TXE)); SPI2->DR = 0x55; // Передача данных while (SPI2->SR & SPI_SR_BSY); while (!(SPI2->SR & SPI_SR_RXNE)); temp = SPI2->DR; // Чтение принятых данных ....... При отладке видно, что все настройки устанавливаются как прописано в коде, а в регистр DR данные 0x55 так и не записывается. На ногах процессора молчок. Тоже самое делал и для SPI1 с учетом бита альтернативной распиновки. Наверное, если взять библиотеку с функциями инициализации все бы заработало, но хочу вот так через "stm32f10x.h". Помогите пожалуйста разобраться. Изменено 18 июня, 2012 пользователем IgorKossak [codebox] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ChipKiller 0 23 января, 2012 Опубликовано 23 января, 2012 · Жалоба зачем же так "долбить" SPI2->CR1 ? ... все можно уместить в пару строк // включим тактирование - порт A, SPI1 RCC->APB2ENR = RCC_APB2ENR_IOPAEN |RCC_APB2ENR_AFIOEN | RCC_APB2ENR_SPI1EN; // set SPI1 AFIO->MAPR &= 0xFFFFFFFE; // clear AFIO_MAPR->SPI1_REMAP bit SPI1->CR1 = (1<<2)|(5<<3)|(1<<6)|(1<<8)|(1<<9); SPI1->CR2 = 0x0000; // set pin GPIOA->BSRR = 0x00000010; GPIOA->CRL = 0xB8B34444; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acvarif 0 23 января, 2012 Опубликовано 23 января, 2012 (изменено) · Жалоба Делал так (под новуб библиотеку периферии). Для работы с AD9832 void SPI1_Init(void) { // PA4 - NSS софтовый PA5 - SPI1 SCK PA7 - SPI1 MOSI RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // NSS: выход push-pull GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_SPI1); // SCK: выход push-pull GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); // MOSI: выход push-pull GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //? SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); GPIOA->ODR |= GPIO_OTYPER_ODR_4; } Запускается без проблем. Но по ходу вопрос. Как переназначить GPIO SPI1 на другие ноги? В новой библиотеке (в предыдущей вроде были) исчезли функции ремапинга. Куда они подевались? Изменено 23 января, 2012 пользователем Acvarif Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alhen 0 23 января, 2012 Опубликовано 23 января, 2012 · Жалоба зачем же так "долбить" SPI2->CR1 ? ... все можно уместить в пару строк Это от безисходности и злобы :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ChipKiller 0 23 января, 2012 Опубликовано 23 января, 2012 (изменено) · Жалоба Это от безисходности и злобы ... ... надеюсь все теперь все ОК ... код из рабочего примера Как переназначить GPIO SPI1 на другие ноги? 1 - посмотреть в datasheet :) .. на других ногах "висит" JTAG, так что помимо установки AFIO_MAPR->SPI1_REMAP нужно позаботиться о JTAG Изменено 23 января, 2012 пользователем ChipKiller Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alhen 0 24 января, 2012 Опубликовано 24 января, 2012 (изменено) · Жалоба ... надеюсь все теперь все ОК ... код из рабочего примера Благодарю за рабочий код, действительно все заработало, с меня пиво :beer: Я разобрался в чем была промашка, надо было назначить выходы в режиме альтернативной функции. GPIOA->CRL |= GPIO_CRL_MODE7; // Выход MOSI PA.7 (50 MHz) GPIOA->CRL &= ~GPIO_CRL_CNF7_0; // Push-Pull GPIOA->CRL |= GPIO_CRL_CNF7_1; // с альтернативной функцией !!!!!! Позволю себе выложить весь код тестовой программы в том же стиле. Такой "долбеж" по регистрам неизбежен на начальном этапе освоения камня, есть ощущение проникновения в сакральный смысл регистров #include "stm32f10x.h" u8 temp; void main() { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Разрешить тактирование порта A. RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Тактирование альтернативных функций GPIO. GPIOA->CRL |= GPIO_CRL_MODE7; // Выход MOSI PA.7 (50 MHz) GPIOA->CRL &= ~GPIO_CRL_CNF7_0; // Push-Pull GPIOA->CRL |= GPIO_CRL_CNF7_1; // с альтернативной функцией !!!!!! GPIOA->CRL &= ~GPIO_CRL_MODE6; // Вход MISO PA.6 GPIOA->CRL &= ~GPIO_CRL_CNF6_0; // GPIOA->CRL |= GPIO_CRL_CNF6_1; // with Pull-Up GPIOA->CRL |= GPIO_CRL_MODE5; // Выход SCK PA.5 (50 MHz) GPIOA->CRL &= ~GPIO_CRL_CNF5_0; // Push-Pull GPIOA->CRL |= GPIO_CRL_CNF5_1; // с альтернативной функцией !!!! GPIOA->CRL |= GPIO_CRL_MODE4; // Выход NSS PA.4 (50 MHz) GPIOA->CRL &= ~GPIO_CRL_CNF4; // Push-Pull General Purpose GPIOA->BSRR = GPIO_BSRR_BS4; // AFIO->MAPR &= ~AFIO_MAPR_SPI1_REMAP; //Сбрасываем REMAP для SPI на PA4-7 RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; SPI1->CR1 &= ~SPI_CR1_SPE; //Запрещаем SPI перед изменениями настроек SPI1->CR1 |= SPI_CR1_BR_0; //Задаем скорость SPI1->CR1 |= SPI_CR1_BR_1; SPI1->CR1 |= SPI_CR1_CPOL; //Задаем режим SPI1->CR1 |= SPI_CR1_CPHA; // SPI1->CR1 &= ~SPI_CR1_DFF; //Формат данных 8 бит SPI1->CR1 &= ~SPI_CR1_CRCEN; //Запрет CRC SPI1->CR1 &= ~SPI_CR1_CRCNEXT; //Отключение передачи CRC SPI1->CR1 &= ~SPI_CR1_RXONLY; //и прочих не fullduplex настроек SPI1->CR1 &= ~SPI_CR1_SSM; //на всякий случай.. SPI1->CR1 &= ~SPI_CR1_SSI; SPI1->CR1 &= ~SPI_CR1_LSBFIRST; //MSB вперед SPI1->CR1 |= SPI_CR1_MSTR; //В режиме Мастер SPI1->CR1 &= ~SPI_CR1_BIDIMODE; SPI1->CR1 &= ~SPI_CR1_BIDIOE; SPI1->CR1 |= SPI_CR1_SPE; // Включаем SPI while(1) { while (SPI1->SR & SPI_SR_BSY); while (!(SPI1->SR & SPI_SR_TXE)); SPI1->DR = 0x55; // Передача данных while (SPI1->SR & SPI_SR_BSY); while (!(SPI1->SR & SPI_SR_RXNE)); temp = SPI1->DR; // Чтение принятых данных } } Кстати, пошагово в отладчике программа не проходит проверку на RXNE и попадает в бесконечный цикл. Видать, где-то, RXNE успевает сброситься. Сам кусок кода с записью и чтением я взял на форуме ST здесь Автор утверждает, что у него код работает только в этом порядке, хотя в мануале RM0041 не рекомендуют проверять BSY при каждой посылке и приеме. Note: Do not use the BSY flag to handle each data transmission or reception. It is better to use the TXE and RXNE flags instead. Изменено 24 января, 2012 пользователем IgorKossak [codebox] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dfyz.s 0 13 июня, 2012 Опубликовано 13 июня, 2012 (изменено) · Жалоба Добрый вечер. Тоже разбираюсь с SPI. Вроде все делаю как в рабочем примере, но почему то не работает. Припаял SPI флешку, но при отправлении данных при отладке программы в регистр ODR записывается 00FF, и так и остается. Уже два дня мучаюсь, что может быть не так? //////////=================SPI=============== void SPI_INIT(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); /* Deinitialize SPI3 peripheral */ SPI_I2S_DeInit(SPI3); // SCK: выход push-pull PC10 GPIO_InitStructure.GPIO_Pin = PIN_EEPROM_SCK; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOC, PIN_SCK , GPIO_AF_SPI3); // MOSI: выход push-pull PC12 GPIO_InitStructure.GPIO_Pin = PIN_EEPROM_MOSI; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOC, PIN_MOSI , GPIO_AF_SPI3); // MISO: выход push-pull PC11 GPIO_InitStructure.GPIO_Pin = PIN_EEPROM_MISO; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOC, PIN_MISO , GPIO_AF_SPI3); //NSS: выход push-pull - use general GPIO for CS A4 GPIO_InitStructure.GPIO_Pin = PIN_EEPROM_SPI_CS; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); //SPI3 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI3, &SPI_InitStructure); SPI_Cmd(SPI3, ENABLE); } Отсылаю так //////////================FOR READ_WRITE SPI=================//////////// void EEPROMSend(char byte){ SPI_I2S_SendData(SPI3, byte); while (SPI_GetFlagStatus(SPI3, SPI_FLAG_TXE) == RESET); } void EEPROMSendByte(char byte){ GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_RESET); SPI_I2S_SendData(SPI3, byte); while (SPI_GetFlagStatus(SPI3, SPI_FLAG_RXNE) == RESET); GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_SET); } char EEPROMReceive(){ char byte; byte = SPI_I2S_ReceiveData(SPI3); while (SPI_GetFlagStatus(SPI3, SPI_FLAG_RXNE) == RESET); return byte; } volatile static uint8_t data=0; int main() { int i= 10; __enable_irq(); //Включаем прерывания LedInit(); SPI_INIT(); NVIC_SetPriority(SPI3_IRQn, 2); //Устанавливаем приоритет прерываний от SPI1 NVIC_EnableIRQ(SPI3_IRQn); //Включаем прерывания от SPI1 //Write Status Register (WRSR) Instruction Sequence i++; EEPROMSendByte(0x06); //command for write sequence EEPROM //for i //Write to EEPROM GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_RESET); EEPROMSend(0x02); //00000010 - write command EEPROMSend(0x00); //address EEPROMSend(0x00); //address EEPROMSend(0x00); //address EEPROMSend(0x00); //data GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_SET); delay(120*5000); /// //Read from EEPROM GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_RESET); EEPROMSend(0x03); //read command EEPROMSend(0x00); //address EEPROMSend(0x00); //address EEPROMSend(0x00); //address data = EEPROMReceive(); //fake read data = EEPROMReceive(); //read GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_SET); data++; Изменено 13 июня, 2012 пользователем IgorKossak [codebox] для длинного кода!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 13 июня, 2012 Опубликовано 13 июня, 2012 · Жалоба // MISO: выход push-pull PC11 Master Input Slave Output Оно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dfyz.s 0 14 июня, 2012 Опубликовано 14 июня, 2012 (изменено) · Жалоба Обновил библиотеки - заработало MOSI, CS и SCLK Сейчас посмотрел на осциллографе, MISO кстати и не работает. Сразу после записи команды чтения CS уходит в 1, то есть строчки data = EEPROMReceive(); //fake read data = EEPROMReceive(); //read Вообще пропускаются. MISO стабильно выдает 1,7 на всем протяжении) Может я что то не понимаю, но при отладке в строчках void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data) { /* Check the parameters */ assert_param(IS_SPI_ALL_PERIPH(SPIx)); /* Write in the DR register the data to be sent */ SPIx->DR = Data; } DR приравнивается 0xFE, хотя Data=0x06? :smile3046: Изменено 14 июня, 2012 пользователем dfyz.s Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 14 июня, 2012 Опубликовано 14 июня, 2012 (изменено) · Жалоба в приведённом коде miso программировался на вывод. Должен быть входом. Изменено 14 июня, 2012 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dfyz.s 0 14 июня, 2012 Опубликовано 14 июня, 2012 · Жалоба На отладчик забил Понял, в чем был косяк. uint8_t EEPROMSend(uint8_t byte){ while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI3, byte); while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI3); } void EEPROMSendByte(uint8_t byte){ GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_RESET); EEPROMSend(byte); GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_SET); } uint8_t EEPROMReceive(void) { return (EEPROMSend(DUMMY_BYTE)); } Необходимо просто отправлять байт и читать одновременно. Но на осциле MISO все равно не работает. Что то дергается, но невысокий уровень. Может Open Drain попробовать? в приведённом коде miso программировался на вывод. Должен быть входом. // MISO: выход push-pull PC11 GPIO_InitStructure.GPIO_Pin = PIN_EEPROM_MISO; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /// Сконфигурирован как MISO. Надо как IN Сделать? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /// ???? или здесь Open Drain поставить? GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 14 июня, 2012 Опубликовано 14 июня, 2012 (изменено) · Жалоба Нет, именно входом. А как это делается на NXP я понятия не имею... как и на STM32. Но знаю точно, что долго искать не пришлось бы, будь я за Вашим компютером. Изменено 14 июня, 2012 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Impartial 0 14 июня, 2012 Опубликовано 14 июня, 2012 · Жалоба Нет, именно входом. А как это делается на NXP я понятия не имею... как и на STM32. Но знаю точно, что долго искать не пришлось бы, будь я за Вашим компютером. Где то так. Для SPI2. GPIOB->CRH &= ~(GPIO_CRH_CNF15 | GPIO_CRH_MODE15); GPIOB->CRH |= GPIO_CRH_CNF15_1 | GPIO_CRH_MODE15; //mosi GPIOB->CRH &= ~(GPIO_CRH_CNF14 | GPIO_CRH_MODE14); GPIOB->CRH |= GPIO_CRH_CNF14_0; //miso GPIOB->CRH &= ~(GPIO_CRH_CNF13 | GPIO_CRH_MODE13); GPIOB->CRH |= GPIO_CRH_CNF13_1 | GPIO_CRH_MODE13; //sck GPIOB->CRH &= ~(GPIO_CRH_CNF12 | GPIO_CRH_MODE12); GPIOB->CRH |= GPIO_CRH_MODE12; //cs Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dfyz.s 0 18 июня, 2012 Опубликовано 18 июня, 2012 (изменено) · Жалоба GPIOB->CRH &= ~(GPIO_CRH_CNF15 | GPIO_CRH_MODE15); GPIOB->CRH |= GPIO_CRH_CNF15_1 | GPIO_CRH_MODE15; //mosi GPIOB->CRH &= ~(GPIO_CRH_CNF14 | GPIO_CRH_MODE14); GPIOB->CRH |= GPIO_CRH_CNF14_0; //miso GPIOB->CRH &= ~(GPIO_CRH_CNF13 | GPIO_CRH_MODE13); GPIOB->CRH |= GPIO_CRH_CNF13_1 | GPIO_CRH_MODE13; //sck GPIOB->CRH &= ~(GPIO_CRH_CNF12 | GPIO_CRH_MODE12); GPIOB->CRH |= GPIO_CRH_MODE12; //cs Это для серии stm32f1xx. У меня же stm32f207. Спасибо за советы, но у меня уже было настроено на вход как видно по моим примерам. В итоге разобрался. Дело было в том, что ядро контроллера работает на частоте 120 МГц и порт не успевает выводить значения, которые задаешь подряд. Приходиться делать задержку. Итоговый код программы. Может кому-то пригодиться #include <stm32f2xx_conf.h> #include <stdio.h> //HSE 25 MHz //HSI 16 MHz // PLL configure 120 MHz signal // PCLK1 - HSE/4 - 30 MHz(APB1); PCLK2 - HSE/2 - 60 MHz(APB2) #define DUMMY_BYTE 0xA5 #define PIN_EEPROM_SPI_CS GPIO_Pin_4 #define PIN_TAMPER GPIO_Pin_13 #define PIN_EEPROM_MOSI GPIO_Pin_12 #define PIN_EEPROM_MISO GPIO_Pin_11 #define PIN_EEPROM_SCK GPIO_Pin_10 #define PIN_SPI_CS 0x0010 #define PIN_SCK GPIO_PinSource10 #define PIN_MISO GPIO_PinSource11 #define PIN_MOSI GPIO_PinSource12 void delay(volatile uint32_t time) { for (; time != 0; time --); } void Led_Init(void) { RCC -> AHB1ENR |= RCC_AHB1ENR_GPIOFEN; GPIOF -> MODER |= GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0 | GPIO_MODER_MODER8_0 ; GPIOF -> OTYPER &= ~(GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7 | GPIO_OTYPER_OT_8); GPIOF -> OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7 | GPIO_OSPEEDER_OSPEEDR8 ; } //////////=================SPI=============== void SPI_INIT(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); /* Deinitialize SPI3 peripheral */ SPI_I2S_DeInit(SPI3); GPIO_PinAFConfig(GPIOC, PIN_SCK , GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOC, PIN_MOSI , GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOC, PIN_MISO , GPIO_AF_SPI3); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // SCK: выход push-pull PC10 GPIO_InitStructure.GPIO_Pin = PIN_EEPROM_SCK; GPIO_Init(GPIOC, &GPIO_InitStructure); // MISO: выход push-pull PC11 GPIO_InitStructure.GPIO_Pin = PIN_EEPROM_MISO; GPIO_Init(GPIOC, &GPIO_InitStructure); // MOSI: выход push-pull PC12 GPIO_InitStructure.GPIO_Pin = PIN_EEPROM_MOSI; GPIO_Init(GPIOC, &GPIO_InitStructure); //NSS: выход push-pull - use general GPIO for CS A4 GPIO_InitStructure.GPIO_Pin = PIN_EEPROM_SPI_CS; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); //SPI3 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI3, &SPI_InitStructure); SPI_Cmd(SPI3, ENABLE); } //////////////============================================================ //////////================FOR READ_WRITE SPI=================//////////// uint8_t EEPROM_Send(uint8_t byte){ while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI3, byte); while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI3); } void EEPROM_SendByte(uint8_t byte){ GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_RESET); EEPROM_Send(byte); GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_SET); delay(2000); } uint8_t EEPROM_Receive(void) { return (EEPROM_Send(DUMMY_BYTE)); } uint8_t EEPROM_ReadStatReg(void) { uint8_t byte; GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_RESET); EEPROM_Send(0x05); byte=EEPROM_Receive(); GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_SET); delay(2000); return (byte); } void EEPROM_BulkErase(void) { EEPROM_SendByte(0xC7); while(EEPROM_ReadStatReg() & 1); } /////========================================================= volatile static uint8_t data=0; volatile static uint8_t RegStat=0; //////===================MAIN int main() { __enable_irq(); //Включаем прерывания Led_Init(); SPI_INIT(); EEPROM_BulkErase(); //Write enable (WREN) Instruction Sequence EEPROM_SendByte(0x06); //command for write sequence EEPROM //Write to EEPROM GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_RESET); EEPROM_Send(0x02); //00000010 - write command EEPROM_Send(0x00); //address EEPROM_Send(0x00); //address EEPROM_Send(0x00); //address EEPROM_Send(0xAA); //data EEPROM_Send(0xBB); //data EEPROM_Send(0xCC); //data while (SPI1->SR & SPI_SR_BSY); GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_SET); delay(2000); while (SPI1->SR & SPI_SR_BSY); while(EEPROM_ReadStatReg() & 1); /// GPIOF->ODR |= GPIO_OTYPER_ODR_6; //Read from EEPROM GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_RESET); EEPROM_Send(0x03); //read command EEPROM_Send(0x00); //address EEPROM_Send(0x00); //address EEPROM_Send(0x00); //address data = EEPROM_Receive(); //read data = EEPROM_Receive(); //read data = EEPROM_Receive(); //read data = EEPROM_Receive(); //read data = EEPROM_Receive(); //read GPIO_WriteBit(GPIOA, PIN_SPI_CS, Bit_SET); delay(2000); /// GPIOF->ODR |= GPIO_OTYPER_ODR_8; delay(8000000); GPIOF->ODR &= ~GPIO_OTYPER_ODR_8; delay(8000000); GPIOF->ODR |= GPIO_OTYPER_ODR_8; GPIOF->ODR &= ~GPIO_OTYPER_ODR_6; delay(8000000); while(1){}; } Думал, что это как то просчитанно. А так в общем все в проге было ОК :=) Изменено 18 июня, 2012 пользователем IgorKossak форматирование (лишние табы) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ВитГо 0 21 октября, 2012 Опубликовано 21 октября, 2012 (изменено) · Жалоба хочу подключить к STM32F4 DISCOVERY дисплей LCD NOKIA 5110 использую CooCox в софт SPI подключение проходит (так я проверил строку инициализации дисплея) для хардварного SPI сначала вызываю инициализацию SPI2 используемые ноги: - PB13 CLK - PB15 MOSI - NSS и MISO не использую так как нужно только записывать данные и SPI2 всегда в режиме мастера // Инициализация SPI2 void SPI2_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); // включили SPI2 SPI_DeInit(SPI2); // сбрасываем настройки SPI2 на первоначальные RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // включили GPIOB GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); // SPI2_CLK GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2); // SPI2_MOSI GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); // сюда задание альтернативных функций 13 и 15 пина тоже переносил. результата нет // GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); // SPI2_CLK // GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2); // SPI2_MOSI // SPI2 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI2, &SPI_InitStructure); SPI_Cmd(SPI2, ENABLE); } частота камня 168 мгц поэтому взял максимальный делитель для SPI2 = 256 далее инициализирую GPIO для других линий дисплея // Инициализация LCD NOKIA 5110 c помощью SPI2 void lcd5110_init(void) { GPIO_InitTypeDef GPIO_InitStructure; unsigned char y, x; // RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // такт GPIOB, для софт SPI, для хард - делается при ините SPI2 // конфигурируем пины порта B как выход // для soft spi // GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; // для хардварного SPI GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10 | GPIO_Pin_14; // общие строки инициализации GPIO_InitStructure.GPIO_Mode =GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); далее работаю с дисплеем, этот код используется и в софт и хард работе SPI c дисплеем // Линии управления LCD в неактивное состояние LCD_CS1; // CS=1 LCD_RST1; // RST=1 delay_ms(10); // пауза 0.2 сек. // сброс дисплея LCD_CS0; // CS=0 LCD_RST0; // RST=0 delay_ms(10); // пауза 0.2 сек. LCD_RST1; // RST=1 LCD_CS1; // CS=1 delay_ms(10); // пауза 0.2 сек. // последовательность инициализации дисплея LCD_DC0; // передача команды LCD_SendData(0x21); LCD_SendData(0xC6); LCD_SendData(0x06); LCD_SendData(0x13); LCD_SendData(0x20); LCD_SendData(0x0C); LCD_DC0; // передача команд LCD_SendData(0x40); LCD_SendData(0x80); LCD_DC1; // передача данных for (y=0;y<6;y++) for (x=0;x<84;x++) LCD_SendData(0x88); LCD_DC0; // передача команд LCD_SendData(0x0C); } и собственно, сама процедура передачи данных на дисплей void LCD_SendData(unsigned char data) { // unsigned char i; // для программного SPI LCD_CS0; // включаем выбор дисплея // хардварный SPI SPI_I2S_SendData(SPI2, data); while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); /* // это реализация программного SPI работает! // программный SPI for(i=0;i<8;i++) { if (data & 0x80) LCD_MOSI1; else LCD_MOSI0; data = data<<1; LCD_SCK0; LCD_SCK0; LCD_SCK0; LCD_SCK1; LCD_SCK1; LCD_SCK1; } */ LCD_CS1; } процедуры вызываю из main() SPI2_Config(); // конфигурация SPI2 lcd5110_init(); // конфигурация LCD почему не работает аппаратный SPI2? Изменено 21 октября, 2012 пользователем ВитГо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться