一.问题与现象:
1.公司的产品之前用的是STM32F103VET6,芯片涨价&高价也买不到的情况下,我们选择了GD32F103VET6进行代替。之前同事直接把ST的程序给烧录进GD中,一下就跑起来了。短时间也没发现什么问题。过了阶段,我们发现,有时设备读取SIM卡的ICCID与无线通讯模组的IMEI读不全。我接收之后,就依照网友的总结GD32E103/F303系列替换STM32F103与STM32到GD32移植攻略对需要修改的地方进行了修改。把软件延时(for与while )进行了适当延长,这些问题就解决了。
2.最近又发现我们读取的MCU内部温度传感器的值不对。换算出来一直是-400到-407跳动。我们用到了5路ADC,3路外部,2路内部(一路内部温度传感器,一路内部参考电压)。用的方式是ADC+DMA的形式读取数据并传输数据。通过调试跟踪发现只有烧录器供电3.3V的时候,读值是正常的。但是当我们的外部一供电,ADC 16通道采集立马变成0XFFF(4095),其他4路任何情况下都是正常的。
二.思考与解决
1.遇到ADC这样的现象。偷懒的我第一步就是开始网上找经验啦。我遇到的问题可能广大网友之前已经遇到过了。找了好些帖子,也有好些经验。GD32F130 多路ADC采样(基于DMA方式)与关于gd32f103的adc的一点说法等等好些文章。但是我的问题依然没有解决。
2.自己动脑筋呗。这样的问题,要么是ADC读取错误,要么是DMA传输错误。那就重新整程序调整做实验分析。
3.用最简单的DEMO进行测试,直接用ADC读取。刚开始用的是ST的库,配置读取,还是一样的趋势。只读取内部温度传感器一路。还是同样的趋势(只有3.3V供电,读取正常,当我们外部供电立马0XFFF)。是不是就是电源的问题了,那就查呗。但是。请看第四条。
4.我们之前一个老一点版本的程序是好使的。任何情况下读取都是正常的。那就有点懵逼了。那我还是见轻巧的来呗。程序对比呗。ADC配置部分,DMA配置部分。都一样。ADC采集调用的部分,也一样。加延时,先配置DMA再开启ADC等等等等。都不行都不行。索性直接不ADC部分的整个函数,main函数直接拷贝替换。还是不行。。。。郁闷的要死。
5.联系GD的FAE。给了GD官方的DEMO。那就用GD的库,GD的DEMO(ADC读取内部温度传感器)。还是一样的趋势。只要我的设备一上电,不行。单独烧录器3.3V供电调试,是OK的。
6.GD的FAE问我们的AD口有没有接高压,比如5V。我咨询了硬件工程师,说是没有。FAE说是之前遇到了有客户接到5V了,ADC采集就不准确了。但是我的其他4路AD采集是准确的呀。我也觉得没有接高压。
7.可是问题没解决呀。那就先一路一路查电源呗。用直流电源接线直接到1117上,哎,还是不行,这个就有点神奇了。直接接3.3V是好的。那就看5V是不是着实有问题呢。看原理图,找硬件工程师。好像有一路LIN那边有5V。
LIN_TX_CPU引脚,一量电压3.7V。
官方手册上:
ADC供电要求: 2.6V到3.6V,一般电源电压为3.3V。
接下来:我直接拿掉R23 。哎 有希望。好使了。着实是接到高压上了。。。是不是问题解决了呢?
为什么是3.7V呢?领导说是3.3V的VDD+0.4左右的二极管压降进行了一个钳位功能。硬件知识有点差。完了继续查。
8.那为什么我们之前的老版本程序是可以的呢。程序中着实有点差距。区别在哪里呢?
老版本的程序中,设备工作,一量25PIN电压是3.3V
新版本程序中,设备工作,一量25PIN电压是3.7V。
那就是,通过程序可以将外部输入的电压调整到3.3V?
9.老版本中,main函数中,有对25脚进行配置,之前是用的LIN功能。
而且这样的配置是在while中的。时不时会配置一下。
//---LIN配置
static void lin_init(void)
{
//初始化
//时钟设置
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitqlt;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
//---USART2串口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//开启中断
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PREEMPTION_PRIORITY_LIN_UART_RX;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_SUB_PRIORITY_LIN_UART_RX;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = LIN_BAUDRATE;
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(USART2, &USART_InitStructure);
USART_ClockInitqlt.USART_Clock= USART_Clock_Disable;
USART_ClockInitqlt.USART_CPOL = USART_CPOL_Low;
USART_ClockInitqlt.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitqlt.USART_LastBit = USART_LastBit_Disable;//
USART_ClockInit(USART2,&USART_ClockInitqlt);
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
USART_ITConfig(USART2,USART_IT_TXE,DISABLE);
USART_Cmd(USART2, ENABLE);
}
10.那我就想着我也初始化一下试试呗。只在main函数开始的时候初始化一次。不行,25脚的电压拉不到3.3V。还是3.7V。
配置如下:放到while中,周期性的初始化。可以了。。
void Uart_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 19200;
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(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
}
三.总结
1.GD32F103像ADC采集加DMA传输这一块。我这边是先配置ADC 在配置DMA的。ADC校准之后也没有加延时。都是可以的。可能与硬件有一定关系,或者说是我已经把库中的相关配置改动了一下。就是上边提到的。
2.看到这的兄弟也给我分析分析下。讨论下。为啥这样的配置就会将电压拉倒3.3V。后边我会继续把这些疑问搞清楚。
版权声明:本文为CSDN博主「Naunyang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Naunyang/article/details/121149766
暂无评论