【MM32F5270开发板试用】手势传感PAJ7620U2的智能家居应用
本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:风云再起
一、序
很高兴能参加极术社区联合灵动微电子组织的【灵动MM32F5270开发板试用】活动,MM32F5270 是一款搭载了安谋科技 STAR-MC1 内核的 MCU 产品,其工作频率可达 120MHz,内置多达 256KB Flash 和 192KB RAM,配置浮点运算单元(Floating Point Unit, FPU)、数字信号处理单元(Digital Signal Processing,DSP)、信号间互联矩阵 MindSwitch、可配置逻辑单元 CLU、三角函数加速单元 CORDIC 等算法加速单元,并集成了丰富的外设模块和充足的 I/O 端口。MM32F5270 相较于现有产品全面提升了性能、存储容量、总线架构和外设配置,旨在覆盖更广泛的工业、汽车和 IoT 应用。
二、PLUS-F5270开发板功能示意框图
三、产品方案设计
疫情当下,非接触性来让设备启动,应用场景越来越适应市场的需求,这次抛砖引玉,大胆地做一次尝试,一起交流学习。
四、硬件及引脚,原理图
1、手势传感PAJ7620U2
2、MM32F5270开发板使用到的引脚
五、部分核心代码:
paj7620u2_iic.h文件:
#ifndef __PAJ7620U2_IIC_H#define __PAJ7620U2_IIC_H#include "board_init.h"#define SDA_GPIO GPIO_PIN_7#define SDA_PORT GPIOC#define SDA_RCC RCC_APB2Periph_GPIOB#define SCL_GPIO GPIO_PIN_6#define SCL_PORT GPIOC#define SCL_RCC RCC_APB2Periph_GPIOB#define SDA_H GPIO_WriteBit(SDA_PORT,SDA_GPIO,1u)#define SDA_L GPIO_WriteBit(SDA_PORT,SDA_GPIO,0u)#define SDA_R GPIO_ReadInDataBit(SDA_PORT,SDA_GPIO)#define SCL_H GPIO_WriteBit(SCL_PORT,SCL_GPIO,1u)#define SCL_L GPIO_WriteBit(SCL_PORT,SCL_GPIO,0u)/* * Macros. */#define APP_I2C_TARGET_ADDR 0x50u /* I2C target device address. */#define APP_I2C_BUF_LEN 16u /* The size of I2C write and read array. */#define APP_I2C_TIMEOUT_TIME 3000u /* Wait for the time when the status flag appears. If exceeds time, don't wait any longer and return to timeout. */#define APP_I2C_TX_LEN 8u /* The number of tx data. */#define APP_I2C_RX_LEN 7u /* The number of rx data. *//* * Variables. */static uint8_t app_i2c_rx_buf[APP_I2C_BUF_LEN]; /* I2C rx buffer. */static uint8_t app_i2c_tx_buf[APP_I2C_BUF_LEN]; /* I2C tx buffer. */static I2C_MasterXfer_Type app_i2c_xfer;uint8_t GS_Write_Byte(uint8_t REG_Address,uint8_t REG_data);uint8_t GS_Read_Byte(uint8_t REG_Address);uint8_t GS_Read_nByte(uint8_t REG_Address,uint16_t len,uint8_t *buf);void GS_i2c_init(void);void GS_WakeUp(void);void IIC_SpeedCtl(unsigned short speed);void SDA_SetGpioMode(uint8_t mode);void SCL_SetGpioMode(uint8_t mode);void IIC_delay(uint16_t n);void app_delay_ms(uint32_t t);void app_delay_us(uint32_t t);#endif
paj7620u2_iic.c文件:
//PAJ2670 I2C初始化void GS_i2c_init(void){ /* Setup I2C initialization values. */ I2C_Master_Init_Type i2c_init; i2c_init.ClockFreqHz = BOARD_I2C_FREQ; i2c_init.BaudRate = I2C_BaudRate_100K; /* Initialize I2C master. */ I2C_InitMaster(BOARD_I2C_PORT, &i2c_init); /* The target device address needs to be configured before enabling. */ I2C_SetTargetAddr(BOARD_I2C_PORT, APP_I2C_TARGET_ADDR); /* Enable I2C. */ I2C_Enable(BOARD_I2C_PORT, true); GPIO_WriteBit(SCL_PORT,SCL_GPIO,1u); GPIO_WriteBit(SDA_PORT,SDA_GPIO,1u); }/****************************************************************************************************************switch SDA GPIO input or output****************************************************************************************************************/void SDA_SetGpioMode(uint8_t mode){ GPIO_Init_Type gpio_init; gpio_init.Pins = SDA_GPIO; if(mode==1) { gpio_init.PinMode = GPIO_PinMode_Out_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; } else gpio_init.PinMode = GPIO_PinMode_In_PullUp; GPIO_Init(SDA_PORT, &gpio_init); GPIO_PinAFConf(SDA_PORT, gpio_init.Pins, GPIO_AF_4); }void SCL_SetGpioMode(uint8_t mode){ GPIO_Init_Type gpio_init; gpio_init.Pins = SCL_GPIO; if(mode==1) { gpio_init.PinMode = GPIO_PinMode_Out_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; } else gpio_init.PinMode = GPIO_PinMode_In_PullUp; GPIO_Init(SCL_PORT, &gpio_init); GPIO_PinAFConf(SCL_PORT, gpio_init.Pins, GPIO_AF_4); }//产生IIC起始信号static void GS_IIC_Start(void){ SDA_SetGpioMode(1); SDA_H; SCL_H; app_delay_us(4); SDA_L; app_delay_us(4); SCL_L;}//产生IIC停止信号static void GS_IIC_Stop(void){ SDA_SetGpioMode(1);//sda线输出 SCL_L; SDA_L; app_delay_us(4); SCL_H; SDA_H; app_delay_us(4);}//等待应答信号到来//返回值:1,接收应答失败// 0,接收应答成功static uint8_t GS_IIC_Wait_Ack(void){ uint8_t ucErrTime=0; SDA_SetGpioMode(0); //SDA设置为输入 SDA_H; app_delay_us(3); SCL_H; app_delay_us(3); while(SDA_R) { ucErrTime++; if(ucErrTime>250) { GS_IIC_Stop(); return 1; } } SCL_L; return 0;}//产生ACK应答static void GS_IIC_Ack(void){ SCL_L; SDA_SetGpioMode(1); SDA_L; app_delay_us(3); SCL_H; app_delay_us(3); SCL_L;}//不产生ACK应答 static void GS_IIC_NAck(void){ SCL_L; SDA_SetGpioMode(1); SDA_H; app_delay_us(2); SCL_H; app_delay_us(2); SCL_L;}//IIC发送一个字节//返回从机有无应答//1,有应答//0,无应答static void GS_IIC_Send_Byte(uint8_t txd){ uint8_t t; SDA_SetGpioMode(1); SCL_L;//拉低时钟开始数据传输 for(t=0;t>7) SDA_H; else SDA_L; txd<<=1; app_delay_us(5); SCL_H; app_delay_us(5); SCL_L; app_delay_us(5); }} //读1个字节,ack=1时,发送ACK,ack=0,发送nACK static uint8_t GS_IIC_Read_Byte(uint8_t ack){ uint8_t i,receive=0; SDA_SetGpioMode(0);//SDA设置为输入 for(i=0;i<8;i++ ) { SCL_L; app_delay_us(4); SCL_H; receive<<=1; if(SDA_R)receive++; app_delay_us(4); } if (!ack) GS_IIC_NAck();//发送nACK else GS_IIC_Ack(); //发送ACK return receive;}//PAJ7620U2写一个字节数据uint8_t GS_Write_Byte(uint8_t REG_Address,uint8_t REG_data){ GS_IIC_Start(); GS_IIC_Send_Byte(PAJ7620_ID); if(GS_IIC_Wait_Ack()) { GS_IIC_Stop();//释放总线 return 1;//没应答则退出 } GS_IIC_Send_Byte(REG_Address); GS_IIC_Wait_Ack(); GS_IIC_Send_Byte(REG_data); GS_IIC_Wait_Ack(); GS_IIC_Stop(); return 0;}//PAJ7620U2读一个字节数据uint8_t GS_Read_Byte(uint8_t REG_Address){ uint8_t REG_data; GS_IIC_Start(); GS_IIC_Send_Byte(PAJ7620_ID);//发写命令 if(GS_IIC_Wait_Ack()) { GS_IIC_Stop();//释放总线 return 0;//没应答则退出 } GS_IIC_Send_Byte(REG_Address); GS_IIC_Wait_Ack(); GS_IIC_Start(); GS_IIC_Send_Byte(PAJ7620_ID|0x01);//发读命令 GS_IIC_Wait_Ack(); REG_data = GS_IIC_Read_Byte(0); GS_IIC_Stop(); return REG_data;}//PAJ7620U2读n个字节数据uint8_t GS_Read_nByte(uint8_t REG_Address,uint16_t len,uint8_t *buf){ GS_IIC_Start(); GS_IIC_Send_Byte(PAJ7620_ID);//发写命令 if(GS_IIC_Wait_Ack()) { GS_IIC_Stop();//释放总线 return 1;//没应答则退出 } GS_IIC_Send_Byte(REG_Address); GS_IIC_Wait_Ack(); GS_IIC_Start(); GS_IIC_Send_Byte(PAJ7620_ID|0x01);//发读命令 GS_IIC_Wait_Ack(); while(len) { if(len==1) { *buf = GS_IIC_Read_Byte(0); } else { *buf = GS_IIC_Read_Byte(1); } buf++; len--; } GS_IIC_Stop();//释放总线 return 0; }//PAJ7620唤醒void GS_WakeUp(void){ GS_IIC_Start(); GS_IIC_Send_Byte(PAJ7620_ID);//发写命令 GS_IIC_Stop();//释放总线}
paj7620u2.c文件:
//手势识别测试void Gesture_test(void){ uint8_t i; uint8_t status; uint8_t key; uint8_t data[2]={0x00}; uint16_t gesture_data; uint8_t ledflash=0; paj7620u2_selectBank(BANK0);//进入BANK0寄存器区域 for(i=0;i<GESTURE_SIZE;i++) { GS_Write_Byte(gesture_arry[i][0],gesture_arry[i][1]);//手势识别模式初始化 } paj7620u2_selectBank(BANK0);//切换回BANK0寄存器区域 i=0; printf("--- Gesture show ---\r\n"); while(1) { status = GS_Read_nByte(PAJ_GET_INT_FLAG1,2,&data[0]);//读取手势状态 if(!status) { gesture_data =(uint16_t)data[1]<<8 | data[0]; if(gesture_data) { switch(gesture_data) { case GES_UP: printf("Up\r\n"); ledflash=1; GPIO_WriteBit(GPIOC,GPIO_PIN_9,1u);GPIO_WriteBit(GPIOB,GPIO_PIN_14,0u);GPIO_WriteBit(GPIOD,GPIO_PIN_2,0u);GPIO_WriteBit(GPIOI,GPIO_PIN_0,0u); break; //向上 case GES_DOWM: printf("Dowm\r\n"); ledflash=1;GPIO_WriteBit(GPIOC,GPIO_PIN_9,0u);GPIO_WriteBit(GPIOB,GPIO_PIN_14,1u);GPIO_WriteBit(GPIOD,GPIO_PIN_2,0u);GPIO_WriteBit(GPIOI,GPIO_PIN_0,0u); break; //向下 case GES_LEFT: printf("Left\r\n"); ledflash=1;GPIO_WriteBit(GPIOC,GPIO_PIN_9,0u);GPIO_WriteBit(GPIOB,GPIO_PIN_14,0u);GPIO_WriteBit(GPIOD,GPIO_PIN_2,1u);GPIO_WriteBit(GPIOI,GPIO_PIN_0,0u); break; //向左 case GES_RIGHT: printf("Right\r\n"); ledflash=1;GPIO_WriteBit(GPIOC,GPIO_PIN_9,0u);GPIO_WriteBit(GPIOB,GPIO_PIN_14,0u);GPIO_WriteBit(GPIOD,GPIO_PIN_2,0u);GPIO_WriteBit(GPIOI,GPIO_PIN_0,1u); break; //向右 default:ledflash=0; break; } app_delay_ms(300); i++; printf("### check %d\r\n",i); if(i==500) { i=0; } }}
main.c文件:
/* * Functions. */int main(void){ uint8_t check_yn =0; BOARD_Init(); printf("hello, world\r\n"); app_delay_ms(500); printf("PAJ7620U2 test\r\n"); while(!paj7620u2_init()) { printf("PAJ7620U2 Error!!!\r\n");check_yn = 1; } if(check_yn==1) { printf("PAJ7620U2 Ok!!!\r\n"); } while (1) {if(check_yn==1) { paj7620u2_sensor_test();//PAJ7620U2传感器测试 } }}