/**
*
* @file SDI-12.c
* @author 吕冬 email:274236076@qq.com
* @date 2014年12月29日18:55:46
* @version v1.0
* @brief SDI-12通讯模块库
* @section 本模块使用的其他模块库
* 1)Container\n
* 2)SLEEP\n
* @section 本模块使用单片机资源
* 1)定时/计数器0(8位定时计数器);\n
* 2)1个I/O口;\n
* @section 免责声明
* 此源代码仅为交流学习使用,禁止用于商业用途。使用者因此产生的任何法律后果与原作者无关。
* @section 介绍
* 此源代码为SDI-12通讯协议的IO模拟驱动代码 \n
* 整个模块已经被封装成了一个数据类型:sdi。尽量使用sdi中的函数指针完成想要的操作\n
* 为了方便代码的维护,尽量避免直接调用功能函数。
*
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "SDI-12.h"
#include "Container.h"
#include "string.h"
#define __SDI12_PIN(val) PIN##val
#define __SDI12_PORT(val) PORT##val
#define __SDI12_DDR(val) DDR##val
#define _SDI12_PIN(val) __SDI12_PIN(val)
#define _SDI12_PORT(val) __SDI12_PORT(val)
#define _SDI12_DDR(val) __SDI12_DDR(val)
#define SDI12_PIN _SDI12_PIN(SDI12_PORTX)
#define SDI12_PORT _SDI12_PORT(SDI12_PORTX)
#define SDI12_DDR _SDI12_DDR(SDI12_PORTX)
#define SETPORT SDI12_PORT |= 0x01<<SDI12_PINXN /**< 数据端口电平拉高 */
#define CLRPORT SDI12_PORT &= ~(0x01<<SDI12_PINXN) /**< 数据端口电平拉低 */
#define GETPORT (SDI12_PIN&(0x01<<SDI12_PINXN)) /**< 读取数据端口电平状态 */
#define ENPORT SDI12_DDR |= 0x01<<SDI12_PINXN /**< 设置数据端口状态为输出模式(推挽输出) */
#define UNPORT SDI12_DDR &= ~(0x01<<SDI12_PINXN) /**< 设置数据端口状态为输入模式(浮空输入) */
#define SDI12_START_RD TCNT0 = 0; TCCR0 |= 0x07 /**< 开启定时器0,时钟源为1024分频器 */
#define SDI12_STOP_RD TCCR0 &= ~(0x07) /**< 关闭定时器0 */
#define SDI12_FLAGS (this->flags)
#define SDI12_SETCMD SDI12_FLAGS |= 1<<SDI12F_CMD /**< 置1发送一般命令标志位 */
#define SDI12_SETMSR SDI12_FLAGS |= 1<<SDI12F_MEASURE /**< 置1发送测量命令标志位 */
#define SDI12_SETSND SDI12_FLAGS |= 1<<SDI12F_SEND /**< 置1发送命令标志位 */
#define SDI12_SETNEW SDI12_FLAGS |= 1<<SDI12F_NEW /**< 置1成功接收数据标志位 */
#define SDI12_CLRCMD SDI12_FLAGS &=~(1<<SDI12F_CMD) /**< 清空发送一般命令标志位 */
#define SDI12_CLRMSR SDI12_FLAGS &=~(1<<SDI12F_MEASURE) /**< 清空发送测量命令标志位 */
#define SDI12_CLRSND SDI12_FLAGS &=~(1<<SDI12F_SEND) /**< 清空发送命令标志位 */
#define SDI12_CLRNEW SDI12_FLAGS &=~(1<<SDI12F_NEW) /**< 清空成功接收数据标志位 */
#define SDI12_CHECKCMD (SDI12_FLAGS&(1<<SDI12F_CMD)) /**< 判断是否发送了一般命令 */
#define SDI12_CHECKMSR (SDI12_FLAGS&(1<<SDI12F_MEASURE)) /**< 判断是否发送了测量命令 */
#define SDI12_CHECKSND (SDI12_FLAGS&(1<<SDI12F_SEND)) /**< 判断是否可发送命令 */
#define SDI12_CHECKNEW (SDI12_FLAGS&(1<<SDI12F_NEW)) /**< 判断是否成功接收数据 */
#define SDI12_SendNum (this->snum)
#define SDI12_SendBuf (this->sbuf)
#define delay833us sleep833us
#define delay415us sleep415us
#define delay67us sleep67us
#define delay15ms sleep15ms
#define delay9ms sleep9ms
//u16 SDI12_FLAGS = 0;
//u8 REC_STRING[40];
//TRoll roll = {REC_STRING,40,0,0,roll_AddData,roll_TakeData};
//char SDI12_SendBuf[10];
//u8 SDI12_SendNum = 0;
//char SDIMSG = 0;
u16 SDI12_REC_BUFFER = 0; /**< SDI12总线数据位读取缓冲区 */
u8 SDI12_REC_COUNTER = 0; /**< SDI12总线数据位读取计数 */
//u8 m_SDICMD = 0, MEASURE = 0;
/**
* @brief SDI-12设备初始化
*
* 主要用于SDI12设备总线的初始化操作\n
* 建议通过SDI-12抽象数据类型调用而不是直接调用,以便于维护
*
* @param this 指向SDI12实例地址
*
* @return 成功返回SDI12_OK
* @note 使用SDI12模块之前,需要先调用此函数初始化,否则会导致严重后果
*/
SDI12RSL SDI12_Init(PTSDI12 this)
{
#ifndef F_CPU
#define F_CPU 7372800
#warning "未定义cpu晶振频率,程序默认设置为7372800"
#endif
//TRoll roll = {REC_STRING,40,0,0,roll_AddData,roll_TakeData};
this->roll.push_back = roll_AddData;
this->roll.pop_back = roll_TakeData;
this->roll.buffer = this->rollbuf;
this->roll.bufsize = SDI12_ROLL_SIZE;
this->flags = 0;
OCR0 = F_CPU/1024/1200-1;
TIMSK |= (1 << OCIE0);//使能比较中断0
TCCR0 |=0x08;//CTC模式,
TCCR0 &=~0x07;//关闭时钟源以停止定时器
//TCCR0 |=0x07;//定时计数器开始,时钟源选择:1024分频
asm("sei");//开总中断
//开始便发送一个指令
SDI12_SendNum = 3;
memcpy(SDI12_SendBuf,"0M!",SDI12_SendNum);
// SDIMSG = SDIMSG_SEND;
return SDI12_OK;
}
/**
* @brief SDI12向数据总线发送1个字节
*
* 底层函数,发送字节
* @param asc 发送到数据线的1字节数据
* @return 成功返回SDI12_OK
* @see SDI12_SendString
* @note 底层函数,不要直接调用
*/
SDI12RSL SDI12_SendByte(char asc)
{
u8 i=0;
u8 even=0;
//开始位
SETPORT;
delay833us();//多延时7us
//数据,先低位,后高位
for(i=0;i<7;i++)
{
if(asc&0x01)
{
CLRPORT;
even++;
}
else
SETPORT;
asc>>=1;
delay833us();//多延时4us
}
//偶校验
if(even&0x01)//如果奇数个1
{
CLRPORT;
}
else
SETPORT;
delay833us();
//停止位
CLRPORT;
delay833us();
// CLRPORT;
return SDI12_OK;
}
/**
* @brief 向数据总线发送一串字符串
*
* 向SDI12数据总线发送一串任意指定的字符串
*
* @param str 指向想要发送的字符串的指针
* @param n_send 字符串中想要发送的字符个数
* @return 成功返回SDI12_OK\n
* @see <相关函数>
* @note <注意>
*/
SDI12RSL SDI12_SendString(char* str, u8 n_send)
{
u8 i=0;
cli();
for(i=0;i<n_send;i++)
{
SDI12_SendByte(*(str+i));
}
sei();
return SDI12_OK;
}
/**
* @brief 读1字节数据
*
* 从SDI12数据总线中读取1个字节的数据
* 此函数中使用了定时器0中断功能
*
* @param dat 将读取到的1字节数据存储到此指针指向的地址空间中
* @return 成功返回SDI12_OK\n
* 等待超时返回SDI12_TIMEOUT\n
* 校验位错误返回SDI12_CHECKERR\n
停止位错误返回SDI12_SBITERR\n
* @note 底层函数,禁止直接调用
*/
SDI12RSL SDI12_ReadByte(char* dat)
{
char rec = 0;//数据接收
u8 sum = 0;//,check = 0;//校验用
u8 i = 0,timeout = 0;
*dat = 0;
//等待起始信号的高电平
//等待SDI12从设备把总线拉低的响应信号
while(!GETPORT)
{
if(timeout>40)
return SDI12_TIMEOUT;
delay67us();
timeout++;
}
//跳过起始位,延时833us
delay415us();
//开始接收信号
SDI12_START_RD;
//TCNT0 = 0;//定时计数器清零
//TCCR0 |= 0x07;// 开启定时器,时钟源为1024分频器
while(SDI12_REC_COUNTER<9)
{
}
SDI12_REC_COUNTER = 0;
SDI12_STOP_RD;
//TCCR0 &= ~0x07;//关闭定时器时钟
//处理接收到的信号
//读取7位数据,每读1位,校验+1,并延时833us
rec = SDI12_REC_BUFFER&0x7F;
for(i=0;i<7;i++)
{
if(rec&(0x01<<i))
sum++;
}
//读校验位,与之前算出的数比对
if((sum&0x01)!=((SDI12_REC_BUFFER>>7)&0x01))
return SDI12_CHECKERR;
//读取停止位,停止位应为逻辑1
if(!(SDI12_REC_BUFFER&0x100))
return SDI12_SBITERR;
//成功返回
*dat = rec;
return SDI12_OK;
}
/**
* @brief 读取字符串
*
* 从SDI12数据总线中读取一串字符串
*
* @param str 指向一个存储读取到的字符串的指针
* @param n_read 读出的字符个数
* @return 成功返回SDI12_OK
* @see SDI12_ReadByte
* @note 此函数风险较大,避免调用,str指向的
没有合适的资源?快使用搜索试试~ 我知道了~
SDI12单总线数据收发代码
共152个文件
html:56个
js:34个
png:33个
4星 · 超过85%的资源 需积分: 50 98 下载量 37 浏览量
2014-12-31
12:54:04
上传
评论 2
收藏 290KB ZIP 举报
温馨提示
当前国外传感器较为流行的SDI12单总线数据通讯协议,由于没有硬件解码,而且收发数据全部都是通过1条数据线完成,所以开发起来难度较大。 本代码,笔者历经1个月的时间完成,使用的处理器为AVR 开发平台是atmelstudio6,整个调试实为不易。 此压缩包中包含了以下内容: 1.SDI12端口驱动源代码 2.HTML格式的源代码说明文档 注: 1.此工程为静态链接库工程,没有main入口函数; 2.工程中引用了Container容器库工程以及SLEEP库工程,此工程笔者会一并上传。 2.此工程通过SDI-12.h头文件进行相关设置; 2.为了方便维护,作者已经将数据打包成了一个抽象数据类型,使用函数,尽量通过SDI12数据类型调用而非直接调用。
资源推荐
资源详情
资源评论
收起资源包目录
SDI12单总线数据收发代码 (152个子文件)
libSDI-12.a 80KB
make.bat 581B
SDI-12.c 13KB
SDI-12.cproj 6KB
doxygen.css 19KB
search.css 4KB
tabs.css 1KB
SDI-12.d 4KB
doxyfile 76KB
SDI-12.h 4KB
_s_d_i-12_8c.html 52KB
_s_d_i-12_8h_source.html 22KB
_s_d_i-12_8h.html 21KB
structabstruct__sdi12.html 13KB
globals.html 13KB
files.html 9KB
globals_defs.html 8KB
structabstruct__sdi12-members.html 7KB
classabstruct__sdi12-members.html 7KB
globals_eval.html 7KB
globals_func.html 6KB
functions.html 6KB
functions_vars.html 6KB
dir_a5ae12a1b1b33445be0bfc17f664dd34.html 6KB
globals_vars.html 6KB
globals_enum.html 5KB
classes.html 5KB
dir_35d20445abbafe8e8ff42be70b01ceaa.html 5KB
dir_155d0b6202f042f992af2593e54b93f4.html 5KB
globals_type.html 5KB
annotated.html 5KB
dir_3d1645b19074a3357feda59c32ceefea.html 5KB
dir_885cc87fac2d91e269af0a5a959fa5f6.html 5KB
index.html 4KB
enumvalues_73.html 971B
variables_73.html 970B
variables_67.html 970B
functions_69.html 970B
variables_66.html 970B
variables_6c.html 970B
variables_72.html 970B
functions_73.html 970B
variables_69.html 970B
typedefs_73.html 969B
typedefs_70.html 969B
defines_75.html 968B
defines_67.html 968B
defines_63.html 968B
defines_70.html 968B
defines_65.html 968B
defines_73.html 968B
classes_61.html 968B
enums_73.html 966B
files_73.html 966B
all_6c.html 964B
all_75.html 964B
all_70.html 964B
all_69.html 964B
all_61.html 964B
all_63.html 964B
all_67.html 964B
all_65.html 964B
all_73.html 964B
all_66.html 964B
all_72.html 964B
nomatches.html 461B
jquery.js 92KB
search.js 24KB
all_73.js 6KB
defines_73.js 2KB
dynsections.js 2KB
enumvalues_73.js 2KB
functions_73.js 1KB
variables_73.js 785B
enums_73.js 347B
all_69.js 333B
variables_72.js 242B
all_72.js 242B
variables_69.js 242B
all_67.js 237B
files_73.js 146B
variables_67.js 138B
variables_6c.js 134B
all_6c.js 134B
variables_66.js 130B
all_66.js 130B
typedefs_73.js 121B
all_63.js 119B
defines_67.js 119B
defines_63.js 119B
all_70.js 119B
typedefs_70.js 119B
all_75.js 117B
defines_75.js 117B
all_65.js 117B
defines_65.js 117B
functions_69.js 111B
defines_70.js 111B
classes_61.js 102B
all_61.js 102B
共 152 条
- 1
- 2
资源评论
- ywylxj2018-01-02还没看,先前看过其他文档,希望详细
- 君而立2018-02-06先看看。主要分装库文件了? 下载下来岂不是也不是源代码?
- kingshenjsskf2017-06-22有一定参考意义
- Jobhot2016-06-22恩,这个接口还是蛮复杂的,谢谢分享。
- chengxunmin2015-07-14东西很好,正需要呢
AgileTortoise
- 粉丝: 67
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功