Получилось добиться от spi максимальной скорости.
Выкинуть все задержки и прерывания 🙂 .
Надеюсь правильно надергал фрагментов кода из своих файлов 🙂 .
//Enable clock access to GPIOA RCC->APB2ENR|=RCC_APB2ENR_IOPAEN; //Enable clock access to alternate function RCC->APB2ENR|=RCC_APB2ENR_AFIOEN
/* PA5-SCK and PA7-MOSI */ //Mode: Output, Speed: 10MHz GPIOA->CRL &= ~(GPIO_CRL_MODE5); GPIOA->CRL &= ~(GPIO_CRL_MODE7); GPIOA->CRL |= (GPIO_CRL_MODE5_0); GPIOA->CRL |= (GPIO_CRL_MODE7_0); //Alternate function push-pull GPIOA->CRL &= ~(GPIO_CRL_CNF5); GPIOA->CRL &= ~(GPIO_CRL_CNF7); GPIOA->CRL |= (GPIO_CRL_CNF5_1); GPIOA->CRL |= (GPIO_CRL_CNF7_1); /*Configure PA4 as output CS*/ GPIOA->CRL&=~(GPIO_CRL_CNF4); GPIOA->CRL|=GPIO_CRL_MODE4_0;
void SpiInit(void) { //SPI1_REMAP=0 Don't remap //Bit 0 SPI1_REMAP: AFIO->MAPR&=~AFIO_MAPR_SPI1_REMAP; //Enable SPI Clock RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; //25.5.1 SPI control register 1 (SPI_CR1) (not used in I2S mode) //Mode: Master /* Bit 2 MSTR: Master selection 0: Slave configuration 1: Master configuration Note: This bit should not be changed when communication is ongoing. It is not used in I2S mode. */ SPI1->CR1 |= SPI_CR1_MSTR; /* Bits 5:3 BR[2:0]: Baud rate control 000: fPCLK/2 001: fPCLK/4 010: fPCLK/8 011: fPCLK/16 100: fPCLK/32 101: fPCLK/64 110: fPCLK/128 111: fPCLK/256 */ //Baud rate to (72MHz / 8 = 9MHz)-010: fPCLK/8 SPI1->CR1 &= ~(SPI_CR1_BR_Msk); SPI1->CR1 |= SPI_CR1_BR_1;//0b010<<3; //MSB first /* Bit 7 LSBFIRST: Frame format 0: MSB transmitted first 1: LSB transmitted first */ SPI1->CR1 &= ~(SPI_CR1_LSBFIRST); //(Full duplex (Transmit/Receive)) /* Bit 10 RXONLY: Receive only This bit combined with the BIDImode bit selects the direction of transfer in 2-line unidirectional mode. This bit is also useful in a multislave system in which this particular slave is not accessed, the output from the accessed slave is not corrupted. 0: Full duplex (Transmit and receive) 1: Output disabled (Receive-only mode) */ SPI1->CR1 &= ~(SPI_CR1_RXONLY); //Data format 8-bit SPI1->CR1 &= ~(SPI_CR1_DFF); //Data format 16-bit //SPI1->CR1 |= (SPI_CR1_DFF); /* Bit 9 SSM: Software slave management When the SSM bit is set, the NSS pin input is replaced with the value from the SSI bit. 0: Software slave management disabled 1: Software slave management enabled Note: This bit is not used in I2S mode Bit 8 SSI: Internal slave select This bit has an effect only when the SSM bit is set. The value of this bit is forced onto the NSS pin and the IO value of the NSS pin is ignored. Note: This bit is not used in I2S mode */ //Software Slave select SPI1->CR1 |= SPI_CR1_SSI; SPI1->CR1 |= SPI_CR1_SSM; /*Set TXDMA bit in CR2*/ //SPI1->CR2|=SPI_CR2_TXDMAEN; //SPI Enable SPI1->CR1 |= SPI_CR1_SPE; //25.5.3 SPI status register (SPI_SR) //Clear initial flags (void)SPI1->SR; (void)SPI1->DR; }
void cs_low() { GPIOA->BSRR=GPIO_BSRR_BR4; } void cs_high() { GPIOA->BSRR=GPIO_BSRR_BS4; }
#define DECODE_MODE_REG 0x09 #define INTENSITY_REG 0x0A #define SCAN_LIMIT_REG 0x0B #define SHUTDOWN_REG 0x0C void write_reg(uint8_t rg, uint8_t dt) { while(SPI1->SR & SPI_SR_BSY){} cs_low(); while(!(SPI1->SR & SPI_SR_TXE)); *((volatile uint8_t *)&SPI1->DR) = (uint8_t)(rg & 0xFFU); while(!(SPI1->SR & SPI_SR_TXE)); *((volatile uint8_t *)&SPI1->DR) = (uint8_t)(dt & 0xFFU); while(SPI1->SR & SPI_SR_BSY){} cs_high(); (void)SPI1->DR; (void)SPI1->SR; }
void clear(void) { for (int i = 0; i < 8; i++) { write_reg(i + 1, 0x00); } } void max7219_init() { write_reg(DISPLAY_TEST_REG, 0); write_reg(SCAN_LIMIT_REG, 7); write_reg(DECODE_MODE_REG, 0); write_reg(SHUTDOWN_REG, 1); clear(); }