stm32驱动AD7708
∑-△模数转换器的原理及应用
∑-△模数转换器的原理及应用张中平(东南大学微电子机械系统教育部重点实验室,南京210096)摘要:∑-△模数转换器由于造价低、精度高、性能稳定及使用方便等特点,越来越广泛地使用在一些高精度仪器仪表和测量设备中,介绍该转换器的基本原理,并重点举例介绍AD7708芯片的应用,该芯片是16 bit模数转换器,与24 bit AD7718引脚相同,可直接升级。
关键词:模数转换器;寄存器;串行口我们通常使用的模数转换器(ADC)大多为积分型和逐次逼近型,积分型转换效果不够好,转换过程中带来的误差比较大;逐次逼近型转换效果较好但制作成本较高,尤其是高位数转换,转换位数越多,精度越高,制作成本就越高。
而∑-△ADC可以以相对逐次逼近型简单的电路结构,而得到低成本,高位数及高精度的转换效果∑-△ADC大多设计为16或24 bit转换精度。
近几年来,在相关的高精度仪器制作领域该转换器得到了越来越广泛的应用[1]。
1 ∑-△ADC的基本工作原理简介∑-△模数转换器的工作原理简单的讲,就是将模数转换过后的数字量再做一次窄带低通滤波处理。
当模拟量进入转换器后,先在调制器中做求积处理,并将模拟量转为数字量,在这个过程中会产生一定的量化噪声,这种噪声将影响到输出结果,因此,采用将转换过的数字量以较低的频率一位一位地传送到输出端,同时在这之间加一级低通滤波器的方法,就可将量化噪声过滤掉,从而得到一组精确的数字量[1,2]。
2 AD7708/AD7718,∑-△ADC的应用AD7708/AD7718是美国ADI公司若干种∑ΔADC中的一种。
其中AD7708为16 bit转换精度,AD7718为24 bit转换精度,同为28条引脚,而且相同引脚功能相同,可以互换。
为方便起见,下面只介绍其中一种,也是我们工作中用过的AD7708。
2.1AD7708的工作原理同其它智能化器件一样,AD7708也可以用软件来调节其所具有的功能,即通过微控制器MCU编程向AD7708的相应寄存器填写适当的参数。
ad7708
引脚功能说明寄存器Communications register 在转换时用来控制所有操作。
所有与communications有关的必须先写入控制字。
在上电或复位后,设备默认为等待写入通信控制字。
STATUS(状态)寄存器包含与转换固有的相关信息。
状态寄存器是一个只读寄存器。
该模式寄存器用于配置转换模式,校准,chop 启用/禁用,参考选择,通道配置和缓冲或无缓冲操作的AINCOM模拟输入。
MODE寄存器是一个读写寄存器。
该ADC控制寄存器是一个读/写寄存器用于选择通道,可输入范围和双极/单极的编程控制。
I / O 控制寄存器是一个读/写寄存器用于配置的运作情况引脚2 I / O端口。
Filter register 是一个读写寄存器用于数据更新速率转换器的编程控制寄存器。
该ADC数据寄存器是一个只读寄存器,其中包含选定通道的数据转换结果。
ADC offset(偏移)寄存器是读写寄存器包含偏移校准数据。
有五个偏移寄存器,一个为每个全差分输入通道。
当配置为伪差分输入模式时,通道共享偏移寄存器。
ADC增益寄存器是读/写寄存器包含增益校准数据。
Communications 只写8位上电复位不适用数据写入通信寄存器决定下一个运作是读或写操作,该类型的读操作,和这一操作发生在哪一个寄存器上。
对于读或写操作,一旦随后的读或写操作在选定的寄存器完成,接口返回到通信寄存器预计写操作。
这是一个默认的状态接口,在上电或复位后,在该AD7708/AD7718 此默认状态等待写入操作在通信寄存器上。
在序列接口丢失的情况下,一个具有高回报至少32位的串行时钟周期的写操作回到默认状态进行重置。
CR0通过CR7表明比特位置。
CR7指第一位的数据流。
CR7写允许位。
一个0必须写入这个位,因此通信寄存器的写操作即将发生。
如果1写入此位,此后位写入都无效。
它将留在此位的位置,直到0写入此位。
一旦0写入此位,剩下的7位都可以写入通信寄存器。
AD7708芯片手册
a
FEATURES 8-/10-Channel, High Resolution ⌺ -⌬ ADCs AD7708 Has 16-Bit Resolution AD7718 Has 24-Bit Resolution Factory-Calibrated Single Conversion Cycle Setting Programmable Gain Front End Simultaneous 50 Hz and 60 Hz Rejection VREF Select™ Allows Absolute and Ratiometric Measurement Capability Operation Can Be Optimized for Analog Performance (CHOP = 0) or Channel Throughput (CHOP = 1) INTERFACE 3-Wire Serial SPITM, QSPI TM, MICROWIRETM, and DSP-Compatible Schmitt Trigger on SCLK POWER Specified for Single 3 V and 5 V Operation Normal: 1.28 mA Typ @ 3 V Power-Down: 30 A (32 kHz Crystal Running) On-Chip Functions Rail-to-Rail Input Buffer and PGA 2-Bit Digital I/O Port APPLICATIONS Industrial Process Control Instrumentation Pressure Transducers Portable Instrumentation Smart Transmitters
MSP430程序库六通过SPI操作AD7708
MSP430程序库<六>通过SPI操作AD7708AD7708是16位的Σ-Δ型AD转换芯片,在低频应用中,AD7708可以作为单电源供电的完整前端。
AD7708内部含有一个PGA(可编程增益放大器),可以完成对信号的放大;PGA范围是20-28八档可编程,当取参考电压2.5v时可以测量量程20mv到2.56v的电压。
AD7708和AD7718引脚功能完全一样,只是位数AD7718是24位的,若用7718,只需改动少部分的程序,16位的部分改成24位即可。
AD7708是通过SPI接口通信的;程序使用前一篇实现的SPI程序与AD芯片通信,可以作为SPI详细的使用示例。
硬件介绍:硬件主要是MSP430的SPI接口和AD7708芯片的说用说明。
msp430的SPI接口:支持主机模式和从机模式,且始终的极性和相位可调,在于AD 转换芯片通信的时候,需要极性一致。
有关msp430的SPI的详细介绍,参考:MSP4 30程序库<五>SPI同步串行通信。
AD7718 的外部引脚有28 个。
按性质主要分为模拟、数字两个部分。
模拟部分引脚有模拟输入、参考电压输入和模拟电源三类。
模拟输入引脚可以配置为8通道或10通道的伪差分输入,他们共同参考AINCOM端。
数字部分引脚有SPI 接口、数据就绪、通用I/O 口和数字电源四类。
SPI 接口的4 根标准信号线分别是片选信号CS 、串行时钟输入SCLK、串行数据输入DIN 和串行数据输出DOUT。
当AD7718接在SPI 总线上时是从器件,从引脚CS 输入低电平信号使能AD7718。
数据就绪RDY 是一个低电平有效的输出引脚。
当所选通道数据寄存器中有有效数据时,输出低电平信号;数据被读出后,输出高电平。
AD7718 的通用I/O 口是2 个一位口P1 和P2。
它们既可配置成输入也可配置成输出,单片机通过SPI 口读写AD7718 片内相关寄存器实现对P1 和P2 的操作。
stm32 AD7705
#ifndef __SPI1_H#define __SPI1_H#include "stm32f10x.h"#define CS_ADC_LOW() GPIO_ResetBits(GPIOA,GPIO_Pin_4) /*Ƭѡ*/#define CS_ADC_HIGH() GPIO_SetBits(GPIOA,GPIO_Pin_4)u8 SPIx_ReadWriteByte(u8 TxData);void delay_ms(u16 time);void delay_us(u16 time);void SPIx_Init(void);void AD7705_WriteByte(u8 Dst_Addr);void Init_AD7705(u8 chnanel);u16 GetData7705_CH1(void);u16 GetData7705_CH2(void);#endif /* __SPI1_H *///AD7705.C#include "AD7705.h"#include "stm32f10x.h"/*SPI1_NSS PA4 CSSPI1_SCK PA5 CLKSPI1_MISO PA6 DOUTSPI1_MOSI PA7 DINPA8 DRDY*/void SPIx_Init(void){SPI_InitTypeDef SPI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO, ENABLE );GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;// AdDrdyGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//PA8配置成上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_8);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//SPI CS DAC8554 AD7705GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_4);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ; //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);SPI_Cmd(SPI1, DISABLE); //失能SPI外设SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI设置为双线双向全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为主SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//SPI发送接收8位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//时钟悬空为高SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//数据捕获于第二个时钟沿SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//内部NSS信号有SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //波特率预分频值256SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据传输从MSB开始SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式SPI_Init(SPI1, &SPI_InitStructure); //SPI寄存器的初始化SPI_Cmd(SPI1, ENABLE); //使能SPI外设CS_ADC_LOW();SPIx_ReadWriteByte(0xff); //启动传输CS_ADC_HIGH();}//SPIx 读写一个字节//TxData:要写入的字节//返回值:读取到的字节u8 SPIx_ReadWriteByte(u8 TxData){u8 retry=0;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位{retry++;if(retry>200)return 0;}SPI_I2S_SendData(SPI1, TxData); //发送数据retry=0;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){retry++;if(retry>200)return 0;}return SPI_I2S_ReceiveData(SPI1); //返回接收到的数据}//写数据void AD7705_WriteByte(u8 Dst_Addr){CS_ADC_LOW(); //使能器件delay_us(20);SPIx_ReadWriteByte(Dst_Addr);delay_us(100);CS_ADC_HIGH();//失能}/********AD7705初始化函数***********/void Init_AD7705(u8 chnanel){u8 i;for(i=0;i<100;i++)/*多于连续32个DIN=1使串口复位*/{AD7705_WriteByte(0xff);//持续DIN高电平写操作,恢复AD7705接口}delay_ms(1);switch(chnanel){case 1:AD7705_WriteByte(0x20); /* 写通讯寄存器选中ch1*/AD7705_WriteByte(0x04);//0x04 /* 1MHz时钟,200Hz数据更新速率*/AD7705_WriteByte(0x10); /*选择设置寄存器,使用chnanel 1*/AD7705_WriteByte(0x44); //写设置寄存器,设置成单极性,无缓冲,增益为1,滤波器工作,自校准break;case 2:AD7705_WriteByte(0x21); /* 写通讯寄存器选中ch2 */AD7705_WriteByte(0x04); /* 1MHz时钟,200Hz数据更新速率*/AD7705_WriteByte(0x11); /*选择设置寄存器,使用chnane 2*/AD7705_WriteByte(0x44); //写设置寄存器,设置成单极性,无缓冲,增益为1,滤波器工作,自校准break;default:break;}}/* 读AD7705转换数据输入通道channel */u16 GetData7705_CH1(void){u16 temp1 = 0;u16 DataL = 0;u16 DataH = 0;Init_AD7705(1); //初始化通道1delay_ms(1);AD7705_WriteByte(0x38); //选中CH1数据寄存器读while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1) //等待数据准备好{}CS_ADC_LOW(); //使能器件delay_us(20);DataH = SPIx_ReadWriteByte(0xff);DataL = SPIx_ReadWriteByte(0xff);delay_us(200);CS_ADC_HIGH(); //片选取消DataH = DataH << 8;temp1 = DataH | DataL;return temp1;}/* 读AD7705转换数据输入通道channe2 */u16 GetData7705_CH2(void){u16 temp2 = 0;u16 DataL = 0;u16 DataH = 0;Init_AD7705(2); //初始化通道2delay_ms(1);AD7705_WriteByte(0x39); //选中CH2数据寄存器读while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1) //等待数据准备好{}CS_ADC_LOW(); //使能器件delay_us(20);DataH = SPIx_ReadWriteByte(0xff);DataL = SPIx_ReadWriteByte(0xff);delay_us(200);CS_ADC_HIGH(); //片选取消DataH = DataH << 8;temp2 = DataH | DataL;return temp2;}void delay_us(u16 time){u16 i=0;while(time--){i=10;while(i--);}}void delay_ms(u16 time){u16 i=0;while(time--){i=12000;while(i--);}}。
AD7708引脚
7708逻辑低输出。当有效数据存在于选择的数据寄存器中,RDY为低。这种高回 报的输出完成了数据寄存器的读操作。如果数据 没有读取,RDY将置高,以防下 次用户操作时溢出。RDY脚在一个校准周期之后返回低电平。RDY不返回高电平直 到MODE位写入允许新的转化或校准 串行数据输出的串行数据从ADC的移位寄存器的输出读入。移位寄存器输出能够 包含芯片上的数据,校准或控制寄存器。 串行数据输入的串行数据从ADC的移位寄存器的输出写入。移位寄存器的数据转 移到校准或控制寄存器依据通信寄存器的选择位。 数字电路的接地 数字供电电压, 3伏或5伏 接32KHz晶振 同上
引脚号 符号 1 2 3 4 5 6 7 8 9 10 11 12 13 AIN7 AIN8 AVDD AGND REFIN1( –) REFIN1( +) AIN1 AIN2 AI REFIN2( )/AIN10 AIN6 P2 AGND P1 RESET SCLK CS
14 15 16 17 18 19 20 21
22 23 24 25 26 27 28
RDY DOUT DIN DGND DVDD XTAL2 XTAL1
功能 模拟输入通道7。可编程增益的模拟输入,可以用来和AINCOM 一起作为伪差分投 入使用,或作为正极输入的一个完全差分输入使用,另一极AIN8。 模拟输入通 8。可编程增益的模拟输入,可以用来和AINCOM 一起作为伪差分投 入使用,或作为负极投入的一个完全差分输入使用,另一极为AIN7。 模拟电源电压 模拟接地 负参考输入。这可以是参考输入AGND和AVDD – 1V之间的任何位置 正参考输入。 REFIN ( + )可以躺在AVDD和AGND之间的任何位置。名义参考电 压[ REFIN ( + ) - REFIN ( - ) ]的2.5V的电源,但部分功能的参考范围 从1V至AVDD 。 。可编程增益的模拟输入,可以用来和AINCOM 一起作为伪差分 模拟输入通道1 投入使用,或作为正极输入的一个完全差分输入使用,另一极AIN2。 模拟输入通道2。可编程增益的模拟输入,可以用来和AINCOM 一起作为伪差分投 入使用,或作为负极投入的一个完全差分输入使用,另一极为AIN1。 模拟输入通道3 。可编程增益的模拟输入,可以用来和AINCOM 一起作为伪差分 投入使用,或作为正极输入的一个完全差分输入使用,另一极AIN4。 模拟输入通道4。可编程增益的模拟输入,可以用来和AINCOM 一起作为伪差分投 入使用,或作为负极投入的一个完全差分输入使用,另一极为AIN3。 模拟输入通道5。可编程增益的模拟输入,可以用来和AINCOM 一起作为伪差分投 入使用,或作为正极输入的一个完全差分输入使用,另一极AIN6。 所有模拟输入参考时,此输入配置伪差分输入模式 正极的参考输入/模拟输入。这种输入可配置作为和REFIN1 ( + )有同样特点 的参考输入或作为额外的模拟输入。当配置为模拟输入时,这个引脚提供一个可 编程增益的模拟输入,可以用来和AINCOM 一起作为伪差分投入使用,或作为正 极输入的一个完全差分输入使用,另一极AIN10。 负参考输入/模拟输入。此引脚可被配置作为参考或模拟输入此引脚可被配置作 为参考或模拟输入。当配置为参考输入的为REFIN2提供负参考输入。当配置为模 拟输入时,这个引脚提供一个可编程增益的模拟输入,可以用来和AINCOM 一起 作为伪差分投入使用,或作为负极输入的一个完全差分输入使用,另一极AIN9。 模拟输入通6。可编程增益的模拟输入,可以用来和AINCOM 一起作为伪差分投入 使用,或作为负极投入的一个完全差分输入使用,另一极为AIN5。 P2可作为通用输入/输出位在AVDD和AGND之间。这个引脚有一个内部弱上拉。 建议,这一针脚是直接AGND 。 同P2 数字输入用于重置的ADC的上电复位状态。这引脚有内部弱上拉至DVDD 时钟 片选
STM32单片机之ADC学习经验总结
STM32 单片机之ADC 学习经验总结
因为公司的产品上需要使用AD 来检测电池电压,要求不是很高,突然想用下DMA+ADC+TIM,以前以为很简单,实际使用中让我觉得很惭愧,
遇到的问题让我一下子蒙了,不停的查资料,不停的测试,终于一个一个的问题都解决了,同时对STM32 的ADC 有了新的认识,并且打算再闲暇时间内将STM32 的资源尽量的实践下。
我用的是STM32F4 来调试ADC3+DMA+TIM1(单通道),首先我先查看了下DMA 的资料,之后参考官方提供的ADC3+DMA 很快可以正常读取数据,之后我直接添加定时器触发AD 转换,结果失败,我开始查资料看手册,逐渐对这三者之间的关系有了一个认识
首先定时器产生触发信号,AD 检测到转换信号后开始转换,每转换一次
就通过DMA 将数据放到指定的内存地址中,直到达到DMA 设定的
DMA_BufferSize 设定值后DMA 置位相应的标志位,从而完成一次DMA 传输。
由上面的关系的可以得知ADC 转换是一次一次即单次非扫描模式(我测试的是AD 单通道),因为连续模式一旦触发就会不停的转换,这样的话定时器触发转换就失去了意义,之后DMA 设置成普通模式,即完成一次DMA 传
输后,停止传输,之后的DMA 请求不被响应,因为DMA 传输完成后以为
着可以进行数据处理了,这个时候为了防止数据被覆盖(网上还有其他方法防止数据被覆盖)。
一种基于STM32的数字多用表的设计
一种基于STM32的数字多用表的设计本项目基于STM32设计了一种高精度、误差小、使用方便的数字多用表,系統功能模块包括直流电压测量、交流电压测量、电阻测量、电流测量、A/D转换模块、STM32嵌入式系统、按键模块、LCD显示八个部分。
测试表明,系统测量值与实际值误差≤2%,电压精确到1mV,电流精确到0.1mA,可应用于对误差有一定要求场合。
标签:仪器仪表;万用表;STM32;AD7705;1 系统整体结构本数字万用表整体设计框图如图1。
直流电压测量、交流电压测量、电阻测量、电流测量四个功能模块为系统采集模块,负责采集相应的信号,采集后经过一定的信号转换电路,转换成A/D转换模块可以识别的电压值;A/D是系统的转换模块,负责将采集的数据进行AD转换,并传输到单片机;单片机是系统的数据处理和控制模块,其实现选档控制、数据处理、显示控制、AD控制等;LCD 是系统的显示模块,实现测量结果的显示。
2 硬件设计2.1 交流电压测量电路将交流信号经过不同量程的放大电路之后,送入检波电路,检波后的直流信号输入A/D芯片进行直流电压的测量,获得直流信号电压值则可计算的交流信号电压有效值,其流程图如图2:待测信号通过运算放大器(OPA2356)将被放大相应倍数,然后送入检波电路,把放大后的交流信号检波成直流信号,检波后的直流信号送入AD7705进行转换。
图中不同电阻对应不同的放大倍数,而实际的放大倍数可能会因为检波二极管的性能有所调整。
2.2电阻测量电路电阻测量电路如图4所示,待测电阻与标准精密电阻分压,检测待测电阻电压,则可根据欧姆定律计算电阻值。
图中各个开关的断开与闭合用于量程选择,而实际设计中这些开关由单片机I/O控制MOS管开关驱动代替,实现对量程的自动选择。
2.3电流测量电路INA282AIDR是一款电流检测芯片,其分压输入为-5~+18V,有单极性输出和双极性输出两种模式,电流测量电路设计如图5所示。
4.1 ad7708
采样/保持器
A/D 转换器
计 算 机
控制逻辑
图3.2(b)多路同步采集分时输入结构
二、分散(分布式)采集式
分布 式数 据采 集系
传感器 调理电路 采样/ 保持器 采样/ 保持器
. . .
计算机
A/D转换器
传感器
. . .
调理电路
. . .
A/D转换器 A/D转换器
统的
典型 结构
传感器
调理电路
采样/ 保持器
•微分线性度极好,不会有非单调性。因为积分
输出是连续的,因此,计数必然是依次进行的,
即从本质上说,不会发生丢码现象。
•积分电路为抑制噪声提供了有利条件。双积分
式ADC是测量输入电压在定时积分时间T1内的平
均值,对干扰有很强的抑制作用,尤其对正负波
形对称的干扰信号抑制效果更好。
(三) Δ-Σ型ADC
量是指电压而言的。在数字系统中,数字
量是离散的,一般用一个称为量子Q的基 本单位来度量。
输出
3Q 2Q Q
输出
3Q 2Q Q Q 2Q 3Q
0
输入
0
Q
2Q (c)
3Q
输入
(a) e Q +Q/2 0 -Q/2
输入
(d)
0
(b)
输入
图3.15 量化特性及量化误差
输出
3Q 2Q Q 0 Q
输出
3Q 2Q Q
控制逻辑
图3.3 (a) 分布式单机数据采集结构
分布式数据采集系统的典型结构
上位机 通信接口
数据 采集站1 … …
数据 采集站2 … …
数据 采集站3
……
数据 采集站N … …
野火STM32ADC(DMA模式)实验详细分析
69.* 输出 :无
70.* 调用 :内部调用
71.*/
72.static void ADC1_Mode_Config(void)
73.{
74.ADC_InitTypeDef ADC_InitStructure; //定义 ADC 结构体
75.DMA_InitTypeDef DMA_InitStructure; //定义 DMA 结构体
volatile作为指令关键字确保本条指令不会因编译器的优化而省略且要求每次直接读值
野火STM32ADC(DMA模式)实验详细分析
发现ADC(DMA模式)实验 啊,DMA 那里地方,讲解不是太详细。按照野火教程上,USART 的DMA 方式实验,没有讲。 所以还有些模糊,今天对照野火的ADC 程序,然后对照库函数,做了个详细的备注.这里只注释adc.c 函数的内容。 新手上路,喜欢搞得详细一些,分享给 和我一样的新手。 哈哈。。。
102.ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启连续转换模式,即不停地进行ADC转换
103.ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不使用外部触发启动
127.
128./* 开启 ADC校准 */
129.ADC_StartCalibration(ADC1);
130./* 等待校准完成*/
131.while(ADC_GetCalibrationStatus(ADC1));
132.
133./* 由于没有采用外部触发,所以使用软件触发ADC转换 */
Σ-Δ模数转换器AD7708输入隔离电路设计
Σ-Δ模数转换器AD7708输入隔离电路设计AD7708 是一种多通道16 位Σ-Δ模数转换器ADC。
它支持4 或5 通道真正差分输入以及8 或10 信道伪差分输入。
这种芯片允许两路信号同时转换,从而提高了多路转换应用中的吞吐率。
其片内还包括可切换的电流源、低端电源开关和一个温度传感器。
该ADC 在3V 电源供电时,在正常工作方式下,功耗电流为2mA;在待机方式下,功耗电流小于10μA。
AD7708 适合宽动态范围和低频应用的低成本、低功耗和性能完整的模拟前端解决方案,并且能对传感器的输出信号直接进行模数转换,而无需信号调理。
输入通道可以编程设置为8 档量程从20mV 到2.56V;输入信号可以被设置为缓冲方式,在缓冲方式下能消除大的源阻抗的影响并通过一个RC 滤波器对噪声进行滤波和衰减RFI;所有的输入信号都可以直接接入而不需要其他的信号放大环节进行调理,使其更适用于宽动态范围和低频信号的测量,如温度、应力、压力传感器等信号。
得益于这种新型ADC 的具体应用包括医用电子仪器、工业过程控制、便携式仪器、压力传感器、智能变送器、称重、温度测量和数据采集设备。
在实际的抗干扰应用中,合理设计前端的隔离电路具有重要应用。
AD7708 输入隔离电路设计隔离电路的设计主要出于两种考虑:第一,保护被测电路和测试电路,使其不至于因测试电路或被测电路的故障而影响整个系统的工作。
第二,减小环境噪声对测试电路的影响。
为保护后级设备、保证测量结果的有效性,测试电路与被测电路必须做到严格的电气隔离,隔离电路应具有较高的精度。
电路的成本和体积也要符合工程需要。
TI 公司的精密线性光耦TIL300 是隔离器件的新产品。
我们采用该器件和Burr-Brown 公司的高隔离DC-DC 芯片DCP0105 完成了模拟量的隔离电路。
stm32_tm7705_ad7705_AD转换程序
/*********spi_tm7705.h**************/#ifndef __SPI_TM7705_H#define __SPI_TM7705_H#include "stm32f10x.h"#include "SysTick.h"/* 片选信号,拉低为选中*/#define CS1_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_4)#define CS1_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_4)#define CS2_LOW() GPIO_ResetBits(GPIOB, GPIO_Pin_0)#define CS2_HIGH() GPIO_SetBits(GPIOB, GPIO_Pin_0)#define CS3_LOW() GPIO_ResetBits(GPIOB, GPIO_Pin_1)#define CS3_HIGH() GPIO_SetBits(GPIOB, GPIO_Pin_1)#define CS4_LOW() GPIO_ResetBits(GPIOB, GPIO_Pin_5)#define CS4_HIGH() GPIO_SetBits(GPIOB, GPIO_Pin_5)/* DRDY拉低为可以读取*/#define DRDY1_LOW() GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12) #define DRDY2_LOW() GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13) #define DRDY3_LOW() GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) #define DRDY4_LOW() GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15) void SPI_TM7705_Init(void);u8 SPI1_ReadWriteByte(u8 TxData);void TM7705_Init(void);void ReadAD(void);#endif /* __SPI_TM7705_H *//*********spi_tm7705.h**************//***********spi_tm7705.c***************//******************** ********************* 文件名:spi_tm7705.c* 描述:spi_tm7705底层应用函数库* 实验平台:* 硬件连接----------------------------** PA5-SPI1-SCK : CLK* PA6-SPI1-MISO : DOUT* PA7-SPI1-MOSI : DIN** PA4:CS1* PB0 : CS2* PB1 : CS3* PB5 : CS4** PB12 : DRDY1* PB13 : DRDY2* PB14 : DRDY3* PB15 : DRDY4* ----------------------------* 库版本:ST3.0.0***********************************************************************************/#include "spi_tm7705.h"u16 ADResult[4];//存储AD结果的数组/*******************************************************************************初始化SPI1与tm7705的接口*******************************************************************************/void SPI_TM7705_Init(void){SPI_InitTypeDef SPI_InitStructure;GPIO_InitTypeDef GPIOA_InitStructure;GPIO_InitTypeDef GPIOB_InitStructure;/* 配置外设时钟*//*!< SPI_FLASH_SPI_CS_GPIO, SPI_FLASH_SPI_MOSI_GPIO,SPI_FLASH_SPI_MISO_GPIO, SPI_FLASH_SPI_DETECT_GPIOand SPI_FLASH_SPI_SCK_GPIO Periph clock enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);/*!< Periph clock enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);/*!< AFIO Periph clock enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);/*!< Configure SCK */GPIOA_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;GPIOA_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIOA_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIOA_InitStructure);// /*!< Configure MISO */// GPIOA_InitStructure.GPIO_Pin = GPIO_Pin_6;// GPIO_Init(GPIOA, &GPIOA_InitStructure);//// /*!< Configure MOSI */// GPIOA_InitStructure.GPIO_Pin = GPIO_Pin_7;// GPIO_Init(GPIOA, &GPIOA_InitStructure);/*!< Configure CS1 */GPIOB_InitStructure.GPIO_Pin = GPIO_Pin_4 ;GPIOB_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIOB_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚速率为50MHZ GPIO_Init(GPIOA, &GPIOB_InitStructure);/*!< Configure CS2,3,4 */GPIOB_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_5;GPIOB_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIOB_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚速率为50MHZ GPIO_Init(GPIOB, &GPIOB_InitStructure);/*!< Configure DRDY1,2,3,4*/GPIOB_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIOB_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIOB_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚速率为50MHZ GPIO_Init(GPIOB, &GPIOB_InitStructure);/* 将片选信号全部拉高*/CS1_HIGH();CS2_HIGH();CS3_HIGH();CS4_HIGH();/* SPI1 configuration *///设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//设置SPI工作模式:设置为主SPISPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置SPI的数据大小:SPI发送接收8位帧构造SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//选择了串行时钟的稳态:时钟悬空高SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//数据捕获于第二个时钟沿SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//NSS信号由硬件〔NSS管脚〕还是软件〔使用SSI位〕管理:部NSS信号有SSI位控制SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//定义波特率预分频的值:波特率预分频值为256SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //flash读写中这里是4 //指定数据传输从MSB位还是LSB位开场:数据传输从MSB位开场SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//CRC值计算的多项式SPI_InitStructure.SPI_CRCPolynomial = 7;//根据SPI_InitStruct中指定的参数初始化外设SPIx存放器SPI_Init(SPI1, &SPI_InitStructure);/* Enable SPI1 */SPI_Cmd(SPI1, ENABLE); //使能SPI外设}/**************************************SPIx 读写一个字节TxData:要写入的字节返回值:读取到的字节*****************************************/u8 SPI1_ReadWriteByte(u8 TxData){while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //检查指定的SPI 标志位设置与否:发送缓存空标志位/* Send byte through the SPI1 peripheral */SPI_I2S_SendData(SPI1, TxData); //通过外设SPI1发送一个数据/* Wait to receive a byte */while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //检查指定的SPI 标志位设置与否:承受缓存非空标志/* Return the byte read from the SPI bus */return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据}/********tm7705初始化函数***********/void TM7705_Init(void){unsigned char i ;CS1_LOW();Delay_us(10);for(i = 0; i < 100; i++){SPI1_ReadWriteByte(0xFF); //持续DIN高电平写操作,恢复tm7705接口}SPI1_ReadWriteByte(0x20) ; //通道1 ,下一个写时钟存放器/********2016.1.21实地测试通过**********SPI1_ReadWriteByte(0x08) ; //写时钟存放器设置更新速率为60Hz,使用部时钟**************************************/SPI1_ReadWriteByte(0x08) ;SPI1_ReadWriteByte(0x10) ; //通道1 ,下一个写设置存放器/********2016.1.21实地测试通过**********SPI1_ReadWriteByte(0x70) ; //写设置存放器,设置成双极性、无缓冲、增益为2、滤波器不工作、自校准**************************************/SPI1_ReadWriteByte(0x70);Delay_us(10);CS1_HIGH();CS2_LOW();Delay_us(10);for(i = 0; i < 100; i++){SPI1_ReadWriteByte(0xFF); //持续DIN高电平写操作,恢复tm7705接口1415 }// SPI1_ReadWriteByte(0x20) ; //通道1 ,下一个写时钟存放器// SPI1_ReadWriteByte(0x09) ; //写时钟存放器设置更新速率为60Hz,使用部时钟// SPI1_ReadWriteByte(0x10) ; //通道1 ,下一个写设置存放器// SPI1_ReadWriteByte(0x78) ; //写设置存放器,设置成双极性、无缓冲、增益为0、滤波器不工作、自校准SPI1_ReadWriteByte(0x20) ; //通道1 ,下一个写时钟存放器SPI1_ReadWriteByte(0x08) ; //写时钟存放器设置更新速率为60Hz,使用部时钟SPI1_ReadWriteByte(0x10) ; //通道1 ,下一个写设置存放器SPI1_ReadWriteByte(0x70) ;Delay_us(10);CS2_HIGH();CS3_LOW();Delay_us(10);for(i = 0; i < 100; i++){SPI1_ReadWriteByte(0xFF); //持续DIN高电平写操作,恢复tm7705接口}SPI1_ReadWriteByte(0x20) ; //通道1 ,下一个写时钟存放器SPI1_ReadWriteByte(0x08) ; //写时钟存放器设置更新速率为60Hz,使用部时钟SPI1_ReadWriteByte(0x10) ; //通道1 ,下一个写设置存放器SPI1_ReadWriteByte(0x70) ; //写设置存放器,设置成双极性、无缓冲、增益为0、滤波器不工作、自校准Delay_us(10);CS3_HIGH();CS4_LOW();Delay_us(10);for(i = 0; i < 100; i++){SPI1_ReadWriteByte(0xFF); //持续DIN高电平写操作,恢复tm7705接口}SPI1_ReadWriteByte(0x20) ; //通道1 ,下一个写时钟存放器SPI1_ReadWriteByte(0x08) ; //写时钟存放器设置更新速率为60Hz,使用部时钟SPI1_ReadWriteByte(0x10) ; //通道1 ,下一个写设置存放器SPI1_ReadWriteByte(0x70) ; //写设置存放器,设置成双极性、无缓冲、增益为0、滤波器不工作、自校准Delay_us(10);CS4_HIGH();}/*******读数*****************/void ReadAD(void){// char DataNotReady = 0x80;char highByte;char lowByte;u16 adcValue;float adcValue1;int ret;int i=0;//TM7705_Init();Delay_us(10);//ad1while(DRDY1_LOW()==1){i+=1;Delay_ms(50);if (i>2)break;}i=0;if(DRDY1_LOW()==0){CS1_LOW();Delay_us(10);SPI1_ReadWriteByte(0x38);//mand for the m to read data register for channel 1 (dec 56)//read 16bit of data ADChighByte = SPI1_ReadWriteByte(0xFF);lowByte = SPI1_ReadWriteByte(0xFF);adcValue = highByte << 8;adcValue = adcValue | lowByte;/****2016.1.21实地测试通过*****adcValue1=(float)adcValue/65535*1.225;*ret=(int)(adcValue1*1000);*****************************/adcValue1=(float)adcValue/3;ret=(int)(adcValue1);ADResult[0]=ret;Delay_us(10);CS1_HIGH();}//ad2while(DRDY2_LOW()==1){i+=1;Delay_ms(50);if (i>2)break;}i=0;if(DRDY2_LOW()==0){CS2_LOW();Delay_us(10);SPI1_ReadWriteByte(0x38);//mand for the m to read data register for channel 1 (dec 56)//read 16bit of data ADChighByte = SPI1_ReadWriteByte(0xFF);lowByte = SPI1_ReadWriteByte(0xFF);adcValue = highByte << 8;adcValue = adcValue | lowByte;adcValue1=(float)adcValue/3;ret=(int)(adcValue1);ADResult[1]=ret;Delay_us(10);CS2_HIGH();}//ad3while(DRDY3_LOW()==1){i+=1;Delay_ms(50);if (i>2)break;}i=0;if(DRDY3_LOW()==0){CS3_LOW();Delay_us(10);SPI1_ReadWriteByte(0x38);//mand for the m to read data register for channel 1 (dec 56)//read 16bit of data ADChighByte = SPI1_ReadWriteByte(0xFF);lowByte = SPI1_ReadWriteByte(0xFF);adcValue = highByte << 8;adcValue = adcValue | lowByte;adcValue1=(float)adcValue/3;ret=(int)(adcValue1);ADResult[2]=ret;Delay_us(10);CS3_HIGH();}//ad4while(DRDY4_LOW()==1){i+=1;Delay_ms(50);if (i>2)break;}i=0;if(DRDY4_LOW()==0){CS4_LOW();Delay_us(10);SPI1_ReadWriteByte(0x38);//mand for the m to read data register for channel 1 (dec 56)//read 16bit of data ADChighByte = SPI1_ReadWriteByte(0xFF);lowByte = SPI1_ReadWriteByte(0xFF);adcValue = highByte << 8;adcValue = adcValue | lowByte;adcValue1=(float)adcValue/3;ret=(int)(adcValue1);ADResult[3]=ret;Delay_us(10);CS4_HIGH();}}/***********spi_tm7705.c***************/。
stm32AD7705
stm32AD7705#ifndef __SPI1_H#define __SPI1_H#include "stm32f10x.h"#define CS_ADC_LOW() GPIO_ResetBits(GPIOA,GPIO_Pin_4) /*??*/#define CS_ADC_HIGH() GPIO_SetBits(GPIOA,GPIO_Pin_4)u8 SPIx_ReadWriteByte(u8 TxData);void delay_ms(u16 time);void delay_us(u16 time);void SPIx_Init(void);void AD7705_WriteByte(u8 Dst_Addr);void Init_AD7705(u8 chnanel);u16 GetData7705_CH1(void);u16 GetData7705_CH2(void);#endif /* __SPI1_H *///AD7705.C#include "AD7705.h"#include "stm32f10x.h"/*SPI1_NSS PA4 CSSPI1_SCK PA5 CLKSPI1_MISO PA6 DOUTSPI1_MOSI PA7 DINPA8 DRDY*/void SPIx_Init(void){SPI_InitTypeDef SPI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO, ENABLE );GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;// AdDrdyGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//PA8配置成上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_8);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//SPI CS DAC8554 AD7705GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_4);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ; //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);SPI_Cmd(SPI1, DISABLE); //失能SPI外设SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI设置为双线双向全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为主SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//SPI发送接收8位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//时钟悬空为高SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//数据捕获于第二个时钟沿SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//内部NSS信号有SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //波特率预分频值256SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据传输从MSB开始SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式SPI_Init(SPI1, &SPI_InitStructure); //SPI寄存器的初始化SPI_Cmd(SPI1, ENABLE); //使能SPI外设CS_ADC_LOW();SPIx_ReadWriteByte(0xff); //启动传输CS_ADC_HIGH();}//SPIx 读写一个字节//TxData:要写入的字节//返回值:读取到的字节u8 SPIx_ReadWriteByte(u8 TxData){u8 retry=0;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位{retry++;if(retry>200)return 0;}SPI_I2S_SendData(SPI1, TxData); //发送数据retry=0;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){retry++;if(retry>200)return 0;}return SPI_I2S_ReceiveData(SPI1); //返回接收到的数据}//写数据void AD7705_WriteByte(u8 Dst_Addr){CS_ADC_LOW(); //使能器件delay_us(20);SPIx_ReadWriteByte(Dst_Addr);delay_us(100);CS_ADC_HIGH();//失能}/********AD7705初始化函数***********/void Init_AD7705(u8 chnanel){u8 i;for(i=0;i<100;i++)/*多于连续32个DIN=1使串口复位*/{AD7705_WriteByte(0xff);//持续DIN高电平写操作,恢复AD7705接口}delay_ms(1);switch(chnanel){case 1:AD7705_WriteByte(0x20); /* 写通讯寄存器选中ch1*/AD7705_WriteByte(0x04);//0x04 /* 1MHz时钟,200Hz数据更新速率*/AD7705_WriteByte(0x10); /*选择设置寄存器,使用chnanel 1*/AD7705_WriteByte(0x44); //写设置寄存器,设置成单极性,无缓冲,增益为1,滤波器工作,自校准break;case 2:AD7705_WriteByte(0x21); /* 写通讯寄存器选中ch2 */AD7705_WriteByte(0x04); /* 1MHz时钟,200Hz数据更新速率*/AD7705_WriteByte(0x11); /*选择设置寄存器,使用chnane 2*/ AD7705_WriteByte(0x44); //写设置寄存器,设置成单极性,无缓冲,增益为1,滤波器工作,自校准break;default:break;}}/* 读AD7705转换数据输入通道channel */u16 GetData7705_CH1(void){u16 temp1 = 0;u16 DataL = 0;u16 DataH = 0;Init_AD7705(1); //初始化通道1delay_ms(1);AD7705_WriteByte(0x38); //选中CH1数据寄存器读while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1) //等待数据准备好{}CS_ADC_LOW(); //使能器件delay_us(20);DataH = SPIx_ReadWriteByte(0xff);DataL = SPIx_ReadWriteByte(0xff);delay_us(200);CS_ADC_HIGH(); //片选取消DataH = DataH << 8;temp1 = DataH | DataL;return temp1;}/* 读AD7705转换数据输入通道channe2 */u16 GetData7705_CH2(void){u16 temp2 = 0;u16 DataL = 0;u16 DataH = 0;Init_AD7705(2); //初始化通道2delay_ms(1);AD7705_WriteByte(0x39); //选中CH2数据寄存器读while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1) //等待数据准备好{}CS_ADC_LOW(); //使能器件delay_us(20);DataH = SPIx_ReadWriteByte(0xff);DataL = SPIx_ReadWriteByte(0xff);delay_us(200);CS_ADC_HIGH(); //片选取消DataH = DataH << 8; temp2 = DataH | DataL; return temp2;}void delay_us(u16 time) {u16 i=0;while(time--){i=10;while(i--);}}void delay_ms(u16 time) {u16 i=0;while(time--){i=12000;while(i--);}}。
STM32的ADC转换最常见的方式
STM32的ADC转换最常见的方式这里的ADC转换也来使用DMA---这个也是STM32的ADC转换最常见的方式。
第一步是了解STM32的ADC对应的GPIO口如下图不用记住,可以查询,我是将它剪下来粘贴到书本的相应章节!第二步是配置相应ADC转换的GPIO口这里使用PC0--PC1static void ADC1_GPIO_Config(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //打开DMA1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 “ RCC_APB2Periph_GPIOC,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入GPIO_Init(GPIOC, &GPIO_InitStructure);}第三步是-配置ADC的DMA配置ADC通道等---#define ADC1_DR_Address ((u32)0x40012400+0x4c) //外设地址__IO uint16_t ADC_ConvertedValue[2];//内存数组staTIc void ADC1_Mode_Config(void){DMA_InitTypeDef DMA_InitStructure;ADC_InitTypeDef ADC_InitStructure;DMA_DeInit(DMA1_Channel1);//---------------ADC的DMA配置--------------------DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //ADC1地址---代表ADC1保存转换值的寄存器DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;//内存地址---用来保存DMA传输过来的ADC转换值----后面直接使用的变量地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设为数据源DMA_InitStructure.DMA_BufferSize = 2; //传输总数据---2通道需要传输2个数据DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址固定DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址自增---总体表示始终从外设ADC1地址处取值---依次保存到连续的两个内存变量中---DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_HalfWord;//外设传输数据单元---半字16位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //内存传输数据单元---半字16位DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环模式---2个数据依次循环接收从外设ADC1传输过来的ADC值---DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高优先级DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止内存传内存DMA_Init(DMA1_Channel1, &DMA_InitStructure);DMA_Cmd(DMA1_Channel1, ENABLE); //再次打开DMA1//------------ADC模式配置------------------------ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式----还有很多模式---这个比较常见ADC_InitStructure.ADC_ScanConvMode = ENABLE ; //扫描模式---采集多通道使用----本程序采集2通道---所以扫描模式ADC_InitStructure.ADC_ConTInuousConvMode = ENABLE; //连续转换模式---不难理解---就是不停地采集---一次接一次ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发转换---触发分为外部触发---比如中断与定时器。
关于STM32的ADCDAC问题集锦
关于STM32的ADC/DAC问题集锦1、STM32的DAC转换是什么开始的呢?问:STM32的DAC转换是什么开始的呢?如何利用DAC输出一个脉宽的控的单脉冲呢?答:DAC是通过写入DAC输出寄存器开始的。
另外,如果想要脉冲,使用TIM功能。
2、STM32的DAC输出电压问:DAC的输出电压是如何调节的呢,输入的数字量和输出的电压怎么不成比例呢,输出电压不符合数据手册上提供的公式(DAC输出= VREF X DOR / 4095),求高人指点,程序如下:#include "stm32f10x_lib.h"#define DAC_DHR8R1_Address 0x40007410DAC_InitTypeDef DAC_InitStructure;DMA_InitTypeDef DMA_InitStructure;ErrorStatus HSEStartUpStatus;uc8 Escalator8bit[50] = {0x0, 0x33, 0x66, 0x99, 0xcc, 0xff};void RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_Configuration(void);void Delay(vu32 nCount);int main(void){#ifdef DEBUGdebug();#endifRCC_Configuration();GPIO_Configuration();NVIC_Configuration();TIM_PrescalerConfig(TIM6, 0xF, TIM_PSCReloadMode_Update);TIM_SetAutoreload(TIM6, 0xFF);TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;DAC_Init(DAC_Channel_1, &DAC_InitStructure);DMA_DeInit(DMA2_Channel3);DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR8R1_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&Escalator8bit;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;DMA_InitStructure.DMA_BufferSize = 6;DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;DMA_InitStructure.DMA_Priority = DMA_Priority_High;DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_Init(DMA2_Channel3, &DMA_InitStructure);DMA_Cmd(DMA2_Channel3, ENABLE);DAC_Cmd(DAC_Channel_1, ENABLE);DAC_DMACmd(DAC_Channel_1, ENABLE);TIM_Cmd(TIM6, ENABLE);while (1){}}void RCC_Configuration(void){RCC_DeInit();RCC_HSEConfig(RCC_HSE_ON);HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS){FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);FLASH_SetLatency(FLASH_Latency_2);RCC_HCLKConfig(RCC_SYSCLK_Div1);RCC_PCLK2Config(RCC_HCLK_Div1);RCC_PCLK1Config(RCC_HCLK_Div2);RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);RCC_PLLCmd(ENABLE);while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);while(RCC_GetSYSCLKSource() != 0x08)}}RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);}void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);}void NVIC_Configuration(void){#ifdef VECT_TAB_RAMNVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);#else /* VECT_TAB_FLASH */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);#endif}void Delay(vu32 nCount){for(; nCount != 0; nCount--);}输出电压为什么不是0~3.3V呢?答1:(u32)&Escalator8bit;你把这个里面的数据强制转换为32位,也就是0x0, 0x33, 0x66, 0x99转换为一个32位的数据,你这样做是不对的。
ad7708源程序代码解析
ad7708源程序代码解析#include "ad7708.h" #include "ucos_ii.h" void Delay_10nop( void { __nop(; __nop(; __nop(; __nop(; __nop(; __nop(; __nop(; __nop(; __nop(; __nop(; } /****************【ADC SPI接口控制】*****************/ u8 AD7708_SPI_RW8(u8 din //SPI读写数据-8bit { u8 i,dout = 0; for(i=0; i<8; i++ { AD7708_CLK_Reset(; Delay_10nop(;if(din & 0x80 //MSB output first { AD7708_MOSI_Set(; } else { AD7708_MOSI_Reset(; } din <<= 1; Delay_10nop(; dout = (dout << 1 |AD7708_MISO(; //read spi data-MSB input first AD7708_CLK_Set(; Delay_10nop(; } return dout; } u16 AD7708_SPI_RW16(u16 din //SPI读写数据-16bit { u16 dout = 0; u8 i; for(i=0; i<16; i++ { AD7708_CLK_Reset(; Delay_10nop(; if(din & 0x8000 //MSB output first { AD7708_MOSI_Set(; } else { AD7708_MOSI_Reset(; } din <<= 1;Delay_10nop(; dout = (dout << 1 | AD7708_MISO(; //read spi data-MSB input firstAD7708_CLK_Set(; Delay_10nop(; } return dout; } /*************【AD7708读准备好位,软判断】**************/ //u8 AD7708_Ready(void //{ // u8 ready; // // ready = AD7708_RW(ADC_R, ADC_rSTATUS, 0, 0, DAT_8b; // return ready & 0x80; //}/*******************【AD7708初始化】********************/ voidAD7708_Init(void //AD7708初始化 { vu8 ID = 0; vu16 uu = 0;OSTimeDlyHMSM(0,0,0,500; //AD7708上电后要等300ms才能稳定晶振 //ResetAD7708 AD7708_RST_Reset(; OSTimeDlyHMSM(0,0,0,10;AD7708_RST_Set(; OSTimeDlyHMSM(0,0,0,10; //Set ADC's SCLK and CS //AD7708_CS_Set(;AD7708_CLK_Set(; AD7708_RW(ADC_W, ADC_rFILTER, 0xff, 0, DAT_8b; //set filter register,设置转换频率为 5.35hz,周期为186.77ms AD7708_RW(ADC_W,ADC_rCONTROL, 0x0F, 0, DAT_8b;//配置ADC control register 为单极输入,输入范围为 2.56 AD7708_RW(ADC_W, ADC_rMODE, 0x12, 0, DAT_8b; //禁止chop,单通道转换模式,不是连续转化模式AD7708_RW(ADC_W, ADC_rIOCON, 0x30, 0, DAT_8b; //set IO control register ID = AD7708_RW(ADC_R, ADC_rID, 0, 0, DAT_8b; //AD7708读ID Start_ADC_Convert(0, 7; //启动AD通道0转换,以便在200毫秒时读出数据} /*******************【AD7708读写控制】******************/ //rw: 0-write 1-read //AD7708读写控制 //type: 0-u8 rw 1-u16 rw u16 AD7708_RW(u8 rw, u8addr, u8 d8, u16 d16, u8 type { u16 data = 0; //AD7708_CS_Clear(;AD7708_SPI_RW8(addr | (rw<<6; if(!type data = AD7708_SPI_RW8(d8; else data =AD7708_SPI_RW16(d16; //AD7708_CS_Set(; return data; } /*******************【AD7708启动ADC转换】***************/ //AD7708启动ADC转换//u8 ChIndex[10] = {0xF8, 0xE8, 0x48, 0x38, 0x08, 0x28, 0x18, 0x78, 0x68, 0x58};//根据电路板来调整 //AD Channel No. 10 9 5 4 1 3 2 8 76 u8 ChIndex[10] = {0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0xE8, 0xF8}; //根据电路板来调整 // 1 2 3 4 5 6789 10 void Start_ADC_Convert(u8 ch, u8 range //启动ADC转换 { u8 regdata = 0; ch = (ch < 10 ? ch : 0; //ch在0~9之间regdata = ChIndex[ch] | (range & 0x07; //配置ADC control register为单极输入,输入范围为2.56 //AD7708_RW(ADC_W, ADC_rFILTER, 0xff, 0, DAT_8b;AD7708_RW(ADC_W, ADC_rCONTROL, regdata, 0, DAT_8b;AD7708_RW(ADC_W, ADC_rMODE, 0x12, 0, DAT_8b; //模式寄存器设置,使能CHOP,设置AINCOM无缓冲器的,选择REFIN1为参考,选择10通道 } u16 Read_ADC_Result(u8 next_ch //读取ADC 转换结果 { u8 k = 0; u16 result = 0;while(AD7708_Ready( //硬件的接口是低电平时有效,但是寄存器是高为有效{ AD7708_RW(ADC_W, ADC_rIOCON, 0x31, 0, DAT_8b; //set IO control register OSTimeDlyHMSM(0,0,0,200; while(AD7708_Ready( { AD7708_Init(; //出现故障break; } break; } result = AD7708_RW(ADC_R, ADC_rDATA, 0, 0, DAT_16b;Start_ADC_Convert(next_ch, 7; //选择ADC输入范围为2.56 k =AD7708_RW(ADC_R, ADC_rIOCON, 0x31, 0, DAT_8b; //set IO control registerAD7708_RW(ADC_W, ADC_rIOCON, k^0x01, 0, DAT_8b; //set IO control register return result; }。
STM32用IO口驱动8位2.4TFT
Stm32 用IO口驱动8位液晶程序#include "stm32f10x.h"#include "ILI9320.h"int main(void){SystemInit();GPIO_Config();ILI9325_Initial(); //初始化LCD//delayms(100);//绘制矩形平面// Show_RGB(0,120,0,64,Blue2);// Show_RGB(120,240,0,64,Black);// Show_RGB(0,120,64,128,White);// Show_RGB(120,240,64,128,Blue);// Show_RGB(0,120,128,192,Red);// Show_RGB(120,240,128,192,Magenta);// Show_RGB(0,120,192,256,Green);// Show_RGB(120,240,192,256,Cyan);// Show_RGB(0,120,256,320,Yellow);// Show_RGB(120,240,256,320,Red);//// LCD_PutString(0,0,"专业电子论坛",White,Blue2); // LCD_PutString(0,16,"",White,Blue2); // LCD_PutString(0,32,"专业开发板",White,Blue2);// LCD_PutString(0,48,"浩豚电子科技",White,Blue2);while(1){CLR_Screen(Red); //用背景色清屏CLR_Screen(Yellow);CLR_Screen(Green);}}/*----------------------------------------------------------------320x240彩屏液晶驱动程序----------------------------------------------------------------*/#include"ILI9320.h"#include"stm32f10x.h"void GPIO_Config(){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(LCD_GPIO_DATA_CLK|RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin=LCD_GPIO_DATA_PIN;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(LCD_GPIO_DATA_PORT ,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4 ;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);}/*----------------------------------------------------------------清屏函数输入参数:bColor 清屏所使用的背景色----------------------------------------------------------------*/void CLR_Screen(unsigned int bColor){unsigned int i,j;LCD_SetPos(0,239,0,319);//320x240for (i=0;i<320;i++){for (j=0;j<240;j++)Write_Data_U16(bColor);}}/*----------------------------------------------------------------显示英文字符输入参数:x 横坐标y 纵坐标c 需要显示的字符fColor 字符颜色bColor 字符背景颜色----------------------------------------------------------------*//*#include "8X16.h"void LCD_PutChar8x16(unsigned short x, unsigned short y, char c, unsigned int fColor, unsigned int bColor){unsigned int i,j;LCD_SetPos(x,x+8-1,y,y+16-1);for(i=0; i<16;i++) {unsigned char m=Font8x16[c*16+i];for(j=0;j<8;j++) {if((m&0x80)==0x80) {Write_Data_U16(fColor);}else {Write_Data_U16(bColor);}m<<=1;}}}*//*----------------------------------------------------------------显示英文字符输入参数:x 横坐标y 纵坐标c 需要显示的字符fColor 字符颜色bColor 字符背景颜色----------------------------------------------------------------*//*void LCD_PutChar(unsigned short x, unsigned short y, char c, unsigned int fColor, unsigned int bColor) {LCD_PutChar8x16( x, y, c, fColor, bColor );} *//*----------------------------------------------------------------显示汉字输入参数:x 横坐标y 纵坐标c 需要显示的汉字码fColor 字符颜色bColor 字符背景颜色----------------------------------------------------------------*//*#include "GB1616.h" //16*16汉字字模void PutGB1616(unsigned short x, unsigned short y, unsigned char c[2], unsigned int fColor,unsigned int bColor){unsigned int i,j,k;LCD_SetPos(x, x+16-1,y, y+16-1);for (k=0;k<64;k++) { //64标示自建汉字库中的个数,循环查询内码if ((codeGB_16[k].Index[0]==c[0])&&(codeGB_16[k].Index[1]==c[1])){for(i=0;i<32;i++) {unsigned short m=codeGB_16[k].Msk[i];for(j=0;j<8;j++) {if((m&0x80)==0x80) {Write_Data_U16(fColor);}else {Write_Data_U16(bColor);}m<<=1;}}}}} *//*----------------------------------------------------------------显示字符串可以中英文同时显示输入参数:x 横坐标y 纵坐标*s 需要显示的字符串fColor 字符颜色bColor 字符背景颜色----------------------------------------------------------------*//*void LCD_PutString(unsigned short x, unsigned short y, char *s, unsigned int fColor, unsigned int bColor){unsigned char l=0;while(*s) {if( *s < 0x80){LCD_PutChar(x+l*8,y,*s,fColor,bColor);s++;l++;}else{PutGB1616(x+l*8,y,(unsigned char*)s,fColor,bColor);s+=2;l+=2;}}}*//*----------------------------------------------------------------显示RGB颜色输入参数:x0,y0 起始坐标x1,y1 结束坐标Color 背景颜色----------------------------------------------------------------*//*void Show_RGB (unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1,unsigned int Color){unsigned int i,j;LCD_SetPos(x0,x1,y0,y1);//坐标for (i=y0;i<=y1;i++) //有两个for{for (j=x0;j<=x1;j++)Write_Data_U16(Color);//写颜色}}*//*----------------------------------------------------------------显示图片图片必须是320x240,否则不能正确识别----------------------------------------------------------------*//*void show_photo(void){unsigned char j;unsigned int i;unsigned long s=0;LCD_SetPos(0,240,0,320);//320x240for (i=0;i<75;i++){for (j=0;j<240;j++)Write_Data(0xff,0xff);}for (i=0;i<170;i++){for (j=0;j<55;j++)Write_Data(0xff,0xff);for (j=0;j<130;j++)Write_Data(pic[s++],pic[s++]);for (j=0;j<55;j++)Write_Data(0xff,0xff);}for (i=0;i<75;i++){for (j=0;j<240;j++)Write_Data(0xff,0xff);}}*//*----------------------------------------------------------------写命令、写数据输入参数:x 需要输入的命令16位y 需要输入的数据16位----------------------------------------------------------------*/ void Write_Cmd_Data (unsigned char x,unsigned int y) {Write_Cmd(x);//八位的命令Write_Data_U16(y);}/*----------------------------------------------------------------写16位数据----------------------------------------------------------------*/void Write_Data_U16(unsigned int y){unsigned char m,n;m=y>>8;n=y;Write_Data(m,n);}/*------------------------------------------------------------------------------ 写16位命令---------------------------------------------------------------------------------*/ void Write_Cmd(unsigned int y){unsigned char m,n;m=y>>8;n=y;Write_Cmd1(m,n);}/*----------------------------------------------------------------写命令(双八位)----------------------------------------------------------------*/void Write_Cmd1(unsigned char DH,unsigned char DL){LCD_CS_CLR;LCD_RS_CLR;LCD_RD_SET;LCD_RW_CLR;WriteData(DH);LCD_RW_SET;LCD_CS_SET;LCD_CS_CLR;LCD_RS_CLR;LCD_RD_SET;LCD_RW_CLR;WriteData(DL);LCD_RW_SET;LCD_CS_SET;}/*----------------------------------------------------------------写数据双8位----------------------------------------------------------------*/void Write_Data(unsigned char DH,unsigned char DL){LCD_CS_CLR;LCD_RS_SET;LCD_RW_CLR;LCD_RD_SET;WriteData(DH);LCD_CS_CLR;LCD_RW_SET;LCD_CS_CLR;LCD_RS_SET;LCD_RW_CLR;LCD_RD_SET;WriteData(DL);LCD_RW_SET;LCD_CS_SET;}/*----------------------------------------------------------------延时函数----------------------------------------------------------------*/void delay_us(int time) //延时微秒级函数{do{time--;}while(time>1);}void delayms(uint time) //延时毫秒级函数{while(time!=0){delay_us(1000); time--;}}/*----------------------------------------------------------------液晶初始化----------------------------------------------------------------*/void ILI9325_Initial(void){LCD_RS_SET;LCD_RW_SET;LCD_CS_SET;LCD_RES_SET;delayms(1);LCD_RES_CLR;delayms(10);LCD_RES_SET;delayms(50);Write_Cmd_Data(0x00E5, 0x8000); // Set internal timingWrite_Cmd_Data(0x0000, 0x0001); // 启动振荡Write_Cmd_Data(0x002b, 0x0010); // Set internal timingWrite_Cmd_Data(0x0001,0x0100);Write_Cmd_Data(0x0002,0x0700);Write_Cmd_Data(0x0003,0x1030);Write_Cmd_Data(0x0004,0x0000);Write_Cmd_Data(0x0008,0x0207);Write_Cmd_Data(0x0009,0x0000);Write_Cmd_Data(0x000A,0x0000);Write_Cmd_Data(0x000C,0x0000);Write_Cmd_Data(0x000D,0x0000);Write_Cmd_Data(0x000F,0x0000);//power on sequence VGHVGLWrite_Cmd_Data(0x0010,0x0000);Write_Cmd_Data(0x0011,0x0007);Write_Cmd_Data(0x0012,0x0000);Write_Cmd_Data(0x0013,0x0000);//vghWrite_Cmd_Data(0x0010,0x1290);Write_Cmd_Data(0x0011,0x0227);delayms(100);//vregioutWrite_Cmd_Data(0x0012,0x001d); //0x001b delayms(100);//vom amplitudeWrite_Cmd_Data(0x0013,0x1500); delayms(100);//vom HWrite_Cmd_Data(0x0029,0x0018);Write_Cmd_Data(0x002B,0x000D);//gammaWrite_Cmd_Data(0x0030,0x0004);Write_Cmd_Data(0x0031,0x0307);Write_Cmd_Data(0x0032,0x0002);// 0006 Write_Cmd_Data(0x0035,0x0206);Write_Cmd_Data(0x0036,0x0408);Write_Cmd_Data(0x0037,0x0507);Write_Cmd_Data(0x0038,0x0204);//0200 Write_Cmd_Data(0x0039,0x0707);Write_Cmd_Data(0x003C,0x0405);// 0504 Write_Cmd_Data(0x003D,0x0F02);//ramWrite_Cmd_Data(0x0050,0x0000);Write_Cmd_Data(0x0051,0x00EF);Write_Cmd_Data(0x0052,0x0000);Write_Cmd_Data(0x0053,0x013F);Write_Cmd_Data(0x0060,0xA700);Write_Cmd_Data(0x0061,0x0001);Write_Cmd_Data(0x006A,0x0000);//Write_Cmd_Data(0x0080,0x0000);Write_Cmd_Data(0x0081,0x0000);Write_Cmd_Data(0x0082,0x0000);Write_Cmd_Data(0x0083,0x0000);Write_Cmd_Data(0x0084,0x0000);Write_Cmd_Data(0x0085,0x0000);//Write_Cmd_Data(0x0090,0x0010);Write_Cmd_Data(0x0092,0x0600);Write_Cmd_Data(0x0093,0x0003);Write_Cmd_Data(0x0095,0x0110);Write_Cmd_Data(0x0097,0x0000);Write_Cmd_Data(0x0098,0x0000);Write_Cmd_Data(0x0007,0x0133);Write_Cmd_Data(0x0000,0x0022);//}/*----------------------------------------------------------------画点输入参数:x,y 需要画点坐标color 点的颜色----------------------------------------------------------------*//*void Put_pixel(uchar x,uchar y,unsigned int color){LCD_SetPos(x,x,y,y);Write_Data_U16(color);}*//*----------------------------------------------------------------设置坐标----------------------------------------------------------------*/static void LCD_SetPos(unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1) {Write_Cmd_Data(WINDOW_XADDR_START,x0);Write_Cmd_Data(WINDOW_XADDR_END,x1);Write_Cmd_Data(WINDOW_Y ADDR_START,y0);Write_Cmd_Data(WINDOW_Y ADDR_END,y1);Write_Cmd_Data(GRAM_XADDR,x0);Write_Cmd_Data(GRAM_Y ADDR,y0);Write_Cmd (0x0022);//LCD_WriteCMD(GRAMWR);}/*----------------------------------------------------------------在屏幕上画线输入参数:起始坐标X0,Y0,终止坐标X1,Y1color 线颜色----------------------------------------------------------------*//*void Line( uchar X0,uchar Y0,uchar X1,uchar Y1,unsigned int color){int dx = X1 - X0;int dy = Y1 - Y0;int P = 2 * dy - dx;int dobDy = 2 * dy;int dobD = 2 * (dy - dx);int PointX = 0,PointY = 0;int incx = 0,incy = 0;int distance = 0,xerr = 0,yerr = 0;unsigned int i = 0;if(dx == 0) //k=1斜率为1{PointX = X0;if(Y0 < Y1){PointY = Y0;}else{PointY = Y1;}for(i = 0;i <= ((Y0<Y1) ? (Y1-Y0) : (Y0-Y1));i++) {Put_pixel(PointX,PointY,color);PointY++;}return;}if(dy == 0) //k=0斜率为0{PointY = Y0;if(X0 < X1){PointX = X0;}else{PointX = X1;}for(i = 0;i <= ((X0<X1) ? (X1-X0) : (X0-X1));i++) {Put_pixel(PointX,PointY,color);PointX++;}return;}if(dx > 0)incx = 1;else if(dx == 0)incx = 0;elseincx = -1;if(dy > 0)incy = 1;else if(dy == 0)incy = 0;elseincy = -1;dx = ((X0>X1) ? (X0-X1) : (X1-X0));dy = ((Y0>Y1) ? (Y0-Y1) : (Y1-Y0));if(dx>dy) distance=dx;else distance=dy;PointX = X0;PointY = Y0;for(i=0;i<=distance+1;i++){Put_pixel(PointX,PointY,color);xerr+=dx;yerr+=dy;if(xerr>distance){xerr-=distance;PointX+=incx;}if(yerr>distance){yerr-=distance;PointY+=incy;}}}*//*---------------------------------------------------------------------------绘制矩形框输入参数:矩形的起始位置left,top矩形的结束位置right,bottom矩形框的颜色color-----------------------------------------------------------------------------*/ /*void Rectangle( uchar left,uchar top,uchar right,uchar bottom,unsigned int color){Line(left,top,right,top,color);Line(left,top,left,bottom,color);Line(right,top,right,bottom,color);Line(left,bottom,right,bottom,color);}*//*---------------------------------------------------------------------------绘制平面矩形输入参数:矩形的起始位置left,top矩形的结束位置right,bottom矩形框的颜色color-----------------------------------------------------------------------------*/ /*void Bar( uchar left,uchar top,uchar right,uchar bottom,unsigned int color){uchar i = 0,k = 0;for(k = top;k < bottom;k++){for(i = left+1;i <= right;i++){LCD_SetPos(i,i,k,k);Write_Data_U16(color);}}}*//*---------------------------------------------------------------------------向LCD发送一个0--255的数值-----------------------------------------------------------------------------*/ /*void LCDShow_uCharNumber( uchar x,uchar y,uchar uCharNumber,unsigned int forecolor,unsigned int bkcolor){LCD_PutChar(x,y,uCharNumber/100+'0',forecolor,bkcolor);LCD_PutChar(x+8,y,uCharNumber/10%10+'0',forecolor,bkcolor);LCD_PutChar(x+16,y,uCharNumber%10+'0',forecolor,bkcolor); }*/。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//ad7708.h#ifndef __AD7708_H#define __AD7708_Hvoid AD7708Init(char chop);long AD7708ReadResultData();void AD7708WriteRegister(char addr,long dat);long AD7708ReadRegister(char addr);void AD7708Start(char channel);#endif /* __AD7708_H *///ad7708.c/*----------------------------------------------------------------* Copyright (C) 2011 江苏大学电气学院416 刘中原* 版权所有。
** 文件名:AD7708.c** 文件功能描述:* MSP430F16x,MSP430F14X系列单片机外部AD操作函数* 说明:这个程序库完成通过之前实现的SPI程序完成与AD7708的通* 信,控制AD7708进行校正、AD转换等。
** 功能用方法:把AD7708.c加入到项目,同时在要调用此* 程序库的程序文件中加入包含AD7708.h的语句;这样即可正* 常使用头文件中声明的程序了;详细可参考本工程和* main.c** AD7708 寄存器选择* A3 A2 A1 A0 所选寄存器* 0 0 0 0 写操作,通信寄存器* 0 0 0 0 读操作,状态寄存器* 0 0 0 1 模式寄存器* 0 0 1 0 ADC控制寄存器* 0 0 1 1 滤波寄存器* 0 1 0 0 ADC数据寄存器* 0 1 0 1 ADC偏移寄存器* 0 1 1 0 ADC增益寄存器* 0 1 1 1 I/O控制寄存器* 1 0 0 0 未定义* 1 0 0 1 未定义* 1 0 1 0 未定义* 1 0 1 1 未定义* 1 1 0 0 测试寄存器* 1 1 0 1 测试寄存器* 1 1 1 0 未定义* 1 1 1 1 ID寄存器** 若要用于AD7718,电路可以完全不变,程序把16位读取改为* 24位的即可。
** 创建标识:刘中原20110814** 修改标识:* 修改描述:**----------------------------------------------------------------*/#include "msp430x16x.h" //430寄存器头文件#include "AD7708.h" //ad7708操作头文件,即声明本文件的有用函数#include "Spi.h" //SPI通讯程序库头文件char IsLong[16] = {0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0};char mode,adccon;/**************************************************************************** * 名称:AD7708WriteRegister* 功能:向AD7708寄存器写入* 入口参数:* addr:内部寄存器地址* dat: 要写入的数据* 出口参数:无****************************************************************************/ void AD7708WriteRegister(char addr,long dat){SpiWriteData(addr); //写通信寄存器,通知下个操作:写addr寄存器if(IsLong[addr]) //如果是16位寄存器, 7718则24位若移植要改if内语句{SpiWriteData(dat>>8);}SpiWriteData(0xFF&dat); //写入低位数据}/**************************************************************************** * 名称:AD7708ReadRegister* 功能:从某内部寄存器读出数据* 入口参数:addr:内部寄存器地址* 出口参数:long,读出的数据****************************************************************************/ long AD7708ReadRegister(char addr){char h = 0,l = 0; //高低字节数据SpiWriteData(0x40|addr); //写通信寄存器,通知下个操作:读addr寄存器if(IsLong[addr]){h = SpiWriteData(0xFF);}l = SpiWriteData(0xFF);return ((unsigned int)h<<8)|l;}/**************************************************************************** * 名称:AD7708ReadResultData* 功能:读取转换结果* 入口参数:无* 出口参数:AD采样结果* 说明: AD7708:16位数据;若移植到7718,则是24位数据,需更改多读取一个字节****************************************************************************/ long AD7708ReadResultData(){while((AD7708ReadRegister(0x00)&0x80)==0); //等待转换完成return AD7708ReadRegister(0x04);}/**************************************************************************** * 名称:AD7708Cal* 功能:校准AD7708* 入口参数:channel:要校准的通道;* 出口参数:无* 说明: 完成AD7708的校正工作,此为内部校准,不需接入对应电平;此处不能完* 成系统校准,如需要,可以自行添加。
****************************************************************************/ void AD7708Cal(char channel){adccon = (adccon&0x0f)|(channel<<4);mode = (mode&0xf8)|0x04; //内部0校准AD7708WriteRegister(0x02,adccon); //ADC控制寄存器,channel通道AD7708WriteRegister(0x01,mode); //模式寄存器while((AD7708ReadRegister(0x01)&0x07)!=0x01); //等待校准完成mode = (mode&0xf8)|0x05; //内部满标度校准AD7708WriteRegister(0x01,mode); //模式寄存器while((AD7708ReadRegister(0x01)&0x07)!=0x01); //等待校准完成}/**************************************************************************** * 名称:AD7708Init* 功能:初始化AD7708* 入口参数:chop:斩波允许标志为1,斩波允许,0则不允许* 出口参数:无* 说明: 完成AD7708的初始化工作****************************************************************************/ void AD7708Init(char chop){P3DIR|=BIT0;P3OUT&=~BIT0; //CS选中//主机模式,115200,8位数据位,三线模式,时钟模式1(具体见spi.c)SpiMasterInit(115200,8,3,1); //时钟不是准确的115200(具体见spi.c)_EINT(); //开中断,spi读写程序要需要中断char filter;adccon = 0x0f;if(chop == 0){filter = 0x03; //滤波寄存器设为最小值,可以更改mode = 0x91; //斩波禁止,10通道,无缓冲,空闲模式}else{filter = 0x0D; //滤波寄存器设为最小值,可以更改mode = 0x11; //斩波启用,10通道,无缓冲,空闲模式}AD7708WriteRegister(0x07,0x00); //IO寄存器,不用==AD7708WriteRegister(0x03,filter); //滤波寄存器AD7708WriteRegister(0x02,0x0F); //ADC控制寄存器,0通道,单极性AD7708WriteRegister(0x01,mode); //模式寄存器if(chop == 0)for(int i = 0; i<5;i++){//校准,因只有5个失调寄存器,多的就会覆盖之前的,只校准5个即可AD7708Cal(5);}_DINT();}/**************************************************************************** * 名称:AD7708Start* 功能:AD7708单次转换开始* 入口参数:channel:通道* 出口参数:无* 说明: 单次转换****************************************************************************/ void AD7708Start(char channel){adccon = (adccon&0x0f)|(channel<<4);mode = (mode&0xf8)|0x02;AD7708WriteRegister(0x02,adccon);AD7708WriteRegister(0x01,mode);}。