本帖最后由 suncat0504 于 2024-6-8 20:50 编辑
本次实验使用现成的电流传感器模块获取电流数据。模块用的是ACS758LCB霍尔电流模块,体积小。这个模块我买了很久,都没有做过实验,属于那种看了喜欢,想用了试试的那种。
提供以下几个接口:
1、5V
2、GND
3、TXD
4、VOUT
5、D-CMP
TXD是以9600波特率输出的数据。发送的两个字节的数据帧,BCD码模式。第一个字节的高四位,表示正负,A表示为正,B表示为负。低四位和第二个字节的高四位用来表示电流值的整数。第二个字节的低四位表示电流的小数位。
D-CMP用来接外部比较基准电压,VOUT是比较结果的输出。通过比较外部基准电压和采样电流模块的电压,来判断我们收集的电流是否超出了范围。如果超出范围,Vout会输出高电平,作为报警信号。
很明显,这个模块是用来测试直流更合适。考虑到用来控制可充电电池的充电的,因此用起来没问题。问题是这个模块的电流上限是30A,普通充电电池的电流不会这么大。能否适用于小电流的采样,只能通过实验来试试了。
因为暂时用不到4、5的比较输出功能,实际接线只需要1、2、3即可。在配合单片机操作之前,先看看模块的工作情况,只需要接入电源、地,连上串口接收模块。
板子上有一个发光管坏掉了,导致缺笔段,不影响观感。串口得到的结果:
A000,表示结果为正的0.0A;B001,表示为-0.1A,还不错。
使用芯源开发板的话,需要额外准备一个串口接收来自电流模块的数据。
根据手册和开发板的IO排针输出状况,
使用PA09作为串口接收用。为了调试程序以及显示测量结果,这里先接入一个OLED屏。为此建立一个工程,导入OLED的处理程序。
接下来,引入串口处理程序。串口使用中断方式,每采集到完整的两个字节的数据后,处理并显示到OLED上。
主程序中主要处理代码:
uint8_t readbuff[32] = {'\0'}; // 串口接收缓冲区
uint8_t procflag = 0; // 处理中标志,遇到该标志,串口接收的数据暂时不保存到缓冲区中
uint8_t readpos = 0; // 串口数据接收用指针
void getTestResult(void) {
int8_t isok = 0;
uint8_t v1 = 0; // 整数部分
uint8_t v2 = 0; // 小数部分
char numstr[10]={'\0'};
readbuff[2] = '\0';
if ((readbuff[0] & 0xA0) > 0) {
numstr[0]='A';
isok=1;
} else if ((readbuff[0] & 0xB0) > 0) {
// 负数
numstr[0]='B';
isok=-1;
}
if (isok != 0) {
numstr[1]=(readbuff[0] & 0x0f)+48;
numstr[2]=((readbuff[1] &0xf0)>>4)+48;
numstr[3]=(readbuff[1] & 0x0f)+48;
numstr[4]='\0';
GUI_ShowString(0, 0, (uint8_t*)numstr, 16, 1);
// 正数
v1 = (readbuff[0] & 0x0f) * 10;
v1 = v1+((readbuff[1] & 0xf0)>>4);
v2 = readbuff[1] & 0x0f;
sprintf(numstr, "%2.1f", ((float)v1+0.1*v2) * isok);
GUI_ShowString(0, 16, (uint8_t*)numstr, 16, 1);
}
}
/**
******************************************************************************
** \brief Main function of project
**
** \return uint32_t return value, if needed
**
******************************************************************************/
int32_t main(void) {
//配置RCC
RCC_Configuration();
//配置GPIO
GPIO_Configuration();
//配置UART
UART_Configuration();
//配置NVIC
NVIC_Configuration();
//使能UARTx RC中断
USART_ITConfig(DEBUG_USARTx, USART_IT_RC, ENABLE);
//USART_SendString(DEBUG_USARTx, "\r\nCW32F030 UART Interrupt\r\n");
OLED_Init();
OLED_Clear(0);
//GUI_ShowString(0, 0, (uint8_t*)"Start test...", 8, 1);
while(1) {
//中断收发
if (procflag == 1) {
// 收到两个自己字节的数据
getTestResult();
procflag=0;
}
}
}
串口的初始化代码:
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] 配置GPIO
*
*/
void GPIO_Configuration(void) {
GPIO_InitTypeDef GPIO_InitStructure;
//UART TX RX 复用
DEBUG_USART_AFTX;
DEBUG_USART_AFRX;
GPIO_InitStructure.Pins = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pins = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] 配置UART
*
*/
void UART_Configuration(void) {
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = DEBUG_USART_BaudRate;
USART_InitStructure.USART_Over = USART_Over_16;
USART_InitStructure.USART_Source = USART_Source_PCLK;
USART_InitStructure.USART_UclkFreq = DEBUG_USART_UclkFreq;
USART_InitStructure.USART_StartBit = USART_StartBit_FE;
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(DEBUG_USARTx, &USART_InitStructure);
}
/**
* @brief 配置NVIC
*
*/
void NVIC_Configuration(void) {
//优先级,无优先级分组
NVIC_SetPriority(DEBUG_USART_IRQ, 0);
//UARTx中断使能
NVIC_EnableIRQ(DEBUG_USART_IRQ);
}
/**
* @brief 发送字符串
*
* @param USARTx :USARTx外设
* 参数可以是:
* CW_UART1、CW_UART2、CW_UART3
* @param String :待发送的字符串
*/
void USART_SendString(UART_TypeDef* USARTx, char *String) {
while(*String != '\0') {
USART_SendData_8bit(USARTx, *String);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
String++;
}
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXBUSY) == SET);
}
中断处理中的处理代码:
/**
* @brief This funcation handles UART1
* 串口中断
*/
void UART1_IRQHandler(void) {
/* USER CODE BEGIN */
uint8_t TxRxBuffer;
if(USART_GetITStatus(CW_UART1, USART_IT_RC) != RESET) {
// 接收串口数据
TxRxBuffer = USART_ReceiveData_8bit(CW_UART1);
if (procflag == 0) {
//USART_SendData_8bit(CW_UART1, TxRxBuffer);
if ((TxRxBuffer & 0xA0) > 0 || (TxRxBuffer & 0xB0) > 0) {
readpos = 0;
}
readbuff[readpos] = TxRxBuffer;
readpos=(readpos+1)%2;
if (readpos == 0) {
// 完成两个字节的接收, 建立接收完成标志
procflag = 1;
}
}
//
USART_ClearITPendingBit(CW_UART1, USART_IT_RC);
}
/* USER CODE END */
}
下一步将接入实际测试电流做测试。
|