基于NRF52832实现SIF一线通收发数据处理
实现 基于 数据处理 收发
2023-09-14 09:06:41 时间
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);
else
nrf_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 16
APP_TIMER_DEF(m_sif_1hz_id);
#define TICK_SIF_1HZ_INTERVAL 32767
uint8_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 4
typedef 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");
}
}
}
}
将发送和接收短接在一起,运行效果如下
相关文章
- ASP.NET Core使用Docker-Compose实现多容器应用部署
- java实现人脸识别源码【含测试效果图】——DaoImpl层(UserDaoImpl)
- Java实现 LeetCode 350 两个数组的交集 II(二)
- Java实现 计蒜客 1251 仙岛求药
- Java实现 洛谷 P1583 魔法照片
- Java实现 洛谷 P1149 火柴棒等式
- Java实现预排序
- 纯CSS3实现自定义涂鸦风格的边框
- python实现钉钉文件上传发送,钉钉机器人接收信息
- 实现基于文件验证的vsftpd虚拟用户
- CV之IE之NoGAN:基于fastai框架利用NoGAN算法实现图像增强技术(图片上色实现对旧图像和电影片段进行着色和修复,以爱因斯坦旧照/鲁迅旧照/清末官员生活场景旧照为例)案例应用
- ML之LoR:基于信用卡数据集利用LoR逻辑回归算法实现如何开发通用信用风险评分卡模型之以scorecardpy框架全流程讲解
- NLP:基于textrank4zh库对文本实现提取文本关键词、文本关键短语和文本摘要
- NLP之TEA:基于python编程(jieba库)实现中文文本情感分析(得到的是情感评分)
- 【项目实战】基于Tomcat服务器实现Debug模式下服务不用重启的指引设置
- 基于转换器 (MMC) 技术和电压源转换器 (VSC) 的高压直流 (HVDC) 模型(Matlab&Simulink实现)
- 基于蚁群算法的时延Petri网(ACOTPN)路径规划算法(Matlab代码实现)
- 基于 BP 神经网络特征提取的指纹识别应用(Matlab代码实现)
- 送小公主——哆啦A梦(Python代码实现)
- 基于粒子群优化算法的分布式电源优化调度实现配电网稳定运行(Matlab代码实现)
- 基于燃压缩空气储能系统的零碳微能源互联网优化调度(Matlab代码实现)
- 电力预测|基于新型MDPSO-SVR混合模型的电力预测特征选择(Matlab代码实现)
- 【SVR-SVDD】基于支持向量-SVDD 进行异常检测研究(Matlab代码实现)
- 【Bender】基于Bender进行光线追踪研究(Matlab代码实现)
- Python实现基于Optuna超参数自动优化的LightGBM分类模型(LGBMClassifier算法)项目实战
- 【华为机试真题 Python实现】两个字符串的最长公共子串
- Vue基于$attrs及$listeners实现隔代通信
- leetcode 234. 回文链表 js 实现
- Django 基于Ajax & form 简单实现文件上传
- python web py入门(66)- jQuery - 隐藏显示实现界面大小可变布局
- 通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权
- 【项目实战】基于Avue的前端框架实现一个简单CRUD
- pytorch 22 8种Dropout方法的简介 及 基于Dropout用4行代码快速实现DropBlock
- C++的学习心得和知识总结(十六)|基于EasyX实现小甲鱼Python飞机大战项目(C++版)
- Istio服务网格进阶③:基于Istio服务网格实现灰度发布机制