专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
TI
分享TI LM3S811开发板使用心得 之高精度采集卡制作
2019-08-06 16:38
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
TI MCU
7247
19
1028
本帖最后由 lilihua0721 于 2011-11-30 21:51 编辑
以下是我使用
TI MCU制作高精度采集卡的全部资料
,包括硬件搭建原理图、软见工程文件,液晶资料及ADS1211资料,详情请参考附件。
分别放在以下连续的8个楼层中,有不足的地方请大家指教!
效果图展示:
一、
基于
LM3S811
与
ADS1211
数据采集卡设计硬件部分(全部电路请参考附件)
对于硬件我是采用以前的做的一块
ADS1211
采集卡板跳线来完成实验的,目前并没有针对
LM3S811
设计
PCB
板,在这里给出测试原理图。
1、
电源部分及
ADS1211
的外围电路设计:
在测量过程中,电源是影响测量精度大的因素,所以电源必须要稳定。
以下是我设计的电源部分及
ADS1211
的外围电路设计。
2、
ADS1211
差分输入信号的隔离:
采用了
LM324
用于电压跟随,在此没有做放大(测试差分输入电压为
0~5V
)
具体如下图:
3
、串口通信电路:
考虑到通讯的距离及稳定性采用了
MAX232
转换为
RS232
电平,
具体参考如下:
3、
LM3S811
与
ADS
板接口连接:
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
19条回答
lilihua0721
1楼-- · 2019-08-06 19:32
本帖最后由 lilihua0721 于 2011-11-27 20:57 编辑
一、
基于
LM3S811
与
ADS1211
数据采集卡设计软件部分
(
完整工程文件请参照附件工程文件
)
ADS1211
读写流程
1、
mian.c
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "ADS1211U.h"
#include "Type.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
double UVal;//
计算电压值,
char str[60];//
存放显示字符串
INT32U ADdata; //24 AD
转换器采集到的
AD
值
INT32U Value; //
存放转换电压值放大
10000
倍的结果
INT16U integer=0;//
待转换为字符串整数部分
INT16U decimal=0;//
待转换为字符串小数部分
INT8U i=0; //
记录当前显示通道
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif
/**************************************************************************************
函数名
: void UARTIntHandler(void)
功
能
:
接受中断处理
说
明
:
从接受
FIFO
中取出数据然后发送出去
输
入:无
输
出:无
其
他:无
**************************************************************************************/
void UARTIntHandler(void)
{
INT32U ulStatus;
//
获取中断状态
ulStatus = UARTIntStatus(UART0_BASE, true);
//
清中断
UARTIntClear(UART0_BASE, ulStatus);
//
查接受
FIFO
是否存在数据
while(UARTCharsAvail(UART0_BASE))
{
//
从接受
FIFO
接受到数据后然后通过发送
FIFO
发送出去
UARTCharPutNonBlocking(UART0_BASE, UARTCharGetNonBlocking(UART0_BASE));
}
}
/*****************************************************************************
函数名
: CreanLcd(INT16U
usColor,INT16U X0,INT16U Y0,INT16U X1,INT16U Y1)
功
能
:
清指定区域的,用
usColor
颜 {MOD}对指定区域进行填充
说
明
:
清液晶指定区域
输
入:
usColor
填充颜 {MOD}
X0
、
Y0
第一点左上坐标
X1
、
Y1
第一点右下坐标
输
出:无
其
他:无
*******************************************************************************/
void CreanLcd(INT16U
usColor,INT16U X0,INT16U Y0,INT16U X1,INT16U Y1)
{
INT8U
CmdData[6]={0xAA,0x64,0xCC,0x33,0xC3,0x3C};
INT8U
i=0;
//
发送帧头
for(i=0;i<2;i++)
{
UARTCharPutNonBlocking(UART0_BASE, CmdData
);
}
SysCtlDelay(2*SysCtlClockGet()/3000);
//
发送填充颜 {MOD}
UARTCharPutNonBlocking(UART0_BASE, usColor>>8);
UARTCharPutNonBlocking(UART0_BASE, usColor);
SysCtlDelay(2*SysCtlClockGet()/3000);
//
发送左上
LCD
地址
UARTCharPutNonBlocking(UART0_BASE, X0>>8);
UARTCharPutNonBlocking(UART0_BASE, X0);
UARTCharPutNonBlocking(UART0_BASE, Y0>>8);
UARTCharPutNonBlocking(UART0_BASE, Y0);
SysCtlDelay(2*SysCtlClockGet()/3000);
//
发送右下
LCD
地址
UARTCharPutNonBlocking(UART0_BASE, X1>>8);
UARTCharPutNonBlocking(UART0_BASE, X1);
UARTCharPutNonBlocking(UART0_BASE, Y1>>8);
UARTCharPutNonBlocking(UART0_BASE, Y1);
SysCtlDelay(2*SysCtlClockGet()/3000);
//
发送帧尾及校验位
for(i=2;i<6;i++)
{
UARTCharPutNonBlocking(UART0_BASE, CmdData
);
SysCtlDelay(SysCtlClockGet()/3000);
}
}
加载中...
lilihua0721
2楼-- · 2019-08-06 23:36
本帖最后由 lilihua0721 于 2011-11-27 20:58 编辑
/**************************************************************************
函数名
: void UARTSend(const INT8U *pucBuffer, INT32U ulCount,INT16U XAddr, INT16U YAddr)
功
能
:
清指定区域的,用
usColor
颜 {MOD}对指定区域进行填充
说
明
:
清液晶指定区域
输
入:
pucBuffer
字符串指针
ulCount
字符串个数
XAddr
、
YAddr
显示地址
输
出:无
其
他:无
*****************************************************************************/
void UARTSend(const INT8U *pucBuffer, INT32U ulCount,INT16U XAddr, INT16U YAddr)
{
INT8U
CmdData[6]={0xAA,0x54,0xCC,0x33,0xC3,0x3C};
INT8U
i=0;
//
发送帧头
for(i=0;i<2;i++)
{
UARTCharPutNonBlocking(UART0_BASE, CmdData
);
}
SysCtlDelay(2*SysCtlClockGet()/3000);
//
发送写入
LCD
地址
UARTCharPutNonBlocking(UART0_BASE, XAddr>>8);
UARTCharPutNonBlocking(UART0_BASE, XAddr);
UARTCharPutNonBlocking(UART0_BASE, YAddr>>8);
UARTCharPutNonBlocking(UART0_BASE, YAddr);
SysCtlDelay(2*SysCtlClockGet()/3000);
//
发送显示内容
while(ulCount--)
{
UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++);
SysCtlDelay(SysCtlClockGet()/3000);
}
//
发送帧尾及校验位
for(i=2;i<6;i++)
{
UARTCharPutNonBlocking(UART0_BASE, CmdData
);
SysCtlDelay(SysCtlClockGet()/3000);
}
}
加载中...
lilihua0721
3楼-- · 2019-08-07 02:59
本帖最后由 lilihua0721 于 2011-11-27 21:09 编辑
/******************************************************************************
函数名
: void ADConversion_test(INT8U chn)
功
能
:
测试
24
位
AD
转换器的采样精度
说
明
:
由于采集输入端电压范围为
0~5V
,
5V
对应的满量程为
0x7FFFFF
故:差分输入电压值为:
U = (5*AD)/0x7FFFFF ,
可以知道
U
必然
小于
5V
,乘
10000
后必然小于
0xFFFF
,所以执行以下操作不会越界
integer=(INT16U)(Value/10000);
//
取字符串的整数部分
decimal=(INT16U)(Value%10000);
//
取字符串的小数部分
输
入:无
输
出:无
其
他:无
*****************************************************************************/
void ADConversion_test(INT8U chn)
{
if(chn>=4)
{
return ; //
通道有误,返回!
}
memset(str,0,60);
ADdata = ADCave_ADS1211(chn,3);
UVal=ADdata;
UVal=UVal*5;
UVal=UVal/0x7FFFFF;
Value = (INT32U)(UVal*10000);
//
把
double
型数据强制转换为
32
位整型数据,并放大
//10000
倍
integer=(INT16U)(Value/10000);
//
取字符串的整数部分
decimal=(INT16U)(Value%10000);
//
取字符串的小数部分
if(chn==0)
{
//
清显示区,显示第一通道时清显示区域(不是整个屏幕)
CreanLcd(0xFFFF,0x00,0x50,0x1C2,0xE0);
if(decimal<10)
sprintf(str,
第一通道检测
:AD
值
:0x%x
电压值
:%d.000%dV",ADdata,integer,decimal);
else if(decimal<100)
sprintf(str,"
第一通道检测
:AD
值
:0x%x
电压值
:%d.00%dV",ADdata,integer,decimal);
else if(decimal<1000)
sprintf(str ,"
第一通道检测
:AD
值
:0x%x
电压值
:%d.0%dV",ADdata,integer,decimal);
else
sprintf(str ,"
第一通道检测
:AD
值
:0x%x
电压值
:%d.%dV",ADdata,integer,decimal);
//
发送给串口屏进行显示
UARTSend((INT8U *)str, strlen(str),0x00,0x50);
}
else if(chn==1)
{
if(decimal<10)
sprintf(str,
第二通道检测
:AD
值
:0x%x
电压值
:%d.000%dV",ADdata,integer,decimal);
else if(decimal<100)
sprintf(str,"
第二通道检测
:AD
值
:0x%x
电压值
:%d.00%dV",ADdata,integer,decimal);
else if(decimal<1000)
sprintf(str ,"
第二通道检测
:AD
值
:0x%x
电压值
:%d.0%dV",ADdata,integer,decimal);
else
sprintf(str ,"
第二通道检测
:AD
值
:0x%x
电压值
:%d.%dV",ADdata,integer,decimal);
//
发送给串口屏进行显示
UARTSend((INT8U *)str, strlen(str),0x00,0x70);
}
else if(chn==2)
{
if(decimal<10)
sprintf(str,
第三通道检测
:AD
值
:0x%x
电压值
:%d.000%dV",ADdata,integer,decimal);
else if(decimal<100)
sprintf(str,"
第三通道检测
:AD
值
:0x%x
电压值
:%d.00%dV",ADdata,integer,decimal);
else if(decimal<1000)
sprintf(str ,"
第三通道检测
:AD
值
:0x%x
电压值
:%d.0%dV",ADdata,integer,decimal)
else
sprintf(str ,"
第三通道检测
:AD
值
:0x%x
电压值
:%d.%dV",ADdata,integer,decimal);
//
发送给串口屏进行显示
UARTSend((INT8U *)str, strlen(str),0x00,0x90);
}
else if(chn==3)
{
if(decimal<10)
sprintf(str,
第四通道检测
:AD
值
:0x%x
电压值
:%d.000%dV",ADdata,integer,decimal);
else if(decimal<100)
sprintf(str,"
第四通道检测
:AD
值
:0x%x
电压值
:%d.00%dV",ADdata,integer,decimal);
else if(decimal<1000)
sprintf(str ,"
第四通道检测
:AD
值
:0x%x
电压值
:%d.0%dV",ADdata,integer,decimal);
else
sprintf(str ,"
第四通道检测
:AD
值
:0x%x
电压值
:%d.%dV",ADdata,integer,decimal);
//
发送给串口屏进行显示
UARTSend((INT8U *)str, strlen(str),0x00,0xb0);
}
integer=0;
decimal=0;
}
加载中...
nongfuxu
4楼-- · 2019-08-07 05:34
高精度是ADS1211吧,与LM3S811有什么关系.
ADS1211与任何一个单片机都完成同样功能--->高精度数据采集卡.
加载中...
lilihua0721
5楼-- · 2019-08-07 08:19
精彩回答 2 元偷偷看……
加载中...
lilihua0721
6楼-- · 2019-08-07 08:29
本帖最后由 lilihua0721 于 2011-11-27 21:04 编辑
2、 ADS1211.c
#include "Type.h"
#include "ADS1211U.h"
#include "driverlib/sysctl.h"
/******************************
函数名: void Ads1211Init(void)
功 能: 初始化ADS1211U
说 明: 无
输 入:无
输 出:无
返 回:无
其 他:无
******************************/
void Ads1211Init(void)
{
while(!ADS1211_DRDY());
while(ADS1211_DRDY());
// delay5us(5) ;
/* 设置INSR写入4字节命令字CMR */
WriteAds1211(0x64);
/* 设置输出REF及设置双极性 */
WriteAds1211(0x52);
/* 选择半自动校准模式,增益PGA为1,通道3 */
WriteAds1211(0x22);
/* 根据抽取率=fxin*TMR/(Fdata*512);计算抽取率 */
WriteAds1211(0x81);
/* TMR设置为8;Fdata为1000;Fxin为10M,得到抽取率为312.5 20位有效位 */
WriteAds1211(0x38);
}
/************************************
函数名: void WriteAds1211(INT8U Dat)
功 能: 向ADS1211写入1字节数据
说 明: 无
输 入:Dat
输 出:无
返 回:无
其 他:无
*************************************/
void WriteAds1211(INT8U Dat){
INT8U i,tmp;
/* 移位 */
tmp = Dat;
for(i= 0;i< 8;i++){
/* 模拟时钟高并保持一段时间 */
ADS1211_SCLK_1();
SysCtlDelay(2000*SysCtlClockGet()/30000);
/* 获取数据 */
if(tmp & 0x80) ADS1211_SDIO_1();
else ADS1211_SDIO_0();
/* 模拟时钟低并保持一段时间 */
ADS1211_SCLK_0();
SysCtlDelay(2000*SysCtlClockGet()/30000);
/* 移位 */
tmp <<= 1;
}
}
/****************************************************
函数名: INT8U AdsReadData(tU32 *Dat,INT8U chn)
功 能: 读取ADS1211转换数据
说 明: 读取转换数据通过 Dat 进行返回
输 入:chn:通道号 0->3
输 出:Dat
返 回:0:成功
1:失败
其 他:无
****************************************************/
INT8U AdsReadData(INT32U *Dat,INT8U chn)
{
INT8U i = 0;
INT32U Chr=0;
if(chn>3) return 1;
while(!ADS1211_DRDY());
while(ADS1211_DRDY());
WriteAds1211(0x05);
switch (chn)
{
case 0:
WriteAds1211(0x20);
break;
case 1:
WriteAds1211(0x21);
break;
case 2:
WriteAds1211(0x22);
break;
case 3:
WriteAds1211(0x23);
break;
default:
break;
}
while(!ADS1211_DRDY());
while(ADS1211_DRDY());
WriteAds1211(0xc0); // 读DOR寄存器中3个字节
for(i=0;i<24;i++)
{ // 读取数据
ADS1211_SCLK_1();
SysCtlDelay(2000*SysCtlClockGet()/30000);
Chr <<= 1;
ADS1211_SCLK_0();
SysCtlDelay(2000*SysCtlClockGet()/30000);
Chr += ADS1211_SDOUT()?1:0;
}
ADS1211_SCLK_0(); // ADS1211的SCLK清零
// (*(INT32U_UNION*)&Chr).sBYTE.BHH = 0;
*Dat =Chr;
return 0 ;
}
/**********************************************
函数名: void ADCmid(void)
功 能: 1路A/D转换函数(中值滤波)
说 明: 获取通道channel中值滤波后的A/D转换结果,
返回该通道中值滤波后的A/D转换结果
输 入:channel: 通道号 0->3
输 出:无
返 回:中值AD
其 他:无
***********************************************/
INT32U ADCmid_ADS1211(INT8U chn){
INT32U i,j,k,tmp;
tmp =0;
if((!AdsReadData(&i,chn))&&
(!AdsReadData(&j,chn))&&
(!AdsReadData(&k,chn)))
{
if(i > j)
{
tmp = i;
i = j;
j = tmp;
}
if(k>i)
{
if (k >j)
tmp = j;
else
tmp = k;
}
else
{
tmp = i;
}
}
return tmp;
}
/**************************************
函数名: void ADCave(void)
功 能: 1路A/D转换函数(均值滤波)
说 明: 通道channel进行n次中值滤波,
求和再作均值,得出均值滤波结
果并返回该通道均值滤波后的A/D
转换结果
输 入:chn:通道号 0->3
n:中值滤波次数
输 出:无
返 回:无
其 他:均值AD
**************************************/
INT32U ADCave_ADS1211(INT8U chn,INT8U n)
{
INT8U i=0;
INT32U j=0;
for (i=0; i<n; i++)
{
j += ADCmid_ADS1211(chn);
}
j = j/n;
return j;
}
1、
ADS1211.h
部分
#ifndef _ADS1211U_H
#define _ADS1211U_H
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "Type.h"
/* AD
采集芯片端口定义
*/
#define ADS1211_SCLK_1() (GPIOPinWrite(GPIO_PORTD_BASE,
GPIO_PIN_4, GPIO_PIN_4))
#define ADS1211_SCLK_0()(GPIOPinWrite(GPIO_PORTD_BASE,
GPIO_PIN_4,~GPIO_PIN_4))
#define ADS1211_SDIO_1() (GPIOPinWrite(GPIO_PORTD_BASE,
GPIO_PIN_5, GPIO_PIN_5))
#define ADS1211_SDIO_0() (GPIOPinWrite(GPIO_PORTD_BASE,
GPIO_PIN_5,~GPIO_PIN_5))
#define ADS1211_SDOUT() (GPIOPinRead(GPIO_PORTD_BASE,
GPIO_PIN_6))
#define ADS1211_DRDY() (GPIOPinRead(GPIO_PORTD_BASE,
GPIO_PIN_7))
/*
函数接口
*/
void Ads1211Init(void) ;
void WriteAds1211(INT8U Dat);
INT8U AdsReadData(INT32U *Dat,INT8U chn);
INT32U ADCmid_ADS1211(INT8U chn) ;
INT32U ADCave_ADS1211(INT8U chn,INT8U n) ;
#endif
2、
Type.h
部分
#ifndef _TYPE_H
#define _TYPE_H
/*
类型定义
*/
typedef unsigned char INT8U;/*
无符号
8
位数
*/
typedef signed charINT8S;/*
有符号
8
位数
*/
typedef unsigned short int INT16U;/*
无符号
16
位数
*/
typedef signed short int INT16S; /*
有符号
16
位数
*/
typedef unsigned long intINT32U;/*
无符号
32
位数
*/
typedef signed long int INT32S;/*
有符号
32
位数
*/
typedef float FP32; /*
单精度浮点数
*/
typedef double FP64; /*
双精度浮点数
*/
typedef unsigned char tBoolean;
#endif
加载中...
1
2
3
4
下一页
一周热门
更多
>
相关问题
CPLD的方波输出
4 个回答
11个版本Quartus II 软件下载,安装包网盘合集,附教程,47G!
20 个回答
请大家帮忙到21IC发展大家谈支持我申请新版面
20 个回答
【通知】21ic中国电子网服务条款 (所有人员必读)
1 个回答
满载而归乙亥年,大展鸿途庚子年---集签赢好礼
20 个回答
携手ADI,踏上电子工程师之巅—车辆电气化视频,答题领奖!
1 个回答
如何提升论坛质量,看你了!
20 个回答
【最终名单】二姨家喊你来拿100份新年大礼啦~
20 个回答
相关文章
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
TI
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
一、基于LM3S811与ADS1211数据采集卡设计软件部分(完整工程文件请参照附件工程文件)
ADS1211读写流程
1、mian.c
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "ADS1211U.h"
#include "Type.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
double UVal;//计算电压值,
char str[60];//存放显示字符串
INT32U ADdata; //24 AD转换器采集到的AD值
INT32U Value; //存放转换电压值放大10000倍的结果
INT16U integer=0;// 待转换为字符串整数部分
INT16U decimal=0;// 待转换为字符串小数部分
INT8U i=0; // 记录当前显示通道
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif
/**************************************************************************************
函数名: void UARTIntHandler(void)
功 能: 接受中断处理
说 明: 从接受FIFO中取出数据然后发送出去
输 入:无
输 出:无
其 他:无
**************************************************************************************/
void UARTIntHandler(void)
{
INT32U ulStatus;
//获取中断状态
ulStatus = UARTIntStatus(UART0_BASE, true);
//清中断
UARTIntClear(UART0_BASE, ulStatus);
//查接受FIFO是否存在数据
while(UARTCharsAvail(UART0_BASE))
{
//从接受FIFO接受到数据后然后通过发送FIFO发送出去
UARTCharPutNonBlocking(UART0_BASE, UARTCharGetNonBlocking(UART0_BASE));
}
}
/*****************************************************************************
函数名: CreanLcd(INT16U
usColor,INT16U X0,INT16U Y0,INT16U X1,INT16U Y1)
功 能: 清指定区域的,用usColor颜 {MOD}对指定区域进行填充
说 明: 清液晶指定区域
输 入:usColor填充颜 {MOD}
X0 、Y0第一点左上坐标
X1 、Y1
第一点右下坐标
输 出:无
其 他:无
*******************************************************************************/
void CreanLcd(INT16U
usColor,INT16U X0,INT16U Y0,INT16U X1,INT16U Y1)
{
INT8U
CmdData[6]={0xAA,0x64,0xCC,0x33,0xC3,0x3C};
INT8U
i=0;
//发送帧头
for(i=0;i<2;i++)
{
UARTCharPutNonBlocking(UART0_BASE, CmdData);
}
SysCtlDelay(2*SysCtlClockGet()/3000);
//发送填充颜 {MOD}
UARTCharPutNonBlocking(UART0_BASE, usColor>>8);
UARTCharPutNonBlocking(UART0_BASE, usColor);
SysCtlDelay(2*SysCtlClockGet()/3000);
//发送左上LCD地址
UARTCharPutNonBlocking(UART0_BASE, X0>>8);
UARTCharPutNonBlocking(UART0_BASE, X0);
UARTCharPutNonBlocking(UART0_BASE, Y0>>8);
UARTCharPutNonBlocking(UART0_BASE, Y0);
SysCtlDelay(2*SysCtlClockGet()/3000);
//发送右下LCD地址
UARTCharPutNonBlocking(UART0_BASE, X1>>8);
UARTCharPutNonBlocking(UART0_BASE, X1);
UARTCharPutNonBlocking(UART0_BASE, Y1>>8);
UARTCharPutNonBlocking(UART0_BASE, Y1);
SysCtlDelay(2*SysCtlClockGet()/3000);
//发送帧尾及校验位
for(i=2;i<6;i++)
{
UARTCharPutNonBlocking(UART0_BASE, CmdData);
SysCtlDelay(SysCtlClockGet()/3000);
}
}
/**************************************************************************
函数名: void UARTSend(const INT8U *pucBuffer, INT32U ulCount,INT16U XAddr, INT16U YAddr)
功 能: 清指定区域的,用usColor颜 {MOD}对指定区域进行填充
说 明: 清液晶指定区域
输 入:pucBuffer 字符串指针
ulCount 字符串个数
XAddr 、YAddr
显示地址
输 出:无
其 他:无
*****************************************************************************/
void UARTSend(const INT8U *pucBuffer, INT32U ulCount,INT16U XAddr, INT16U YAddr)
{
INT8U
CmdData[6]={0xAA,0x54,0xCC,0x33,0xC3,0x3C};
INT8U
i=0;
//发送帧头
for(i=0;i<2;i++)
{
UARTCharPutNonBlocking(UART0_BASE, CmdData);
}
SysCtlDelay(2*SysCtlClockGet()/3000);
//发送写入LCD地址
UARTCharPutNonBlocking(UART0_BASE, XAddr>>8);
UARTCharPutNonBlocking(UART0_BASE, XAddr);
UARTCharPutNonBlocking(UART0_BASE, YAddr>>8);
UARTCharPutNonBlocking(UART0_BASE, YAddr);
SysCtlDelay(2*SysCtlClockGet()/3000);
//发送显示内容
while(ulCount--)
{
UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++);
SysCtlDelay(SysCtlClockGet()/3000);
}
//发送帧尾及校验位
for(i=2;i<6;i++)
{
UARTCharPutNonBlocking(UART0_BASE, CmdData);
SysCtlDelay(SysCtlClockGet()/3000);
}
}
/******************************************************************************
函数名: void ADConversion_test(INT8U chn)
功 能: 测试24位AD转换器的采样精度
说 明: 由于采集输入端电压范围为0~5V,5V对应的满量程为0x7FFFFF
故:差分输入电压值为:U = (5*AD)/0x7FFFFF ,可以知道U必然
小于5V,乘10000后必然小于0xFFFF,所以执行以下操作不会越界
integer=(INT16U)(Value/10000);
//取字符串的整数部分
decimal=(INT16U)(Value%10000);
//取字符串的小数部分
输 入:无
输 出:无
其 他:无
*****************************************************************************/
void ADConversion_test(INT8U chn)
{
if(chn>=4)
{
return ; // 通道有误,返回!
}
memset(str,0,60);
ADdata = ADCave_ADS1211(chn,3);
UVal=ADdata;
UVal=UVal*5;
UVal=UVal/0x7FFFFF;
Value = (INT32U)(UVal*10000);
//把double型数据强制转换为32位整型数据,并放大
//10000倍
integer=(INT16U)(Value/10000);
//取字符串的整数部分
decimal=(INT16U)(Value%10000);
//取字符串的小数部分
if(chn==0)
{
//清显示区,显示第一通道时清显示区域(不是整个屏幕)
CreanLcd(0xFFFF,0x00,0x50,0x1C2,0xE0);
if(decimal<10)
sprintf(str,第一通道检测:AD值:0x%x 电压值:%d.000%dV",ADdata,integer,decimal);
else if(decimal<100)
sprintf(str,"第一通道检测:AD值:0x%x 电压值:%d.00%dV",ADdata,integer,decimal);
else if(decimal<1000)
sprintf(str ,"第一通道检测:AD值:0x%x 电压值:%d.0%dV",ADdata,integer,decimal);
else
sprintf(str ,"第一通道检测:AD值:0x%x 电压值:%d.%dV",ADdata,integer,decimal);
//发送给串口屏进行显示
UARTSend((INT8U *)str, strlen(str),0x00,0x50);
}
else if(chn==1)
{
if(decimal<10)
sprintf(str,第二通道检测:AD值:0x%x 电压值:%d.000%dV",ADdata,integer,decimal);
else if(decimal<100)
sprintf(str,"第二通道检测:AD值:0x%x 电压值:%d.00%dV",ADdata,integer,decimal);
else if(decimal<1000)
sprintf(str ,"第二通道检测:AD值:0x%x 电压值:%d.0%dV",ADdata,integer,decimal);
else
sprintf(str ,"第二通道检测:AD值:0x%x 电压值:%d.%dV",ADdata,integer,decimal);
//发送给串口屏进行显示
UARTSend((INT8U *)str, strlen(str),0x00,0x70);
}
else if(chn==2)
{
if(decimal<10)
sprintf(str,第三通道检测:AD值:0x%x 电压值:%d.000%dV",ADdata,integer,decimal);
else if(decimal<100)
sprintf(str,"第三通道检测:AD值:0x%x 电压值:%d.00%dV",ADdata,integer,decimal);
else if(decimal<1000)
sprintf(str ,"第三通道检测:AD值:0x%x 电压值:%d.0%dV",ADdata,integer,decimal)
else
sprintf(str ,"第三通道检测:AD值:0x%x 电压值:%d.%dV",ADdata,integer,decimal);
//发送给串口屏进行显示
UARTSend((INT8U *)str, strlen(str),0x00,0x90);
}
else if(chn==3)
{
if(decimal<10)
sprintf(str,第四通道检测:AD值:0x%x 电压值:%d.000%dV",ADdata,integer,decimal);
else if(decimal<100)
sprintf(str,"第四通道检测:AD值:0x%x 电压值:%d.00%dV",ADdata,integer,decimal);
else if(decimal<1000)
sprintf(str ,"第四通道检测:AD值:0x%x 电压值:%d.0%dV",ADdata,integer,decimal);
else
sprintf(str ,"第四通道检测:AD值:0x%x 电压值:%d.%dV",ADdata,integer,decimal);
//发送给串口屏进行显示
UARTSend((INT8U *)str, strlen(str),0x00,0xb0);
}
integer=0;
decimal=0;
}
ADS1211与任何一个单片机都完成同样功能--->高精度数据采集卡.
2、 ADS1211.c
#include "Type.h"
#include "ADS1211U.h"
#include "driverlib/sysctl.h"
/******************************
函数名: void Ads1211Init(void)
功 能: 初始化ADS1211U
说 明: 无
输 入:无
输 出:无
返 回:无
其 他:无
******************************/
void Ads1211Init(void)
{
while(!ADS1211_DRDY());
while(ADS1211_DRDY());
// delay5us(5) ;
/* 设置INSR写入4字节命令字CMR */
WriteAds1211(0x64);
/* 设置输出REF及设置双极性 */
WriteAds1211(0x52);
/* 选择半自动校准模式,增益PGA为1,通道3 */
WriteAds1211(0x22);
/* 根据抽取率=fxin*TMR/(Fdata*512);计算抽取率 */
WriteAds1211(0x81);
/* TMR设置为8;Fdata为1000;Fxin为10M,得到抽取率为312.5 20位有效位 */
WriteAds1211(0x38);
}
/************************************
函数名: void WriteAds1211(INT8U Dat)
功 能: 向ADS1211写入1字节数据
说 明: 无
输 入:Dat
输 出:无
返 回:无
其 他:无
*************************************/
void WriteAds1211(INT8U Dat){
INT8U i,tmp;
/* 移位 */
tmp = Dat;
for(i= 0;i< 8;i++){
/* 模拟时钟高并保持一段时间 */
ADS1211_SCLK_1();
SysCtlDelay(2000*SysCtlClockGet()/30000);
/* 获取数据 */
if(tmp & 0x80) ADS1211_SDIO_1();
else ADS1211_SDIO_0();
/* 模拟时钟低并保持一段时间 */
ADS1211_SCLK_0();
SysCtlDelay(2000*SysCtlClockGet()/30000);
/* 移位 */
tmp <<= 1;
}
}
/****************************************************
函数名: INT8U AdsReadData(tU32 *Dat,INT8U chn)
功 能: 读取ADS1211转换数据
说 明: 读取转换数据通过 Dat 进行返回
输 入:chn:通道号 0->3
输 出:Dat
返 回:0:成功
1:失败
其 他:无
****************************************************/
INT8U AdsReadData(INT32U *Dat,INT8U chn)
{
INT8U i = 0;
INT32U Chr=0;
if(chn>3) return 1;
while(!ADS1211_DRDY());
while(ADS1211_DRDY());
WriteAds1211(0x05);
switch (chn)
{
case 0:
WriteAds1211(0x20);
break;
case 1:
WriteAds1211(0x21);
break;
case 2:
WriteAds1211(0x22);
break;
case 3:
WriteAds1211(0x23);
break;
default:
break;
}
while(!ADS1211_DRDY());
while(ADS1211_DRDY());
WriteAds1211(0xc0); // 读DOR寄存器中3个字节
for(i=0;i<24;i++)
{ // 读取数据
ADS1211_SCLK_1();
SysCtlDelay(2000*SysCtlClockGet()/30000);
Chr <<= 1;
ADS1211_SCLK_0();
SysCtlDelay(2000*SysCtlClockGet()/30000);
Chr += ADS1211_SDOUT()?1:0;
}
ADS1211_SCLK_0(); // ADS1211的SCLK清零
// (*(INT32U_UNION*)&Chr).sBYTE.BHH = 0;
*Dat =Chr;
return 0 ;
}
/**********************************************
函数名: void ADCmid(void)
功 能: 1路A/D转换函数(中值滤波)
说 明: 获取通道channel中值滤波后的A/D转换结果,
返回该通道中值滤波后的A/D转换结果
输 入:channel: 通道号 0->3
输 出:无
返 回:中值AD
其 他:无
***********************************************/
INT32U ADCmid_ADS1211(INT8U chn){
INT32U i,j,k,tmp;
tmp =0;
if((!AdsReadData(&i,chn))&&
(!AdsReadData(&j,chn))&&
(!AdsReadData(&k,chn)))
{
if(i > j)
{
tmp = i;
i = j;
j = tmp;
}
if(k>i)
{
if (k >j)
tmp = j;
else
tmp = k;
}
else
{
tmp = i;
}
}
return tmp;
}
/**************************************
函数名: void ADCave(void)
功 能: 1路A/D转换函数(均值滤波)
说 明: 通道channel进行n次中值滤波,
求和再作均值,得出均值滤波结
果并返回该通道均值滤波后的A/D
转换结果
输 入:chn:通道号 0->3
n:中值滤波次数
输 出:无
返 回:无
其 他:均值AD
**************************************/
INT32U ADCave_ADS1211(INT8U chn,INT8U n)
{
INT8U i=0;
INT32U j=0;
for (i=0; i<n; i++)
{
j += ADCmid_ADS1211(chn);
}
j = j/n;
return j;
}
1、
ADS1211.h部分
#ifndef _ADS1211U_H
#define _ADS1211U_H
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "Type.h"
/* AD采集芯片端口定义 */
#define ADS1211_SCLK_1() (GPIOPinWrite(GPIO_PORTD_BASE,
GPIO_PIN_4, GPIO_PIN_4))
#define ADS1211_SCLK_0()(GPIOPinWrite(GPIO_PORTD_BASE,
GPIO_PIN_4,~GPIO_PIN_4))
#define ADS1211_SDIO_1() (GPIOPinWrite(GPIO_PORTD_BASE,
GPIO_PIN_5, GPIO_PIN_5))
#define ADS1211_SDIO_0() (GPIOPinWrite(GPIO_PORTD_BASE,
GPIO_PIN_5,~GPIO_PIN_5))
#define ADS1211_SDOUT() (GPIOPinRead(GPIO_PORTD_BASE,
GPIO_PIN_6))
#define ADS1211_DRDY() (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7))
/* 函数接口 */
void Ads1211Init(void) ;
void WriteAds1211(INT8U Dat);
INT8U AdsReadData(INT32U *Dat,INT8U chn);
INT32U ADCmid_ADS1211(INT8U chn) ;
INT32U ADCave_ADS1211(INT8U chn,INT8U n) ;
#endif
2、Type.h部分
#ifndef _TYPE_H
#define _TYPE_H
/* 类型定义 */
typedef unsigned char INT8U;/* 无符号8位数*/
typedef signed charINT8S;/* 有符号8位数*/
typedef unsigned short int INT16U;/* 无符号16位数 */
typedef signed short int INT16S; /* 有符号16位数 */
typedef unsigned long intINT32U;/* 无符号32位数 */
typedef signed long int INT32S;/* 有符号32位数 */
typedef float FP32; /* 单精度浮点数 */
typedef double FP64; /* 双精度浮点数 */
typedef unsigned char tBoolean;
#endif
一周热门 更多>