新手入门
积分 17
金钱 17
注册时间 2022-3-14
在线时间 3 小时
7 金钱
异常现象是无法实现通信,也读不到adc的硬件信息,而且只要一连DRDY引脚,程序就会变得非常缓慢,lcd显示电压的速度变得很慢,led也不闪烁而是常量。(啊啊啊啊吖,麻了)
这是我的源代码
#include "stm32f10x.h"
#include "R_LED.h"
#include "delay.h"
#include "adc.h"
#include "lcd.h"
#include "usart.h"
#include "sys.h"
#include "ADS1256.h"
int main()
{
int32_t iTemp;
float fTemp;
float temp;
u16 ADCx;
LED_GPIO_CONFIG();
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200);
LCD_Init();
Adc_Init();
POINT_COLOR=BLUE;
LCD_ShowString(60,130,200,16,16,"ADC_CH0_VAL:");
LCD_ShowString(60,150,200,16,16,"ADC_CH0_VOL:");
POINT_COLOR=GREEN;
delay_ms(500);
SPI2_Init();
#if 1
{
uint8_t id;
id = ADS1256_ReadChipID();
if (id != 3)
{
printf("Error, ASD1256 Chip ID = 0x%X\r\n", id);
}
else
{
printf("Ok, ASD1256 Chip ID = 0x%X\r\n", id);
}
}
#endif
ADS1256_CfgADC(ADS1256_GAIN_1, ADS1256_30SPS);
ADS1256_StartScan(0);
while(1)
{
ADCx=Get_Adc_Average(ADC_Channel_1,10);
LCD_ShowxNum(156,130,ADCx,4,24,0);
temp=(float)ADCx*(3.3/4096);
ADCx=temp;
LCD_ShowxNum(156,150,temp,1,24,0);//显示电压值
temp-=ADCx;
temp*=1000;
LCD_ShowxNum(172,150,temp,3,24,0X80);
LED_1_SW(OFF);
delay_ms(250);
LED_1_SW(ON);
delay_ms(250);
// temp/=1000;
// printf("ADC1_CH0_VOL:%.7f\r\n",temp);
for (u8 i = 0; i < 8; i++)
{
/*
计算公式 = 2 * VREF/(PGA * (2^23 - 1)) ,这里VREF是2.5V,PGA = 1
计算实际电压值(近似估算的),如需准确,请进行校准
*/
iTemp = ((int64_t)g_tADS1256.AdcNow[i] * 2500000) / 4194303;
fTemp = (float)iTemp / 1000000;
printf("CH%d=%07d(%fV) ", i, g_tADS1256.AdcNow[i], fTemp);
if(i == 3)
{
printf("\r\n");
}
}
printf("\r\n\r\n");
}
}
这是ADS1256驱动
/********************************************
SPI2 STM32 ADS1256
NSS -- PE1 -- CS
SCK -- PB13 -- SCLK
MISO -- PB14 -- DOUT
MOSI -- PB15 -- DIN
PE2 -- DRDY
// PB11 -- RESET
********************************************/
#include "stm32f10x.h"
#include "stdio.h"
#include "delay.h"
#include "ADS1256.h"
/* 寄存器定义: Table 23. Register Map --- ADS1256数据手册第30页 */
enum
{
/* 寄存器地址, 后面是复位后缺省值 */
REG_STATUS = 0, // x1H
REG_MUX = 1, // 01H
REG_ADCON = 2, // 20H
REG_DRATE = 3, // F0H
REG_IO = 4, // E0H
REG_OFC0 = 5, // xxH
REG_OFC1 = 6, // xxH
REG_OFC2 = 7, // xxH
REG_FSC0 = 8, // xxH
REG_FSC1 = 9, // xxH
REG_FSC2 = 10, // xxH
};
/* 命令定义: TTable 24. Command Definitions --- ADS1256数据手册第34页 */
enum
{
CMD_WAKEUP = 0x00, // Completes SYNC and Exits Standby Mode 0000 0000 (00h)
CMD_RDATA = 0x01, // Read Data 0000 0001 (01h)
CMD_RDATAC = 0x03, // Read Data Continuously 0000 0011 (03h)
CMD_SDATAC = 0x0F, // Stop Read Data Continuously 0000 1111 (0Fh)
CMD_RREG = 0x10, // Read from REG rrr 0001 rrrr (1xh)
CMD_WREG = 0x50, // Write to REG rrr 0101 rrrr (5xh)
CMD_SELFCAL = 0xF0, // Offset and Gain Self-Calibration 1111 0000 (F0h)
CMD_SELFOCAL= 0xF1, // Offset Self-Calibration 1111 0001 (F1h)
CMD_SELFGCAL= 0xF2, // Gain Self-Calibration 1111 0010 (F2h)
CMD_SYSOCAL = 0xF3, // System Offset Calibration 1111 0011 (F3h)
CMD_SYSGCAL = 0xF4, // System Gain Calibration 1111 0100 (F4h)
CMD_SYNC = 0xFC, // Synchronize the A/D Conversion 1111 1100 (FCh)
CMD_STANDBY = 0xFD, // Begin Standby Mode 1111 1101 (FDh)
CMD_RESET = 0xFE, // Reset to Power-Up Values 1111 1110 (FEh)
};
ADS1256_VAR_T g_tADS1256;
static const uint8_t s_tabDataRate[ADS1256_DRATE_MAX] =
{
0xF0, /* 复位时缺省值 */
0xE0,
0xD0,
0xC0,
0xB0,
0xA1,
0x92,
0x82,
0x72,
0x63,
0x53,
0x43,
0x33,
0x20,
0x13,
0x03
};
static void ADS1256_Send8Bit(uint8_t _data);
static uint8_t ADS1256_Recive8Bit(void);
static void ADS1256_WaitDRDY(void);
//static void ADS1256_ResetHard(void);
static void ADS1256_DelaySCLK(void);
static void ADS1256_DelayDATA(void);
static void ADS1256_WriteCmd(uint8_t _cmd);
static void ADS1256_WriteReg(uint8_t _RegID, uint8_t _RegValue);
static uint8_t ADS1256_ReadReg(uint8_t _RegID);
static int32_t ADS1256_ReadData(void);
static void ADS1256_SetChannal(uint8_t _ch);
static void ADS1256_SetDiffChannal(uint8_t _ch);
void SPI2_Init(void)//spi初始化
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// //CS_1();
// GPIO_SetBits(GPIOE,GPIO_Pin_1);
// //SCK_0(); /* SPI总线空闲时,钟线是低电平 */
// GPIO_ResetBits(GPIOB,GPIO_Pin_13);
// //DIN_1();
// GPIO_SetBits(GPIOB,GPIO_Pin_15);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE);//
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
//MOSI SCK
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//MISO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//SPI2 NSS PE1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE,&GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_1); //NSS set 1
//SPI2 DRDY PE2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOE,&GPIO_InitStructure);
//spi2
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS =SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial =7;
SPI_Init(SPI2, &SPI_InitStructure);
//enable SPI2
SPI_Cmd(SPI2,ENABLE);
ADS1256_Send8Bit(0xff); //启动传输
}
void ADS1256_CfgADC(ADS1256_GAIN_E _gain, ADS1256_DRATE_E _drate)
{
g_tADS1256.Gain = _gain;
g_tADS1256.DataRate = _drate;
ADS1256_StopScan(); /* 暂停CPU中断 */
// ADS1256_ResetHard(); /* 硬件复位 */
delay_us(10);
ADS1256_WaitDRDY();
{
uint8_t buf[4]; /* 暂存ADS1256 寄存器配置参数,之后连续写4个寄存器 */
buf[0] = (0 << 3) | (1 << 2) | (1 << 1);
buf[1] = 0x08; /* 高四位0表示AINP接 AIN0, 低四位8表示 AINN 固定接 AINCOM */
buf[2] = (0 << 5) | (0 << 2) | (_gain << 0);
/* 因为切换通道和读数据耗时 123uS, 因此扫描中断模式工作时,最大速率 = DRATE_1000SPS */
buf[3] = s_tabDataRate[_drate]; // DRATE_10SPS; /* 选择数据输出速率 */
CS_0(); /* SPI片选 = 0 */
ADS1256_Send8Bit(CMD_WREG | 0); /* 写寄存器的命令, 并发送寄存器地址 */
ADS1256_Send8Bit(0x03); /* 寄存器个数 - 1, 此处3表示写4个寄存器 */
ADS1256_Send8Bit(buf[0]); /* 设置状态寄存器 */
ADS1256_Send8Bit(buf[1]); /* 设置输入通道参数 */
ADS1256_Send8Bit(buf[2]); /* 设置ADCON控制寄存器,增益 */
ADS1256_Send8Bit(buf[3]); /* 设置ADC采样率 */
CS_1(); /* SPI片选 = 1 */
}
delay_us(50);
}
static void ADS1256_DelaySCLK(void)
{
__IO uint16_t i;
/*
取 5 时,实测高电平200ns, 低电平250ns <-- 不稳定
取 10 以上,可以正常工作, 低电平400ns 高定400ns <--- 稳定
*/
for (i = 0; i < 30; i++)
{
__NOP();
}
}
static void ADS1256_DelayDATA(void)
{
/*
Delay from last SCLK edge for DIN to first SCLK rising edge for DOUT: RDATA, RDATAC,RREG Commands
最小 50 个tCLK = 50 * 0.13uS = 6.5uS
*/
delay_us(10); /* 最小延迟 6.5uS, 此处取10us */
}
static void ADS1256_Send8Bit(uint8_t _data)
{
uint8_t i;
/* 连续发送多个字节时,需要延迟一下 */
ADS1256_DelaySCLK();
ADS1256_DelaySCLK();
/* ADS1256 要求 SCL高电平和低电平持续时间最小 200ns */
for(i = 0; i < 8; i++)
{
if (_data & 0x80)//& 1000 0000
{
DIN_1();
}
else
{
DIN_0();
}
SCK_1();
ADS1256_DelaySCLK();
_data <<= 1;
SCK_0(); /* <---- ADS1256 是在SCK下降沿采样DIN数据, 数据必须维持 50nS */
ADS1256_DelaySCLK();
}
}
static uint8_t ADS1256_Recive8Bit(void)
{
uint8_t i;
uint8_t read = 0;
ADS1256_DelaySCLK();
/* ADS1256 要求 SCL高电平和低电平持续时间最小 200ns */
for (i = 0; i < 8; i++)
{
SCK_1();
ADS1256_DelaySCLK();
read = read<<1;
SCK_0();
if (DOUT_IS_HIGH())
{
read++;
}
ADS1256_DelaySCLK();
}
return read;
}
static void ADS1256_WriteReg(uint8_t _RegID, uint8_t _RegValue)
{
CS_0(); /* SPI片选 = 0 */
ADS1256_Send8Bit(CMD_WREG | _RegID); /* 写寄存器的命令, 并发送寄存器地址 */
ADS1256_Send8Bit(0x00); /* 寄存器个数 - 1, 此处写1个寄存器 */
ADS1256_Send8Bit(_RegValue); /* 发送寄存器值 */
CS_1(); /* SPI片选 = 1 */
}
static uint8_t ADS1256_ReadReg(uint8_t _RegID)
{
uint8_t read;
CS_0(); /* SPI片选 = 0 */
ADS1256_Send8Bit(CMD_RREG | _RegID); /* 写寄存器的命令, 并发送寄存器地址 */
ADS1256_Send8Bit(0x00); /* 寄存器个数 - 1, 此处读1个寄存器 */
ADS1256_DelayDATA(); /* 必须延迟才能读取芯片返回数据 */
read = ADS1256_Recive8Bit(); /* 读寄存器值 */
CS_1(); /* SPI片选 = 1 */
return read;
}
static void ADS1256_WriteCmd(uint8_t _cmd)
{
CS_0(); /* SPI片选 = 0 */
ADS1256_Send8Bit(_cmd);
CS_1(); /* SPI片选 = 1 */
}
uint8_t ADS1256_ReadChipID(void)
{
uint8_t id;
ADS1256_WaitDRDY();
id = ADS1256_ReadReg(REG_STATUS);
return (id >> 4);
}
static void ADS1256_SetChannal(uint8_t _ch)
{
if (_ch > 7)
{
return;
}
ADS1256_WriteReg(REG_MUX, (_ch << 4) | (1 << 3)); /* Bit3 = 1, AINN 固定接 AINCOM */
}
void ADS1256_SetDiffChannal(uint8_t _ch)
{
if (_ch == 0)
{
ADS1256_WriteReg(REG_MUX, (0 << 4) | 1); /* 差分输入 AIN0, AIN1 */
}
else if (_ch == 1)
{
ADS1256_WriteReg(REG_MUX, (2 << 4) | 3); /* 差分输入 AIN2, AIN3 */
}
else if (_ch == 2)
{
ADS1256_WriteReg(REG_MUX, (4 << 4) | 5); /* 差分输入 AIN4, AIN5 */
}
else if (_ch == 3)
{
ADS1256_WriteReg(REG_MUX, (6 << 4) | 7); /* 差分输入 AIN6, AIN7 */
}
}
static void ADS1256_WaitDRDY(void)
{
uint32_t i;
for (i = 0; i < 40000000; i++)
{
if (DRDY_IS_LOW())
{
break;
}
}
if (i >= 40000000)
{
printf("ADS1256_WaitDRDY() Time Out ...\r\n"); /* 调试语句. 用语排错 */
}
}
static int32_t ADS1256_ReadData(void)
{
uint32_t read = 0;
CS_0(); /* SPI片选 = 0 */
ADS1256_Send8Bit(CMD_RDATA); /* 读数据的命令 */
ADS1256_DelayDATA(); /* 必须延迟才能读取芯片返回数据 */
/* 读采样结果,3个字节,高字节在前 */
read = ADS1256_Recive8Bit() << 16;
read += ADS1256_Recive8Bit() << 8;
read += ADS1256_Recive8Bit() << 0;
CS_1(); /* SPI片选 = 1 */
/* 负数进行扩展。24位有符号数扩展为32位有符号数 */
if (read & 0x800000)
{
read += 0xFF000000;
}
return (int32_t)read;
}
int32_t ADS1256_GetAdc(uint8_t _ch)
{
int32_t iTemp;
/* ADS1256 数据手册第21页 */
if(_ch >7)
return 0;
ADS1256_WaitDRDY(); /* 等待 DRDY = 0 */
ADS1256_SetChannal(_ch); /* 切换模拟通道 */
delay_us(5);
ADS1256_WriteCmd(CMD_SYNC);
delay_us(5);
ADS1256_WriteCmd(CMD_WAKEUP);
delay_us(25);
__set_PRIMASK(1); /* 禁止中断 */
iTemp = g_tADS1256.AdcNow[_ch];
__set_PRIMASK(0); /* 使能中断 */
return iTemp;
// return (int32_t)ADS1256_ReadData();
}
void ADS1256_StartScan(uint8_t ScanMode)
{
/* PE2外部中断,DEDY
配置 DEDY 作为中断输入口,下降沿触发 */
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
g_tADS1256.ScanMode = ScanMode;
/* 开始扫描前, 清零结果缓冲区 */
{
uint8_t i;
g_tADS1256.Channel = 0;
for (i = 0; i < 8; i++)
{
g_tADS1256.AdcNow[i] = 0;
}
}
/* Enable AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//
/* Connect EXTI2 Line to PE2 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
/* Configure EXTI2 line */
EXTI_InitStructure.EXTI_Line=EXTI_Line2;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI2 Interrupt priority */
NVIC_InitStructure.NVIC_IRQChannel= EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void ADS1256_StopScan(void)
{
/* 禁止外部中断 */
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line2;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=DISABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel= EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelCmd =DISABLE;
NVIC_Init(&NVIC_InitStructure);
}
void ADS1256_ISR(void)
{
/* 读取采集结构,保存在全局变量 */
ADS1256_SetChannal(g_tADS1256.Channel); /* 切换模拟通道 */
delay_us(5);
ADS1256_WriteCmd(CMD_SYNC);
delay_us(5);
ADS1256_WriteCmd(CMD_WAKEUP);
delay_us(25);
if (g_tADS1256.Channel == 0)
{
g_tADS1256.AdcNow[7] = ADS1256_ReadData(); /* 注意保存的是上一个通道的数据 */
}
else
{
g_tADS1256.AdcNow[g_tADS1256.Channel-1] = ADS1256_ReadData(); /* 注意保存的是上一个通道的数据 */
}
if (++g_tADS1256.Channel >= 8)
{
g_tADS1256.Channel = 0;
}
}
void EXTI2_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line2) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line2); //清除中断标志位
ADS1256_ISR();
// 执行上面的代码完毕后,再次清零中断标志
EXTI_ClearITPendingBit(EXTI_Line2); // 清除中断标志位
}
}
这个是驱动头文件
#ifndef _ADS1256_H
#define _ADS1256_H
#include "stdint.h"
#define DIN_1() GPIO_SetBits(GPIOB,GPIO_Pin_15)
#define DIN_0() GPIO_ResetBits(GPIOB,GPIO_Pin_15)
#define DOUT_IS_HIGH() (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14) ==Bit_SET)
#define DRDY_IS_LOW() (GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) == Bit_RESET)
#define SCK_1() GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define SCK_0() GPIO_ResetBits(GPIOB,GPIO_Pin_13)
#define CS_1() GPIO_SetBits(GPIOE,GPIO_Pin_1)
#define CS_0() GPIO_ResetBits(GPIOE,GPIO_Pin_1)
/* 增益选项 */
typedef enum
{
ADS1256_GAIN_1 = (0), /* 增益1(缺省) */
ADS1256_GAIN_2 = (1), /* 增益2 */
ADS1256_GAIN_4 = (2), /* 增益4 */
ADS1256_GAIN_8 = (3), /* 增益8 */
ADS1256_GAIN_16 = (4), /* 增益16 */
ADS1256_GAIN_32 = (5), /* 增益32 */
ADS1256_GAIN_64 = (6), /* 增益64 */
}ADS1256_GAIN_E;
/* 采样速率选项 */
/* 数据转换率选择
11110000 = 30,000SPS (default)
11100000 = 15,000SPS
11010000 = 7,500SPS
11000000 = 3,750SPS
10110000 = 2,000SPS
10100001 = 1,000SPS
10010010 = 500SPS
10000010 = 100SPS
01110010 = 60SPS
01100011 = 50SPS
01010011 = 30SPS
01000011 = 25SPS
00110011 = 15SPS
00100011 = 10SPS
00010011 = 5SPS
00000011 = 2.5SPS
*/
typedef enum
{
ADS1256_30000SPS = 0,
ADS1256_15000SPS,
ADS1256_7500SPS,
ADS1256_3750SPS,
ADS1256_2000SPS,
ADS1256_1000SPS,
ADS1256_500SPS,
ADS1256_100SPS,
ADS1256_60SPS,
ADS1256_50SPS,
ADS1256_30SPS,
ADS1256_25SPS,
ADS1256_15SPS,
ADS1256_10SPS,
ADS1256_5SPS,
ADS1256_2d5SPS,
ADS1256_DRATE_MAX
}ADS1256_DRATE_E;
#define ADS1256_DRAE_COUNT = 15;
typedef struct
{
ADS1256_GAIN_E Gain; /* 增益 */
ADS1256_DRATE_E DataRate; /* 数据输出速率 */
int32_t AdcNow[8]; /* 8路ADC采集结果(实时)有符号数 */
uint8_t Channel; /* 当前通道 */
uint8_t ScanMode; /*扫描模式0-》8,1-》4 */
}ADS1256_VAR_T;
void SPI2_Init(void);//初始化SPI_ADS1256
void ADS1256_CfgADC(ADS1256_GAIN_E _gain, ADS1256_DRATE_E _drate);
uint8_t ADS1256_ReadChipID(void);
int32_t ADS1256_ReadAdc(uint8_t _ch);
void ADS1256_StartScan(uint8_t ScanMode);
void ADS1256_StopScan(void);
int32_t ADS1256_GetAdc(uint8_t _ch);
uint8_t ADS1256_ReadReg(uint8_t _RegID);
extern ADS1256_VAR_T g_tADS1256;
#endif
我来回答