|
|
我想用CC2530监测mpu6050模块并将数据无线传输给接收板,再由接收板将数据通过串口显示出来,由于是点对点传输,所以我只是简单将无线点灯实验做了一些修改,通过T3定时器中断实现数据的发送。后来发现如下问题:发射端的数据确实实现了一秒一次发送,而且通过串口显示在屏幕上也很稳定,但是接收端只可以接收到确定mpu6050准备完毕的信息以及mpu6050监测到的一次数据,随后就不能再接收到信息了。求各位大神帮我看一下,真的被困扰好多天了。
************************************************************
Filename: light_switch.c
Description: This application function either as a light or a
switch toggling the ligh. The role of the
application is chosen in the menu with the joystick at initialisation.
Push S1 to enter the menu. Choose either switch or
light and confirm choice with S1.
Joystick Up: Sends data from switch to light
***********************************************************************************/
/***********************************************************************************
* INCLUDES
*/
#include <hal_lcd.h>
#include <hal_led.h>
#include <hal_joystick.h>
#include <hal_assert.h>
#include <hal_board.h>
#include <hal_int.h>
#include <string.h>
#include "hal_mcu.h"
#include "hal_button.h"
#include "hal_rf.h"
#include "util_lcd.h"
#include "basic_rf.h"
#include "IIC.h"
#include "MPU6050.h"
/***********************************************************************************
* CONSTANTS
*/
// Application parameters
#define RF_CHANNEL 25 // 2.4 GHz RF channel
// BasicRF address definitions
#define PAN_ID 0x2007
#define SWITCH_ADDR 0x2520
#define LIGHT_ADDR 0xBEEF
#define APP_PAYLOAD_LENGTH 72
#define LIGHT_TOGGLE_CMD 0
// Application states
#define IDLE 0
#define SEND_CMD 1
// Application role
#define NONE 0
#define SWITCH 1
#define LIGHT 2
#define APP_MODES 2
/***********************************************************************************
* LOCAL VARIABLES
*/
static uint8 pTxData[APP_PAYLOAD_LENGTH];
static uint8 pRxData[APP_PAYLOAD_LENGTH];
static basicRfCfg_t basicRfConfig;
uint count=0;
// Mode menu
static menuItem_t pMenuItems[] =
{
#ifdef ASSY_EXP4618_CC2420
// Using Softbaugh 7-seg display
" L S ", SWITCH,
" LIGHT ", LIGHT
#else
// SRF04EB and SRF05EB
"Switch", SWITCH,
"Light", LIGHT
#endif
};
static menu_t pMenu =
{
pMenuItems,
N_ITEMS(pMenuItems)
};
#ifdef SECURITY_CCM
// Security key
static uint8 key[]= {
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
};
#endif
//unsigned char tempV = 0;
int16_t ax, ay, az;
float x,y,z;
int16_t temperature;
int16_t gx, gy, gz;
float ggx,ggy,ggz;
float f_temperature;
//char strTemp[64];
char str[9]="M0:";
/***********************************************************************************
* LOCAL FUNCTIONS
*/
static void appLight();
static void appSwitch();
static uint8 appSelectMode(void);
void InitUart0(void)
{
PERCFG = 0x00; //外设控制寄存器 USART 0的IO位置:0为P0口位置1
P0SEL = 0x0c; //P0_2,P0_3用作串口(外设功能)
P2DIR &= ~0xC0; //P0优先作为UART0
U0CSR |= 0x80; //设置为UART方式
U0GCR |= 11;
U0BAUD |= 216; //波特率设为115200
UTX0IF = 0; //T0 TX中断标志初始置位0
U0CSR |= 0x40; //允许接收
IEN0 |= 0x84; //开总中断允许接收中断
}
void Uart0SendString(char *Data, int len)
{
uint i;
for(i=0; i<len; i++)
{
U0DBUF = *Data++;
while(UTX0IF == 0);
UTX0IF = 0;
}
}
void DelayMS(uint msec)
{
uint i,j;
for (i=0; i<msec; i++)
for (j=0; j<535; j++);
}
void InitClockTo32M(void)
{
CLKCONCMD &= ~0x40; //设置系统时钟源为 32MHZ晶振
while(CLKCONSTA & 0x40); //等待晶振稳定
CLKCONCMD &= ~0x47; //设置系统主时钟频率为 32MHZ
}
void InitT3()
{
T3CTL |= 0x08 ; //开溢出中断
T3IE = 1; //开总中断和T3中断
T3CTL |= 0xE0; //128分频,128/16000000*N=0.5S,N=62500
//T3CTL &= ~0x03; //自动重装 00->0xff 62500/255=245(次)
T3CTL &= ~0x00;
T3CTL |= 0x10; //启动
EA = 1; //开总中断
}
/***********************************************************************************
* @fn appLight
*
* @brief Application code for light application. Puts MCU in endless
* loop waiting for user input from joystick.
*
* @param basicRfConfig - file scope variable. Basic RF configuration data
* pRxData - file scope variable. Pointer to buffer for RX data
*
* @return none
*/
static void appLight()
{
// halLcdWriteLine(HAL_LCD_LINE_1, "Light");
// halLcdWriteLine(HAL_LCD_LINE_2, "Ready");
#ifdef ASSY_EXP4618_CC2420
halLcdClearLine(1);
halLcdWriteSymbol(HAL_LCD_SYMBOL_RX, 1);
#endif
// Initialize BasicRF
basicRfConfig.myAddr = LIGHT_ADDR;
if(basicRfInit(&basicRfConfig)==FAILED) {
HAL_ASSERT(FALSE);
}
basicRfReceiveOn();
InitUart0();
// Main loop
while (TRUE) {
while(!basicRfPacketIsReady());
if(basicRfReceive(pRxData, APP_PAYLOAD_LENGTH, NULL)>0) {
halLedToggle(1);
Uart0SendString(pRxData, strlen(pRxData));
DelayMS(2000);
}
}
}
/***********************************************************************************
* @fn appSwitch
*
* @brief Application code for switch application. Puts MCU in
* endless loop to wait for commands from from switch
*
* @param basicRfConfig - file scope variable. Basic RF configuration data
* pTxData - file scope variable. Pointer to buffer for TX
* payload
* appState - file scope variable. Holds application state
*
* @return none
*/
static void appSwitch()
{
// halLcdWriteLine(HAL_LCD_LINE_1, "Switch");
// halLcdWriteLine(HAL_LCD_LINE_2, "Joystick Push");
// halLcdWriteLine(HAL_LCD_LINE_3, "Send Command");
#ifdef ASSY_EXP4618_CC2420
halLcdClearLine(1);
halLcdWriteSymbol(HAL_LCD_SYMBOL_TX, 1);
#endif
//pTxData[0] = LIGHT_TOGGLE_CMD;
//pTxData[0]='a';
// Initialize BasicRF
basicRfConfig.myAddr = SWITCH_ADDR;
if(basicRfInit(&basicRfConfig)==FAILED) {
HAL_ASSERT(FALSE);
}
// Keep Receiver off when not needed to save power
basicRfReceiveOff();
unsigned char tempV = 0;
char strTemp[64];
InitClockTo32M(); //设置系统时钟源
InitUart0();
IIC_Init();
//InitT3(); //IIC初始化
while(1)
{
tempV = MPU6050_GetDeviceID();
//这个值如果打印为 [WHOE AM I]0x68, 那么表示已经正确辨认到mpu6050了
sprintf(strTemp, "[WHOE AM I ?] chip ID = 0x%02x(if = 0x68, is OK)\n", tempV);
//pTxData[0]='a';
for(int i=0;i<64;i++)
pTxData[i]=strTemp[i];
basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH);
//halLedToggle(1);
// Put MCU to sleep. It will wake up on joystick interrupt
halIntOff();
halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global
// interrupt enable
halIntOn();
InitT3();
if(tempV == MPU6050_ADDRESS_AD0_LOW) //测试是否 mpu6050 已经读到
{
MPU6050_Initialize(); //初始化mpu6050
while(1);
}
else
{
//mpu6050连接失败
sprintf(strTemp, "MPU6050_Initialize FAIL");
//串口打印该数据
//Uart0SendString(strTemp, strlen(strTemp));
for(int i=0;i<64;i++)
pTxData[i]=strTemp[i];
basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH);
//halLedToggle(1);
// Put MCU to sleep. It will wake up on joystick interrupt
halIntOff();
halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global
// interrupt enable
halIntOn();
}
DelayMS(2000);
// if( halJoystickPushed() ) { //bu qiujie tech
/* if(halButtonPushed()==HAL_BUTTON_1){
basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH);
// Put MCU to sleep. It will wake up on joystick interrupt
halIntOff();
halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global
// interrupt enable
halIntOn();*/
}
}
#pragma vector = T3_VECTOR
__interrupt void T3_ISR(void)
{
char strTemp[64];
unsigned char tempV = 0;
IRCON = 0x00; //清中断标志, 也可由硬件自动完成
if(count++ > 980) //245次中断后LED取反,闪烁一轮(约为0.5 秒时间)
{
//halLedToggle(1); //经过示波器测量确保精确
count = 0; //计数清零
if((tempV = MPU6050_GetDeviceID()) == MPU6050_ADDRESS_AD0_LOW) //连续测试是否 mpu6050 已经读到
{
//读取mpu6050的实时数据
MPU6050_GetRawAccelGyro(&ax, &ay, &az, &temperature, &gx, &gy, &gz);
//转换成温度单位为度的数据
x=ax/16384.00;
y=ay/16384.00;
z=az/16384.00;
ggx=gx/131.00;
ggy=gy/131.00;
ggz=gz/131.00;
//x = -12;
//x =1.2;
f_temperature = (float)temperature/340.0 + 36.53;
//sprintf(strTemp, "[%f %f %f] : [%7d = %.02fC] : [%f %f %f]\n", \
x, y, z, temperature, f_temperature, ggx, ggy, ggz);
sprintf(strTemp, "[%f %f %f] : [%f %f %f]\n", \
x, y, z, ggx, ggy, ggz);
for(int i=0;i<70;i++)
pTxData[i]=strTemp[i];
Uart0SendString(pTxData, strlen(pTxData));
DelayMS(2000);
basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH);
// Put MCU to sleep. It will wake up on joystick interrupt
halIntOff();
halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global
// interrupt enable
halIntOn();
halLedToggle(1);
//串口打印该数据
DelayMS(2000); //延时函数使用定时器方式
basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH);
halIntOff();
halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global
// interrupt enable
halIntOn();
halLedToggle(1);
}
}
}
/***********************************************************************************
* @fn main
*
* @brief This is the main entry of the "Light Switch" application.
* After the application modes are chosen the switch can
* send toggle commands to a light device.
*
* @param basicRfConfig - file scope variable. Basic RF configuration
* data
* appState - file scope variable. Holds application state
*
* @return none
*/
void main(void)
{
uint8 appMode = NONE;
// Config basicRF
basicRfConfig.panId = PAN_ID;
basicRfConfig.channel = RF_CHANNEL;
basicRfConfig.ackRequest = TRUE;
#ifdef SECURITY_CCM
basicRfConfig.securityKey = key;
#endif
// Initalise board peripherals
halBoardInit();
// halJoystickInit();//BY QIUJIE
// Initalise hal_rf
if(halRfInit()==FAILED) {
HAL_ASSERT(FALSE);
}
// Indicate that device is powered
halLedSet(1);
// Print Logo and splash screen on LCD
// utilPrintLogo("Light Switch");
// Wait for user to press S1 to enter menu
// while (halButtonPushed()!=HAL_BUTTON_1);
// halMcuWaitMs(350);
// halLcdClear();
// Set application role
// appMode = appSelectMode();
// halLcdClear();
// appMode = SWITCH;
// Transmitter application
// if(appMode == SWITCH) {
// No return from here
//注:函数appSwitch()和appLight()只能打开一个
//作为开关板打开此函数(appSwitch)
//appSwitch();
//被点灯的板打开此函数(appLight)
appLight();
// }
// Receiver application
// else if(appMode == LIGHT) {
// No return from here
// }
// Role is undefined. This code should not be reached
// HAL_ASSERT(FALSE);
}
/**********************'g;******************************************************************
* @fn appSelectMode
*
* @brief Select application mode
*
* @param none
*
* @return uint8 - Application mode chosen
*/
static uint8 appSelectMode(void)
{
halLcdWriteLine(1, "Device Mode: ");
return utilMenuSelect(&pMenu);
}
|
|