ZigBee心电传输(二)
不管怎样,还是在高手的帮助下完成了前面的硬件部分,现在进行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心电传输(二)的更多相关文章
- ZigBee心电传输(三)
这段时间因为另外一个项目需要,我搞Zed板去了.现在接着上一步的工作吧,继续把心电做完.这里想要测试一下把心电波形数据传输出来,然后用协调器接收,并从串口显示出来.之后再用ZigBee转蓝牙,从而可以 ...
- ZigBee心电传输(一)
第一次接触模拟的东西哈,也算是一次新的学习旅程以及对ZigBee的再一次探索吧. 首先是方案制定,以及采用芯片AD8232,这样节省了不少时间,把模拟的东西都搬到数字上了,不过还是需要学习不少模电知识 ...
- 关于Http 传输二维json
传输一维的好说 public static String doPost(String url) { String result = new String(); OutputStream out = n ...
- ZigBee基础
Zigbee技术 Zigbee由Zigbee联盟制定的无线网络协议,在IEEE 802.15.4标准的基础上设计,是一种自愈.安全和稳健的网状网协议,可扩展到更大范围内的数百个节点.主要用于距离短.功 ...
- 小白日记3:kali渗透测试之被动信息收集(二)-dig、whios、dnsenum、fierce
一.DIG linux下查询域名解析有两种选择,nslookup或者dig.Dig(Domain Information Groper)是一个在类Unix命令行模式下查询DNS包括NS记录,A记录,M ...
- 第十二章 NIO
12.NIO 12.1 Java NIO 概述 1课时 12.2 Java NIO.2 之Path.Paths 与 Files 的使用 1课时 12.3 自动资源管理 1课时 12.4 缓冲区(Buf ...
- linux 配置SSH网络传输数据安全方案,JDK,Tomcat和Eclipes
一.通过ssh实现安全远程访问linux系统 ssh :secure shell 加密: 1. 对称加密 (加密密钥与解密密钥相同) des .aes 2. 非对称加密(加密密钥与解密密钥不同) RS ...
- Java基础——NIO(二)非阻塞式网络通信与NIO2新增类库
一.NIO非阻塞式网络通信 1.阻塞与非阻塞的概念 传统的 IO 流都是阻塞式的.也就是说,当一个线程调用 read() 或 write() 时,该线程被阻塞,直到有一些数据被读取或写入,该线程在 ...
- 从"嘿,今晚..."谈消息安全传输中的技术点
一.初级阶段:信息裸传 特点:在网络上传递明文 黑客定理一:网络上传递的数据是不安全的,属网络于黑客公共场所,能被截取 结果:传递明文无异于不穿衣服裸奔 改进方案:先加密,再在网络上传输 二.进阶阶段 ...
随机推荐
- 前端 HTML基础
前端三大利器概述 学习前端,不得不学习前端中的三大利器:html + css + javascript.那么这三个组件分别起到什么作用呢?以人体为例,单单具有html属性的人,只是一个裸体的人偶(理解 ...
- HTML与CSS入门——第五章 使用文本块和列表
知识点: 1.在页面上对齐文本的方法 2.三种HTML列表的使用方法 3.在列表中放置列表的方法 5.1 在页面上对齐文本: 父元素内子元素文本的居中:在控制父元素的text-align:center ...
- IIS Express 终极玩法
进入正题之前,先吐嘈下微软的win10升级吧.之前有意不想将win 7 旗舰版(也是破解版哈)升到win 10,自从微软推出win10后,其本上对其没多大兴趣,感觉系统各种卡顿,各种不流畅,界面各种不 ...
- java下文件遍历,与删除
package cn.stat.p1.file; import java.io.File; public class newfilelist { /** * @param args */ public ...
- effective_c++条款20,用pass-by-reference-to-const替换pass-by-value
pass-by-value void f(A a); 1)导致复制是浪费资源 2)多态是导致对象切割 所以我们使用 void f(const A& a) 上面的话针对class,不针对基本类型 ...
- HDU 2063 裸奔的二分图最大匹配
#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#inc ...
- java学习笔记 (7) —— 实现简单的上传处理
1.下载apache 的 commons-fileupload.jar 包及 commons-io.jar 2.引入到lib 文件夹下 3.新建uploadApache.jsp <%@ page ...
- sql解释执行顺序
一.查询的逻辑执行顺序 (1) FROM left_table (3) join_type JOIN right_table (2) ON join_condition (4) WHERE where ...
- kafka安装及Kafka-PHP扩展的使用
话说用了就要有点产出,要不然过段时间又忘了,所以在这里就记录一下试用Kafka的安装过程和php扩展的试用. 实话说,如果用于队列的话,跟PHP比较配的,还是Redis.用的顺手,呵呵,只是Redis ...
- 关于python27 中文编码
本博文已移致独立博客:www.pubwin2009.net 传送门:http://www.pubwin2009.net/index.php/pubwin/42.html 看了网上好多的资料,以前一直不 ...