主题中讨论的其他器件:CC2541、 TPS62730
你好。 我正在尝试使用 MMA7660 (加速计)将 CC2541连接到 I2C。 我设法对 MMA7660寄存器进行写入、也进行了读取。 但是、当我尝试读取倾斜寄存器时、
Success = accRead (MMA7660_tilt、& rTILT、sizeof (rTILT));
rTILT 取值0x00。 如果我在线路成功= accRead (MMA7660_tilt 和 rTILT、sizeof (rTILT))之后放置一个检查点、则 rTILT 等于0x00、这不是真的。 如果我在 succeed= accRead (MMA7660_tilt 和 rTILT、sizeof (rTILT))行上放置一个点; 然后我进行分步操作、那么我得到的值为0c02、这是正确的值。
请帮帮我!
我引述了该方案的案文。
/*********
*包括
*
#include "bcomdef.h"
#include "OSAL.h"
#include "OSAL_PwrMgr.h"
#include "onboard.h"
#include "hal_adc.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_i2c.h"
#include "rgb_data.h"
#include "mma7660.h"
#include "gatt.h"
#include "hci.h"
#include "gapgattserver.h"
#include "gattservapp.h"
#include "gatt_profile_uuid.h"
#if 已定义(PLUS_Broadcaster)
#include "peripheralBroadcaster .h"
其他
#include "peripheral.h"
#endif
#include "gapbondmgr.h"
#include "devinfoservice.h"
#include "proxy.h"
#include "adcservice.h"
#include "加速 计.h"
#include "simplekeys.h"
#include "keyfobdemo.h"
/*********
*宏
*
/*********
*常量
*
//加电和启动广播之间的延迟(以 ms 为单位)
#define STARTDELAY 500
как часто обновлять данные на светодиод μ s (в мс μ s)
#define RGB_WRITE_PERIOD 3000
//蜂鸣器本身停止之前的蜂鸣次数
#define RGB_MAX_BITS 24.
как часто проверять АЦП μ s (в мс μ s)
#define ADC_CHECK_PERIOD 10000
как часто читать акселерометр μ s (в мс μ s)
#define ACCEL_READ_PERIOD 2000
//发送通知前加速计的最小变化
#define ACCEL_CHANGE_THRESHOLD 5.
//GAP 外设角色所需的连接参数
//使用有限的可发现模式广播30.72,然后停止,或者
//使用常规可发现模式无限期广播
#define DEFAULT_DISCOVELOAD_MODE GAP_ADTYPE_FLAGS_LIMITED
//#define DEFAULT_DISCOVERAING_MODE GAP_ADTYPE_FLAGS_GENERAL
//如果启用了自动参数更新请求,则最小连接间隔(单位为1.25ms,80=100ms)
#define DEFAULT_MIVEed_MIN_CONN_INTERVAL 80
//如果启用了自动参数更新请求,则最大连接间隔(单位为1.25ms,800=1000ms)
#define DEFAULT_MODED_MAX_CONN_INTERVAL 800
//启用自动参数更新请求时要使用的从器件延迟
#define DEFAULT_REGLED_SLAVE_LON延 时0
//如果启用了自动参数更新请求,则监控超时值(10ms、1000=10s 的单位)
#define DEFAULT_MODED_CONN_TIMEOUT 1000
//在建立连接时是否启用自动参数更新请求
#define DEFAULT_ENABLE_UPDATE_REQUEST TRUE
//连接暂停外围设备时间值(以秒为单位)
#define DEFAULT_CONN_PAUSE_PERIFICE_PERFRAD 5.
// keyfobProximityState 值
#define keyfu_PROXSTATE_INITIALIZED 0 //初始化后或由于链路终止而广播
#define keyfu_PROXSTATE_connected;in_range 1 //已连接并处于主器件的"在范围内"、如所定义
//接近曲线
#define keyfu_PROXSTATE_PATH_LOSS 2 //已连接主器件并"超出范围"、如所定义
//接近曲线
#define keyfu_PROXSTATE_LINK_LOSS 3 //由于监护超时而断开连接
// RGB 状态值
#define RGB_OFF 0
#define RGB_ON 1.
// keyfobAlertState 值
#define ALERT_State_off 0
#define ALERT_STATE_LOW 1.
#define ALERT_State_High 2.
#define State_0 0
#define State_1 1.
#define State_2 2.
//公司标识符:Texas Instruments Inc.(13)
#define TI_COMPANY_ID 0x000D
#define INVALID_CONNHELDLE 0xFFFF
#if 已定义(PLUS_Broadcaster)
#define ADV_IN_CONN_WAIT 500 //延迟500ms
#endif
/*********
* typedef
*
/*********
*全局变量
*
/*********
*外部变量
*
/*********
外部功能
*
/*********
*局部变量
*
静态 uint8 keyfobapp_taskID;//用于内部任务/事件处理的任务 ID
静态 gaprole_states_t gapProfileState = GAPROLE_init;
// GAP -扫描 RSP 数据(最大大小= 31字节)
静态 uint8 deviceName[]=
{
//完整名称
0x0F、//第一个数据结构的长度(不包括长度字节的11个字节)
0x09、// AD 类型=完整的本地名称
0x4b、//'K'
0x65、//'e'
0x79、//'y'
0x66、//'f'
0x6f、//'o'
0x62、//"b"
0x64、//'d'
0x65、//'e'
0x6d、//"m"
0x6f、//'o'
0x5f、//'_'
0x41、//'A'
0x44、//'D'
0x43、//"C"
};
// GAP -广播数据(最大大小= 31字节、尽管如此
//在进行广告宣传时最好保持短接以节省功耗)
//间隙-Реклама данные(максимальный размер= 31 байт、хотя это
//лучше всего хранить в краткосрочной экономии энергии во время 广告)
静态 uint8 advertData[]=
{
0x02、//第一个数据结构的长度(不包括长度字节的2个字节)
GAP_ADTYPE_FLAGS、// AD 类型=标志
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED、
//服务 UUID,通知中央设备包含哪些服务
//中
0x07、//第二个数据结构的长度(7个字节、不包括长度字节)
GAP_ADTYPE_16BIT_more、//可用16位 UUID 列表,但不完整列表
LO_UINT16 (LINK_LOW_SERV_UUID)、//链接丢失服务(接近配置文件)
hi_uint16 (link_loss _serv_UUID)、
LO_UINT16 (immediate_alert_SERV_UUID),//立即警报服务(接近/查找本人配置文件)
hi_uint16 (immediate_alert_serV_UUID),
LO_UINT16 (TX_PWR_LEVEL_SERV_UUID)、// Tx 功率级别服务(接近配置文件)
HI_UINT16 (TX_PWR_LEVEL_SERV_UUID)
};
// GAP GATT 属性
静态 uint8 attDeviceName[GAP_DEVICE_NAME_LEN]="TI BLE 密钥卡_ADC";
静态 uint8 state_key;
静态 uint8 evt = 0;
静态 uint8 accelEnabler = false;
静态 uint8 MMA7660_XOUT = 0x00;
静态 uint8 MMA7660_弹 出= 0x01;
静态 uint8 MMA7660_ZOUT = 0x02;
静态 uint8 MMA7660_tilt = 0x03;
静态 uint8 MMA7660_SRST = 0x04;
静态 uint8 MMA7660_SPCNT = 0x05;
静态 uint8 MMA7660_INTSU = 0x06;
静态 uint8 MMA7660_MODE = 0x07;
静态 uint8 MMA7660_SR = 0x08;
静态 uint8 MMA7660_PDET = 0x09;
静态 uint8 MMA7660_PD = 0x0A;
静态 uint8 HAL_MMA7660_I2C_ADDRESS = 0x4C;
静态 uint8水平线= false;
静态 bool sysResetRequest = false;
静态 bool long_press = false;
/*********
*本地函数
*
静态空 keyfobADC_ProcessOSALMSG (osal_event_hdr_t *pMsg);
static void keyfobADC_keys( uint8 keys);
static void peripheralStateNotificationCB( gaprole_states_t newState );
static void accelEnabableChangeCB( void );
void accelRead (void *hor);
/*********
*配置文件回调
*
// GAP 角色回调
静态 gapRolesCBs_t 密钥卡_PeripheralCBs =
{
peripheralStateNotificationCB、//配置文件状态更改回调
空//从控制器读取有效的 RSSI
};
// GAP 债券经理回调
静态 gapBondCbs_t keyfap_BondMgrCs =
{
空、//密码回调(不被应用程序使用)
空//配对/绑定状态回调(不被应用使用)
};
静态 accelCBs_t 密钥卡_AccelCBs =
{
accelEnabableChangeCB、
};
/*********
*公共函数
*
/*********
*@fn KeyFobApp_Init
*
*@遥控钥匙应用任务的简要初始化功能。
*这是在初始化期间调用的、应包含
*任何特定于应用的初始化(例如硬件
*初始化/设置、表初始化、加电
很棒的酒店 )。
*
*@param task_id -由 OSAL 分配的 ID。 此 ID 应为
*用于发送消息和设置计时器。
*
*@返回无
*
空 KeyFobApp_Init( uint8 task_id )
{
keyfobapp_TaskID = task_id;
//设置间隙
void GAP_SetParamValue( TGAP_CONN_PAUST_PERUSTRUSE_PERAPHERAL_DEFAULT_CONN_PAUSE_PERAPHET );
//设置 GAP 外围设备角色配置文件
{
//对于 CC2540DK-MINI 密钥卡、在按下按钮之前器件不会开始广播
uint8 inited_advertising_enable = false;
//通过将此值设置为零,器件将在之后进入等待状态
//可发现30.72秒,并且不会再次进行广播
//直到启用程序设置回 true
uint16 gapRole_AddertOffTime = 0;
uint8 enable_update_request = default_enable_update_request;
uint16 desired _min_interval = default_desired _min_CONN_interval;
uint16 desired _max_interval = default_desed_MAX_CONN_interval;
UINT16所需的从器件延迟= DEFAULT_LEVed_SLAVE_DELUTRAT;
uint16 desired _conn_timeout = default_desed_conn_timeout;
//设置 GAP 角色参数
GAPRole_SetParameter( GAPROLE_advertise_enabled,sizeof ( uint8 ),&inition_advertising_enable );
GAPRole_SetParameter( GAPROLE_GOOD_OFF_TIME,sizeof ( uint16 ),&gapRole_AddertOffTime );
GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA,sizeof ( deviceName ),deviceName );
GAPRole_SetParameter( GAPROLE_advertise_data,sizeof ( advertData ),advertData );
GAPRole_SetParameter ( GAPROLE_PARAM_UPDATE_ENABLE,sizeof ( uint8 ),ENABLE_UPDATE_REQUEST );
GAPRole_SetParameter (GAPROLE_MIN_CONN_INTERVAL、sizeof (uint16)、&desired _MIN_INTERVAL);
GAPRole_SetParameter (GAPROLE_MAX_CONN_INTERVAL、sizeof (uint16)、&desired _max_interval);
GAPRole_SetParameter( GAPROLE_SLAVE_DELUMMER,sizeof ( uint16 ),&desired Slave_latency );
GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTICLIER,sizeof ( uint16 ),&desed_conn_TIMEOUT );
}
//设置 GAP 属性
GGS_SetParameter (GGS_DEVICE_NAME_ATT、GAP_DEVICE_NAME_LEN、attDeviceName);
//设置 GAP 绑定管理器
{
uint8线对模式= GAPBOND_Pairing_mode_wait_for_Req;
UINT8 MIPTM = true;
uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
uint8绑定= true;
GAPBondMgr_SetParameter( GAPBOND_Pairing_mode,sizeof ( uint8 ),&pairMode );
GAPBondMgr_SetParameter( GAPBOND_MITM_protection,sizeof ( uint8 ),&MIPTM );
GAPBondMgr_SetParameter( GAPBOND_IO_Capabilities,sizeof ( uint8 ),&ioCap );
GAPBondMgr_SetParameter( GAPBOND_BLUCGE_ENABLED,sizeof ( uint8 ),&bond );
}
//初始化 GATT 属性
GGS_AddService (GATT_All_services);// GAP
GATTServApp_AddService ( GATT_All_services );// GATT 属性
DevInfo_AddService();//设备信息服务
Accel_AddService (GATT_All_services);//加速计配置文件
accStop();
HalLedSet((HAL_LED_1| HAL_LED_2)、HAL_LED_MODE_OFF );
P0SEL = 0;//将端口0配置为 GPIO
P1SEL = 0;//将端口1配置为 GPIO
P2SEL = 0;//将端口2配置为 GPIO
P0DIR = 0x3C;//端口0引脚 P0.0和 P0.1作为输入(按钮)、引脚 P0.6、P0.7作为输入(ADC)
//所有其他(P0.2-P0.7)作为输出
P1DIR = 0xFF;//所有端口1引脚(P1.0-P1.7)作为输出
P2DIR = 0x1F;//所有端口1引脚(P2.0-P2.4)作为输出
P0 = 0x03;//端口0上的所有引脚均为低电平、P0.0和 P0.1除外(按钮)
P1 = 0;//端口1上的所有引脚均为低电平
P2 = 0;//端口2上的所有引脚均为低电平
//初始化 ADC
HalAdcInit();
//注册所有关键事件-此应用程序将处理所有关键事件
RegisterForKeys( keyfobapp_taskID );
#IF 定义(DC_DC_P0_7)
//启用堆栈以切换 TPS62730 (直流/直流转换器)上的旁路控制
HCI_EXT_MapPmIoPortCmd (HCI_EXT_PM_IO_PORT_P0、HCI_EXT_PM_IO_PORT_PIN7);
#endif //定义(DC_DC_P0_7)
//设置延迟的配置文件启动
OSAL_START_timerEx (keyfobapp_TaskID、KFDA_START_DEVICE_EVT、STARTDELAY);
}
/*********
*@fn KeyFobApp_ProcessEvent
*
*@密钥卡应用任务事件处理器简介。 此函数
调用*以处理任务的所有事件。 事件
*包括计时器、消息和任何其他用户定义的事件。
*
*@param task_id - OSAL 分配的任务 ID。
*@参数事件-要处理的事件。 这是位图和 CAN
*包含多个事件。
*
*@返回无
*
uint16 KeyFobApp_ProcessEvent( uint8 task_id,uint16事件)
{
if (事件和 SYS_EVENT_MSG)
{
uint8 *pMsg;
if ((pMsg = osal_msg_receive (keyfobapp_TaskID))!= NULL)
{
keyfobADC_ProcessOSALMSG ((osal_event_HDR_t *) pMsg);
//释放 OSAL 消息
void osal_msg_dealloc( pMsg );
}
//返回未处理的事件
返回(事件^ SYS_EVENT_MSG);
}
if (事件和 KFDA_START_DEVICE_EVT)
{
//启动设备
void GAPRole_StartDevice (&keyfap_PeripheralCBs);
//启动 Bond Manager
void GAPBondMgr_Register (&keyfaps_BondMgrCBs);
//启动加速计配置文件
void Accel_RegisterAppCBs (&keyfap_AccelCBs);
//将 LED1设置为打开以提供电源的反馈,并设置一个计时器以关闭
HalLedSet (HAL_LED_1、HAL_LED_MODE_ON);
OSAL_pwrmgr_device ( PWRMGR_AYST_ON );//使 LED 持续亮起。
OSAL_start_timerEx (keyfobapp_TaskID、KFDA_powerON_LED_TIMEOUT_EVT,1000);
返回(事件^ KFDA_START_DEVICE_EVT);
}
if (事件和 KFDA_POWERON_LED_TIMEOUT_EVT)
{
OSAL_pwrmgr_device ( PWRMGR_battery );//在 LED 关闭后恢复到电池模式
HalLedSet (HAL_LED_1、HAL_LED_MODE_OFF);
返回(事件^ KFDA_POWERON_LED_TIMEOUT_EVT);
}
if (事件和 KFDA_ACCEL_READ_EVT)
{
uint8 rTILT;
uint8 rMODE;
uint8模式= 0;
uint8 SR = 0;
uint8 INTSU = 0;
UINT8 PDET = 0;
uint8 PD = 0;
uint8 SPCNT = 0;
易失性 uint32kk = 0;
bool 成功;
///-------- Инициализация MMA7660--- //
MODE = 0x00;//待机模式
SPCNT = 0x00;
INTSU =(1 << INTSU_gint)|(1 << INTSU_SHINTZ);
PDET =(1 << PDET_XDA)|(1 << PDET_YDA)|(1 << PDET_ZDA);
SR = 0x60;
PD = 0x00;
//SR |=(1 << SR_AMSR0);// 64采样/秒
//SR |=(1 << SR_AMSR0)|(1 << SR_AMSR2);// 4样本/秒
//SR |=(1 << SR_FILT2)|(1 << SR_FILT1)|(1 << SR_FILT0);
//INTSU |= 1 << INTSU_SHINTZ;//Прерывание по встряске Z
Задаем адрес устройства и частоту обмена μ s
HalI2CInit (HAL_MMA7660_I2C_address、i2cClock_267KHZ);
Запись в регистр μ s значение μ s
accWrite (MMA7660_mode、&mode、sizeof (mode));
对于(kk = 0;kk < 180;kkk++)
{
}
Запись в регистр μ s SPCNT
accWrite (MMA7660_SPCNT、&SPCNT、sizeof (SPCNT));
对于(kk = 0;kk < 180;kkk++)
{
}
Запись в регистр μ s INTSU
accWrite (MMA7660_INTSU、&INTSU、sizeof (INTSU));
对于(kk = 0;kk < 180;kkk++)
{
}
Запись в регистр μ s PDET
accWrite (MMA7660_PDET、&PDET、sizeof (PDET));
对于(kk = 0;kk < 180;kkk++)
{
}
Запись в регистр μ s SR
accWrite (MMA7660_SR、&SR、sizeof (SR));
对于(kk = 0;kk < 180;kkk++)
{
}
Запись в регистр μ A PD
accWrite (MMA7660_PD、&PD、sizeof (PD));
对于(kk = 0;kk < 180;kkk++)
{
}
Устанавливаем μ s 激活模式
MODE |=(1 << MODE_MODE);//工作模式
accWrite (MMA7660_MODE、&MODE、sizeof (MODE));//запись в регистр 模式
对于(kk = 0;kk < 254;kk++)
{
}
//-------------------------------------------- //
//mode = 0x00;
成功= accRead (MMA7660_tilt、&rTILT、sizeof (rTILT));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! не передается rTILT
if (((rTILT & 0x01)=0x01)||((rTILT & 0x02)=0x02))
{
OSAL_START_timerEx (keyfobapp_TaskID、KFDA_ADC_CHECK_EVT,1000);
}
返回(事件^ KFDA_ACCEL_READ_EVT);
}
для определния однократного или длительного нажатия кнопки μ s
if (事件和 KFDA_KEYS_EVT)
{
if (sysResetRequest)(如果(sysResetRequest))
{
long_press = true;
if (gapProfileState!= GAPROLE_Connected)
{
UINT8 CURRENT_ADV_ENABLE_STATUS;
uint8 new_adv_enabled_status;
//查找当前的 GAP 广播状态
GAPRole_GetParameter (GAPROLE_advertise_enabled,¤t_adv_enabled_status);
if (current_adv_enabled_status == false)
{
new_adv_enabled_status = true;
}
其他
{
new_adv_enabled_status = false;
}
//将 GAP 广播状态更改为与当前状态相反
GAPRole_SetParameter( GAPROLE_advertise_enabled,sizeof ( uint8 ),&new_adv_enabled_status );
}
}
返回(事件^ KFDA_KEYS_EVT);
}
if (事件和 KFDA_ADC_CHECK_EVT)
{
ADC_MeasLevel ();
返回(事件^ KFDA_ADC_CHECK_EVT);
}
//丢弃未知事件
返回0;
}
/*********
*@fn keyfobADC_ProcessOSALMSG
*
*@简短处理传入任务消息。
*
*@param pMsg -要处理的消息
*
*@返回无
*
静态空 keyfobADC_ProcessOSALMSG (osal_event_hdr_t *pMsg)
{
switch ( pMsg->event )
{
大小写键_更改:
keyfobADC_keys(((keyChange_t *)pMsg)--> keys);
中断;
}
}
/*********
*@fn keyfobADC_keys
*
*@brief 会处理此设备的所有重要事件。
*
*@param shift -如果在 shift/alt 中、则为 true。
*@param keys -密钥事件的位字段。 有效条目:
* HAL_KEY_SW_2
* HAL_KEY_SW_1
*
*@返回无
*
静态空 keyfobADC_keys( uint8 keys )
{
uint8 SK_Keys = 0;
if (keys & HAL_key_sw_1)
{
SK_Keys |= SK_KEY_LEFT;
}
if (keys & HAL_key_sw_2)
{
sysResetRequest = true;
OSAL_START_timerEx (keyfobapp_TaskID、KFDA_keys_EVT,2000);
SK_Keys |= SK_KEY_RIGHT;
}
if (!(keys & HAL_key_sw_2))
{
如果(!long_press)
{
OSAL_START_timerEx (keyfobapp_TaskID、KFDA_ACCEL_READ_EVT、3000);
}
sysResetRequest =错误;
long_press = false;
}
SK_SetParameter( SK_KEY_attr,sizeof ( uint8 ),&SK_Keys );
}
/*********
*@fn peripheralStateNotificationCB
*
*@从配置文件中简要通知状态更改。
*
*@param newState - new state
*
*@返回无
*
静态空 peripheralStateNotificationCB( gaprole_states_t newState )
{
UINT16 connHandle = INVALID_CONNHEANDLE;
uint8 valFalse = false;
if (gapProfileState!= newState)
{
switch( newState )
{
案例 GAPROLE_Started:
{
//从 BD addr 设置系统 ID
uint8 systemId[DevInfo_system_ID_LEN];
GAPRole_GetParameter (GAPROLE_BD_ADDR、systemId);
//向上移动三个字节
SystemID[7]= systemId[5];
SystemID[6]= systemId[4];
SystemID[5]= systemId[3];
//将中间字节设置为零
SystemID[4]= 0;
SystemID[3]= 0;
DevInfo_SetParameter (DevInfo_system_ID、DevInfo_system_ID_LEN、systemId);
}
中断;
//如果状态更改为已连接,则最初假设密钥卡在范围内
案例 GAPROLE_advertising:
{
//我们正在宣传的视觉反馈。
HalLedSet (HAL_LED_2、HAL_LED_MODE_ON);
}
中断;
//如果状态更改为已连接,则最初假设密钥卡在范围内
案例 GAPROLE_Connected:
{
GAPRole_GetParameter( GAPROLE_CONNNANDLE,connHandle );
#if 已定义(PLUS_Broadcaster)
OSAL_START_timerEx (keyfobapp_TaskID、KFD_ADV_IN_CONNECT_EVT、ADV_IN_CONN_WAIT);
#endif
//关闭显示我们正在广播的 LED
HalLedSet (HAL_LED_2、HAL_LED_MODE_OFF);
}
中断;
案例 GAPROLE_等待:
{
//将加速计使能的属性值更改为 false
Accel_SetParameter (ACCEL_enabler、sizeof (valFalse)、&valFalse);
//停止加速因子
accelEnabableChangeCB();// SetParameter 不会触发回调
//关闭显示我们正在广播的 LED
HalLedSet (HAL_LED_2、HAL_LED_MODE_OFF);
}
中断;
案例 GAPROLE_WAITING_FACT_TIMEOUT:
{
//将加速计使能的属性值更改为 false
Accel_SetParameter (ACCEL_enabler、sizeof (valFalse)、&valFalse);
//停止加速因子
accelEnabableChangeCB();// SetParameter 不会触发回调
}
中断;
默认值:
//不执行任何操作
中断;
}
}
gapProfileState = newState;
}
/*********
*@fn accelEnabableChangeCB
*
*@当启用器属性时、加速计配置文件调用的简短描述
*已更改。
*
*@param none
*
*@返回无
*
static void accelEnabableChangeCB( void )
{
bStatus_t status = Accel_GetParameter( ACCEL_enabler,accelEnabler );
if (status == Success)(如果(状态==成功))
{
IF (加速器)
{
//选择加速计
//accelInit();
OSAL_START_timerEx (keyfobapp_TaskID、KFDA_ACCEL_READ_EVT、ACCEL_READ_PERIOD);
}否则
{
accStop();
OSAL_STOP_timerEx (keyfobapp_TaskID、KFDA_ACCEL_READ_EVT);
}
}
}
/*********
(三 /