2 Star 0 Fork 1

xingkebin/SPO2

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
ACM_Funcs.c 18.03 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
/*
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 作者 日期
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 魏彬 2014年7月30日
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 描述
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 加速度计配置
这块内容,直接套用之前晓宇给的程序,仅在初始化处做了简单的修改。
同时对tran运动阈值设置,如果超过一定值,那么会motion_flag置位,表明有
剧烈运动。
* 修改:1、增加对角度的识别 ,sleep模式可能会影响 kebin
* 2、增加运动中断唤醒设备(计划)
**********************************************************************/
#include "p32mx150f128b.h"
#include "stdio.h"
#include "extern_func.h"
#include "Port_init.h"
#include <plib.h>
#define ACMAddress_W 0x38
#define ACMAddress_R 0x39
//*********************Function declerations***************//
unsigned char initACM(void);
unsigned char initACM1(void);
unsigned char disableACM(void);
unsigned char ACM_Read(unsigned char, unsigned char, unsigned char*);
unsigned char ACM_Write(unsigned char, unsigned char, unsigned char*);
unsigned char ACM_data_read(void);
unsigned char ACM_orientation_read(void);
unsigned char ACM_motion_read(void);
unsigned char ACM_trans_read(void);
unsigned char ACM_mode_read(void);
unsigned char ACM_INT_read(void);
void ACM_INT_Process(void);
unsigned char ACM_STATYS_BUF = 0;
unsigned char ACM_MOTION_BUF = 0;
unsigned char ACM_ORIENTATION_BUF = 0;
unsigned char ACM_TRANS_BUF = 0;
unsigned char ACM_MODE_BUF = 0;
unsigned char ACM_INT_BUF = 0;
unsigned short int ACM_DATA_BUF[3];
unsigned char Sys_State_ACM_New = 0;
unsigned char ACM_RESULT = 0;
enum ORIENTATION Orientation = PUF,Orientation_Bef= PUF;
/*****************************************************/
/*加速度传感器中断的初始化
传感器的INT1引脚对应MCU的RB4,即INT4,目前配置位为较低的中断优先级
*/
void ACMint_init() {
IEC0bits.INT4IE = 0;
IFS0bits.INT4IF = 0;
IPC4bits.INT4IP = 1;
IPC4bits.INT4IS = 3;
INTCONbits.INT4EP = 1; //上升沿触发中断
IFS0bits.INT4IF = 0;
IEC0bits.INT4IE = 1;
}
unsigned char initACM1(void) {
unsigned char I2C1_Error = 0, temp; //I2C1 error bit
if (ACM_Read(0X2A, 1, &temp))
I2C1_Error = 1;
temp &= 0XFE;
if (ACM_Write(0X2A, 1, &temp))
I2C1_Error = 1;
delay(100);
if (ACM_Read(0X2A, 1, &temp))
I2C1_Error = 1;
temp &= 0XC7;
temp |= 0X20;
if (ACM_Write(0X2A, 1, &temp))
I2C1_Error = 1;
if (ACM_Read(0X11, 1, &temp))
I2C1_Error = 1;
temp |= 0X40;
if (ACM_Write(0X11, 1, &temp))
I2C1_Error = 1;
if (ACM_Read(0X2C, 1, &temp))
I2C1_Error = 1;
temp |= 0X22;
if (ACM_Write(0X2C, 1, &temp))
I2C1_Error = 1;
if (ACM_Read(0X2D, 1, &temp))
I2C1_Error = 1;
temp |= 0X90;
if (ACM_Write(0X2D, 1, &temp))
I2C1_Error = 1;
if (ACM_Read(0X2E, 1, &temp))
I2C1_Error = 1;
temp &= 0XEF;
if (ACM_Write(0X2E, 1, &temp))
I2C1_Error = 1;
temp = 0X05;
if (ACM_Write(0X12, 1, &temp))
I2C1_Error = 1;
if (ACM_Read(0X2A, 1, &temp))
I2C1_Error = 1;
temp |= 0X01;
if (ACM_Write(0X2A, 1, &temp))
I2C1_Error = 1;
delay(100);
}
//*****************************************************//
/*加速度传感器的初始化配置
仅使能了TRANS中断,详见0x2D寄存器,以及0x1F和0x20寄存器
*/
unsigned char initACM(void) {
unsigned char I2C1_Error = 0; //I2C1 error bit
unsigned char ACM_Set_Buf[0x32] = {
///////Status
0b00000000, //0x00
///////Data
0b00000000, //0x01
0b00000000, //0x02
0b00000000, //0x03
0b00000000, //0x04
0b00000000, //0x05
0b00000000, //0x06
0b00000000, //0x07 N/A
0b00000000, //0x08 N/A
0b00000000, //0x09 N/A
0b00000000, //0x0A N/A
///////System mode
0b00000000, //0x0B
///////INT source
0b00000000, //0x0C
///////Device ID
0b00000000, //0x0D
///////Dynamic range and high pass filter
0b00010000, //0x0E RW //HPF,2g
0b00010010, //0x0F RW //high pass cut-off setting
///////Orientation
0b00000000, //0x10
0b11000000, //0x11 RW //Portrait/Landscape Detection is Enabled.
0b00000010, //0x12 RW //orientation debonce counter:2*80mS=160ms
0b00000000, //0x13
0b00000000, //0x14 //orientation threshold and hysteresis
///////motion and free fall
0b11011000, //0x15 RW//禁止Z轴。kebin,1g>0.252g
0b00000000, //0x16
0b00000100, //0x17 RW //motion/free fall threshold 0b00000100//web ,0.063g/LSB *4=0.252g &&&
0b00001010, //0x18 RW //motion/free fall debonce counter 0b00000011 //web,10开始减 80ms*10=800ms
0b00000000, //0x19 N/A
0b00000000, //0x1A N/A
0b00000000, //0x1B N/A
0b00000000, //0x1C N/A
///////Transient acceleration detection
0b00011110, //0x1D RW
0b00000000, //0x1E
0b00000100, //0x1F RW //transient detection threshold 0b00000001 //web,0.063g/LSB*4=0.252g
0b00000111, //0x20 RW //transient debonce counter 0b00000011 //web,80ms*7=560ms
///////Tap detection
0b00000000, //0x21 RW
0b00000000, //0x22
0b00000000, //0x23 RW
0b00000000, //0x24 RW
0b00000000, //0x25 RW
0b00000000, //0x26 RW
0b00000000, //0x27 RW
0b00000000, //0x28 RW
///////Auto-wake/sleep detection
0b00001000, //0x29 RW //the time delay counter for entering the sleep mode:320ms*8=2560mS=2.56s
///////Config
0b11110101, //0x2A RW //CONFIG1,sleep:1.56Hz,active:6.25Hz
0b00001101, //0x2B RW //CONFIG2,Auto-SLEEP is enabled,
0b01111010, //0x2C RW //CONFIG3
//0b00100000, //0x2D RW //CONFIG4 0b10110000 // 0b00100000,//web
0b10110100, //0x2D RW //CONFIG4,kebin
//0b10111101,//0b00000000,//0b10111101, //0x2E RW //CONFIG5 web
0b00001001, //0x2E RW //CONFIG5 kebin,INT2
///////Offset correctoin
0b00000000, //0x2F RW //Offset X
0b00000000, //0x30 RW //Offset Y
0b00000000, //0x31 RW //Offset Z
};
/////////////////////////////
unsigned char i = 0b01000000;
if (ACM_Write(0x2B, 1, &i)) //reset
I2C1_Error = 1;
delay(100);
i = 0b00000000;
if (ACM_Write(0x2A, 1, &i)) //reset
I2C1_Error = 1;
delay(100);
if (ACM_Write(0x0E, 1, ACM_Set_Buf + 0x0E)) //XYZ_DATA_CFG
I2C1_Error = 1;
if (ACM_Write(0x0F, 1, ACM_Set_Buf + 0x0F)) //HP_FILTER_CUTOFF
I2C1_Error = 1;
if (ACM_Write(0x11, 1, ACM_Set_Buf + 0x11)) //PL_CFG
I2C1_Error = 1;
if (ACM_Write(0x12, 1, ACM_Set_Buf + 0x12)) //
I2C1_Error = 1;
if (ACM_Write(0x15, 1, ACM_Set_Buf + 0x15)) //FF_MT_CFG
I2C1_Error = 1;
if (ACM_Write(0x17, 1, ACM_Set_Buf + 0x17)) //FF_MT_THS
I2C1_Error = 1;
if (ACM_Write(0x18, 1, ACM_Set_Buf + 0x18)) //FF_MT_COUNT
I2C1_Error = 1;
if (ACM_Write(0x1D, 1, ACM_Set_Buf + 0x1D)) //TRANSIENT_CFG
I2C1_Error = 1;
if (ACM_Write(0x1F, 1, ACM_Set_Buf + 0x1F)) //TRANSIENT_THS
I2C1_Error = 1;
if (ACM_Write(0x20, 1, ACM_Set_Buf + 0x20)) //TRANSIENT_COUNT
I2C1_Error = 1;
if (ACM_Write(0x21, 1, ACM_Set_Buf + 0x21)) //PULSE_CFG
I2C1_Error = 1;
if (ACM_Write(0x23, 1, ACM_Set_Buf + 0x23)) //PULSE_THSX
I2C1_Error = 1;
if (ACM_Write(0x24, 1, ACM_Set_Buf + 0x24)) //PULSE_THSY
I2C1_Error = 1;
if (ACM_Write(0x25, 1, ACM_Set_Buf + 0x25)) //PULSE_THSZ
I2C1_Error = 1;
if (ACM_Write(0x26, 1, ACM_Set_Buf + 0x26)) //PULSE_TMLT
I2C1_Error = 1;
if (ACM_Write(0x27, 1, ACM_Set_Buf + 0x27)) //PULSE_LTCY
I2C1_Error = 1;
if (ACM_Write(0x28, 1, ACM_Set_Buf + 0x28)) //PULSE_WIND
I2C1_Error = 1;
if (ACM_Write(0x29, 1, ACM_Set_Buf + 0x29)) //ASLP_COUNT
I2C1_Error = 1;
if (ACM_Write(0x2B, 1, ACM_Set_Buf + 0x2B)) //CTRL_REG2
I2C1_Error = 1;
if (ACM_Write(0x2C, 1, ACM_Set_Buf + 0x2C)) //CTRL_REG3
I2C1_Error = 1;
if (ACM_Write(0x2D, 1, ACM_Set_Buf + 0x2D)) //CTRL_REG4
I2C1_Error = 1;
if (ACM_Write(0x2E, 1, ACM_Set_Buf + 0x2E)) //CTRL_REG5
I2C1_Error = 1;
if (ACM_Write(0x2F, 1, ACM_Set_Buf + 0x2F)) //OFF_X
I2C1_Error = 1;
if (ACM_Write(0x30, 1, ACM_Set_Buf + 0x30)) //OFF_Y
I2C1_Error = 1;
if (ACM_Write(0x31, 1, ACM_Set_Buf + 0x31)) //OFF_Z
I2C1_Error = 1;
if (ACM_Write(0x2A, 1, ACM_Set_Buf + 0x2A)) //CTRL_REG1
I2C1_Error = 1;
return I2C1_Error;
}
//************************disable the ACM module*******************//
unsigned char disableACM(void) {
unsigned char I2C1_Error = 0; //I2C1 error bit
unsigned char acm_disable = 0b11110100;
if (ACM_Write(0x2A, 1, &acm_disable)) //CTRL_REG1
I2C1_Error = 1;
return I2C1_Error;
}
//**********************read accelerometer************************//
//this function reads up to 256 bytes from the accelerometer.
//returns the error message. 1=error, 0=no error
//TP_RedAddr: the start register address to read
//n: number of registers to read
//TPBuffer_ptr: the pointer of data buffer where the received data to be saved
unsigned char ACM_Read(unsigned char ACM_RegAddr, unsigned char n, unsigned char* ACMBuffer_ptr) {
unsigned char I2C1_Error = 0; //I2C1 error bit
unsigned char i = 0;
if (start_I2C1())
I2C1_Error = 1; //start
if (putchar_I2C1(ACMAddress_W))
I2C1_Error = 1; //send address
if (putchar_I2C1(ACM_RegAddr))
I2C1_Error = 1; //send register address
if (restart_I2C1())
I2C1_Error = 1; //restart
if (putchar_I2C1(ACMAddress_R))
I2C1_Error = 1; //send address
for (; i < n; i++) {
*ACMBuffer_ptr++ = getchar_I2C1();
if (i < (n - 1)) {
if (ack_I2C1())
I2C1_Error = 1;
}
}
if (nack_I2C1())
I2C1_Error = 1;
if (stop_I2C1())
I2C1_Error = 1;
return I2C1_Error;
}
//**********************write accelerometer************************//
//this function writes up to 256 bytes to the accelerometer.
//returns the error message. 1=error, 0=no error
//ACM_RedAddr: the start register address to read
//n: number of registers to read
//ACMBuffer_ptr: the pointer of data buffer where the data to be written
unsigned char ACM_Write(unsigned char ACM_RegAddr, unsigned char n, unsigned char* ACMBuffer_ptr) {
unsigned char I2C1_Error = 0; //I2C1 error bit
unsigned char i = 0;
if (start_I2C1())
I2C1_Error = 1; //start
if (putchar_I2C1(ACMAddress_W))
I2C1_Error = 1; //send address
if (putchar_I2C1(ACM_RegAddr))
I2C1_Error = 1; //send register address
for (; i < n; i++) {
if (putchar_I2C1(*ACMBuffer_ptr++))
I2C1_Error = 1; //send address
}
if (stop_I2C1())
I2C1_Error = 1;
return I2C1_Error;
}
//*******************accelerometer data read*********************//
unsigned char ACM_data_read(void) {
unsigned char I2C1_Error = 0; //I2C1 error bit
unsigned char acm_buf_temp[6];
if (ACM_Read(0x00, 1, &ACM_STATYS_BUF)) //status byte read
I2C1_Error = 1;
if (ACM_Read(0x01, 1, acm_buf_temp)) //X_MSB
I2C1_Error = 1;
if (ACM_Read(0x02, 1, acm_buf_temp + 1)) //X_LSB
I2C1_Error = 1;
if (ACM_Read(0x03, 1, acm_buf_temp + 2)) //Y_MSB
I2C1_Error = 1;
if (ACM_Read(0x04, 1, acm_buf_temp + 3)) //Y_LSB
I2C1_Error = 1;
if (ACM_Read(0x05, 1, acm_buf_temp + 4)) //Z_MSB
I2C1_Error = 1;
if (ACM_Read(0x06, 1, acm_buf_temp + 5)) //Z_LSB
I2C1_Error = 1;
ACM_DATA_BUF[0] = (acm_buf_temp[0] << 8) + acm_buf_temp[1] + 0x8000; //X, the "+0x8000" is to move the base line to 0x8000
ACM_DATA_BUF[1] = (acm_buf_temp[2] << 8) + acm_buf_temp[3] + 0x8000; //Y
ACM_DATA_BUF[2] = (acm_buf_temp[4] << 8) + acm_buf_temp[5] + 0x8000; //Z
////test////
putstringUART1("\r\nX=");
putcharUART1(ACM_DATA_BUF[0]);
putcharUART1(ACM_DATA_BUF[0] >> 8);
putstringUART1(" Y=");
putcharUART1(ACM_DATA_BUF[1]);
putcharUART1(ACM_DATA_BUF[1] >> 8);
putstringUART1(" Z=");
putcharUART1(ACM_DATA_BUF[2]);
putcharUART1(ACM_DATA_BUF[2] >> 8);
putstringUART1("\r\n");
///////////
return I2C1_Error;
}
//*******************accelerometer data read*********************//
unsigned char ACM_orientation_read(void) {
unsigned char I2C1_Error = 0; //I2C1 error bit
if (ACM_Read(0x10, 1, &ACM_ORIENTATION_BUF)) //status byte read
I2C1_Error = 1;
else{
//putstringUART1("ACM_ORIENTATION_BUF:\r\n");
//UART1_Put_hex(ACM_ORIENTATION_BUF);
if (ACM_ORIENTATION_BUF & 0x80) {//ACM_ORIENTATION_BUF
if (ACM_ORIENTATION_BUF & 0x40)//LO
{
}
Orientation_Bef=Orientation;
switch (ACM_ORIENTATION_BUF & 0x07) {
case 0:Orientation = PUF;
//putstringUART1("PUF\r\n");
break;
case 1:Orientation = PUB;
//putstringUART1("PUB\r\n");
break;
case 2:Orientation = PDF;
//putstringUART1("PDF\r\n");
break;
case 3:Orientation = PDB;
//putstringUART1("PDB\r\n");
break;
case 4:Orientation = LRF;
//putstringUART1("LRF\r\n");
break;
case 5:Orientation = LRB;
//putstringUART1("LRB\r\n");
break;
case 6:Orientation = LLF;
//putstringUART1("LLF\r\n");
break;
case 7:Orientation = LLB;
//putstringUART1("LLB\r\n");
break;
}
}
}
return I2C1_Error;
}
//*******************accelerometer data read*********************//
unsigned char ACM_motion_read(void) {
unsigned char I2C1_Error = 0; //I2C1 error bit
if (ACM_Read(0x16, 1, &ACM_MOTION_BUF)) //status byte read
{
I2C1_Error = 1;
//putstringUART1("MOTION_ERROR!\r\n");
}
else
{motion_flag = 1;
////test////
//putstringUART1("MOT=");
//SendDecimalismDta(ACM_MOTION_BUF);
//putstringUART1("\r\n");
///////////
}
return I2C1_Error;
}
//*******************accelerometer data read*********************//
unsigned char ACM_trans_read(void) {
unsigned char I2C1_Error = 0; //I2C1 error bit
if (ACM_Read(0x1E, 1, &ACM_TRANS_BUF)) //status byte read
I2C1_Error = 1;
else
{
motion_flag = 1;
////test////
// putstringUART1("TNS=");
// SendDecimalismDta(ACM_TRANS_BUF);
// putstringUART1("\r\n");
///////////
//超过阈值时,置位表明有剧烈运动
}
return I2C1_Error;
}
//*******************accelerometer data read*********************//
unsigned char ACM_mode_read(void) {
unsigned char I2C1_Error = 0; //I2C1 error bit
if (ACM_Read(0x0B, 1, &ACM_MODE_BUF)) //status byte read
I2C1_Error = 1;
////test////
/* putstringUART1("MOD=");
putcharUART1(ACM_MODE_BUF);
putstringUART1("\r\n");*/
///////////
return I2C1_Error;
}
//*******************accelerometer data read*********************//
unsigned char ACM_INT_read(void) {
unsigned char I2C1_Error = 0; //I2C1 error bit
unsigned char acm_buf_temp[6];
if (ACM_Read(0x0C, 1, &ACM_INT_BUF)) //status byte read
I2C1_Error = 1;
////test////
/* putstringUART1("ACM INT=");
putcharUART1(ACM_INT_BUF);*/
///////////
return I2C1_Error;
}
//*******************accelerometer data read*********************//
void ACM_INT_Process(void) {
ACM_INT_BUF = 1;
Sys_State_ACM_New = 1;
while (ACM_INT_BUF != 0) //为了进入这个while,才把ACM_INT_BUF置为1
{ //读取所有6个对应寄存器清除6个中断标志位,kebin
//putstringUART1("in the while:\r\n");
if (ACM_INT_read() == 0) //if no error
{
//putstringUART1("ACM_INT_BUF:");
//SendDecimalismDta(ACM_INT_BUF);
//putstringUART1("\r\n");
if ((ACM_INT_BUF & 0b10000000) != 0) //sleep/wake int
{
// putstringUART1("ACM_mode_read!\r\n");
ACM_mode_read();
}
if ((ACM_INT_BUF & 0b00100000) != 0) //trans int
{
//putstringUART1("ACM_trans_read!\r\n");
ACM_trans_read();
}
if ((ACM_INT_BUF & 0b00010000) != 0) //orientation int ,增加功能用于屏幕转动,kebin
{
//putstringUART1("ACM_orientation_read!\r\n");
ACM_orientation_read();
}
if ((ACM_INT_BUF & 0b00001000) != 0) //pulse int
{
}
if ((ACM_INT_BUF & 0b00000100) != 0) //motion/free fall int
{
// putstringUART1("ACM_motion_read!\r\n");
ACM_motion_read();
}
if ((ACM_INT_BUF & 0b00000001) != 0) //data ready int
{
}
ACM_INT_BUF=0;
} else {
disableACM();
disableI2C1();
initI2C1();
initACM();
// putstringUART5_DM("ACM restarted\r\n");
break;
}
}
/*
if (ACM_TRANS_BUF != 0) //if new transient event is detected
{
ACM_RESULT = (ACM_ORIENTATION_BUF & 0b00000111) + 0b10000000;
ACM_TRANS_BUF = 0; //clear the buffer
} else {
ACM_RESULT = (ACM_ORIENTATION_BUF & 0b00000111);
}
*/
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/kerr.xing/SPO2.git
git@gitee.com:kerr.xing/SPO2.git
kerr.xing
SPO2
SPO2
master

搜索帮助