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