1,STM32DMA(Direct Memory Access)是指由STMicroelectronics公司出品的一款支持直接内存存取的技术。DMA是一种用于高速数据传输的技术,通过DMA,可以在不占用CPU资源的情况下,将数据从一个设备传输到另一个设备,提高了系统效率和数据传输速度。
STM32DMA是一种硬件DMA实现,支持多种数据传输方式,包括UART、SPI、I2C等多种外设接口,是STM32系列芯片中的重要组成部分。STM32DMA能够使数据传输过程中不产生CPU中断,支持多种数据传输方式,支持多路DMA通道,从而支持多任务并行传输。
STM32DMA具有以下特点:
1.可靠性高:由于是硬件DMA,因此DMA传输效率高、稳定性好、可靠性高。
2.传输效率高:由于采用硬件DMA,因此减少了CPU的干预,从而提高了数据传输的效率。
3.支持多种传输方式:STM32DMA可以支持多种传输方式,如UART、SPI、I2C等多种外设接口。
4.支持多路DMA通道:STM32DMA支持多路DMA通道,从而支持多任务并行传输。
5.较低的功耗:由于不需要CPU的参与,因此DMA传输不会耗费太多的功耗。
2,温度转换公式
在 STM32 微控制器中,内部温度传感器的输出值可以通过 ADC(模数转换器)进行采集和转换。对于大多数 STM32 微控制器来说,内部温度传感器的输出值需要经过一定的转换公式才能得到实际的温度数值。
一般来说,转换公式如下所示:
[ \text{温度} = \frac{V_{25} - V_{SENSE}}{Avg_Slope} + 25^\circ C ]
其中:
- ( V_{25} ) 是微控制器工作时的温度传感器输出电压,通常为 1.43V 左右。
- ( V_{SENSE} ) 是经过 ADC 转换后的内部温度传感器输出电压。
- ( Avg_Slope ) 是温度-电压斜率,通常为 4.3 mV/°C 左右。
- ( 25^\circ C ) 是为了补偿温度传感器的误差而添加的偏移量,因为在 ( 25^\circ C ) 时传感器的输出电压理论上应该等于 ( V_{25} )。
例如:当使用STM32F103系列微控制器时,内部温度传感器的输出电压(VSENSE)可以通过ADC采集到,假设采集到的数字值为ADC_value,则可以通过以下公式计算实际温度:
float temperature;
uint16_t V25 = 1430; // 1.43V对应的ADC数值
uint16_t Avg_Slope = 43; // 温度-电压斜率,单位为4.3mV/°C
temperature = ((float)V25 - (float)ADC_value) / Avg_Slope + 25.0f;
在这个例子中,我们假设V25为1430,Avg_Slope为43。通过以上公式,我们可以将采集到的ADC数值转换为实际的温度值。
3,电压转换公式
在STM32微控制器中,如果要通过ADC采集电压值并转换为实际电压,可以使用以下公式:
[ \text{实际电压值} = \frac{V_{\text{SENSE}}}{2^{N}} \times V_{\text{REF}} ]
其中:
- ( V_{\text{SENSE}} ) 是经过ADC转换后得到的数字值。
- ( N ) 是ADC的位数,例如12位ADC,( N = 12 )。
- ( V_{\text{REF}} ) 是ADC的参考电压,通常为微控制器芯片上的参考电压,例如3.3V或者5V。
通过这个公式,你可以将ADC采集到的数字值转换为实际的电压值。
例如:假设我们使用的是一款12位的STM32微控制器,参考电压为3.3V。
如果我们通过ADC采集到的数字值为ADC_value,那么可以使用以下公式将其转换为实际的电压值:
float VREF = 3.3; // 参考电压为3.3V
uint16_t ADC_resolution = 4096; // 12位ADC,所以2^12=4096
float voltage;
voltage = ((float)ADC_value / ADC_resolution) * VREF;
在这个例子中,我们将采集到的ADC数值转换为实际的电压值,并存储在变量voltage中。这样,我们就可以通过ADC采集到的数字值计算出对应的实际电压值。
需要注意的是,不同型号的 STM32 微控制器可能会有略微不同的参数,因此在具体应用中,建议查阅相关的芯片手册或数据表以获取准确的转换公式和参数数值。
DMA实验要求:
利用ADC采集电位器以及芯片内部温度传感器的数据,在main函数中启动ADC转换以及DMA传输,最后在DMA完成中断中打印采集到的数据
步骤:
(1)PA4设置为ADC1_IN4,打开内部传感器通道
(2)使能串口1(USART1)
(3)使能时钟:外部晶振,配置时钟
(4)设置ADC中断:打开扫描模式,打开DMA请求(如果无法使能,就先做第5步);规则通道:采样周期,15周期
(5)设置DMA:添加数据流,add->ADC1(其余默认)
(6)设置DMA2中断(211)
程序如下:
主程序:
uint16_t adc_value[2] = {0}; //数据寄存器是16位,定义为全局变量
while (1)
{
HAL_ADC_Start_DMA(&hadc1, (uint32_t*) adc_value, 2);
//内存,目的;//2指传输两个量(量就是数据的位宽)
HAL_Delay(1000);
}
ADC函数:
extern uint16_t adc_value[2];
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1)
{
printf("adc_value[0] = %d,adc_value[1] = %d\n",adc_value[0],adc_value[1]);
}
}
运行结果: