基于stm32f103c8t6单片机ACS712 直流电流测量传感器示例代码
时间: 2023-09-03 16:07:05 浏览: 342
下面是基于stm32f103c8t6单片机和ACS712直流电流测量传感器的示例代码:
```C
#include "stm32f10x.h"
#define ADC1_DR_Address ((uint32_t)0x4001244C)
// 定义ADC1的值
__IO uint16_t ADC1_ConvertedValue;
// 初始化ADC1
void ADC1_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
// 使能ADC1和DMA1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 配置GPIOA.1为模拟输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置DMA1通道1
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC1_ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
// 使能DMA1通道1
DMA_Cmd(DMA1_Channel1, ENABLE);
// 配置ADC1
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
// 配置ADC1通道1的采样时间和转换序列
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
// 使能ADC1 DMA
ADC_DMACmd(ADC1, ENABLE);
// 使能ADC1
ADC_Cmd(ADC1, ENABLE);
// 开始ADC1的转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
// 初始化串口1
void USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 使能USART1和GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置USART1的TX引脚为复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART1的RX引脚为浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART1
USART_InitStructure.USART_BaudRate = 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_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
// 使能USART1
USART_Cmd(USART1, ENABLE);
}
// 发送字符串到串口1
void USART1_SendString(char* str)
{
while (*str != '\0')
{
USART_SendData(USART1, (uint16_t)(*str++));
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
}
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
ADC1_Init();
USART1_Init();
while (1)
{
// 将ADC1_ConvertedValue转换为电压值
float voltage = ADC1_ConvertedValue * 3.3 / 4096;
// 将电压值转换为电流值
float current = (voltage - 1.65) / 0.066;
// 将电流值转换为字符串
char str[20];
sprintf(str, "Current: %.2fA\r\n", current);
// 发送字符串到串口1
USART1_SendString(str);
// 等待一段时间
for (int i = 0; i < 1000000; i++);
// 点亮LED
GPIO_SetBits(GPIOC, GPIO_Pin_13);
// 等待一段时间
for (int i = 0; i < 1000000; i++);
// 熄灭LED
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
}
}
```
在示例代码中,我们使用了ADC1和DMA1来读取ACS712的模拟输出。ADC1的采样时间设置为239.5个时钟周期,这样可以保证最高的精度。ADC1每次采样后,会将结果写入ADC1_DR寄存器中,然后DMA1会将这个结果读取到ADC1_ConvertedValue变量中。我们可以将ADC1_ConvertedValue转换为电压值,然后再将电压值转换为电流值。最后,我们将电流值发送到串口1,并将LED交替点亮和熄灭。
需要注意的是,ACS712会在0A附近输出1.65V的直流电压,因此需要将读取到的电压值减去1.65V,然后再除以0.066V/A,才能得到真正的电流值。
如果你使用的是其他型号的单片机或者其他型号的直流电流测量传感器,那么示例代码需要做一些修改。
阅读全文