使用單片機型號STC15W408AS-35I-DIP20,焊接效果如附件圖。使用程序可以讀取所有紅外探頭的ADC數(shù)值,可以進行IIC通信。
這種單片機一次具有8個ADC,一個芯片就能實現(xiàn)8個探頭的數(shù)據(jù)轉換。
這樣的設計可以實現(xiàn)紅外巡線等功能。
IMG_20221106_172232_edit_1858734296485128.jpg (2.25 MB, 下載次數(shù): 23)
下載附件
2022-11-6 17:23 上傳
IMG_20221106_172239.jpg (1.81 MB, 下載次數(shù): 21)
下載附件
2022-11-6 17:23 上傳
示意圖.jpg (1.15 MB, 下載次數(shù): 19)
下載附件
2022-11-6 18:15 上傳
# 紅外巡線測試結果
2022年8月23日23:10:10
## 裝車效果
只裝了一塊彎的,效果很好。
探頭頂端距離地面大約8mm(目測)。
## 我的程序
### 從機
從機傳輸數(shù)據(jù)的時候LED亮起。
6個探頭的從機傳回的數(shù)據(jù):\[data*6] \[0] \[addr]
8個探頭的從機傳回的數(shù)據(jù):\[data*8]
### 主機
主機使用STM32F401CCU6,配置IIC2引腳,波特率為一個非標準的傳輸波特率(10000,標準值為100k(標準IIC)或400k(高速IIC))。
主機對所有地址的從機進行檢測,對每個從機,會循環(huán)嘗試傳輸,直到傳輸成功或傳輸次數(shù)達到5次為止。
把所有從機地址檢測完畢之后重新開始。
主機接收到數(shù)據(jù)之后通過UART(115200)傳輸給電腦,使用串口調試助手(HEX)可以打開查看。
## 數(shù)據(jù)傳輸
使用IIC總線傳輸,經(jīng)過我的調試,可以在8從機上穩(wěn)定運行。
總共只需要4個線,2電源線和2數(shù)據(jù)線。
## 測試數(shù)據(jù)結果
懸空 0x00-0x10
黑 0x08-0x20
白 0xB0-0xFF
## 測試樣例

順時針方向分別是0和1號,也就是上圖中左邊是1、右邊是0;測得數(shù)據(jù):
```MATLAB
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 15 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 15 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 15 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 15 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 14 13 01 00 31 AC D8 F2 EF C0 01 01
EC F2 C8 16 15 13 01 00 31 AC D8 F2 EF C0 01 01
```
數(shù)據(jù)格式:
\[數(shù)據(jù)*6](每個探頭的ADC轉換值,從左到右) \[發(fā)送成功所使用的的次數(shù)] \[從機地址]
- 位于白色上面的data\[0]\[0:3]給出了白色范圍內的值
- 位于黑色上面的data\[0]\[4:6]給出了黑色范圍內的值
- 位于過渡位置的data\[1]\[0]給出了中間值0x31,偏離過渡位置的data\[1]\[1]給出了比較靠近白色的值
- 位于白色上面的data\[1]\[2:6]給出了白色范圍內的值
- 所有傳輸均使用1次嘗試完成
- 可以連續(xù)運行10分鐘無故障
## 其他
經(jīng)過測試,也可以比較好地分辨出紫色、藍色等。
## 總結
本次實驗比較成功,我設計的系統(tǒng)比較安全、靈敏、可靠、高效。
單片機源程序如下:
- #include <I2C.h>
- #include <STC15.h>
- #include <intrins.h>
- // #include "./include/delay.h"
- sbit LED = P3 ^ 4;
- sbit I2C_SCL = P3 ^ 6;
- sbit I2C_SDA = P3 ^ 7;
- #if 0
- //定義LED燈引腳
- sbit Data[8] = {P37, P36, P35, P33, P32, P31, P30, P54};
- #endif
- void delay(unsigned int delay_time) // 1毫秒@22.1184MHz
- {
- unsigned char i, j;
- for (; delay_time > 0; delay_time--) {
- _nop_();
- _nop_();
- i = 22;
- j = 128;
- do {
- while (--j)
- ;
- } while (--i);
- }
- }
- void InitADC();
- unsigned char GetADCResult(unsigned char ch);
- #define ADC_POWER 0x80 // ADC電源控制位
- #define ADC_FLAG 0x10 // ADC完成標志
- #define ADC_START 0x08 // ADC起始控制位
- #define ADC_SPEEDLL 0x00 // 540個時鐘
- #define ADC_SPEEDL 0x20 // 360個時鐘
- #define ADC_SPEEDH 0x40 // 180個時鐘
- #define ADC_SPEEDHH 0x60 // 90個時鐘
- /*----------------------------
- 初始化ADC
- ----------------------------*/
- void InitADC() {
- P1ASF = 0xff; //設置P1口為AD口,0xff表示8通道全開
- ADC_RES = 0; //清除結果寄存器
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
- delay(20); // ADC上電并延時
- }
- /*----------------------------
- 讀取ADC結果
- ----------------------------*/
- unsigned char GetADCResult(unsigned char ch) {
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
- _nop_(); //等待4個NOP
- _nop_();
- _nop_();
- _nop_();
- while (!(ADC_CONTR & ADC_FLAG))
- ; //等待ADC轉換完成
- ADC_CONTR &= ~ADC_FLAG; // Close ADC
- return ADC_RES; //返回ADC結果
- }
- /*
- void test(void){
- while(1){
- I2C_SCL=1;
- delay(10);
- I2C_SDA=1;
- delay(10);
- I2C_SCL=0;
- delay(10);
- I2C_SDA=0;
- delay(10);
- LED = !LED;
- }
- }*/
- /*----------------------------
- 主程序由此開始
- ----------------------------*/
- #define ADDR 0x17 //定義從機地址/編號
- unsigned char TX_data[2], ADC_data[8], i;
- void main() {
- LED = 1;
- InitADC();
- delay(10);
- while (1) {
- for (i = 0; i < 8; i++)
- ADC_data[7 - i] = GetADCResult(i);
- // TX_data[0] = 0; //初始化為沒有黑線
- // TX_data[1] = 0; //初始化為從第0個位置找到黑線
- // for (i = 0; i < 8; i++) {
- // if (ADC_data[i] < 0x40) { //掃描到黑線
- // TX_data[1] = i; //從第i個開始掃到黑線
- // i++;
- // TX_data[0]++; //掃描到黑線的數(shù)量
- // while (i < 8 && ADC_data[i] < 0x40) {
- // i++;
- // TX_data[0]++;
- // }
- // break;
- // }
- // }
- // while (!I2C_Write(TX_data, ADDR, 2))
- // ;
- P37 = ADC_data[0] > 0x38 ? 1 : 0;
- P36 = ADC_data[1] > 0x40 ? 1 : 0;
- P35 = ADC_data[2] > 0x40 ? 1 : 0;
- P33 = ADC_data[3] > 0x40 ? 1 : 0;
- P32 = ADC_data[4] > 0x40 ? 1 : 0;
- P31 = ADC_data[5] > 0x40 ? 1 : 0;
- P30 = ADC_data[6] > 0x40 ? 1 : 0;
- P54 = ADC_data[7] > 0x38 ? 1 : 0;
- delay(1);
- }
- }
復制代碼
|