目錄總結
實現nrf24l01/si24r1廣播通訊
使用stm32cubemx建立工程。
使用到的外設有:
usart1----debug除錯
spi1----無線模組連線
usb----上位機通訊
要使用廣播通訊,就不能使用ack模式,需使用no ack模式,注意修改暫存器。
且使用中斷接收無線資料,注意中斷資料處理
最終無線部分的**如下
static uint8_t spix_readwritebyte(spi_handletypedef *hspi, uint8_t byte)
return d_read;
}static uint8_t si24r1_write_reg(uint8_t reg, uint8_t value)
static uint8_t si24r1_read_reg(uint8_t reg)
// 在指定位置讀出指定長度的資料
static uint8_t si24r1_read_buf(uint8_t reg, uint8_t *pbuf, uint8_t len)
si24r1_spi_cs_disable();
return status;
}// 在指定位置寫指定長度的資料
static uint8_t si24r1_write_buf(uint8_t reg, uint8_t *pbuf, uint8_t len)
si24r1_spi_cs_disable();
return status;
}void si24r1_config(void)
// 檢測24l01是否存在
uint8_t si24r1_check(void) ;
uint8_t i;
si24r1_write_buf(nrf_write_reg + tx_addr, buf, 5);
si24r1_read_buf(tx_addr, buf, 5);
for (i = 0; i < 5; i++)
if (buf[i] != 0xa5) break;
if (i != 5) return 1; //檢測24l01錯誤
return 0; //檢測到24l01
}void si24r1_txpacket(uint8_t *txbuf)
void si24r1_rx_mode(void)
void si24r1_tx_mode(void)
static uint8_t nrf_rx_data[rx_pload_width + 1];
void si24r1_rx_iqr(void)
if (status & 0xf0)
si24r1_write_reg(flush_rx, 0xff);
si24r1_write_reg(flush_tx, 0xff);
si24r1_ce_high();
}
main.c**如下
int main(void)
si24r1_config();
si24r1_rx_mode();
printf("si24r1 init ok!\r\n");
creatmessagelist(&usbrecvdatamessagelist);
creatmessagelist(&si24r1recvdatamessagelist);
message msg;
uint8_t recvdatabuf[32];
uint8_t len;
uint8_t whilecnt = 0;
while (1)
if (getmessagelist(&si24r1recvdatamessagelist, &msg) != 0)
if (whilecnt++ >= 100)
hal_delay(1);}}
stm32 這端會接收所有資料,並上傳到上位機,具體業務可在上位機這端處理。
上位機是用c#寫的,部分**如下:
int portdatasend(int localaddr, int destaddr, int len, byte buf)
if (!checkaddr(destaddr))
if (!checklen(len))
byte serialsendbuf = new byte[64];
serialsendbuf[0] = (byte)((localaddr & 0xff00) >> 8);
serialsendbuf[1] = (byte)((localaddr & 0x00ff));
serialsendbuf[2] = (byte)((destaddr & 0xff00) >> 8);
serialsendbuf[3] = (byte)((destaddr & 0x00ff));
serialsendbuf[4] = (byte)((len & 0x00ff));
for (int i = 0; i < len; i++)
sptmain.write(serialsendbuf,0, 64);
return 0;
}private void portdatarecvived(object sender, serialdatareceivedeventargs e)
if (data[4] > data_max_len)
int srcaddr, desaddr, len;
srcaddr = (data[0] << 8) + data[1];
desaddr = (data[2] << 8) + data[3];
len = data[4];
string recvstring = system.text.encoding.default.getstring(data, 5, len);
if (!chbdata.checked)
}string nowtime = datetime.now.tostring("hh:mm:ss", datetimeformatinfo.invariantinfo);
if (n == 33)
}else if (n == 32)
}private void btnsenddata_click(object sender, eventargs e)
if (txbsenddata.text == "")
else
}portdatasend(localaddr, destaddr, txbsenddata.text.length, system.text.encoding.default.getbytes(txbsenddata.text));
}private void txblocal_keypress(object sender, keypresseventargs e)}}
private void txbdest_keypress(object sender, keypresseventargs e)}}
stm32用的usb使用的cdc模擬串列埠,底層usb每次傳送的包為64bytes;
使用這種no ack模式,就類似於廣播,不在侷限於晶元的6v1這種模式,可以各種自定義。
也就類似於 udp之於tcp吧。
nRF24L01 使用說明
bit0 prim rx設定工作模式,傳送或接收,0 傳送 1 接收。bit1 pwm up設定是否上電,晶元在傳送或接收完成後根據此位判斷是進入powerdown模式 0 還是進入standby模式 1 bit2 crco設定crc的位元組數,0 1byte 1 2byte。bit3 en crc...
NRF24L01的通訊距離
nrf24l01模組的傳輸距離由 使用什麼天線 是否加了功率晶元 程式中選擇的傳輸速率 空曠和有障礙物 四個因素決定。目前市場上的nrf24l01有三種模組。1.天線在pcb上 零售價6元 15元 該模組的天線在pcb上,沒有加功率晶元,屬於傳輸距離最短的模組。空曠條件下,經過實測,2m傳輸速率下1...
nRF24L01無線溫度檢測
在當今的工農業生產中,需要進行溫濕度採集的場合越來越多,準確方便地測量溫度變得至關重要。傳統的有線測溫方式存在著佈線複雜,線路容易老化,線路故障難以排查,裝置重新布局要重新佈線等問題。特別是在有線網路不通暢或由於現場環境因素的限制而不便架設線路的情況下,給溫濕度的資料採集帶來了很大的麻煩。要想監測到...