Alhen 0 January 23, 2012 Posted January 23, 2012 (edited) · Report post Второй день пытаюсь вызвать к жизни 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". Помогите пожалуйста разобраться. Edited June 18, 2012 by IgorKossak [codebox] Quote Share this post Link to post Share on other sites More sharing options...
ChipKiller 0 January 23, 2012 Posted January 23, 2012 · Report post зачем же так "долбить" 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; Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 January 23, 2012 Posted January 23, 2012 (edited) · Report post Делал так (под новуб библиотеку периферии). Для работы с 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 на другие ноги? В новой библиотеке (в предыдущей вроде были) исчезли функции ремапинга. Куда они подевались? Edited January 23, 2012 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
Alhen 0 January 23, 2012 Posted January 23, 2012 · Report post зачем же так "долбить" SPI2->CR1 ? ... все можно уместить в пару строк Это от безисходности и злобы :rolleyes: Quote Share this post Link to post Share on other sites More sharing options...
ChipKiller 0 January 23, 2012 Posted January 23, 2012 (edited) · Report post Это от безисходности и злобы ... ... надеюсь все теперь все ОК ... код из рабочего примера Как переназначить GPIO SPI1 на другие ноги? 1 - посмотреть в datasheet :) .. на других ногах "висит" JTAG, так что помимо установки AFIO_MAPR->SPI1_REMAP нужно позаботиться о JTAG Edited January 23, 2012 by ChipKiller Quote Share this post Link to post Share on other sites More sharing options...
Alhen 0 January 24, 2012 Posted January 24, 2012 (edited) · Report post ... надеюсь все теперь все ОК ... код из рабочего примера Благодарю за рабочий код, действительно все заработало, с меня пиво :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. Edited January 24, 2012 by IgorKossak [codebox] Quote Share this post Link to post Share on other sites More sharing options...
dfyz.s 0 June 13, 2012 Posted June 13, 2012 (edited) · Report post Добрый вечер. Тоже разбираюсь с 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++; Edited June 13, 2012 by IgorKossak [codebox] для длинного кода!!! Quote Share this post Link to post Share on other sites More sharing options...
GenaSPB 3 June 13, 2012 Posted June 13, 2012 · Report post // MISO: выход push-pull PC11 Master Input Slave Output Оно? Quote Share this post Link to post Share on other sites More sharing options...
dfyz.s 0 June 14, 2012 Posted June 14, 2012 (edited) · Report post Обновил библиотеки - заработало 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: Edited June 14, 2012 by dfyz.s Quote Share this post Link to post Share on other sites More sharing options...
GenaSPB 3 June 14, 2012 Posted June 14, 2012 (edited) · Report post в приведённом коде miso программировался на вывод. Должен быть входом. Edited June 14, 2012 by Genadi Zawidowski Quote Share this post Link to post Share on other sites More sharing options...
dfyz.s 0 June 14, 2012 Posted June 14, 2012 · Report post На отладчик забил Понял, в чем был косяк. 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); Quote Share this post Link to post Share on other sites More sharing options...
GenaSPB 3 June 14, 2012 Posted June 14, 2012 (edited) · Report post Нет, именно входом. А как это делается на NXP я понятия не имею... как и на STM32. Но знаю точно, что долго искать не пришлось бы, будь я за Вашим компютером. Edited June 14, 2012 by Genadi Zawidowski Quote Share this post Link to post Share on other sites More sharing options...
Impartial 0 June 14, 2012 Posted June 14, 2012 · Report post Нет, именно входом. А как это делается на 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 Quote Share this post Link to post Share on other sites More sharing options...
dfyz.s 0 June 18, 2012 Posted June 18, 2012 (edited) · Report post 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){}; } Думал, что это как то просчитанно. А так в общем все в проге было ОК :=) Edited June 18, 2012 by IgorKossak форматирование (лишние табы) Quote Share this post Link to post Share on other sites More sharing options...
ВитГо 0 October 21, 2012 Posted October 21, 2012 (edited) · Report post хочу подключить к 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? Edited October 21, 2012 by ВитГо Quote Share this post Link to post Share on other sites More sharing options...