STM32 IIC通信之PAJ7620U2手势识别模块驱动程序源码详解

发布者:science56最新更新时间:2020-08-02 来源: 51hei关键字:STM32  IIC通信  PAJ7620U2  手势识别模块 手机看文章 扫描二维码
随时随地手机看文章

大家好。本人小白一个,最近在自学stm32,想用手势识别模块做一点好玩的,正好借此巩固IIC 通信的内容。


很多人刚刚接触IIC、SPI、CAN等通信方式时都会有一堆的问题:为什么要学它?学它可以做什么?我该怎么去学习它呢?我就在这里和大家分享一下自己学习时的所思所感吧,若有表述不对之处,还请各位大佬指出,我好立刻改正。


话不多说,先上硬货。
一、回答上面的问题:
1、什么是IIC通信呢?简单,两条线通信同步串行总线。(在此不做更多说明)
2、为什么要学习这些看起来“根本没多大用处”的通信协议呢?大哥,你总不能永远靠串口吃饭吧,况且真正到了实际项目中,通信的方式要根据环境选择,你总不能想当然的自己决定吧,学好这些通信方式,你才敢有底气去接手一些大项目吧。
3、该怎么学呢?个人觉得,刚刚学习阶段,只要理解大概原理,然后会熟练调用函数就可以了。


二、初识IIC通信:
1、认识IIC的两根线:SCL时钟线和SDA数据线。顾名思义,时钟线,是为整个通信过程提供了时钟信号,也可以说,是作为通信时的“参照物”(后面会说明).SDA即是数据线,在每一个周期里发送0或者1,用这些0和1传输数据。


2、如何传输数据呢?
首先,要传输数据,你总的告诉“另一半”传输开始了吧,所以,开始信号是必不可少的,对应也要有结束信号咯,你的“另一半"接收到了数据,总得告诉你一声吧,所以,应答信号也是少不了的。记住啦,它一点也不难,还有,我会按照我的理解方式来描述它,不会枯燥的。


3.这些信号如何通过两根线就实现呢????
刚才提到了,时钟线SCL作为参照,对、没错,就是这个参照物起了作用。
开始信号:SCL为高电平时,SDA由高电平向低转变。传输开始。
结束信号:SCL为高电平时,SDA由低电平向高转变。传输结束。
应答信号:接收数据的IC 在接收完8个bit的数据之后,向发送数据的IC返回特定脉冲的低电平,表示数据已被签收。


放到实际实验中怎么理解呢?CPU向受控单元发送一段数据之后,等待受控单元发送一个应答信号,若未接受到应答信号,表示受控单元发生故障。这些信号中,只有开始信号时必须的。而且,只有当SCL上为低电平时,SDA上的电平才允许发生变化。(这些资源网上太多了)
这些东西通俗易懂,是必须要了解的。


三、在实战中解读IIC通信。
其实,在工程中用到的绝大部分是调用IIC相关函数。


下面就用手势识别模块举例,我用的是正点原子配套的PAJ7620U2.


首先是初始化IIC对应的引脚 (我认为硬件IIC和软件IIC所实现的功能都一样,不过模拟IIC使用的更广泛,因为方便啊,而且,stm32硬件IIC引脚很鸡肋,还不如不用)。


PAJ2670U2 I2C初始化,(SDASCL都被拉高,表示为空闲状态)

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又该怎么配置?是否要开启对应的时钟?是否可以产生中断?等等,这些东西都是用给外设配置的,通信方式的底层函数基本是不会变的,你要做的就是基于已有的几种命令,与你的IC进行通信。
2、IIC根本不难,然而,就代表不用敲代码了吗?错,大错特错,好记性不如烂笔头,找一个IIC通信例程,敲几遍.C文件里的代码,对于以后做项目还是很有帮助的。
3.不要懒惰,学习这几种通信方式,最好是对比着学习,在接下来的几天里,我将会以这几种方式,分别呈上我对几种通信方式的理解。大牛不喜勿喷,谢谢。
我曾许下十年,只为最美的遇见。


实验目的:
学习ATK-PAJ7620U2手势识别模块的使用,实现9个手势识别(GS)和接近距离(PS)的检测功能,输出结果显示在LCD液晶中。
   
硬件资源:
1,DS0、DS1(连接在PA8PD2)
2,串口1(波特率:115200,PA9/PA10连接在板载USB转串口芯片CH340上面)
3,ALIENTEK 2.8/3.5/4.3/7寸TFTLCD模块(通过GPIO驱动,连接关系见lcd.h)  
4,按键KEY0(PC5)/KEY1(PA15)/WK_UP(PA0)
5,ATK-PAJ7620U2手势识别模块一个(连接在PC11(SDA),PC12(SCL),INT未用到),可直接插在板上ATK-MODULE的接口。
   
实验现象:
本实验功能简介:本实验用于测试ATK-PAJ7620U2手势识别模块,包含两个测试:
1,手势识别(GS)测试-通过KEY1按键进入此项测试。实现PAJ7620U2自带9个手势识别的检测,向上(Up)、向下(Dowm)、向左(Left)、向右(Right)、向前(Forward)、向后(Backward)、顺时针(Clockwise)、逆时针(Counterclockwise)、和挥动(Wave)。当识别到正确的手势,DS1灯会闪烁,同时手势结果显示在LCD屏幕上,并且串口输出。DS0灯闪烁提示程序正在运行,按下KEY_UP按键,可返回主菜单页面。

2,接近检测(PS)测试-通过KEY0按键进入此项测试。实现读取PAJ7620U2接近物体的体积大小和亮度的传感器数据,显示在LCD屏幕上,并串口输出。


同时DS0灯闪烁,提示程序正在运行,当按下KEY_UP按键,可返回主菜单页面。
        
另外,本例程将PAJ7620U2的读写操作函数加入USMART控制,我们可以通过USMART对PAJ7620U2进行控制。
   
注意事项:
1,4.3寸和7寸屏需要比较大电流,USB供电可能不足,请用外部电源适配器(推荐外接12V 1A电源).

2,本例程在LCD_Init函数里面(在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区域

void paj7620u2_selectBank(bank_e bank)

{

        switch(bank)

        {

                case BANK0: GS_Write_Byte(PAJ_REGITER_BANK_SEL,PAJ_BANK0);break;//BANK0寄存器区域

                case BANK1: GS_Write_Byte(PAJ_REGITER_BANK_SEL,PAJ_BANK1);break;//BANK1寄存器区域

        }

                        

}


//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寄存器区域

        data = GS_Read_Byte(0x00);//读取状态

        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寄存器区域

        for(i=0;i        {

                GS_Write_Byte(init_Array[i][0],init_Array[i][1]);//初始化PAJ7620U2

        }

    paj7620u2_selectBank(BANK0);//切换回BANK0寄存器区域

        

        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寄存器区域

        for(i=0;i        {

                GS_Write_Byte(gesture_arry[i][0],gesture_arry[i][1]);//手势识别模式初始化

        }

        paj7620u2_selectBank(BANK0);//切换回BANK0寄存器区域

        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]);//读取手势状态                        

                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("Uprn");            ledflash=1;      break; //向上

                                        case GES_DOWM:             LCD_ShowString(100,250,200,16,24,"Dowm        ");      

                                                                          printf("Dowmrn");          ledflash=1;      break; //向下

                                        case GES_LEFT:             LCD_ShowString(100,250,200,16,24,"Left        ");           

[1] [2] [3]
关键字:STM32  IIC通信  PAJ7620U2  手势识别模块 引用地址:STM32 IIC通信之PAJ7620U2手势识别模块驱动程序源码详解

上一篇:STM32通过两个按键变量控制多种花样灯亮法源程序
下一篇:stm32f103 DMA接收定长数据和不定长数据

推荐阅读最新更新时间:2024-11-12 15:59

STM32 SWD模式下SPI3无法使用的问题
总结一下spi3的问题,因为spi3的nss口与JTAG有共用引脚,所以配置错误会导致SPI3无法使用。需要注意以下三点就可以了: 1.将PA15配置为普通IO口,GPIO_Mode_Out_PP 2.开启AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 3.关闭JTAG功能,使能SWD GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE) ; 其他的SPI口正常配置,因为板子重启后默认为JTAG模式,虽然在调试时使用了SWD,但PA15依然不是普通的IO口,当把它重新配置时,一定要开启AFIO
[单片机]
STM32驱动LCD12864显示屏
我们做一个电子产品,往往需要实现人机交互的功能。那么人机交互的方式除了输出到上位机通过电脑去显示,显示器也是一个很不错的方式,可用于一些不能使用电脑的场合。LCD12864显示器中的一种,具有价格低廉,操作简单的优点。今天就为大家带来一个STM32驱动12864的例程,使用SPI串行通信,仅仅需要三根数据线就可以完成通信。废话不多说,进入正题。 接线: RS----PB15 RW----PB14 EN----PB13 PSB---GND 1.初始化IO口以及显示屏 void Lcd_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2P
[单片机]
STM32学习之串口
第一步:把串口用的引脚设置。接收的为 GPIO_Mode_IN_FLOATING; //浮空输入 发送的为GPIO_Mode_AF_PP; // 复用推挽输出 第二部设置 void NVIC_Configuration(void) NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel ; // 全局中断、、 NVIC_InitStructure.NVIC_IRQChannelPreemptio
[单片机]
STM32入门学习笔记之低功耗实验
13.1 STM32低功耗模式概述 STM32在系统或电源复位后,芯片处于运行状态,此时HCLK为CPU提供时钟,内核执行程序代码,当CPU不需要继续运行时,可以采用低功耗模块来降低芯片的运行电流,STM32有3种低功耗模式: (1)睡眠模式:内核停止,外设继续运行 (2)待机模式:1.8V的内核电源被关闭,SRAM内容丢失,PLL,HIS,HSE振荡器断电,此模式下最低电流2uA (3)停机模式:停止所有时钟,此模式下最低电流20uA 上述三种模式的配置与唤醒条件如下表所示。 模式 进入操作 唤醒 睡眠 WFI指令 任一中断 WFE指令 唤醒事件 待机 PDDS位+SLEEPDEEP位+WFI或者WFE WKUP
[单片机]
STM32笔记:RCC结构与配置流程
以前使用STM32写程序的时候,使用的都是默认时钟。因此写数码管显示、A/D测量电压的时候都没有去关心RCC时钟配置这个事情。那时候只知道在配置外设的时候使用GPIO_InitTypeDef或者ADC_InitTypeDef这些结构体对外设进行初始化,以及使用RCC_APB2PeriphClockCmd或者RCC_ADCCLKConfig函数对外设的时钟开启与配置。 这几天尝试使用STM32的USB通信写一个鼠标,发现一些例程中有关于时钟配置的代码,才注意起这个事情。为此进行了一些学习,并且记录如下的笔记。 一、RCC的结构 以下是STM32时钟系统的结构图: 从图中,我们可以看到,ST
[单片机]
<font color='red'>STM32</font>笔记:RCC结构与配置流程
STM32实战1:按键点亮LED小灯 hh
#include sys.h #include key.h void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//初始化时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPI
[单片机]
STM32按键消抖——入门状态机思维
在嵌入式软件开发中,状态机编程是一个十分重要的编程思想,它也是嵌入式开发中一个常用的编程框架。掌握了状态机编程思想,可以更加逻辑清晰的实现复杂的业务逻辑功能。 1 状态机思想 状态机,或称有限状态机FSM(Finite State Machine),是一种重要的编程思想。 状态机有3要素:状态、事件与响应 状态:系统处在什么状态? 事件:发生了什么事? 响应:此状态下发生了这样的事,系统要如何处理? 状态机编程前,首先要根据需要实现的功能,整理出一个对应的状态转换图(状态机图),然后就可以根据这个状态转换图,套用状态机编程模板,实现对应是状态机代码了。 状态机编程主要有 3 种方法:switch-case 法、表格驱动法、函数
[单片机]
<font color='red'>STM32</font>按键消抖——入门状态机思维
stm32看门狗复位技巧编辑
一、看门狗复位的应用技巧包括三个方面: 1:判断是否需要使用。如果要使用看门狗的话,需要做一些寄存器的配置,在程序区的某些地方也要加入喂狗指令来防止看门狗复位,有一定的工作量,所以用与不用需要考虑一下。能不使用看门狗的场合,要求是系统即使死机也问题不大,等待人过来断电复位即可的情况。但是这种情况已经很少了,所以绝大多数情况下看门狗都要加上。比如有温控功能的电热水器,假如电加热已经启动,但是系统死机了,温控失效,电加热也不会关闭,这时水温就会一直升高,直到水被蒸干,然后电加热损坏或引发火灾,或者人被开水烫伤。这时有看门狗复位,系统就会恢复正常,检测到温度够了,就会关闭电加热的。 2、保证看门狗工作正常。看门狗除了进行寄存器配置之外,
[单片机]
<font color='red'>stm32</font>看门狗复位技巧编辑
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved