2639|0

6107

帖子

4

TA的资源

版主

楼主
 

【KW41z】一起来玩 thread +多路继电器控制 [复制链接]

本帖最后由 damiaa 于 2017-7-31 09:30 编辑

一起来玩 thread +多路继电器控制目前继电器还是用LED代替显示,这样不至于那么恐怖,因为我用的是交流继电器。









介绍一下:

从pin_mux.c和原理图对照了解FRDM_KW41Z板子配置的IO口,看 哪些没用到,哪些用到哪里了。
PTC4  是    button SW3
PTC5 是    button SW4
PTA18, LED   RGB_B
PTA19, LED   RGB_G
PTB0,         PTB0 LED3
PTC1          LED  RGB_R
PTC18    PTC1
PTC16,PTC17,PTC18,PTC19 SPI总线 AT45DB041E芯片
PTC6,PTC7      UART0
PTB0,PTB1,PTC1,PTC2,PTC3   I2C
PTB17,连 到时钟了,暂时不管 它。
PTA16(J2-4),PTA17(J2-5)好像是没用哦。
PTB18,PTB2,PTB3,J4-2,J4-3 ,J4-4没用 那就用这三个IO控制继电器吧!!!

pin_mux.c中:
PIN_MUX.C中加入初始化时钟和GPIO函数
//---------------------------------------------------------------------------------------------------------
//PTB18,PTB2,PTB3,J4-2,J4-3 ,J4-4没用
#define PIN2_IDX                         2u   /*!< Pin number for pin 0 in a port */
#define PIN3_IDX                         3u   /*!< Pin number for pin 1 in a port */
#define PIN18_IDX                       18u   /*!< Pin number for pin 18 in a port */

/*
// 注意:这里IO口方向还没定哦,特别注意啊!!!:
void BOARD_InitRELAYs(void) {
CLOCK_EnableClock(kCLOCK_PortB);                           /* Port B Clock GateControl: Clock enabled */
    PORT_SetPinMux(PORTB, PIN2_IDX, kPORT_MuxAsGpio);         /* PORTB2 is configured as out */
    PORT_SetPinMux(PORTB, PIN3_IDX, kPORT_MuxAsGpio);         /* PORTB3 is configured as out*/
    PORT_SetPinMux(PORTB, PIN18_IDX, kPORT_MuxAsGpio);          /* PORTB18 is configured as out */
}

2,在头文件PIN_MUX.h 中加入该函数
void BOARD_InitRELAYs(void)

3,LED.c中加入

void RELAY_Init(void)
{
BOARD_InitRELAYs();//这里初始化时钟,把IO变为GPIO
(void)GpioOutputPinInit(relayPins, 3);//这里吧继电器设置为输出
}

//RELAY_t 1,2,3 RELAY_MOde_t mode  on/off 1,0
static void RELAY_Set
(
    const gpioOutputPinConfig_t * pOutputConfig,  
    RELAY_OpMode_t operation
)
{
     if(operation ==off)
        GpioSetPinOutput(pOutputConfig);;
    if(operation ==on)
     GpioClearPinOutput(pOutputConfig);
}
//  RELAY_Operate(RELAY1,on);
//  RELAY_Operate(RELAY2,off);
void RELAY_Operate
(
   RELAY_t relay,
   RELAY_OpMode_t operation
)
{
   if(relay==RELAY1)
     RELAY_Set( relayPins,operation);
   if(relay==RELAY2)
     RELAY_Set( relayPins,operation);
   if(relay==RELAY3)
     RELAY_Set( relayPins,operation);
}

4,Led.h中加入
#define RELAY1 0x1;
#define RELAY2 0x2;
#define RELAY3 0x4;
typedef uint8_t RELAY_t;
typedef enum RELAY_OpMode_tag{
  on,
  off
}RELAY_OpMode_t;
extern void RELAY_Init(void);
extern void RELAY_Operate(RELAY_t led,  RELAY_OpMode_t operation);

5,gpio_pins.c中加入
//-------------------------------------------------
gpioOutputPinConfig_t relayPins[] = {
    {
       .gpioPort = gpioPort_B_c,
       .gpioPin = 2,
       .outputLogic = 1,
       .slewRate = pinSlewRate_Slow_c,
       .driveStrength = pinDriveStrength_Low_c
    },
    {
       .gpioPort = gpioPort_B_c,
       .gpioPin = 3,
       .outputLogic = 1,
       .slewRate = pinSlewRate_Slow_c,
       .driveStrength = pinDriveStrength_Low_c
    },
    {
       .gpioPort = gpioPort_B_c,
        .gpioPin = 18,
       .outputLogic = 1,
       .slewRate = pinSlewRate_Slow_c,
       .driveStrength = pinDriveStrength_Low_c
    },
};

6,Gpio_pins.h中加入  
extern gpioOutputPinConfig_t relayPins[];
//----------------------------------------------------------------   

7,app_init.c中void main_task(uint32_t param) ==》BOARD_InitLEDs()后面加入函数
   RELAY_Init();

下面理清一下coap的发送和接受,看到哪里加入继电器的操作函数
从shell_ip_c中可以看出,发送coap CON POST 2001::1 /led on 这样的命令传送 coap消息。
#define APP_LED_URI_PATH                        "/led"
#define APP_TEMP_URI_PATH                       "/temp"
#define APP_SINK_URI_PATH                       "/sink"
这几个控制LED,温度等的路径在router_eligible_device_app.c中
/*==================================================================================================
Private functions
==================================================================================================*/
/*!*************************************************************************************************
\private
\fn    static void APP_InitCoapDemo(void)
\brief Initialize CoAP demo.
***************************************************************************************************/
static void APP_InitCoapDemo
(
    void
)
{
   coapRegCbParams_t cbParams[] = {{APP_CoapLedCb,  (coapUriPath_t*)&gAPP_LED_URI_PATH},
                                    {APP_CoapTempCb, (coapUriPath_t *)&gAPP_TEMP_URI_PATH},
#if LARGE_NETWORK
                                    {APP_CoapResetToFactoryDefaultsCb, (coapUriPath_t*)&gAPP_RESET_URI_PATH},
#endif
                                    {APP_CoapSinkCb, (coapUriPath_t *)&gAPP_SINK_URI_PATH}};
    /*Register Services in COAP */
   coapStartUnsecParams_t coapParams = {COAP_DEFAULT_PORT, AF_INET6};
   mAppCoapInstId = COAP_CreateInstance(NULL, &coapParams, gIpIfSlp0_c,(coapRegCbParams_t *)cbParams,
                                        NumberOfElements(cbParams));
}
这里吧这个LED的路径和处理函数APP_CoapLedCb,联系起来了。其他的像温度也是一样。其实我们完全可以在这里另辟蹊径整一个新路径和新的回调函数王道上面,
这样就可以不用\led 不如用\relay。后续再整吧。
/*!*************************************************************************************************
\private
\fn    static void APP_CoapLedCb(sessionStatus sessionStatus, void *pData,
                                  coapSession_t *pSession, uint32_tdataLen)
\brief This function is the callback function for CoAP LED message.
\brief It performs the required operations and sends back a CoAP ACK message.
\param [in]    sessionStatus   Status for CoAP session
\param [in]    pData           Pointer to CoAP message payload
\param [in]    pSession        Pointer to CoAP session
\param [in]    dataLen         Length of CoAP payload
***************************************************************************************************/
static void APP_CoapLedCb
(
   coapSessionStatus_t sessionStatus,
    void*pData,
   coapSession_t *pSession,
   uint32_t dataLen
)
{
    /*Process the command only if it is a POST method */
   if((pData) && (sessionStatus == gCoapSuccess_c) &&(pSession->code == gCoapPOST_c))
    {
       APP_ProcessLedCmd(pData, dataLen);
    }
    /*Send the reply if the status is Success or Duplicate */
   if((gCoapFailure_c != sessionStatus) && (gCoapConfirmable_c ==pSession->msgType))
    {
       /* Send CoAP ACK */
       COAP_Send(pSession, gCoapMsgTypeAckSuccessChanged_c, NULL, 0);
    }
}
也就是说上面就是CO AP传送命令控制另一台LED的响应函数。那我们在这里放个RELAY的控制估计就能动起来,不过。

继续void APP_CoapLedCb函数,发现处理分两部分,一是处理LED,二是coap应答
if((pData) && (sessionStatus ==gCoapSuccess_c) && (pSession->code == gCoapPOST_c))
    {
       APP_ProcessLedCmd(pData, dataLen); //一是处理LED
    }

    /*Send the reply if the status is Success or Duplicate */
   if((gCoapFailure_c != sessionStatus) && (gCoapConfirmable_c ==pSession->msgType))
    {
       /* Send CoAP ACK */
       COAP_Send(pSession, gCoapMsgTypeAckSuccessChanged_c, NULL, 0);// 二是coap应答

    }

static void APP_ProcessLedCmd
(
   uint8_t *pCommand,
   uint8_t dataLen
)
{
    /*Set mode state */
   APP_SetMode(mThrInstanceId, gDeviceMode_Application_c);
   mFirstPushButtonPressed  = FALSE;

    /*Process command */
   if(FLib_MemCmp(pCommand, "on",2))
    {
       App_UpdateStateLeds(gDeviceState_AppLedOn_c);
    }
    elseif(FLib_MemCmp(pCommand, "off",3))
    {
       App_UpdateStateLeds(gDeviceState_AppLedOff_c);
    }
    elseif(FLib_MemCmp(pCommand, "toggle",6))
    {
       App_UpdateStateLeds(gDeviceState_AppLedToggle_c);
    }
    elseif(FLib_MemCmp(pCommand, "flash",5))
    {
       App_UpdateStateLeds(gDeviceState_AppLedFlash_c);
    }
    elseif(FLib_MemCmp(pCommand, "rgb",3))
    {
       char* p = (char *)pCommand + strlen("rgb");
       uint8_t redValue = 0, greenValue = 0, blueValue = 0;
       appDeviceState_t appState = gDeviceState_AppLedRgb_c;

       dataLen -= strlen("rgb");




此内容由EEWORLD论坛网友damiaa原创,如需转载或用于商业用途需征得作者同意并注明出处
        while(dataLen != 0)
        {
           if(*p == 'r')
           {
               p++;
               dataLen--;
               redValue = NWKU_atoi(p);
           }

           if(*p == 'g')
           {
               p++;
               dataLen--;
               greenValue = NWKU_atoi(p);
           }

           if(*p == 'b')
           {
               p++;
               dataLen--;
               blueValue = NWKU_atoi(p);
           }
           dataLen--;
           p++;
        }

       /* Update RGB values */
#if gLedRgbEnabled_d
       Led_UpdateRgbState(redValue, greenValue, blueValue);
#else
       appState = gDeviceState_AppLedOff_c;

       if(redValue || greenValue || blueValue)
        {
           appState = gDeviceState_AppLedOn_c;
        }
#endif
       App_UpdateStateLeds(appState);
       /* If device is leader and has received a RGB LED off command and therewere no previous button presses */
       if((gpaThrAttr[mThrInstanceId]->devRole == gThrDevRole_Leader_c)&&
          (!redValue && !greenValue && !blueValue) &&(leaderLedTimestamp == 0))
        {
           leaderLedTimestamp = (TMR_GetTimestamp()/1000000) +gAppRestoreLeaderLedTimeout_c;
        }
    }
    elseif(FLib_MemCmp(pCommand, "color wheel",11))
    {
#if gLedRgbEnabled_d
       App_UpdateStateLeds(gDeviceState_AppLedColorWheel_c);
#else
       App_UpdateStateLeds(gDeviceState_AppLedFlash_c);
#endif
    }
}

APP_ProcessLedCmd具体分析了coap命令的内容和长度,分别出来,如”on” “off” “toggle” “flash” “rgb” "color wheel"
所以我们把继电器放 这里更好:
把前面 的控制继电器的语句放这里:
static void APP_ProcessLedCmd
(
。。。
//放最后面吧--------------------------------------------------------------------
       if(FLib_MemCmp(pCommand, "rallon",6))
        {
           RELAY_Operate(RELAY1,on);
           RELAY_Operate(RELAY2,on);
           RELAY_Operate(RELAY3,on);
        }
       if(FLib_MemCmp(pCommand, "r1on",4))
        {
           RELAY_Operate(RELAY1,on);
        }
       if(FLib_MemCmp(pCommand, "r2on",4))
        {
          RELAY_Operate(RELAY2,on);
       }

       if(FLib_MemCmp(pCommand, "r3on",4))
        {
          RELAY_Operate(RELAY3,on);
       }

       if(FLib_MemCmp(pCommand, "rallon",6))
        {
           RELAY_Operate(RELAY1,on);
           RELAY_Operate(RELAY2,on);
           RELAY_Operate(RELAY3,on);
        }

       if(FLib_MemCmp(pCommand, "ralloff",7))
        {
           RELAY_Operate(RELAY1,off);
           RELAY_Operate(RELAY2,off);
           RELAY_Operate(RELAY3,off);
       }   
       if(FLib_MemCmp(pCommand, "r1off",5))
        {
           RELAY_Operate(RELAY1,off);
        }   
       if(FLib_MemCmp(pCommand, "r2off",5))
        {
           RELAY_Operate(RELAY2,off);
       }   
       if(FLib_MemCmp(pCommand, "r3off",5))
        {
          RELAY_Operate(RELAY3,off);
       }   
       //-------------------------------------------------------------------
}

这样程序的事就可以了。
下面用putty连接两个模块,一个模块下程序下去,另外一个控制它就可以了。具体如开始的图片。谢谢。

此帖出自NXP MCU论坛
点赞 关注(1)
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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