数据处理"/>
基于NRF52832实现SIF一线通收发数据处理
SIF协议
- 一次传输一帧数据,传输结束后要求线路空闲状态为低电平,每次传输需一次性完整传输所有数据。
信号定义
-
Tosc定义: 250us <Tosc<2ms,推荐值:500us
-
同步信号
-
数据0信号:
-
数据1信号:
SIF数据发送例程,这里Tosc使用(16+1)/32768*1000000=518uS
/**
* @brief 开启sense事件中断
*/
void BSP_gpiote_init(nrfx_gpiote_pin_t pin,nrfx_gpiote_evt_handler_t pin_evt_handler,nrf_drv_gpiote_in_config_t *config)
{NRF_LOG_INFO("charge_int_flag");if (!nrf_drv_gpiote_is_init()){ nrf_drv_gpiote_init(); }nrf_drv_gpiote_in_config_t in_config={ \.is_watcher = false, \.hi_accuracy = true, \.pull = NRF_GPIO_PIN_PULLUP, \.sense = NRF_GPIOTE_POLARITY_TOGGLE, \};if(config == NULL){config = &in_config;}nrf_drv_gpiote_in_init(pin, config, pin_evt_handler);nrf_drv_gpiote_in_event_enable(pin, true);}/**
* @brief 关闭GPIOTE事件中断
*/
void disable_gpiote_evt_handler(nrfx_gpiote_pin_t pin)
{NRF_LOG_INFO("disable_charge_handler");nrf_drv_gpiote_in_event_disable(pin);nrf_drv_gpiote_in_uninit(pin);nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL);}/**
* @brieaf enable or disable gpio interrupt
*/
void gpiote_interrupt_switching(bool flag,nrfx_gpiote_pin_t pin)
{if(flag)nrf_drv_gpiote_in_event_enable(pin, true);elsenrf_drv_gpiote_in_event_disable(pin);
}#define SIF_TX_PIN 8#define sif_low_level() nrf_gpio_pin_clear(SIF_TX_PIN)
#define sif_high_level() nrf_gpio_pin_set(SIF_TX_PIN)APP_TIMER_DEF(m_sif_id);
#define TICK_SIF_INTERVAL 16APP_TIMER_DEF(m_sif_1hz_id);
#define TICK_SIF_1HZ_INTERVAL 32767uint8_t test_data[32] = {0x12,0x34,0x56,0x78};typedef struct
{uint8_t *pData;uint8_t len;uint8_t state;uint8_t pos;uint8_t mask_data;uint32_t hi_tosc;uint32_t lo_tosc;
}SIF_SEND_DATA_T;typedef enum
{END_SEND,DATA_HEADER,DATA_SEND,
}E_SEND_DATA_STATE;SIF_SEND_DATA_T g_send_data;
void sif_send_handler(void);static void timer_sif_timeout_handler(void * p_context)
{UNUSED_PARAMETER(p_context);if(g_send_data.state != END_SEND){sif_send_handler();}}void send_data_ready(uint8_t *dat,uint8_t len)
{g_send_data.pData = dat;g_send_data.len = len;g_send_data.state = DATA_SEND;g_send_data.lo_tosc = SYNC_LOW_TOSC;g_send_data.hi_tosc = SYNC_HIGH_TOSC;g_send_data.pos = 8;g_send_data.mask_data = 0x80;}void sif_send_handler(void)
{if(g_send_data.lo_tosc){sif_low_level();g_send_data.lo_tosc--;}else if(g_send_data.hi_tosc){sif_high_level();g_send_data.hi_tosc--; }else{sif_low_level(); if(g_send_data.pos--){
// NRF_LOG_INFO("pData %X len %d pos %d %d",g_send_data.pData[0],g_send_data.len,g_send_data.pos,g_send_data.pData[0] & g_send_data.mask_data ? 1:0);if(g_send_data.pData[0] & g_send_data.mask_data){g_send_data.lo_tosc = ONE_TOSC;g_send_data.hi_tosc = TWO_TOSC;}else{g_send_data.hi_tosc = ONE_TOSC;g_send_data.lo_tosc = TWO_TOSC;}g_send_data.mask_data >>= 1;g_send_data.lo_tosc--;}else {// NRF_LOG_INFO("pData %X len %d",g_send_data.pData[0],g_send_data.len); if(--g_send_data.len == 0){g_send_data.state = END_SEND;}else{g_send_data.pData++; g_send_data.pos = 8;g_send_data.mask_data = 0x80;}}}}static void sif_1hz_handler(void * p_context)
{UNUSED_PARAMETER(p_context);send_data_ready(test_data,SIF_DATA_LEN);
}void sif_init(void)
{BSP_gpiote_init(SIF_RX_PIN,sif_int_handler,NULL);nrf_gpio_cfg_output(SIF_TX_PIN);uint32_t err_code = app_timer_create(&m_sif_id,APP_TIMER_MODE_REPEATED,timer_sif_timeout_handler); APP_ERROR_CHECK(err_code);app_timer_start(m_sif_id,TICK_SIF_INTERVAL,NULL);err_code = app_timer_create(&m_sif_1hz_id,APP_TIMER_MODE_REPEATED,sif_1hz_handler); APP_ERROR_CHECK(err_code);app_timer_start(m_sif_1hz_id,TICK_SIF_1HZ_INTERVAL,NULL);}
SIF接收例程
#include "app_timer.h"#define SIF_RX_PIN 9#define ONE_TOSC 1
#define TWO_TOSC (ONE_TOSC*2)
#define SYNC_LOW_TOSC (ONE_TOSC*32)
#define SYNC_HIGH_TOSC (ONE_TOSC*1)#define SIF_DATA_LEN 4typedef struct
{uint8_t recv_buf[32];uint8_t len;uint8_t pos;uint8_t state;uint32_t tsoc_cal;uint32_t sync_tsoc;}SIF_RECV_DATA_T;typedef enum
{END_RECV,RECV_HEADER,DATA_RECV,
}E_RECV_DATA_STATE;SIF_RECV_DATA_T g_sif_recv_data;void sif_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{static uint32_t low_time;static uint32_t high_time;static uint32_t pre_tick;uint32_t cur_tick = app_timer_cnt_get(); uint32_t diff = cur_tick >= pre_tick ? cur_tick-pre_tick : ((uint32_t)-1)-cur_tick+pre_tick;pre_tick = cur_tick;
// NRF_LOG_INFO("diff %d",diff);if(nrf_gpio_pin_read(pin)) // hi{if(g_sif_recv_data.state == END_RECV){g_sif_recv_data.sync_tsoc = diff;g_sif_recv_data.state = RECV_HEADER;}else if(g_sif_recv_data.state == DATA_RECV) {low_time = diff; }}else{if(g_sif_recv_data.state == RECV_HEADER){g_sif_recv_data.tsoc_cal = diff;if(g_sif_recv_data.sync_tsoc > g_sif_recv_data.tsoc_cal * 4){g_sif_recv_data.sync_tsoc = 0;g_sif_recv_data.state = DATA_RECV;g_sif_recv_data.len = 0;g_sif_recv_data.pos = 8;memset(g_sif_recv_data.recv_buf,0,sizeof(g_sif_recv_data.recv_buf));}else{g_sif_recv_data.state = END_RECV;}}else if(g_sif_recv_data.state == DATA_RECV){uint8_t level;uint32_t max_diff,min_diff;if(low_time > diff) // low {level = 0;max_diff = low_time;min_diff = diff;}else{level = 1;max_diff = diff;min_diff = low_time; }if((max_diff > g_sif_recv_data.tsoc_cal *7/5) && (min_diff > g_sif_recv_data.tsoc_cal *7/10 )){g_sif_recv_data.recv_buf[g_sif_recv_data.len] <<= 1;g_sif_recv_data.recv_buf[g_sif_recv_data.len] |= level;if(--g_sif_recv_data.pos == 0){g_sif_recv_data.pos = 8;NRF_LOG_INFO("SIF RECV %x",g_sif_recv_data.recv_buf[g_sif_recv_data.len]);if(++g_sif_recv_data.len >= SIF_DATA_LEN){g_sif_recv_data.len = 0;g_sif_recv_data.state = END_RECV; NRF_LOG_INFO("============================================"); }}}else{g_sif_recv_data.state = END_RECV; // 出错NRF_LOG_INFO("SIF RECV ERR");}}}}
将发送和接收短接在一起,运行效果如下
更多推荐
基于NRF52832实现SIF一线通收发数据处理
发布评论