pixy php,Pixy2与STM32进行SPI通信
簡單來說,如果你通過檢索從而看到這篇文章,那就假設你已經知道Pixy2是用來干什么的(一款功能強大的開源視覺傳感器),以及你已擁有一些STM32基礎。你可以通過訪問官方手冊來獲得更多關于Pixy2的相關信息。
如果你已經非常了解Pixy2的運作模式,只是想快速與STM32建立通信,那么你可以直接參考我的代碼:
通常情況下Pixy2是搭配Arduino使用的,并且Pixy2能通過SPI以2 Mbits/秒的速度向Arduino發送信息。不過如果讓Pixy2與不同的平臺進行通信,首先就要確定以哪種方式進行通信。官方給出Pixy2支持的通信方式有SPI、I2C、UART、USB和Analog/digital,并且通信速度USB>SPI>I2C>UART>A/D。本文將具體描述Pixy2與STM32的SPI通信。
設置與連接
首先,你需要去官網下載一個叫PixyMon的軟件,它能讓你在Windows或Mac平臺對Pixy2進行設置。
將你的Pixy2與電腦用USB線連接后,打開軟件,在Configure-Interface-Data out port選項中,我們選擇Arduino ICSP SPI。是的,即使是與Arduino通信的SPI選項,也可以應用到STM32上,其他選項不用更改。
設置好后,我們把Pixy2與電腦連接的USB斷開,用杜邦線將Pixy2與STM32連接,我這里用的STM32是正點原子的STM32mini開發板。在連接之前,我們先看一下Pixy2的管腳圖:
在Arduino ICSP SPI模式中主要用到(1)(3)(4)三個管腳,還有5V和GND與STM32的5V和GND直接相連就行了,兩者具體的連接方法如下:
Pin 1 (SPI MISO) ? PA6 (STM32 SPI MISO signal)
Pin 4 (SPI MOSI) ? PA7 (STM32 SPI MOSI signal)
Pin 3 (SPI SCK) ? PA5 (STM32 SPI SCK signal)
Pin 2 ? 5V (STM32 5V)
Pin 6 ? GND (STM32 GND)
串口協議
Pixy2是以數據包的形式來和上位機進行通信的,也就是說,想要和Pixy2通信,你必須向Pixy2發送一個請求數據包,然后Pixy2再把你想要得到的數據或者狀態用數據包發給你。所以你的請求/反饋數據包就像下面的格式:
Requests-(你發給pixy的)
字節
說明
數值
0-1
16-bit sync
174, 193 (0xc1ae)
2
Type of packet
(varies)
3
Length of payload in bytes (len)
(varies)
4-len
Variable length payload
(varies)
Responses-(pixy發給你的)
字節
說明
數值
0-1
16-bit sync
175, 193 (0xc1af)
2
Type of packet
(varies)
3
Length of payload in bytes (len)
(varies)
4-5
16-bit checksum
sum of payload bytes
6-len
Variable length payload
(varies)
就拿請求數據包來說,上位機向Pixy2發送長度為 len 字節的數據包,其中0-1字節是同步碼,同步碼又分為:
帶校驗位的同步碼 0xc1af
不帶校驗位的同步碼 0xc1ae
所以你的請求數據包里的0-1字節一般是固定的,然后剩下的字節根據你想要Pixy2反饋的功能來改變。至于每種功能的詳細格式,官網的手冊已經詳細列出了,你細品。
Pixy2收到上位機發送的數據包后,會根據要求返送一個包含著數據的包,也是以同步碼打頭,后面跟著就是你想要的數據了,不同的請求數據包有不同的反饋數據包,至于Pixy2發出的同步碼有什么用,我們會在實例中具體講述。你可以用UART串口把這些數據打印在電腦屏幕上,這會更好的幫助你了解Pixy2的通信原理。
實例1
現在,就以STM32用SPI通信向Pixy2發送一個請求版本的數據包,來獲取Pixy2版本,并將Pixy2返回的數據打印在屏幕上的一個實例。
根據官網的說明:
getVersion()
Request:
字節
說明
數值
0-1
16-bit sync
174, 193 (0xc1ae)
2
Type of packet
14
3
Length of payload
0
就是說,你想獲取Pixy2的版本,你要發送4個字節的數據包給Pixy查詢,前兩個字節是同步碼,第三個是14,第四個是0,我們來看看,怎么樣用Keil來寫這個發送數據包的程序。
#define PIXY_CHECKSUM_SYNC 0xc1af //帶校驗位的同步碼
#define PIXY_NO_CHECKSUM_SYNC 0xc1ae //不帶校驗位的同步碼
#define GETVERSION_LENSEND 4 //發送數據包長度
#define GETVERSION_LENRECEIVED 22 //接收數據包長度,先假設是22個字節
uint8_t i, header_buf[16]; //header_buf用來存放發送的數據
uint8_t recvBuf[32]; //recvBuf用來存放接收到的數據
void Pixy2_SendRecvPacket_getVersion(uint8_t* received)
{
header_buf[0] = PIXY_NO_CHECKSUM_SYNC&0xff; //把同步碼拆開
header_buf[1] = PIXY_NO_CHECKSUM_SYNC>>8;
header_buf[2] = 0x0e; //14
header_buf[3] = 0x00; //0
for (i=0;i
SPI1_ReadWriteByte(header_buf[i]);
for(i=0;i
received[i]=SPI1_ReadWriteByte(0XFF);
}
int main(void)
{
while(1)
{
key=KEY_Scan(0);
if(key==WKUP_PRES) //WK_UP按下后就發送版本查詢數據包
{
Pixy2_SendRecvPacket_getVersion(recvBuf); //發送并接收數據
printf("Received %d bytes.\r\n", GETVERSION_LENRECEIVED);
for (i=0; i
printf("%hhu: %#x\r\n", i, recvBuf[i]);
}
}
}
跟著注釋,是不是也不難看懂?雖然這些程序并不完整,但它能夠完整的表達與Pixy2通信的整個過程。按下開發板上WK_UP按鍵后,發送并接收數據包,然后用串口顯示接收到的字節,我們打開串口調試助手來康康:
仔細看,接收到的字節,第一個是0x6c,第二個是0,講道理不應該是0xaf和0xc1嗎?因為Pixy2發送的數據包,一定會以同步碼打頭,那現在接收到的這兩個是啥東西?我也不知道,但我知道這兩個數據肯定不是我們想要的。可以看到字節7,8,9分別是0xaf,0xaf,0xc1。有兩個0xaf,而且好像字節8,9是我們想要的同步碼,那是不是可以寫一個語句來判斷字節7如果是0xaf,那么接下來所有的數據都是我們想要的,所以只用將字節7之后的字節放入recvBuf[]就行了呢?看如下的程序:
uint8_t PIXY_GET_FLAG_AF=0XAF;//af標志字節
void Pixy2_SendRecvPacket_getVersion(uint8_t* received)
{
header_buf[0] = PIXY_NO_CHECKSUM_SYNC&0xff;
header_buf[1] = PIXY_NO_CHECKSUM_SYNC>>8;
header_buf[2] = 0x0e;
header_buf[3] = 0x00;
for (i=0;i
SPI1_ReadWriteByte(header_buf[i]);
//接收數據但不寫入received[]直到接收到的數據為0xaf
while (PIXY_GET_FLAG_AF!=SPI1_ReadWriteByte(0XFF));
//接收第二個0xaf以及之后的字節
for(i=0;i
received[i]=SPI1_ReadWriteByte(0XFF);
}
對之前的程序進行修改,加入了一行關鍵語句,我們再來看看串口調試助手的輸出:
好像有點像我們希望看到的數據了,其實在官網上有一段說明,就是通過向Pixy2發送獲取版本(getVersion())數據包,你會得到的字節,如下圖:
對比看下我們獲得的字節,發現我們的數據是正確的(雖然根據版本不同,數據可能不同),程序也是可行的。
還能通過STM32來獲取Pixy2看到色塊的坐標,如下圖:
其實Pixy2是一款非常好玩的視覺傳感器,它能應用到許多場合,在它的官網手冊中列出了所有的功能數據包格式,獲取版本就是其中之一,每種功能包的格式以請求數據包格式和其對應的反饋數據包格式給出,你可以根據手冊中的請求數據包格式來寫程序,然后對比手冊中的反饋數據包格式和你真正接收到的數據,看看自己的程序是否有效。下面列出了一些我寫的,認為比較重要的一些請求數據包程序庫,你可以根據我的格式來寫其他你需要的功能程序庫,當然你也可以用更優化的方法來自己寫。
pixy2.c
#include "delay.h"
#include "sys.h"
#include "spi.h"
#include "pixy2.h"
uint8_t i, header_buf[16], PIXY_GET_FLAG_AF=0XAF;
//getVersion()獲取版本
void Pixy2_SendRecvPacket_getVersion(uint8_t* received)
{
header_buf[0] = PIXY_NO_CHECKSUM_SYNC&0xff;
header_buf[1] = PIXY_NO_CHECKSUM_SYNC>>8;
header_buf[2] = 0x0e;
header_buf[3] = 0x00;
for (i=0;i
SPI1_ReadWriteByte(header_buf[i]);
while (PIXY_GET_FLAG_AF!=SPI1_ReadWriteByte(0XFF));
for(i=0;i
received[i]=SPI1_ReadWriteByte(0XFF);
}
//getBlocks()獲取色塊
void Pixy2_SendRecvPacket_getBlocks(uint8_t* received, uint8_t sigmap, uint8_t numBlocks)
{
header_buf[0] = PIXY_NO_CHECKSUM_SYNC&0xff;
header_buf[1] = PIXY_NO_CHECKSUM_SYNC>>8;
header_buf[2] = 0x20;
header_buf[3] = 0x02;
header_buf[4] = sigmap;
header_buf[5] = numBlocks;
for (i=0;i
SPI1_ReadWriteByte(header_buf[i]);
while (PIXY_GET_FLAG_AF!=SPI1_ReadWriteByte(0XFF));
for(i=0;i
received[i]=SPI1_ReadWriteByte(0XFF);
}
//setCameraBrightness()調節相機亮度
void Pixy2_SendRecvPacket_setCameraBrightness(uint8_t* received, uint8_t brightness)
{
header_buf[0] = PIXY_NO_CHECKSUM_SYNC&0xff;
header_buf[1] = PIXY_NO_CHECKSUM_SYNC>>8;
header_buf[2] = 0x10;
header_buf[3] = 0x01;
header_buf[4] = brightness;
for (i=0;i
SPI1_ReadWriteByte(header_buf[i]);
while (PIXY_GET_FLAG_AF!=SPI1_ReadWriteByte(0XFF));
for(i=0;i
received[i]=SPI1_ReadWriteByte(0XFF);
}
//setLamp()開關照明燈
void Pixy2_SendRecvPacket_setLamp(uint8_t* received, uint8_t upper, uint8_t lower)
{
header_buf[0] = PIXY_NO_CHECKSUM_SYNC&0xff;
header_buf[1] = PIXY_NO_CHECKSUM_SYNC>>8;
header_buf[2] = 0x16;
header_buf[3] = 0x02;
header_buf[4] = upper;
header_buf[5] = lower;
for (i=0;i
SPI1_ReadWriteByte(header_buf[i]);
while (PIXY_GET_FLAG_AF!=SPI1_ReadWriteByte(0XFF));
for(i=0;i
received[i]=SPI1_ReadWriteByte(0XFF);
}
pixy2.h
#ifndef __PIXY2_H
#define __PIXY2_H
#include "sys.h"
#define PIXY_DEFAULT_ARGVAL 0x80000000
#define PIXY_BUFFERSIZE 0x104
#define PIXY_CHECKSUM_SYNC 0xc1af
#define PIXY_NO_CHECKSUM_SYNC 0xc1ae
#define PIXY_SEND_HEADER_SIZE 4
#define PIXY_MAX_PROGNAME 33
#define GETVERSION_LENSEND 4
#define GETVERSION_LENRECEIVED 22
#define GETBLOCKS_LENSEND 6
#define GETBLOCKS_LENRECEIVED 20
#define setBrightness_LENSEND 5
#define setBrightness_LENRECEIVED 10
#define setLamp_LENSEND 6
#define setLamp_LENRECEIVED 10
void Pixy2_SendRecvPacket_getVersion(uint8_t* received);
void Pixy2_SendRecvPacket_getBlocks(uint8_t* received, uint8_t sigmap, uint8_t numBlocks);
void Pixy2_SendRecvPacket_setCameraBrightness(uint8_t* received, uint8_t brightness);
void Pixy2_SendRecvPacket_setLamp(uint8_t* received, uint8_t upper, uint8_t lower);
#endif
當然,你們可以下載整個project來參考:
歡迎大家討論與指正~!
以上。
總結
以上是生活随笔為你收集整理的pixy php,Pixy2与STM32进行SPI通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wacom linux 驱动下载,Dri
- 下一篇: Ajax技术WEB开发__WEB2.0中