ADS1251无法采集数据
用ATMEGA128单片机驱动ADS1251AD转换芯片,ADS1251个引脚的连接:CLK与外部8MHz有源晶振连接,提供芯片工作时钟。SCLK与单片机的PB4相连接,PB4对应单片机引脚功能为8位定时器输出,使用CTC模式产生19.819KHz的数据输出时钟。DOUT引脚与单片机的PA0(普通I/O)连接。通过USART把AD转换数据发送给上位机。具体程序如下所示:
# include "iom128v.h"
#include <macros.h>
#include <stdio.h>
#include <delay.h>
#define f_count 185 //OCR0的值,即计数器的top值
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
uchar data_temp1=0,
data_temp2=0,
data_temp3=0; //定义AD数据接收寄存器
//-----------------------------------------------------------
#define CPU_fosc 7372800 // 单片机晶振7.3728MHz
#define baud 9600 //串口波特率9600
#define baud_set (uint)((ulong)CPU_fosc/(16*(ulong)baud)-1)
//--------------------------串口初始化------------------------
void USART_Init (uint data)
{
UBRR1H = (uchar) (data>>8); //波特率高位设置
UBRR1L = (uchar) (data) ; //波特率低位设置
UCSR1B = (1<<TXEN1) | (1<<RXEN1); //串口输出和输入使能
UCSR1C = 3<<UCSZ10; //设置帧格式:8个数据位,2个停止位
}
extern int _textmode;
//***********************************************************************
// 用于输出的标准格式函数,用printf输出到UART1
//***********************************************************************
int putchar(char c)
{
if (_textmode && c == '\n')
putchar('\r');
while ( !(UCSR1A & (1<<UDRE1)) ) // UDRE, data register empty
;
UDR1 = c;
return c;
}
//发送一个字节
void USART_Tran_bit(uchar data)
{
while(!(UCSR1A&(1<<UDRE1)));
UDR1=data;
}
//发送字符串
void USART_Tran_float(uchar *pstr)
{
while(*pstr)
{
USART_Tran_bit(*pstr);
pstr++;
}
USART_Tran_bit(0x0a); //回车换行
}
//--------------------------接收数据-----------------------
uchar USART_Receive(void)
{
while (! (UCSR1A & (1<<RXC1))) //等待接受数据
;
return UDR1; //从缓存器中获取并返回数据
}
/*
CTC模式频率:foc=fclk/(2*N*(1+OCR0)),
foc=7.3728MHz/(2*1*186)=19.819KHz.
*/
void CTC_Init()
{
DDRB= 1<<PB4; //定义PB4引脚为输出
PORTB &= ~BIT(4) ; //初始化PB4输出“0”
// TCCR0=0x19; //配置T/C的工作模式为CTC模式
TCCR0=0x00; //关闭定时器0
OCR0=f_count; //设置的TOP值
TIMSK=0x02; //输出比较匹配中断使能
TIFR=0x02; //清空中断标志位
}
//中断程序
#pragma interrupt_handler TIMER0_ISR:16
void TIMER0_ISR()
{
OCR0=f_count; //改变OCR0的值可以改变输出频率
TIFR |= 0x02; //写"1"到TIFR的TOV0位清除溢出标志位TOV0
}
//-------------------------AD转换程序-----------------------
void AD_Conver(void)
{
uchar i;
//-----AD初始化过程
DDRB =1<<PB4; //定义PB4引脚为输出
PORTB |= BIT(4); //PB4引脚输出高电平
delay_nms(3);
PORTB &= ~BIT(4); //PB4输出为低电平
DDRA = 0xfe; //定义PA0引脚为输入
PORTA = 1<<PA0;//PA0输入带上拉电阻
while((PINA&0x01)==0x00); //等待DOUT引脚拉低
//-------AD数据接收
while(!(PINA&0x01)); //等待DOUT拉高
delay_10us();
delay_10us();
delay_10us();//延时30usDRDY mode
// DDRA =0xfe; //定义PA0为输入
while(PINA&0x01);//等待进入DOUT模式
for(i=0;i<8;i++)
{
TCCR0=0x19; //开启定时器0的CTC模式
if(PINA&0x01)
data_temp3 |= 0x01; //检测接收到的数据是否为"1"
data_temp3 <<1; //将数据左移一位
if(i==7)
TCCR0=0x00; //关闭定时器0
}
for(i=0;i<8;i++)
{
TCCR0=0x19; //开启定时器0的CTC模式
if(PINA&0x01)
data_temp2 |= 0x01; //检测接收到的数据是否为"1"
data_temp2 <<1; //将数据左移一位
if(i==7)
TCCR0=0x00; //关闭定时器0
}
for(i=0;i<8;i++)
{
TCCR0=0x19; //开启定时器0的CTC模式
if(PINA&0x01)
data_temp1 |= 0x01; //检测接收到的数据是否为"1"
data_temp1 <<1; //将数据左移一位
if(i==7)
TCCR0=0x00; //关闭定时器0
}
}
void main(void)
{
CTC_Init(); //CTC模式初始化
SREG|=0x80; //开启总中断
USART_Init(baud_set);//串口初始化
// TCCR0=0x19; //开启定时器0的CTC模式
while(1)
{
AD_Conver(); //调用函数采集当前转换数据
delay_nms(100);
USART_Tran_bit(data_temp1);
USART_Tran_bit(data_temp2);
USART_Tran_bit(data_temp3);
}
}
将本程序下载到单片机中后测试clk引脚有精准的8MHz时钟输出,用示波器测量DOUT引脚的波形,呈现的波形大致显示:266.8KHz频率很不稳定,
能帮我看看这是哪的问题吗?
DOUT 是数据通信接口, 波形代表了数据, 不同的数据自然波形不同.
我看你得先研究一下 SPI 通信时序, 并不复杂
SPI时序也看过,SPI时钟配置中时钟频率应该如何设置,设置成8MHz相应的DATA OUT Rate 20.38KHz呢,还是有一定的配置方法!您有调试成功的程序吗?可以发我一份吗,我的QQ邮箱1838224421@qq.com
8tDADY = 384 * clk,DADY mode = 36 * clk,在计算个模式的时间时,clk时钟应该采用本设计中的8MHz外部时钟呢还是8MHz时钟经过6分频之后的modulator frequency 的1.333MHz时钟呢!