目前已完成,2m距離,傳輸10000個連續數字,每個數字兩字節大小,即總共20000個字節160000bit,用時7s,大約2.3萬bit/s,即22.4kB/s,誤碼率為0
1.png (138.22 KB, 下載次數: 56)
下載附件
2020-10-26 14:25 上傳
2.png (998.37 KB, 下載次數: 59)
下載附件
2020-10-25 14:07 上傳
1.png (916.9 KB, 下載次數: 53)
下載附件
2020-10-25 14:07 上傳
發射與接收程序:
- #include "stm32f10x.h"
- #include "delay.h"
- #include "sensor.h"
- #include "usart.h"
- #include "usmart.h"
- /*
- 程序整體思路:
- ① 把每個要發射的數據轉成二進制,再將二進制的每一位逐1發射出去;
- ② 需要3個信號表示一個數據,分別用高電平持續的不同時間表示不同
- 信號:起始信號、0信號、1信號,分別對應p1,p2,p3;
- ③ 默認狀態LED是亮的,起始信號發射的時候,將LED引腳置高,并延遲
- p1的時間,再進行翻轉,兩次這樣的p1高電平時間即代表起始信號;
- ④ 數據信號需要緊跟著起始信號,一次起始信號之后就是16位的0、1數
- 據信號,對于0信號,則是高電平持續p2時間,再翻轉,對于1信號,
- 則是高電平持續p3時間;
- ⑤ 因此只需要設置好每個信號之間的時間參數,使用滴答定時器計數的
- 延遲函數達到持續的效果,然后只要判斷即將發射的數據的各個位,
- 即可將一個數據發射出去。
-
- * 2020.8.30 —— by afeng
- 1、優化程序,優化部分變量,讓程序運行的更快,盡量與接收端同步。
- * 2020.8.25 —— by afeng
- 1、優化發射端串口助手,使其能夠實時自動刷新電腦可用的串口,當該串口掉線,則會自動關閉連接。
- 2、優化串口助手的顯示區域部分,通過設置光標的位置使得文字可以從上至下顯示。
- * 2020.8.23 —— by afeng
- 1、加入連續發射多個數據的函數,并支持不同起始數據和結束數據,然后
- 注冊到USMART調試組件,以達到從串口助手來控制發射的數據。
- 2、結合了自己的基于QT的串口助手,把本工程的USMART組件與該調試助手
- 結合起來使用,更方便調參。
- * 2020.8.20 —— by afeng
- 1、開始使用USMART調試組件,可以在串口助手通過函數帶參數的方式在線修改
- 各個參數,在后面不同距離下改變參數有著極大的便利性,免去了重復修改
- 、編譯和燒錄代碼的繁瑣過程。
- 2、解決了二進制數據位錯誤的BUG,是由于自己不夠熟練位操作引起的,最后
- 決定使用數字1的移位操作來提取出每個數據的各個二進制位。
- 3、實現了基于滴答定時器的長時間延遲,由于該定時器只有16位,基于ST庫寫
- 的延遲函數一次最大不能超過2s,經過額外編程實現能夠一次延遲10s以上。
- 4、剔除了每次數據都需要結束信號的方案,使得發射時間進一步提升,其實每
- 個數據的起始信號也可以作為每個數據的區分了。
-
- * 2020.8.19 —— by afeng
- 1、使用函數將十進制轉二進制,并能夠將每一個位通過亮-暗表示0-1將二進制
- 各個位成功發射出去,測得最小時間參數可以達到300us左右,但是由于接收
- 端的限制以及距離的影響,這個參數需要每次調整。
- */
- //連續發射數據
- void emitSeriesData(uint16_t start,uint16_t end)
- {
- uint16_t i,len=end+1;
- if((start>0) && (end>start))
- {
- printf("發送從 %d 到 %d ,共 %d 個數據。\r\n",start,end,(end+1-start));
- printf("正在發送……\r\n");
- emitData(start); emitData(end); emitData((end+1-start)); //先發送本次數據塊的信息
- delay_ms(10);
- for(i=start;i<len;i++)
- {
- emitData(i); //開始循環發送,從開始數據位開始發送
- if(i%100 == 0) printf("%d ",i);
- }
- LED = 0;
- printf("\r\n本次已發送完成。\r\n");
- }
- }
- int main(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級
- uart_init(115200); //串口初始化為115200
- delay_init(); //延時函數初始化
- LedConfigInit(); //初始化光源引腳及發射相關參數
- usmart_dev.init(SystemCoreClock/1000000); //初始化 USMART,實現在串口修改發射相關參數
- LED = 0; //發射前默認光源開啟
- printf("當前參數:\r\n"); lookUpCurrentParameter();
- printf("\r\n等待發射數據……\r\n");
- emitSeriesData(1,5);
- while(1)
- {
- //直到等到發射命令從串口進入,才進行發射
-
- }
- }
復制代碼
- #define dataLen 12000
- uint16_t dataBuf[dataLen] __attribute__((at(Bank1_SRAM3_ADDR)));
- uint16_t dataCurrentPos=0;
- int main(void)
- {
- uint16_t recvWorkCounts=0;
- uint8_t j=0,startRecvFlag=0;
- uint16_t i=0,recvData,dataInfo[3]; //dataInfo用來檢驗一次數據接收的起始數據和結尾數據
- uint16_t errorCounts=0; //用來記錄接收錯誤的數據個數
- uint32_t recvTime_us; //用來記錄接收用時
-
- delay_init(); //延時函數初始化
- uart_init(115200); //串口初始化為115200
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級
- TIM3_CountTime_Init(); //用于計時接收數據的時間
- LdrConfigInit(); //初始化光敏傳感器的引腳和輸入捕獲功能
- usmart_dev.init(SystemCoreClock/1000000); //初始化 USMART,實現在串口修改接收相關參數
- FSMC_SRAM_Init(); //初始化外部SRAM
- LCD_Init();
- memset(dataBuf,0,sizeof(dataBuf)); //全都初始化為0
-
- POINT_COLOR=RED;//設置字體為紅色
- LCD_ShowString(60,50,200,16,16,"My Class Design");
- LCD_ShowString(60,70,200,16,16,"2020-9-4 @By afeng");
- LCD_ShowString(60,90,230,16,16,"Visible Light Communication.");
- POINT_COLOR=BLUE;//設置字體為藍色
- LCD_ShowString(60,160,200,16,24,"WorkCounts :");
- LCD_ShowString(60,200,200,16,24,"errorCounts :"); //LCD_ShowNum(230,200,10000,5,24)
- LCD_ShowString(60,240,200,16,24,"usingTime/us:"); //LCD_ShowNum(230,240,200000000,9,24)
- POINT_COLOR=BLACK;
- LCD_ShowNum(230,160,0,9,24);
- LCD_ShowNum(230,200,0,9,24);
- LCD_ShowNum(230,240,0,9,24);
-
- printf("等待接收數據……\r\n");
- while(1)
- {
- recvData = receiveData(); //阻塞等待接收一個數據
-
- if((!startRecvFlag) && recvData) //先接收起始數據和結束數據、及總的長度
- {
- dataInfo[j] = recvData;
- j++;
- if(j==3)
- {
- j = 0; //若結束+1-起始 = 長度,則準備進入接收數據
- if((dataInfo[1]+1-dataInfo[0]) == dataInfo[2]) startRecvFlag = 1;
- else printf("此次接收失敗!請重新發送數據!\r\n");
- }
- }
-
- if(startRecvFlag) //開始接收數據
- {
- printf("receiving...\r\n");
- startRecvFlag = 0;
- startCountRunningTime(); //開始計時
- for(i=dataInfo[0];i<(dataInfo[1]+1);i++) //循環接收數據
- {
- recvData = receiveData(); //阻塞接收
- if(recvData==i) dataBuf[dataCurrentPos++] = recvData;
- else
- {
- if(recvData!=0)
- {
- dataCurrentPos = recvData-i;
- dataBuf[dataCurrentPos++] = recvData;
- i = recvData;
- }
- }
- }
- recvTime_us = getRunningTime(); //結束接收計時并得到時間
-
- printf("接收完成!正在檢驗數據……\r\n"); //檢驗數據
- dataCurrentPos=0;
- for(i=dataInfo[0];i<(dataInfo[1]+1);i++)
- {
- if(dataBuf[dataCurrentPos]!=i)
- {
- errorCounts++;
- printf("【err】 ");
- }
- else printf("%d ",dataBuf[dataCurrentPos]);
- dataCurrentPos++;
- }
- recvWorkCounts++;
- printf("\r\n");
- printf("-----------------------------------------------------\r\n");
- printf("處理完成! 錯誤數據: %d 個 總接收用時: %d us (%.3f ms --> %.2f s)\r\n", \
- errorCounts,recvTime_us,(recvTime_us/1000.0),(recvTime_us/1000000.0));
- printf("-----------------------------------------------------\r\n\r\n");
- LCD_ShowNum(230,200,recvWorkCounts,9,24);
- LCD_ShowNum(230,200,errorCounts,9,24);
- LCD_ShowNum(230,240,recvTime_us,9,24);
- errorCounts = 0;
- recvData = 0;
- dataCurrentPos=0;
- memset(dataBuf,0,sizeof(dataBuf));
- printf("等待接收數據……\r\n");
- }
- }
- }
復制代碼
原理圖: 無
仿真: 無
代碼:
STM32代碼.7z
(256.53 KB, 下載次數: 65)
2020-10-26 14:26 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|