12.STM32F103C8T6+CUBEMX+AHT20+中断(/DMA)+BT04蓝牙

        接着之前的改一下,注意波特率改成9600了,开了串口干脆改成蓝牙吧顺手的事。

运行效果:

        这篇运行成功的代码是开启NVIC,改成DMA只需要把接收和发送函数后面的  _IT  改成  _DMA  就行了,也就是 AHT20_Get();和AHT20_Measure();这两个函数里面需要改。


一、配置cubemx的I2C1+NVIC以及USART2

                开了USART2,把下面波特率改成9600即可 


二、写代码

        由于中断和DMA都是是非阻塞模式(与上一篇轮询模式不同,轮询模式要等待所有数据发送、接受完才会向下执行,所有有个等待时间Time,之前设置的HAL_MAX_DELAY),它会将任务交给外设后向下执行,所以要设置状态机,以及使用回调函数。

        设置状态机就是把上一篇里的void AHT20_Read(float *Temperature, float *Humidity)函数分解成多个函数,详情可见keysking的解析。

状态机:

0:初始状态,发送测量命令                AHT20_Measure();

1:正在发送                                         Tx回调函数

(在通过AHT20_Measure();的HAL_I2C_Master_Transmit_IT();发送命令数据全部到从机后,由I2C中断调用,此时状态机到达2)

2、完成发送,等待80ms后读取           AHT20_Get();

3、读取中                                             Rx回调函数

4、读取完成,数据解析并展示             AHT20_Analysis(&temperature, &humidity);

回调函数分别在5137和5154行

void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)


AHT20.c


#include "AHT20.h"

/***************手册第八面5.4****************/

#define AHT20_ADDRESS 0x70
uint8_t readBuffer[6] = {0};

void AHT20_Init()
{
  uint8_t readBuffer;
  HAL_Delay(40);			//上电后要等待40ms
  HAL_I2C_Master_Receive(&hi2c1, AHT20_ADDRESS, &readBuffer, 1, HAL_MAX_DELAY);		//读取温湿度值
  if ((readBuffer & 0x08) == 0x00)		//判断校准使能位Bit[3]是否为0
  {
    uint8_t sendBuffer[3] = {0xBE, 0x08, 0x00};
    HAL_I2C_Master_Transmit(&hi2c1, AHT20_ADDRESS, sendBuffer, 3, HAL_MAX_DELAY);		//发送数组
  }
}

void AHT20_Read(float *Temperature, float *Humidity)
{
  uint8_t sendBuffer[3] = {0xAC, 0x33, 0x00};
  uint8_t readBuffer[6] = {0};

  HAL_I2C_Master_Transmit_IT(&hi2c1, AHT20_ADDRESS, sendBuffer, 3);		//直接发送触发测量命令
  HAL_Delay(80);									//等待80ms待测量完成
  HAL_I2C_Master_Receive_IT(&hi2c1, AHT20_ADDRESS, readBuffer, 6);		//读取

  if ((readBuffer[0] & 0x80) == 0x00)			//判断读取状态字Bit[7]是否为0
  {
    uint32_t data = 0;	
		
    data = ((uint32_t)readBuffer[3] >> 4) + ((uint32_t)readBuffer[2] << 4) + ((uint32_t)readBuffer[1] << 12);		//拼接数据
    *Humidity = data * 100.0f / (1 << 20);			//注意%以及float型

    data = (((uint32_t)readBuffer[3] & 0x0F) << 16) + ((uint32_t)readBuffer[4] << 8) + (uint32_t)readBuffer[5];	
    *Temperature = data * 200.0f / (1 << 20) - 50;
  }
}

/*************发送命令,等待测量***************/
void AHT20_Measure(){
  static uint8_t sendBuffer[3] = {0xAC, 0x33, 0x00};
  HAL_I2C_Master_Transmit_IT(&hi2c1, AHT20_ADDRESS, sendBuffer, 3);	
}

/******************读取********************/
void AHT20_Get(){
  HAL_I2C_Master_Receive_IT(&hi2c1, AHT20_ADDRESS, readBuffer, 6);	
}

/******解析数据函数,要有两个向外传递数据的float指针入参**********/
void AHT20_Analysis(float *Temperature, float *Humidity){		
	 if ((readBuffer[0] & 0x80) == 0x00)			//判断读取状态字Bit[7]是否为0
  {
    uint32_t data = 0;	
		
    data = ((uint32_t)readBuffer[3] >> 4) + ((uint32_t)readBuffer[2] << 4) + ((uint32_t)readBuffer[1] << 12);		//拼接数据
    *Humidity = data * 100.0f / (1 << 20);			//注意%以及float型

    data = (((uint32_t)readBuffer[3] & 0x0F) << 16) + ((uint32_t)readBuffer[4] << 8) + (uint32_t)readBuffer[5];	
    *Temperature = data * 200.0f / (1 << 20) - 50;
  }
}

AHT20.h

#ifndef __AHT20_H
#define __AHT20_H

#include "I2C.h"
#include "main.h"

void AHT20_Init();
void AHT20_Read(float *Temperature, float *Humidity);
void AHT20_Measure();
void AHT20_Get();
void AHT20_Analysis(float *Temperature, float *Humidity);
#endif

I2C.c(加入了回调函数)

/* USER CODE BEGIN 0 */
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c){
	if(hi2c == &hi2c1)
		aht20State = 2;
}


void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c){
	if(hi2c == &hi2c1)
		aht20State = 4;
}
/* USER CODE END 0 */

main.h(加了全局变量申明)

/* USER CODE BEGIN ET */
extern uint8_t aht20State;
/* USER CODE END ET */

main.c

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
	AHT20_Init();
	float temperature, humidity; 
	char message[50];           
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		if(aht20State == 0){
			AHT20_Measure();
			aht20State = 1;
		}else if(aht20State == 2){
			HAL_Delay(80);
			AHT20_Get();
			aht20State = 3;
		}else if(aht20State == 4){
			AHT20_Analysis(&temperature, &humidity);
			sprintf(message, "Temperature: %.1f,Humidity: %.1f %%\r\n", temperature, humidity);		
			HAL_UART_Transmit(&huart2, (uint8_t *)message, strlen(message), HAL_MAX_DELAY);
			HAL_Delay(1000);		
			
			aht20State = 0;
		}
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值