آموزش STM32آموزش آردوینوآموزش های ARM

آموزش ارتباط بین آردوینو و STM32 با پروتکل SPI

سلام. آموزش ارتباط بین آردوینو و STM32 با پروتکل SPI را آماده کردیم.

انتقال اطلاعات بین Arduino و STM32 با SPI

در آموزش قبلی ما با نحوه برقراری ارتباط I2C بین آردوینو و STM32 آشنا شدیم. در این آموزش ما این دو برد را از طریق ارتباط SPI به هم متصل خواهیم کرد. در هر طرف، یک ال سی دی کاراکتری و یک پتانسیومتر قرار گرفته است. مقدار آنالوگ به دیجیتال شده ی هر پتانسیومتر، در ال سی دی مقابل نمایش داده میشود. درباره آنالوگ به دیجیتال در STM32 بیشتر بدانید.

با چرخاندن پتانسیومتر در یک طرف ، می توانید مقدار آن را در LCD از طرف دیگر مشاهده کنید. فیلم زیر به شما در درک نحوه کار این پروژه کمک میکند.

مقایسه ارتباط SPI در STM32 و آردوینو

برد STM32 دارای دو لاین برای ارتباط SPI است در حالی که آردوینو Uno دارای یک لاین است. Arduino Uno دارای میکروکنترلر ATMEGA328 در آن است و STM32F103C8 دارای ARM Cortex-M3 است که باعث می شود آن سریعتر از Arudino Board باشد.

پین های SPI در STM32F103C8

در تصویر زیر پین های SPI در STM32F103C8 نمایش داده شده است.

جزئیات پین های STM32

SPI لاین 1 پین STM32
MOSI1 PA7 یا PB5
MISO1 PA6 یا PB4
SCK1 PA5 یا PB3
SS1 PA4 یا PA15
SPI لاین 2
MOSI2 PB15
MISO2 PB14
SCK2 PB13
SS2 PB12

پین های SPI در Arduino

در تصویر زیر پین های پروتکل SPI در برد آردوینو Uno مشخص شده است.

پین های SPI در Arduino

SPI لاین پین آردوینو
MOSI 11 یا ICSP-4

MISO 12 یا ICSP-1
SCK 13 یا ICSP-3
SS 10

مدار برقراری ارتباط SPI بین آردوینو و STM32

تصویر زیر مدار و نحوه اتصال برد آردوینو به STM32 را نشان میدهد.

نحوه اتصال برد آردوینو به STM32

در جدول زیر پین های اتصال برای ارتباط STM32 SPI با Arduino نشان داده شده است.

SPI پین STM32 Arduino
MOSI PA7 11
MISO PA6 12
SCK PA5 13
SS1 PA4 10

در جدول زیر پین های متصل به دو ال سی دی کاراکتری 16*2 با STM32F103C8 و Arduino به طور جداگانه نشان داده شده است. فراموش نکنید که Arduino GND و STM32F103C8 GND را به هم متصل کنید.

پین ال سی دی STM32 آردوینو
VSS GND GND
VDD +5V +5V
V0 متصل به پتانسیومتر متصل به پتانسیومتر
RS PB0 2
RW GND GND
E PB1 3
D4 PB10 4
D5 PB11 5
D6 PC13 6
D7 PC14 7
A +5V +5V
K GND GND

قطعات مورد نیاز

  1. STM32 – برد توسعه (BluePill) (STM32F103C8T6)
  2. برد آردوینو Uno
  3. ال سی دی کاراکتری 16*2
  4. پتانسیومتر 10 کیلو اهم – چهار عدد
قطعات مورد نیاز را از فروشگاه قطعات آیرنکس تهیه کنید.

کد ارتباط SPI بین آردوینو و STM32

کتابخانه <SPI.h> در برنامه نویسی STM32F103C8 استفاده می شود. می توان با استفاده از درگاه USB بدون استفاده از پروگرامر FTDI برد STM32 را برنامه ریزی کرد : آموزش برنامه نویسی STM32 با پورت USB در اینجا ما از Arduino UNO و STM32F103C8 با دو نمایشگر LCD 16X2 جداگانه استفاده خواهیم کرد. دو پتانسیلومتر همچنین به پین STM32 PA0 و Arduino A0 برای تعیین مقادیر ارسال (0 تا 255) برای انتقال اطلاعات بین هر دو برد، به هر برد متصل میشود.

ورودی آنالوگ با چرخش پتانسیومتر در پین PA0 STM32  تا 3.3V گرفته می شود. سپس این مقدار ورودی به مقدار آنالوگ به دیجیتال (0 تا 4096) تبدیل می شود و این مقدار دیجیتال به (0 تا 255) تبدیل می شود زیرا می توانیم فقط داده های 8 بیتی (بایت) را از طریق ارتباط SPI ارسال کنیم. به طور مشابه در سمت Arduino مقدار ورودی آنالوگ را در پین آردوینو A0 از (0 تا 5 ولت) با استفاده از پتانسیومتر می گیریم. و مجدداً این مقدار ورودی به مقدار آنالوگ به دیجیتال (0 تا 1023) تبدیل می شود و این مقدار دیجیتالی به (0 تا 255) تبدیل می شود.

اگر در مورد این مطلب سوالی دارید در قسمت نظرات بپرسید

این آموزش دارای دو برنامه یکی برای STM32 و دیگری برد Arduino است. کد کامل برای هر دو قسمت در پایان آموزش قرار داده شده است. در اینجا بعضی از قسمت های کد را بررسی میکنیم.

توضیحات برنامه نویسی STM32

1. اول از همه ما باید کتابخانه SPI را برای استفاده از توابع ارتباطی SPI و کتابخانه LCD را برای استفاده از توابع LCD درج کنیم. همچنین پین های LCD را برای LCD 16×2 تعریف می کنیم. در مورد اتصال LCD به STM32 بیشتر بدانید.

#include<SPI.h>    
#include<LiquidCrystal.h> 
const int rs = PB0, en = PB1, d4 = PB10 , d5 = PB11 , d6 = PC13, d7 = PC14;  
LiquidCrystal lcd(rs,en,d4,d5,d6,d7);

2. در void setup()

ارتباط سریال را با Baud Rate 9600 شروع کنید.

Serial.begin(9600);  

سپس ارتباط SPI را شروع کنید.

SPI.begin(); 

سپس تقسیم کننده Clock را برای ارتباطات SPI تنظیم کنید. من تقسیم کننده 16 را تنظیم کرده ام.

SPI.setClockDivider(SPI_CLOCK_DIV16);   

سپس پین SS HIGH را تنظیم کنید زیرا ما هیچگونه انتقالی را به آردوینو را شروع نکردیم.

digitalWrite(SS,HIGH);    

3. در void loop()

قبل از ارسال هر مقدار به آردوینو، ما باید مقدار انتخاب را Low کنیم.

digitalWrite(SS, LOW);   

بعد مقدار آنالوگ را از پتانسیومتر متصل به متصل به پین ​​PA0 STM32 میخوانیم.

int pot = analogRead(PA0);  

سپس این مقدار را بر یک بایت (0 تا 255) تبدیل میکنیم.

byte MasterSend = map(pot,0,4096,0,255);  

در اینجا مرحله مهم آمده است ، در عبارت زیر مقدار POT تبدیل شده ذخیره شده در متغیر Mastersend را به Arduino ارسال می کنیم ، و همچنین مقدار را از Arduino دریافت می کنیم و آن را در متغیر masterereceive ذخیره می کنیم.

 Mastereceive = SPI.transfer(Mastersend);

سپس مقادیر دریافت شده با تاخیر 0.5 ثانیه ای به طور مداوم دریافت و نمایش داده میشوند. برای دیدن نتیجه در سریال موتور Arduino IDE از serial.println () استفاده می کنیم.

Serial.println("Slave Arduino to Master STM32");                               
Serial.println(MasterReceive  lcd.setCursor(0,0);                                                         
 lcd.print("Master: STM32");
 lcd.setCursor(0,1);                                                   
 lcd.print("SalveVal:");                                                         
 lcd.print(MasterReceive  delay(500);
 digitalWrite(SS, HIGH); 

کد کامل STM32

کد کامل قسمت STM32 ارتباط SPI در باکس زیر آورده شده است.

#include<SPI.h>                                                 
#define SS PA4                                                              
#include<LiquidCrystal.h>   
                              
const int rs = PB0, en = PB1, d4 = PB10 , d5 = PB11 , d6 = PC13, d7 = PC14; 
LiquidCrystal lcd(rs,en,d4,d5,d6,d7); 
                       
void setup (void)
{
  lcd.begin(16,2);                            
  lcd.setCursor(0,0);                      
  lcd.print("CIRCUIT DIGEST");                
  delay(3000);                    
  lcd.clear();                             
  Serial.begin(9600);     
  pinMode(SS,OUTPUT);                
  SPI.begin();                            
  SPI.setClockDivider(SPI_CLOCK_DIV16);     
  digitalWrite(SS,HIGH);                        
}

void loop(void)
{   
  byte MasterSend,MasterReceive;  
  int pot = analogRead(PA0);                              
  MasterSend = map(pot,0,4096,0,255);                            
  digitalWrite(SS, LOW);                                
  MasterReceive=SPI.transfer(MasterSend);                         
  Serial.println("Slave Arduino to Master STM32");                
  Serial.println(MasterReceive);                                
  lcd.setCursor(0,0);                                                          
  lcd.print("Master: STM32");
  lcd.setCursor(0,1);                                                    
  lcd.print("SalveVal:");                                                         
  lcd.print(MasterReceive);                                 
  delay(500);
  digitalWrite(SS, HIGH);                                                
  lcd.clear();
}

توضیحات برنامه نویسی Arduino

1. مانند STM32، برای برد Arduino هم اول از همه ما باید کتابخانه SPI را برای استفاده از توابع ارتباطی SPI و کتابخانه LCD برای استفاده از توابع LCD درج کنیم. همچنین پین های LCD را برای LCD 16×2 تعریف میشود.

#include<SPI.h>  
#include<LiquidCrystal.h> 
 LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

2. در void setup()

ارتباط سریال را با نرخ Baud Rate 9600 شروع می کنیم.

Serial.begin(9600);  

در زیر عبارت MISO را به عنوان OUTPUT تعیین می کنیم. داده های ارسال شده از طریق MISO از آردوینو ارسال می شوند.

pinMode(MISO,OUTPUT);   

اکنون SPI را در حالت برده با استفاده از SPI Control Register ثبت میکنیم.

SPCR |= _BV(SPE);

سپس برای ارتباط SPI وقفه را فعال میکنیم . اگر داده ای از STM32 دریافت شده باشد ، سرویس وقفه روتین فعال می شود و مقدار دریافت شده گرفته می شود.

SPI.attachInterrupt();   

مقدار از SPDR گرفته شده و در متغیر Slavereceived ذخیره می شود. این کار در کد زیر اتفاق می افتد.

ISR (SPI_STC_vect)
{
  Slavereceived = SPDR;                  
  received = true;                       
}

3. در void loop ()

مقدار آنالوگ را از پتانسیومتر Arduino متصل به پین ​​A0 میخوانیم.

int pot = analogRead(A0);

مقدار آن را به یک بایت از 0 به 255 تبدیل میکنیم.

Slavesend = map(pot,0,1023,0,255);

مرحله مهم بعدی ارسال مقدار تبدیل شده به STM32F10C8 است ، بنابراین مقدار را در رجیستری SPDR قرار میدهیم. از رجیستر SPDR برای ارسال و دریافت مقادیر استفاده می شود.

SPDR = Slavesend;

سپس مقدار دریافتی (SlaveReceive) را از STM32F103C8 بر روی LCD با تاخیر 0.5 ثانیه ای نمایش میدهیم و سپس مرتبا آن مقدار را بروزرسانی میکنیم.

 lcd.setCursor(0,0);                     
 lcd.print("Slave: Arduino");
 lcd.setCursor(0,1);                                                    
 lcd.print("MasterVal:");   
 Serial.println("Master STM32 to Slave Arduino");  
 Serial.println(SlaveReceived);                  
 lcd.print(SlaveReceived);                       
 delay(500);

کد کامل Arduino

کد کامل قسمت Arduino ارتباط SPI در باکس زیر آورده شده است.

#include<SPI.h>                      
#include<LiquidCrystal.h>   
        
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);    
volatile boolean received;
volatile byte SlaveReceived,Slavesend;

void setup()
{ 
  lcd.begin(16,2);          
  lcd.setCursor(0,0);            
  lcd.print("CIRCUIT DIGEST");       
  delay(3000);                 
  lcd.clear();           
  Serial.begin(9600);      
  pinMode(MISO,OUTPUT);           
  SPCR |= _BV(SPE);          
  received = false;
  SPI.attachInterrupt();         
}

ISR (SPI_STC_vect)        
{
  SlaveReceived = SPDR;       
  received = true;              
}

void loop()
{ 
  int pot = analogRead(A0);     
  Slavesend = map(pot,0,1023,0,255);                                 
  SPDR = Slavesend;          
  lcd.setCursor(0,0);                     
  lcd.print("Slave: Arduino");
  lcd.setCursor(0,1);                                                     
  lcd.print("MasterVal:");    
  Serial.println("Master STM32 to Slave Arduino");   
  Serial.println(SlaveReceived);                  
  lcd.print(SlaveReceived);         
  delay(500);
  lcd.clear();
}
4.6 (7 نفر)

برای دریافت مطالب جدید کانال تلگرام یا پیج اینستاگرام ما را دنبال کنید.

محمد رحیمی

محمد رحیمی هستم. سعی میکنم در آیرنکس مطالب مفید قرار بدهم. سوالات مربوط به این مطلب را در قسمت نظرات همین مطلب اعلام کنید. سعی میکنم در اسرع وقت به نظرات شما پاسخ بدهم.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *