標題: STM32 IIC通信之PAJ7620U2手勢識別模塊驅(qū)動程序源碼詳解 [打印本頁]
作者: 不知廉恥 時間: 2019-1-26 18:16
標題: STM32 IIC通信之PAJ7620U2手勢識別模塊驅(qū)動程序源碼詳解
大家好。本人小白一個,最近在自學stm32,想用手勢識別模塊做一點好玩的,正好借此鞏固IIC 通信的內(nèi)容。
很多人剛剛接觸IIC、SPI、CAN等通信方式時都會有一堆的問題:為什么要學它?學它可以做什么?我該怎么去學習它呢?我就在這里和大家分享一下自己學習時的所思所感吧,若有表述不對之處,還請各位大佬指出,我好立刻改正。
話不多說,先上硬貨。
一、回答上面的問題:
1、什么是IIC通信呢?簡單,兩條線通信同步串行總線。(在此不做更多說明)
2、為什么要學習這些看起來“根本沒多大用處”的通信協(xié)議呢?大哥,你總不能永遠靠串口吃飯吧
,況且真正到了實際項目中,通信的方式要根據(jù)環(huán)境選擇,你總不能想當然的自己決定吧,學好這些通信方式,你才敢有底氣去接手一些大項目吧。
3、該怎么學呢?個人覺得,剛剛學習階段,只要理解大概原理,然后會熟練調(diào)用函數(shù)就可以了。
二、初識IIC通信:
1、認識IIC的兩根線:SCL時鐘線和SDA數(shù)據(jù)線。顧名思義,時鐘線,是為整個通信過程提供了時鐘信號,也可以說,是作為通信時的“參照物”(后面會說明).SDA即是數(shù)據(jù)線,在每一個周期里發(fā)送0或者1,用這些0和1傳輸數(shù)據(jù)。
2、如何傳輸數(shù)據(jù)呢?
首先,要傳輸數(shù)據(jù),你總的告訴“另一半”傳輸開始了吧
,所以,開始信號是必不可少的,對應也要有結(jié)束信號咯,你的“另一半"接收到了數(shù)據(jù),總得告訴你一聲吧,所以,應答信號也是少不了的。記住啦,它一點也不難,還有,我會按照我的理解方式來描述它,不會枯燥的。
3.這些信號如何通過兩根線就實現(xiàn)呢????
剛才提到了,時鐘線SCL作為參照,對、沒錯,就是這個參照物起了作用。
開始信號:SCL為高電平時,SDA由高電平向低轉(zhuǎn)變。傳輸開始。
結(jié)束信號:SCL為高電平時,SDA由低電平向高轉(zhuǎn)變。傳輸結(jié)束。
應答信號:接收數(shù)據(jù)的IC 在接收完8個bit的數(shù)據(jù)之后,向發(fā)送數(shù)據(jù)的IC返回特定脈沖的低電平,表示數(shù)據(jù)已被簽收。
放到實際實驗中怎么理解呢?CPU向受控單元發(fā)送一段數(shù)據(jù)之后,等待受控單元發(fā)送一個應答信號,若未接受到應答信號,表示受控單元發(fā)生故障。這些信號中,只有開始信號時必須的。而且,只有當SCL上為低電平時,SDA上的電平才允許發(fā)生變化。(這些資源網(wǎng)上太多了)
這些東西通俗易懂,是必須要了解的。
三、在實戰(zhàn)中解讀IIC通信。
其實,在工程中用到的絕大部分是調(diào)用IIC相關函數(shù)。
下面就用手勢識別模塊舉例,我用的是正點原子配套的PAJ7620U2.
首先是初始化IIC對應的引腳 (我認為硬件IIC和軟件IIC所實現(xiàn)的功能都一樣,不過模擬IIC使用的更廣泛,因為方便啊,而且,stm32硬件IIC引腳很雞肋,還不如不用)。
PAJ2670U2 I2C初始化,(SDA\SCL都被拉高,表示為空閑狀態(tài))
void GS_i2c_init(void)//
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_11|GPIO_Pin_12);//PB11,PB12 被拉高
}
開始信號:
static void GS_IIC_Start(void)
{
GS_SDA_OUT();//
GS_IIC_SDA=1;
GS_IIC_SCL=1;
delay_us(4);
GS_IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
GS_IIC_SCL=0;//
}
說實話,感覺這樣照著程序COPY代碼太土了,而且浪費大家時間。下面,重要的干貨來了。
1、要明確一點,IIC是一種通信方式,不要習慣性想著IIC又該怎么配置?是否要開啟對應的時鐘?是否可以產(chǎn)生中斷?等等,這些東西都是用給外設配置的,通信方式的底層函數(shù)基本是不會變的,你要做的就是基于已有的幾種命令,與你的IC進行通信。
2、IIC根本不難,然而,就代表不用敲代碼了嗎?錯,大錯特錯,好記性不如爛筆頭,找一個IIC通信例程,敲幾遍.C文件里的代碼,對于以后做項目還是很有幫助的。
3.不要懶惰,學習這幾種通信方式,最好是對比著學習,在接下來的幾天里,我將會以這幾種方式,分別呈上我對幾種通信方式的理解。大牛不喜勿噴,謝謝。
我曾許下十年,只為最美的遇見。
實驗目的:
學習ATK-PAJ7620U2手勢識別模塊的使用,實現(xiàn)9個手勢識別(GS)和接近距離(PS)的檢測功能,輸出結(jié)果顯示在LCD液晶中。
硬件資源:
1,DS0、DS1(連接在PA8\PD2)
2,串口1(波特率:115200,PA9/PA10連接在板載USB轉(zhuǎn)串口芯片CH340上面)
3,ALIENTEK 2.8/3.5/4.3/7寸TFTLCD模塊(通過GPIO驅(qū)動,連接關系見lcd.h)
4,按鍵KEY0(PC5)/KEY1(PA15)/WK_UP(PA0)
5,ATK-PAJ7620U2手勢識別模塊一個(連接在PC11(SDA),PC12(SCL),INT未用到),可直接插在板上ATK-MODULE的接口。
實驗現(xiàn)象:
本實驗功能簡介:本實驗用于測試ATK-PAJ7620U2手勢識別模塊,包含兩個測試:
1,手勢識別(GS)測試-通過KEY1按鍵進入此項測試。實現(xiàn)PAJ7620U2自帶9個手勢識別的檢測,向上(Up)、向下(Dowm)、
向左(Left)、向右(Right)、向前(Forward)、向后(Backward)、順時針(Clockwise)、逆時針(Counterclockwise)、
和揮動(Wave)。當識別到正確的手勢,DS1燈會閃爍,同時手勢結(jié)果顯示在LCD屏幕上,并且串口輸出。DS0燈閃爍提示程序正在
運行,按下KEY_UP按鍵,可返回主菜單頁面。
2,接近檢測(PS)測試-通過KEY0按鍵進入此項測試。實現(xiàn)讀取PAJ7620U2接近物體的體積大小和亮度的傳感器數(shù)據(jù),顯示在LCD屏幕上,并串口輸出。
同時DS0燈閃爍,提示程序正在運行,當按下KEY_UP按鍵,可返回主菜單頁面。
另外,本例程將PAJ7620U2的讀寫操作函數(shù)加入USMART控制,我們可以通過USMART對PAJ7620U2進行控制。
注意事項:
1,4.3寸和7寸屏需要比較大電流,USB供電可能不足,請用外部電源適配器(推薦外接12V 1A電源).
2,本例程在LCD_Init函數(shù)里面(在lcd.c),用到了printf,如果不初始化串口1,將導致液晶無法顯示!!
3,模塊是屬于光學器件,傳感器表層的不潔凈,會容易導致測量不佳。所以模塊在使用前,保持傳感器表層的清潔度,工作時請勿用手去觸摸,以免導致模塊工作不正常。
單片機源程序如下:
- #include "paj7620u2.h"
- #include "paj7620u2_cfg.h"
- #include "delay.h"
- #include "usart.h"
- #include "led.h"
- #include "lcd.h"
- #include "key.h"
- //選擇PAJ7620U2 BANK區(qū)域
- void paj7620u2_selectBank(bank_e bank)
- {
- switch(bank)
- {
- case BANK0: GS_Write_Byte(PAJ_REGITER_BANK_SEL,PAJ_BANK0);break;//BANK0寄存器區(qū)域
- case BANK1: GS_Write_Byte(PAJ_REGITER_BANK_SEL,PAJ_BANK1);break;//BANK1寄存器區(qū)域
- }
-
- }
- //PAJ7620U2喚醒
- u8 paj7620u2_wakeup(void)
- {
- u8 data=0x0a;
- GS_WakeUp();//喚醒PAJ7620U2
- delay_ms(5);//喚醒時間>400us
- GS_WakeUp();//喚醒PAJ7620U2
- delay_ms(5);//喚醒時間>400us
- paj7620u2_selectBank(BANK0);//進入BANK0寄存器區(qū)域
- data = GS_Read_Byte(0x00);//讀取狀態(tài)
- if(data!=0x20) return 0; //喚醒失敗
-
- return 1;
- }
- //PAJ7620U2初始化
- //返回值:0:失敗 1:成功
- u8 paj7620u2_init(void)
- {
- u8 i;
- u8 status;
-
- GS_i2c_init();//IIC初始化
- status = paj7620u2_wakeup();//喚醒PAJ7620U2
- if(!status) return 0;
- paj7620u2_selectBank(BANK0);//進入BANK0寄存器區(qū)域
- for(i=0;i<INIT_SIZE;i++)
- {
- GS_Write_Byte(init_Array[i][0],init_Array[i][1]);//初始化PAJ7620U2
- }
- paj7620u2_selectBank(BANK0);//切換回BANK0寄存器區(qū)域
-
- return 1;
- }
- //主菜單
- void paj7620u2_test_ui(void)
- {
- POINT_COLOR=BLUE;//設置字體為藍色
- LCD_Fill(30,170,300,300,WHITE);
- LCD_ShowString(30,170,200,16,16,"KEY1: Gesture test");//手勢識別測試
- LCD_ShowString(30,190,200,16,16,"KEY0: Ps test ");//接近距離測試
-
- }
- //手勢識別測試
- void Gesture_test(void)
- {
- u8 i;
- u8 status;
- u8 key;
- u8 data[2]={0x00};
- u16 gesture_data;
- u8 ledflash=0;
- paj7620u2_selectBank(BANK0);//進入BANK0寄存器區(qū)域
- for(i=0;i<GESTURE_SIZE;i++)
- {
- GS_Write_Byte(gesture_arry[i][0],gesture_arry[i][1]);//手勢識別模式初始化
- }
- paj7620u2_selectBank(BANK0);//切換回BANK0寄存器區(qū)域
- i=0;
- POINT_COLOR=BLUE;//設置字體為藍色
- LCD_Fill(30,170,300,300,WHITE);
- LCD_ShowString(30,180,200,16,16,"KEY_UP: Exit the test");
- LCD_ShowString(30,210,200,16,16,"Gesture test");
- POINT_COLOR=RED;//設置字體為藍色
- while(1)
- {
- key = KEY_Scan(0);
- if(key==WKUP_PRES)
- {
- GS_Write_Byte(PAJ_SET_INT_FLAG1,0X00);//關閉手勢識別中斷輸出
- GS_Write_Byte(PAJ_SET_INT_FLAG2,0X00);
- break;
- }
- status = GS_Read_nByte(PAJ_GET_INT_FLAG1,2,&data[0]);//讀取手勢狀態(tài)
- if(!status)
- {
- gesture_data =(u16)data[1]<<8 | data[0];
- if(gesture_data)
- {
- switch(gesture_data)
- {
- case GES_UP: LCD_ShowString(110,250,200,16,24,"UP ");
- printf("Up\r\n"); ledflash=1; break; //向上
- case GES_DOWM: LCD_ShowString(100,250,200,16,24,"Dowm ");
- printf("Dowm\r\n"); ledflash=1; break; //向下
- case GES_LEFT: LCD_ShowString(100,250,200,16,24,"Left ");
- printf("Left\r\n"); ledflash=1; break; //向左
- case GES_RIGHT: LCD_ShowString(100,250,200,16,24,"Right ");
- printf("Right\r\n"); ledflash=1; break; //向右
- case GES_FORWARD: LCD_ShowString(80,250,200,16,24,"Forward ");
- printf("Forward\r\n"); ledflash=1; break; //向前
- case GES_BACKWARD: LCD_ShowString(80,250,200,16,24,"Backward ");
- printf("Backward\r\n"); ledflash=1; break; //向后
- case GES_CLOCKWISE: LCD_ShowString(70,250,200,16,24,"Clockwise ");
- printf("Clockwise\r\n"); ledflash=1; break; //順時針
- case GES_COUNT_CLOCKWISE: LCD_ShowString(50,250,200,16,24,"AntiClockwise");
- printf("AntiClockwise\r\n"); ledflash=1; break; //逆時針
- case GES_WAVE: LCD_ShowString(100,250,200,16,24,"Wave ");
- printf("Wave\r\n"); ledflash=1; break; //揮動
- default: ledflash=0; break;
-
- }
- if(ledflash)//DS1閃爍
- {
- LED1=0;delay_ms(80);LED1=1;delay_ms(80);
- LED1=0;delay_ms(80);LED1=1;delay_ms(80);
- LCD_ShowString(40,250,200,16,24," ");
- ledflash=0;
- }
- }
-
- }
- delay_ms(50);
- i++;
- if(i==5)
- {
- LED0=!LED0;//提示系統(tǒng)正在運行
- i=0;
- }
- }
- }
- //接近檢測測試
- void Ps_test(void)
- {
- u8 i;
- u8 key;
- u8 data[2]={0x00};
- u8 obj_brightness=0;
- u16 obj_size=0;
-
- paj7620u2_selectBank(BANK0);//進入BANK0寄存器區(qū)域
- for(i=0;i<PROXIM_SIZE;i++)
- {
- GS_Write_Byte(proximity_arry[i][0],proximity_arry[i][1]);//接近檢測模式初始化
- }
- paj7620u2_selectBank(BANK0);//返回BANK0寄存器區(qū)域
- i=0;
- POINT_COLOR=BLUE;//設置字體為藍色
- LCD_Fill(30,170,300,300,WHITE);
- LCD_ShowString(30,180,200,16,16,"KEY_UP: Exit the test");
- LCD_ShowString(30,210,200,16,16,"Ps test");
- LCD_ShowString(30,240,200,16,16,"Brightness");
- LCD_ShowString(160,240,200,16,16,"Size");
- POINT_COLOR=RED;//設置字體為藍色
-
- while(1)
- {
- key = KEY_Scan(0);
- if(key==WKUP_PRES) break;
-
- obj_brightness = GS_Read_Byte(PAJ_GET_OBJECT_BRIGHTNESS);//讀取物體亮度
- data[0] = GS_Read_Byte(PAJ_GET_OBJECT_SIZE_1);//讀取物體大小
- data[1] = GS_Read_Byte(PAJ_GET_OBJECT_SIZE_2);
- obj_size = ((u16)data[1] & 0x0f)<<8 | data[0];
- LCD_ShowxNum(50,270,obj_brightness,3,24,0);
- LCD_ShowxNum(152,270,obj_size,3,24,0);
- printf("obj_brightness: %d\r\n",obj_brightness);
- printf("obj_size: %d\r\n",obj_size);
-
- delay_ms(100);
- i++;
- if(i==5)
- {
- LED0=!LED0;//提示系統(tǒng)正在運行
- i=0;
- }
- }
-
- }
- //PAJ7620U2傳感器測試
- void paj7620u2_sensor_test(void)
- {
- u8 i=0;
- u8 key;
-
- paj7620u2_test_ui();//主菜單顯示
- while(1)
- {
- key = KEY_Scan(0);//按鍵掃描
- if(key)
- {
- switch(key)
- {
- case KEY1_PRES: Gesture_test(); break;//手勢檢測模式
- case KEY0_PRES: Ps_test(); break;//接近檢測模式
- }
- paj7620u2_test_ui();
- }
- delay_ms(50);
- i++;
- if(i==5)
- {
- LED0=!LED0;//提示系統(tǒng)正在運行
- i=0;
- }
-
- }
- }
復制代碼
主程序:
- #include "led.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include "lcd.h"
- #include "key.h"
- #include "usmart.h"
- #include "paj7620u2.h"
-
- int main(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 設置中斷優(yōu)先級分組2
- delay_init(); //延時函數(shù)初始化
- uart_init(115200); //串口初始化為115200
- LED_Init(); //初始化與LED連接的硬件接口
- LCD_Init(); //初始化LCD
- KEY_Init(); //按鍵初始化
- usmart_dev.init(72); //初始化USMART
- POINT_COLOR=RED; //設置字體為紅色
- LCD_ShowString(30,50,200,16,16,"Mini STM32");
- LCD_ShowString(30,70,200,16,16,"Sensor PAJ7620U2 TEST");
- LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
- LCD_ShowString(30,110,200,16,16,"2017/8/23");
- POINT_COLOR=BLUE;//設置字體為藍色
- while(!paj7620u2_init())//PAJ7620U2傳感器初始化
- {
- printf("PAJ7620U2 Error!!!\r\n");
- LCD_ShowString(30,140,200,16,16,"PAJ7620U2 Error!!!");
- delay_ms(500);
- LCD_ShowString(30,140,200,16,16," ");
- delay_ms(500);
- LED0=!LED0;//DS0閃爍
-
- }
- printf("PAJ7620U2 OK\r\n");
- LCD_ShowString(30,140,200,16,16,"PAJ7620U2 OK");
- while(1)
- {
- paj7620u2_sensor_test();//PAJ7620U2傳感器測試
- }
- }
復制代碼
所有資料51hei提供下載:
(標準庫版本,適合MiniV3 STM32開發(fā)板)擴展實驗22 ATK-PAJ7620模塊實驗.7z
(245.78 KB, 下載次數(shù): 377)
2019-1-26 21:00 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者: curster 時間: 2019-1-29 14:38
#include "paj7620u2_cfg.h"
#include "key.h"
怎麼沒有這兩個副程序,上面的程序有呼叫到這兩個副程序的,煩有空補上好嗎?
作者: sunmeu 時間: 2019-7-25 09:11
他的那個文檔里有的
作者: IdeaMing 時間: 2019-9-23 20:33
識別距離有多遠啊
作者: hupl 時間: 2019-10-8 15:48
5到15厘米
作者: hupl 時間: 2019-10-8 16:05
看了他這個文檔,受益菲淺,真是感謝
作者: 天上天下 時間: 2019-10-15 14:41
可以編譯,謝謝分享~
作者: clean03 時間: 2020-3-17 09:08
可以在51單片機上實現(xiàn)嗎
作者: 天使老掉毛007 時間: 2020-4-26 18:34
我測手勢的靈敏度不高什么情況?有時間能測出來,有時間測不出來?并且不能連續(xù)測
作者: bwsz 時間: 2020-5-15 19:54
挺不錯的 謝謝分享
作者: jinglixixi 時間: 2020-6-12 10:28
感謝分享
作者: 風的等待 時間: 2020-6-15 14:19
學習下。謝謝分享
作者: G28197 時間: 2020-7-24 16:00
正想用這個做一個感應控制器,不知道PAJ7620U2的庫文件怎么寫
作者: gaopc 時間: 2020-10-12 23:11
PAJ7620U2的IIC地址是多少?可以修改嗎?謝謝!
作者: Shitianz 時間: 2021-3-22 14:50
感謝樓主分享,受益匪淺
作者: 13349986936 時間: 2021-4-28 09:22
感謝樓主分享,受益匪淺
作者: 1468123699 時間: 2022-2-21 10:36
感謝樓主分享,受益匪淺
歡迎光臨 (http://www.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
日韩视频91
|
日韩欧美在线观看
|
久久一区二区视频
|
久久青
|
天天色天天射天天干
|
91精品久久久
|
国产精品国产成人国产三级
|
国产精品综合色区在线观看
|
国产精品色
|
天天射天天干
|
欧美一区二区三区在线看
|
国产日韩精品在线
|
免费黄色的视频
|
精品国产视频在线观看
|
91精产国品一二三区
|
国产一区二区三区在线看
|
三级黄色片在线播放
|
欧美在线看片
|
99国产精品久久久
|
国产精品欧美一区二区
|
国产欧美一区二区三区另类精品
|
日韩av在线一区
|
亚洲精品久久久久久久久久久久久
|
国产精品免费观看视频
|
四虎成人精品永久免费av九九
|
久久国产精品一区二区三区
|
国产在线视频一区
|
成人性视频免费网站
|
成人免费在线
|
亚洲资源在线
|
久久一区精品
|
色婷婷久久久久swag精品
|
国产精品成人一区二区三区
|
国产一区二区久久
|
欧美看片|
成人精品在线观看
|
男人的天堂在线视频
|
一区二区精品在线
|
国产成人亚洲精品
|
精品久久久久久
|
激情一区二区三区
|