Saya sudah mencoba untuk mendapatkan SPI1 pada STM32F103C8 ( papan Blue Pill ) yang bekerja dengan benar untuk beberapa waktu sekarang. Karena saya baru mulai belajar ARM, saya hanya mencoba untuk memindahkan data ke register geser 74HC595 dan mengaitkannya untuk menerangi satu byte LED. Saya tidak membaca kembali data apa pun, jadi saya hanya memiliki garis MOSI, SCK dan SS.
Pada awalnya saya tidak mendapatkan apa-apa, tetapi membaca beberapa contoh online saya dapat memperbaiki masalah pertama ini untuk mendapatkan komunikasi (saya perlu mengatur pin GPIOA dengan benar dan mengatur perangkat lunak SS).
Masalah utama saat ini adalah bahwa jika saya tidak menyertakan resistor pull-up di semua lini (MOSI, SCK, dan SS) mikrokontroler tidak menampilkan apa pun pada saluran apa pun (diperiksa dengan cakupan). Selain itu, setelah menambahkan resistor pull-up, waktu naik pada pulsa sangat lambat sehingga saya tidak dapat menggunakan frekuensi terlalu tinggi (dengan resistor pull-up 10 kΩ, saya terbatas pada sekitar 250 kHz SCK, dan beralih hingga 330 Ω sekitar 4 MHz). Saya bekerja pada papan tempat memotong roti, tetapi bahkan dengan AVR dan kabel messier saya bisa mendapatkan 4 MHz SPI bekerja tanpa masalah tanpa resistor tambahan dan bentuk gelombang lebih bersih.
Berikut adalah dua gambar (maaf atas kondisi buruk layar lingkup saya) mentransmisikan byte 0b01110010 pada jam 250 kHz. Jejak atas adalah SCK dan bagian bawah adalah MOSI. Gambar pertama adalah dengan resistor pull-up 10 kΩ dan yang kedua dengan resistor pull-up 330 that yang membuat bentuk gelombang jauh lebih baik (tetapi seharusnya tidak diperlukan).
Saya menghargai bantuan untuk mencari tahu apa yang terjadi.
Bagian yang relevan dari kode saya adalah:
#define SS_LOW GPIOA->BSRR |= 1 << 4 + 16;
#define SS_HIGH GPIOA->BSRR |= 1 << 4;
// SPI GPIO configuration
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
GPIOA->CRL |= 0b0011 << 4 * 4; // Set pin A4 as PP out 50mHz for SS
GPIOA->CRL |= 0b1011 << 5 * 4; // Set pin A5 AltFunc PP out 50mHz for SCK
GPIOA->CRL |= 0b1011 << 7 * 4; // Set pin A7 AltFunc PP out 50mHz for MOSI
SS_HIGH;
// SPI1 configuration
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // Enable SPI1 clock
SPI1->CR1 |= SPI_CR1_SSM; // Software SS
SPI1->CR1 |= SPI_CR1_SSI;
SPI1->CR1 |= SPI_CR1_BR_0; // Set prescaler
SPI1->CR1 |= SPI_CR1_BR_1;
SPI1->CR1 |= SPI_CR1_BR_2;
SPI1->CR1 |= SPI_CR1_MSTR; // Master mode
SPI1->CR1 |= SPI_CR1_SPE; // Enable SPI
// Transmit byte
SS_LOW;
SPI1->DR = 0b01110010;
while(!(SPI1->SR & SPI_SR_TXE));
while(SPI1->SR & SPI_SR_BSY);
SS_HIGH;
Jawaban:
Anda harus mengatur ulang nilai pin yang Anda ubah sebelum mengatur bit.
Nilai reset GPIOA_CRL adalah 0x4444 4444. Jadi setiap pin diinisialisasi dengan 0b0100, jika Anda melakukan | = 0b0011 Anda berakhir dengan 0b0111 yang merupakan output drain terbuka. Sama dengan 0b1011 menjadi 0b1111 dan itu adalah fungsi alternatif tiriskan terbuka.
Jadi, Anda perlu melakukan sesuatu seperti ini:
sumber