暑期培训第十天

ADS1256问题分析:

从理论和官方上说的来看:选择单端输入可以采集到±5.0v的电压,我一开始选用官方例程STM32F103的发现选用单端老是采集不到负电压。

我的分析思路是这样的:先看一下这个计算过程有没有问题(但是这个没有理论知识其实发现不了什么问题,只能是对比一下其他例程)、然后检查了一下引脚是不是有没接好的(发现是没有的)、最后就是问问实验室的小伙伴(他们都以为我mode模式这些没选对)

后面我就选择换一个例程试一下,一下子就可以了。

我这里自己分析了一下,其中可能存在的问题:引脚初始化出现外设冲突了。

void ADS1256_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	// 初始化时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  			
	// 初始化io口
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_8| GPIO_Pin_3; 							
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  				
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_4; 								
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  				
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	RST_L;
	Delay_1ms(1);
	RST_H;
	Delay_1ms(100);
	CS_H;
	SCLK_L;
	DIN_H;
}

(这是采集不到负电压的引脚初始化)

为什么说是引脚冲突呢?我一开始有这个想法是因为例程里面有LCD初始化和显示字符串,库函数没问题,但是初始化可以,显示字符串没有。

我看了一眼官方给的引脚分配图:

这个初始化的很多引脚其实都和这里面的不建议使用撞上了

这个也是我现在晚上时间写分析才想到的,当时没有联想到这一块。后面有时间可以再去验证一下这一块。这个究竟是不是引脚和这里面列出来的的冲突了,才导致一系列的问题

后面换了一个初始化函数就没有问题了

void ADS1256_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	// 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);  			
	// 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_6; 							
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  				
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; 								
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  				
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 								
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  				
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	RST_L;
	Delay_1ms(1);
	RST_H;
	Delay_1ms(100);
	CS_H;
	SCLK_L;
	DIN_H;
}

我查了一下表格,发现这些引脚都没冲突,具体一点是我没有外接oled外设,不冲突

所以,以后就是要养成,配置GPIO和看别人的代码的时候关注一下这个有没有和官方函数冲突

养成看这个表格的习惯

还有一个今天学到的就是,这个.c和.h中的编程习惯很值得我学习

具体来说:

#ifndef _ads1256_H
#define _ads1256_H
#include "stm32f10x.h"

/* 寄存器地址, 后面是复位后缺省值 */
#define REG_STATUS	(0)	// x1H		状态寄存器
#define	REG_MUX    	(1) // 01H		输入多路复用器控制寄存器


/* 命令定义: TTable 24. Command Definitions --- ADS1256数据手册第34页 */
#define	CMD_WAKEUP		(0x00)	// Completes SYNC and Exits Standby Mode 0000  0000 (00h)		完成SYNC并退出待机状态
#define	CMD_RDATA   	(0x01) 	// Read Data 0000  0001 (01h)		读取数据

#define PGA_1            0x00
#define PGA_2            0x01

extern uint32_t ADS1256_GetAdc(uint8_t channel);
extern void ADS1256_CfgADC(uint8_t gain, uint8_t drate);

#endif

这种将置位电平和一些有关这个模块的寄存器和命令写在.h中,这样查找起来很方便。

/*
*********************************************************************************************************
*	函 数 名: ADS1256_Send8Bit
*	功能说明: 向SPI总线发送8个bit数据。 不带CS控制。
*	形    参: _data : 数据
*	返 回 值: 无
*********************************************************************************************************
*/
void ADS1256_Send8Bit(uint8_t data)
{
	uint8_t i;

	/* 连续发送多个字节时,需要延迟一下 */
	Delay_ns(250);
	Delay_ns(250);
	/* ADS1256 要求 SCL高电平和低电平持续时间最小 200ns  */
	for(i = 0; i < 8; i++)
	{
		if (data & 0x80)
		{
			DIN_H;
		}
		else
		{
			DIN_L;
		}
		SCLK_H;
		Delay_ns(250);
		data <<= 1;
		SCLK_L;			/* <----  ADS1256 是在SCK下降沿采样DIN数据, 数据必须维持 50nS */
		Delay_ns(250);
	}
}

.c文件和这样列出来一个说明,然后我就现用了

/*
*********************************************************************************************************
*	函 数 名: Srd_05VDC_Init
*	功能说明: 初始化继电器,用相关的引脚来控制选通
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void Srd_05VDC_Init(void)
{	
	//定义一个结构体变量
	GPIO_InitTypeDef GPIO_InitStructure;			
	
	//配置引脚:设置为PE0推挽输出
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	//开启时钟
	GPIO_Init(GPIOE, &GPIO_InitStructure);
	Srd_H;	//初始默认是:常闭
#ifndef _SRD_H
#define _SRD_H
#include <stm32f10x.h>



/* 命令定义: 引脚、高低电平 */
#define	Srd				(GPIOE,GPIO_Pin_0)
#define	Srd_L			GPIO_ResetBits(GPIOE , GPIO_Pin_0)
#define	Srd_H			GPIO_SetBits(GPIOE , GPIO_Pin_0)



void Srd_05VDC_Init(void);



#endif

学习和使用串口屏问题:

因为这次输出的信息很多,我觉得2.8寸的LCD不够用,所以就用上了陶晶驰的串口屏。

今天速成了一下基础教学,看了他们在B站的教学视频。

我现在就是会用一些基本操作:

页面转化:弹起和按下事件中写入page x(转化回来其实就是类似的,逆向思维)

赋值改变:文本就是tx.txt="xxx"、数字就是nx.val=xxx(这个注意不能多加空格、文本的文字要在字库之内才可以显示、数字不能超出范围)

通过调试输入,来实现调试:改改赋值之类的

但是因为我最后是要通过单片机来控制修改数据,肯定是要通过串口来和这个进行通信,因为USART1已经用来和串口调试助手通信了,我就选用USART3来进行通信

//串口三的初始化:用来和串口屏进行通信
//初始化引脚、串口3的信息、中断服务配置
void uart3_init(u32 bound)
{
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//时钟GPIOB、USART3
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	
	//USART1_TX   PB10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//USART1_RX	  PB11
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);  
	
	  //Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
	//USART 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART3, &USART_InitStructure);
	
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断
	USART_Cmd(USART3, ENABLE);                    //使能串口 
}

这些就是基本配置了,然后看网上的代码有给的发送函数之类的,我就直接拿来用了。

		sprintf((char*)buf,"page1.n0.val=%d",res);
		//printf("%s\n",buf);
		HMISends((char*)buf);
		HMISendb(0xff);

核心就是:将buf数组强转到char类型,然后赋值,通过发送函数发送过去,最后固定发送0xff结束

我其实今天是卡在这个HMISends中的每一步都没问题,但是结束就没有跳到下一步了(我这里使用led1的点亮来判断到底是到了哪一步),晚上想了想感觉是卡在中断服务助手里面。

所以我发现,自己对串口的理解真的还是很浅,就是串口的执行过程,我其实还是没有太懂。

具体一点就是应该去加深一下,串口这个一整个流程中代码是怎么跑的,去看例程里面自己之前没有注意到的细节。

但是这个发送的语法,有效性也有待检测。

发现问题,分析问题,解决问题。

这个能力我还是有待提升。

最后说说今天get到一个初始化的小点:

之前学习RDA5820的时候,中间就有一个whlie循环是在等5820初始化完成才往下跑代码。

今天晚上和硬件测试4051和Srd继电器的时候,我发现不管我怎么改变控制位,输出就是没有变化,我还以为是自己运气爆棚了,这硬件品控问题这么快就给我碰到了。

后面发现,一些基本的闪烁指示灯都没有亮,我就想到可能是初始化都没有

出现这个问题可能是因为,我把ADS1256初始化代码放在前面,但是又没有接入单片机的引脚中,这样可能就导致了初始化失败。

void PeripheralInit(void)
{	
	SystemInit();										//系统函数初始化
	Delay_1ms(100);									//等待稳定
		
	//Srd_05VDC_Init();							//继电器初始化控制引脚为:PE0
	Delay_50ms(1);
	CD4051_Init();
	Delay_1ms(10);
	
	ADS1256_GPIO_Init();						//ADC GPIO初始化
	USART_Configuration(); 					//配置串口波特率为115200
	Delay_5ms (10);								
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值