不管怎样,还是在高手的帮助下完成了前面的硬件部分,现在进行ZigBee的心电AD采集和转换。需要把ZigBee重新拾起来。

首先明确下目标和思路吧,目标是将模拟心电信号通过AD转换,变为数字信号,再用ZigBee传输出来。思路是利用Zstack协议栈,来写程序,通过ADC触发DMA,触发事件,将数据传输到串口或者直接从无线发送出去。

首先是ADC的配置,要配置就必须了解ADC的几个寄存器了。

包括:ADCCFG,ADCCON1,ADCCON2,ADCCON3,ADCH和ADCL

cc2430的ADC可以使用多达八个ADC输入引脚,要配置一个端口0引脚为一个ADC输入,ADCCFG寄存器相应的位置1,这个寄存器选择端口0引脚为非ADC输入。在使用ADC时,通过在ADCCFG寄存器的初始化代码中设置所需的位,ADCCFG寄存器的设置将覆盖P0SEL的设置。

接下来就是3个控制寄存器,ADCCON1是EOC-ST-STSEL[1:0]-RCTRL[1:0]-保留(11),其中EOC当被ADCH和ADCL被读取后才清零。ST表示开始转换,设置成1后,转换完成了会清零。STSEL表示启动转换的选择,00为外部触发,01为全速转换,10为定时器1的通道0的比较事件,11表示ST为1;低4位不涉及,可以全部置1.

ADCCON2,SREF[1:0]-SDIV[1:0]-SCH[3:0],SREF用于设置参考电压,00为内部参考电压,01为AIN7上的外部参考电压,10为AVDD_SOC引脚的电压,11为AIN6和AIN7的差分输入电压。SDIV表示抽取率,决定了采样时间和分辨率。SCH表示序列通道选择。

ADCCON3类似ADCCON2,用于额外采样。

其次,怎样写程序是AD工作,并且将数据读出来,用数字量表示。

这一步是关键,心电的ADC采样到底怎么来设置才能读出数据呢。得一步一步试试。

参照晚上的一些心电程序:http://blog.csdn.net/ohexiwei/article/details/8013570

差不多能知道配置过程,经过一些尝试我的初步配置过程如下:

static uint8 adcRef;
static int16 reading = 0;

void HalAdcInit (void)
{
#if (HAL_ADC == TRUE)
adcRef = HAL_ADC_REF_AVDD;
#endif
}

uint16 HalAdcseriesRead (uint8 channel, uint8 resolution)
{

uint8 i, resbits;
uint8 adcChannel = 1;
/*
* If Analog input channel is AIN0..AIN7, make sure corresponing P0 I/O pin is enabled. The code
* does NOT disable the pin at the end of this function. I think it is better to leave the pin
* enabled because the results will be more accurate. Because of the inherent capacitance on the
* pin, it takes time for the voltage on the pin to charge up to its steady-state level. If
* HalAdcRead() has to turn on the pin for every conversion, the results may show a lower voltage
* than actuality because the pin did not have time to fully charge.
*/
if (channel < 8)
{
for (i=0; i < channel; i++)
{
adcChannel <<= 1;
}
}
/* Enable channel */
ADCCFG |= adcChannel;
/* Convert resolution to decimation rate */
switch (resolution)
{
case HAL_ADC_RESOLUTION_8:
resbits = HAL_ADC_DEC_064;
break;
case HAL_ADC_RESOLUTION_10:
resbits = HAL_ADC_DEC_128;
break;
case HAL_ADC_RESOLUTION_12:
resbits = HAL_ADC_DEC_256;
break;
case HAL_ADC_RESOLUTION_14:
default:
resbits = HAL_ADC_DEC_512;
break;
}
/* writing to this register starts the extra conversion */
ADCCON3 = channel | resbits | adcRef ;

ADCCON1 |= HAL_ADC_STSEL_ST;

ADCCON1 |= HAL_ADC_START;
/* Wait for the conversion to be done */
while (!(ADCCON1 & HAL_ADC_EOC));

/* Disable channel after done conversion */
ADCCFG &= (adcChannel ^ 0xFF);

/* Read the result */
reading = (uint16)ADCL;
reading |=(uint16)(ADCH << 8);

/* Treat small negative as 0 */
/*if (reading < 0)
reading = 0;*/

switch (resolution)
{
case HAL_ADC_RESOLUTION_8:
reading >>= 8;
break;
case HAL_ADC_RESOLUTION_10:
reading >>= 6;
break;
case HAL_ADC_RESOLUTION_12:
reading >>= 4;
break;
case HAL_ADC_RESOLUTION_14:
default:
reading >>= 2;
break;
}
return ((uint16)reading);
}

讲一下我的配置过程吧:首先是参考电压,选择一般网上程序都用的HAL_ADC_REF_AVDD,什么意思,就是外部的一个参考电压,这个电压加在引脚:AVDD_SOC上,我看了一下我的板子,刚好这个脚是接在3.3的电源电压上。接下来是分辨率/抽取率选择14位的,对于新手总是觉得越大越好,通道我选择了0通道。然后是ADCCON1进行控制了,就两个语句ADCCON1 |= HAL_ADC_STSEL_ST;ADCCON1 |= HAL_ADC_START;这两个语句就是开启转换的一个命令,接下来是

/* Wait for the conversion to be done */
while (!(ADCCON1 & HAL_ADC_EOC));

/* Disable channel after done conversion */
ADCCFG &= (adcChannel ^ 0xFF);

/* Read the result */
reading = (uint16) (ADCL);
reading |= (uint16) (ADCH << 8);

等待转换结束,读取数据。好了加电调试,有数据出来了,不过问题也来了,出来的数据不对,数据都是10000以上的,

对照数据手册,可以知道,电压值对应从ADCH和ADCL读出来的数据。如下:

这就奇怪了,最大才8191,刚开始以为我以为是reading的数据类型问题,我将reading统统改成uint16,还是一样,都会超过8191,也就是意味着这个电压是个负值,可是怎么可能呢,我加的一直是正电压(这里注意了一下,我用信号发生器产生信号,一定要加一个正偏置的电压,否则输出会有负值,这个新手不太注意,负值大了会把管脚烧坏),所以还是各种不解。继续分析吧从每个配置开始,首先我不确定的是VREF,这里的VREF我纠结了好久,数据手册里面也没有再提到。后来才知道,这个VREF就是对应ADCCON2和ADCCON3寄存器中所说的参考电压。我对寄存器改了好几次,改成内部参考电压,AIN7引脚输如的外部电压,差分方式没试,都不对,都还是负值,大于8191。又查了数据类型的定义,cc2530的定义如下:

/* ------------------------------------------------------------------------------------------------
* Types
* ------------------------------------------------------------------------------------------------
*/
typedef signed char int8;
typedef unsigned char uint8;

typedef signed short int16;
typedef unsigned short uint16;

typedef signed long int32;
typedef unsigned long uint32;

typedef unsigned char bool;

typedef uint8 halDataAlign_t;

很基本的,都对。接下来再看看分辨率,这时我想起了,一个帖子cc2430和cc2530的不同:http://blog.csdn.net/xukai871105/article/details/7318886

里面讲到了cc2530和2430,ADC分辨率虽然有14位的选项,但是硬件上其实没有达到这个精度和水平,所以软件配置都是12最高了,那么就对了,我一直配置的是14位,但是数据读出来是12位的,怪不得老是大很多,2位刚好是4倍,我给一个1.5v的电压应该是4000多的值,却返回16000多的,这不是刚好4倍,终于找到根源了,两天了。。。。

立马我把配置改成12位的,果然,数据稳定了,而且都在0-8191之间了。加上方波,出现了高低的正常波形数据。。。。!!!感动的啊,我终于自己也解决了个问题了。接下来我想验证一下这个14位和12位的关系,我将配置改成14位,然后将读出来的数据右移2位,读数据,果然啊,和12位一样了,稳定!

总算是把问题解决了。

next,加上心电的波形再试试。后面再加上自己的帧格式,就能传输心电波形了哈!

ZigBee心电传输(二)的更多相关文章

  1. ZigBee心电传输(三)

    这段时间因为另外一个项目需要,我搞Zed板去了.现在接着上一步的工作吧,继续把心电做完.这里想要测试一下把心电波形数据传输出来,然后用协调器接收,并从串口显示出来.之后再用ZigBee转蓝牙,从而可以 ...

  2. ZigBee心电传输(一)

    第一次接触模拟的东西哈,也算是一次新的学习旅程以及对ZigBee的再一次探索吧. 首先是方案制定,以及采用芯片AD8232,这样节省了不少时间,把模拟的东西都搬到数字上了,不过还是需要学习不少模电知识 ...

  3. 关于Http 传输二维json

    传输一维的好说 public static String doPost(String url) { String result = new String(); OutputStream out = n ...

  4. ZigBee基础

    Zigbee技术 Zigbee由Zigbee联盟制定的无线网络协议,在IEEE 802.15.4标准的基础上设计,是一种自愈.安全和稳健的网状网协议,可扩展到更大范围内的数百个节点.主要用于距离短.功 ...

  5. 小白日记3:kali渗透测试之被动信息收集(二)-dig、whios、dnsenum、fierce

    一.DIG linux下查询域名解析有两种选择,nslookup或者dig.Dig(Domain Information Groper)是一个在类Unix命令行模式下查询DNS包括NS记录,A记录,M ...

  6. 第十二章 NIO

    12.NIO 12.1 Java NIO 概述 1课时 12.2 Java NIO.2 之Path.Paths 与 Files 的使用 1课时 12.3 自动资源管理 1课时 12.4 缓冲区(Buf ...

  7. linux 配置SSH网络传输数据安全方案,JDK,Tomcat和Eclipes

    一.通过ssh实现安全远程访问linux系统 ssh :secure shell 加密: 1. 对称加密 (加密密钥与解密密钥相同) des .aes 2. 非对称加密(加密密钥与解密密钥不同) RS ...

  8. Java基础——NIO(二)非阻塞式网络通信与NIO2新增类库

    一.NIO非阻塞式网络通信 1.阻塞与非阻塞的概念  传统的 IO 流都是阻塞式的.也就是说,当一个线程调用 read() 或 write() 时,该线程被阻塞,直到有一些数据被读取或写入,该线程在 ...

  9. 从"嘿,今晚..."谈消息安全传输中的技术点

    一.初级阶段:信息裸传 特点:在网络上传递明文 黑客定理一:网络上传递的数据是不安全的,属网络于黑客公共场所,能被截取 结果:传递明文无异于不穿衣服裸奔 改进方案:先加密,再在网络上传输 二.进阶阶段 ...

随机推荐

  1. PHP字符串的编码问题(转)

    大家都知道,不同字符编码,其在内存占用的字节数不一样.如ASCII编码字符占用1个字节,UTF-8编码的中文字符是3字节,GBK为2个字节.   PHP 也自带几种字符串截取函数,其中常用到的就是 s ...

  2. Linux文件的查找

    一直以来,总是记不住文件的查找命令,今天记在博客里,希望可以记得更牢! 1.脚本文件名的查询 which命令(寻找执行文件) #which ifconfig 2.文件名的查找 whereis 命令 # ...

  3. mybatis分页插件以及懒加载

    1.   延迟加载 延迟加载的意义在于,虽然是关联查询,但不是及时将关联的数据查询出来,而且在需要的时候进行查询. 开启延迟加载: <setting name="lazyLoading ...

  4. Java初转型-Maven入门

    原系列名:Maven学习总结(一) 原博文出自于:http://www.cnblogs.com/xdp-gacl/p/3498271.html 感谢! 一.Maven的基本概念 Maven(翻译为&q ...

  5. 关于使用Jsonp做跨域请求

    今天在使用Jsonp做跨域请求的练习时碰上这样一个问题 代码如下 <!DOCTYPE html> <html> <head> <meta charset=&q ...

  6. windows身份验证,那么sqlserver的连接字符串的

    Data Source=计算机名称或ip地址;Initial Catalog=数据库名称;Integrated Security=True windows身份验证不需要psw的Provider=SQL ...

  7. 【nodejs学习】2.网络相关

    1.官方文档的一个小例子 //http是内置模块 var http = require('http'); http.createServer(function(request, response){ ...

  8. centos上如何安装git

    安装依赖包 1.yum -y install zlib-devel openssl-devel perl cpio expat-devel gettext-devel 2.yum install au ...

  9. 实现类似QQ的折叠效果

    //  主要核心是点击自定义header来展开和收起每一组里面的cell,模型里面应该有isShow此属性来记录开展还是收起. //  ViewController.m//  实现类似QQ的折叠效果/ ...

  10. ./configure 时候报错c++ 编译器不能执行

    ./configure时报错:configure: error: C++ compiler cannot create executables .哎,今天重装测试服务器上的系统,设置好IP可以远程访问 ...