Перейти к содержанию

le2x

Members
  • Постов

    8
  • Зарегистрирован

  • Посещение

Весь контент le2x

  1. В общем понял что nss для работы в режиме slave и multimaster и что этот вариант мне не подходит управление осуществляю при помощи GPIO. Всем спасибо за помощь. Ниже рабочий код. #include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_spi.h" int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //LATCH_DIO - разрешение записи в регистр (LOW) GPIO_InitTypeDef latch; latch.GPIO_Speed = GPIO_Speed_2MHz; latch.GPIO_Mode = GPIO_Mode_Out_PP; latch.GPIO_Pin = GPIO_Pin_8 ; GPIO_Init(GPIOA, &latch); //выводы под SPI CLK_DIO - GPIO_Pin_5, DATA_DIO - GPIO_Pin_7 GPIO_InitTypeDef gpio; gpio.GPIO_Speed = GPIO_Speed_2MHz; gpio.GPIO_Mode = GPIO_Mode_AF_PP; gpio.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7; GPIO_Init(GPIOA, &gpio); // настраиваем SPI1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); SPI_InitTypeDef spi; spi.SPI_Direction = SPI_Direction_1Line_Tx; spi.SPI_Mode = SPI_Mode_Master; spi.SPI_DataSize = SPI_DataSize_16b; spi.SPI_CPOL = SPI_CPOL_Low; //полярность сигнала синхронизации spi.SPI_CPHA = SPI_CPHA_1Edge; //фронт синхронизации spi.SPI_NSS = SPI_NSS_Soft; spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; spi.SPI_FirstBit = SPI_FirstBit_MSB; //передавать сначала младший бит spi.SPI_CRCPolynomial = 15; SPI_Init(SPI1, &spi); SPI_Cmd(SPI1, ENABLE); while(1) { while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);// регистр TX пустой? SPI_I2S_SendData(SPI1, 0xC0F1);// пишем в TX данные, начало передачи while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);// ждём окончания передачи GPIO_ResetBits(GPIOA, GPIO_Pin_8);// делаем перепад на LATCH_DIO GPIO_SetBits(GPIOA, GPIO_Pin_8); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);// регистр TX пустой? SPI_I2S_SendData(SPI1, 0xF9F2);// пишем в TX данные, начало передачи while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);// ждём окончания передачи GPIO_ResetBits(GPIOA, GPIO_Pin_8);// делаем перепад на LATCH_DIO GPIO_SetBits(GPIOA, GPIO_Pin_8); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);// регистр TX пустой? SPI_I2S_SendData(SPI1, 0xA4F4);// пишем в TX данные, начало передачи while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);// ждём окончания передачи GPIO_ResetBits(GPIOA, GPIO_Pin_8);// делаем перепад на LATCH_DIO GPIO_SetBits(GPIOA, GPIO_Pin_8); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);// регистр TX пустой? SPI_I2S_SendData(SPI1, 0xB0F8);// пишем в TX данные, начало передачи while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);// ждём окончания передачи GPIO_ResetBits(GPIOA, GPIO_Pin_8);// делаем перепад на LATCH_DIO GPIO_SetBits(GPIOA, GPIO_Pin_8); } }
  2. Уважаемый @Yurkin2015 вы абсолютно правы. Надо было мне сразу заглянуть в даташит на 74HC595 и тогда бы я увидел эту диаграмму. Поправил фронт и полярность в настройках GPIO. Ваш код действительно работает. Также он работает и в таком варианте когда сначала на линию LATCH_DIO устанавливаем 0, передаем данные по SPI c проверкой флагов и устанавливаем на LATCH_DIO = 1, так что теперь все логично и понятно. Спасибо. Осталось поиграть с SPI_NSS дабы не задействовать отдельную ногу под LATCH_DIO
  3. В общем заработало в таком варианте #include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_spi.h" void delay (uint32_t time_delay) //функция задержки { uint32_t i; for (i=0;i<time_delay;i++); } int main(void) { // настраиваем выводы 4-7 порта A на альтернативный режим работы RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // LATCH_DIO - разрешение записи в регистр (LOW) GPIO_InitTypeDef latch; latch.GPIO_Speed = GPIO_Speed_2MHz; latch.GPIO_Mode = GPIO_Mode_Out_PP; latch.GPIO_Pin = GPIO_Pin_8 ; GPIO_Init(GPIOA, &latch); //выводы под SPI GPIO_InitTypeDef gpio; gpio.GPIO_Speed = GPIO_Speed_2MHz; gpio.GPIO_Mode = GPIO_Mode_AF_PP; gpio.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOA, &gpio); // настраиваем SPI1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); SPI_InitTypeDef spi; spi.SPI_Direction = SPI_Direction_1Line_Tx; spi.SPI_Mode = SPI_Mode_Master; spi.SPI_DataSize = SPI_DataSize_16b; spi.SPI_CPOL = SPI_CPOL_Low; //полярность сигнала синхронизации spi.SPI_CPHA = SPI_CPHA_2Edge; //фронт синхронизации spi.SPI_NSS = SPI_NSS_Soft; spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; spi.SPI_FirstBit = SPI_FirstBit_MSB; //передавать сначала младший бит spi.SPI_CRCPolynomial = 15; SPI_Init(SPI1, &spi); SPI_Cmd(SPI1, ENABLE); while(1) { GPIO_SetBits(GPIOA, GPIO_Pin_8); SPI_I2S_SendData(SPI1, 0xC0F1); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); GPIO_ResetBits(GPIOA, GPIO_Pin_8); delay(10000); GPIO_SetBits(GPIOA, GPIO_Pin_8); SPI_I2S_SendData(SPI1, 0xF9F2); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); GPIO_ResetBits(GPIOA, GPIO_Pin_8); delay(10000); GPIO_SetBits(GPIOA, GPIO_Pin_8); SPI_I2S_SendData(SPI1, 0xA4F4); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); GPIO_ResetBits(GPIOA, GPIO_Pin_8); delay(10000); GPIO_SetBits(GPIOA, GPIO_Pin_8); SPI_I2S_SendData(SPI1, 0xB0F8); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); GPIO_ResetBits(GPIOA, GPIO_Pin_8); delay(10000); } } Сначала нужно установить 1 на LATCH_DIO, затем передать два байта по SPI, затем установить 0 на LATCH_DIO. Вот это как раз и странно, должно быть все наоборот. Получается LATCH_DIO нельзя подключить к SPI_NSS выходу, либо подключать через инвертор (элемент НЕ, транзистор по схеме с ОЭ). Но в примере для Arduino все логично. Что тогда не так?
  4. Я кажется понял свою ошибку, посмотрел внимательнее на схему и понял что не нужно никаких 64 бита передавать в регистр а всего 16. Первые байт отвечают за номер индикатора а второй значение на сегментах. Так что должно все получиться с SPI. Да действительно так и есть, загорелись все 4 индикатора, правда не цифрами а кракозябрами, осталось подобрать правильные коды символов
  5. Принципиальная электрическая схема и изображение платы во вложении. Пины микроконтроллера: LATCH_DIO - GPIO_Pin_8 CLK_DIO - GPIO_Pin_5 DATA_DIO - GPIO_Pin_7
  6. GPIO_ResetBits(GPIOA, GPIO_Pin_8); SPI_I2S_SendData(SPI1, 0x80F1); //delay (100000); while( !(SPI1->SR & SPI_I2S_FLAG_TXE) || SPI1->SR & SPI_I2S_FLAG_BSY ); SPI_I2S_SendData(SPI1, 0x80F2); //delay (100000); while( !(SPI1->SR & SPI_I2S_FLAG_TXE) || SPI1->SR & SPI_I2S_FLAG_BSY ); SPI_I2S_SendData(SPI1, 0x80F4); //delay (100000); while( !(SPI1->SR & SPI_I2S_FLAG_TXE) || SPI1->SR & SPI_I2S_FLAG_BSY ); SPI_I2S_SendData(SPI1, 0x80F8); //delay (100000); while( !(SPI1->SR & SPI_I2S_FLAG_TXE) || SPI1->SR & SPI_I2S_FLAG_BSY ); GPIO_SetBits(GPIOA, GPIO_Pin_8); Попробовал и с задержкой и с проверкой флагов, бесполезно, он зажигает последний индикатор и все тут. Получается последней отрабатывает вот эта строка SPI_I2S_SendData(SPI1, 0x80F8); пробовал ее закоментить тогда зажигается третий индикатор, последней отрабатывает строка SPI_I2S_SendData(SPI1, 0x80F4); Хочу зажечь все четыре индикатора.
  7. Типа вот так что ли? #include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_spi.h" void delay (uint32_t time_delay) //функция задержки { uint32_t i; for (i=0;i<time_delay;i++); } int main(void) { // настраиваем выводы 4-7 порта A на альтернативный режим работы RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // LATCH_DIO - разрешение записи в регистр (LOW) GPIO_InitTypeDef latch; latch.GPIO_Speed = GPIO_Speed_2MHz; latch.GPIO_Mode = GPIO_Mode_Out_PP; latch.GPIO_Pin = GPIO_Pin_8 ; GPIO_Init(GPIOA, &latch); GPIO_SetBits(GPIOA, GPIO_Pin_8); //устанывливаем на линнии запрет приема данных //выводы под SPI GPIO_InitTypeDef gpio; gpio.GPIO_Speed = GPIO_Speed_2MHz; gpio.GPIO_Mode = GPIO_Mode_AF_PP; gpio.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOA, &gpio); // настраиваем SPI1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); SPI_InitTypeDef spi; spi.SPI_Direction = SPI_Direction_1Line_Tx; spi.SPI_Mode = SPI_Mode_Master; spi.SPI_DataSize = SPI_DataSize_16b; spi.SPI_CPOL = SPI_CPOL_Low; //полярность сигнала синхронизации spi.SPI_CPHA = SPI_CPHA_1Edge; //фронт синхронизации spi.SPI_NSS = SPI_NSS_Soft; spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; spi.SPI_FirstBit = SPI_FirstBit_MSB; //передавать сначала младший бит spi.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &spi); SPI_Cmd(SPI1, ENABLE); GPIO_ResetBits(GPIOA, GPIO_Pin_8); SPI_I2S_SendData(SPI1, 0x80F1); SPI_I2S_SendData(SPI1, 0x80F2); SPI_I2S_SendData(SPI1, 0x80F4); SPI_I2S_SendData(SPI1, 0x80F8); GPIO_SetBits(GPIOA, GPIO_Pin_8); while(1) { } } Так не работает. Причем могу за комментировать строки GPIO_ResetBits(GPIOA, GPIO_Pin_8); GPIO_SetBits(GPIOA, GPIO_Pin_8); результат не меняется Кстати пытаюсь к STM32 подключить Arduino Multifunction Shield http://arduinolearning.com/code/multi-function-shield-examples.php И у них оно примерно так и работает: digitalWrite(LATCH_DIO,LOW); shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_MAP[Value]); shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] ); digitalWrite(LATCH_DIO,HIGH); Проверял код из примера в ссылке на Arduino mega 2560, этот шилд отлично все отображает
  8. Добрый день коллеги! Имеется микроконтроллер STM32F103C8, к нему подключен внешняя микросхема - регистр разрядностью 64 бита. Управление происходит по трем линиям: LATCH_DIO - разрешение записи в регистр (LOW) CLK_DIO - синхронизация DATA_DIO - данные (последовательно, побитно) Очень напоминает работу SPI поэтому и решил для начала попробовать приспособить его. Но ничего не вышло так-как по SPI в одном пакете может передать максимально 16 бит данных. Полагаю что необходимо использовать GPIO для этого. Но вот беда не могу понять как из переменной извлечь биты данных и установить их на DATA_DIO последовательно? Или может быть есть еще какие-то решения? Разработку веду в CoIDE v.1.7
×
×
  • Создать...