SPI pada STM32 tidak akan bekerja tanpa resistor pullup dan bahkan berkinerja buruk


8

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.

Resistor pull-up 10 kΩ dan clock 250 kHz

Resistor pull-up 330 and dan 250 kHz membuat gelombang jauh lebih bagus

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;

Apa pengaturan Anda? Bagaimana kabel Anda terhubung? Apakah Anda menggunakan papan khusus atau papan tempat memotong roti?
Tarick Welling

Saya menggunakan papan tempat memotong roti. The 74hc595 didukung dari 3.3V dari papan pil biru (ini tepatnya: revspace.nl/File:Bluepill.jpg ). Kabel hanya pergi dari dan ke register geser adalah MOSI, SCK dan SS. Saya yakin kabelnya benar, saya memeriksanya berkali-kali (dan sekali lagi sebelum menjawab Anda).
jjpprr

Jawaban:


12

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:

// Reset pin configuration
GPIOA->CRL &= ~(0b1111 << 4 * 4);  // Reset Pin A4
GPIOA->CRL &= ~(0b1111 << 5 * 4);  // Reset Pin A5
GPIOA->CRL &= ~(0b1111 << 7 * 4);  // Reset Pin A7
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

Ini dia !! Terima kasih banyak, saya tahu itu akan menjadi sesuatu yang sangat sederhana. Seharusnya membaca baris pertama pada GPIOA_CRL dari datasheet, saya hanya berasumsi nilai reset semua nol. Sekarang itu berfungsi sebagai pesona.
jjpprr

@ jjpprr juga butuh beberapa saat untuk menyadari juga :-) Senang saya bisa membantu. Jika Anda akan menggunakan I²C pada F103, bersiaplah untuk perjalanan yang berat, saya ingat itu mengerikan.
Arsenal

: O akan mempertimbangkannya, setelah mengaktifkan USART dan menjalankannya, giliran I2Cs. Terimakasih atas peringatannya.
jjpprr

Hal yang paling menonjol di mana interupsi saya dapatkan tanpa sumber interupsi yang mengacaukan mesin negara saya. Pada akhirnya saya melakukan pendekatan yang tidak menggunakan interupsi I²C sama sekali (tetapi interupsi DMA untuk akhir transmisi) dan hanya melakukan polling bit I²C untuk memulai dan hal-hal lain, tetapi aplikasi saya harus tetap menunggu I²C selesai. , jadi saya tidak mendapatkan waktu dengan interupsi.
Arsenal

Apakah ini hanya dengan F103 atau juga chip STM32 lainnya? Karena rencana saya adalah menggunakannya hanya untuk memahami ICM stm32 tetapi kemudian beralih ke F091 untuk proyek-proyek kecil dan F446 untuk hal-hal yang lebih menuntut.
jjpprr
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.