一、任务描述
使用正点原子精英板,利用板子上的485通信电路读出一485通信的传感器数据,当按键按下后串口发出读取数据指令后,开始启动定时器计时,当串口收到传感器回复的数据时,结束计时,实现检测传感器回复数据的时间长度。
二、cubemx设置
1、设置串口下载
2、设置时钟源
3、设置定时器,每隔10毫秒定时时间到
4、设置串口
5、设置GPIO引脚,两个按键引脚,两个LED引脚,一个485控制引脚
最后生成程序代码。
三、485通讯电路
需要注意的是,除了收发引脚之外,还要有RS485_RE引脚来控制485芯片的收发,当该引脚为高电平时,485芯片处于发送的状态,当该引脚为低电平时,485芯片处于接收的状态。
四、程序代码
1、添加key.c
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,WKUP按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!!
uint8_t KEY_Scan(uint8_t mode)
{
static uint8_t key_up=1; //按键松开标志
if(mode==1)key_up=1; //支持连按
if(key_up&&(KEY0==0||KEY1==0))
{
HAL_Delay(10);
key_up=0;
if(KEY0==0) return KEY0_PRES;
else if(KEY1==0) return KEY1_PRES;
}else if(KEY0==1&&KEY1==1)key_up=1;
return 0; //无按键按下
}
2、添加usart1.c
#include "usart1.h"
#include "usart.h"
/**********重定义函数**********/
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (uint8_t) ch;
return ch;
}
//串口1发送串口屏数据send_data
void UserUart1Send(uint8_t *send_data,uint8_t send_len)
{
while(send_len--)
{
HAL_UART_Transmit(&huart2,send_data++,1,20);
}
}
3、tim.c中代码添加
/* USER CODE BEGIN 1 */
uint16_t count=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
// 这个回调函数 是共用的,因此需要先判断,是不是定时器2;
if(htim->Instance == htim2.Instance)
{
count++;//每隔10ms加一
}
}
/* USER CODE END 1 */
4、main.c中添加
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "key.h"
#include "usart1.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8_t key=0;
char press_cmd[7]=":010188";
uint8_t pre_rec_buf[22];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
//接收回调函数---接收气压数值字符
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
if(huart==&huart2)
{
// HAL_UART_Receive_IT(&huart1,(uint8_t*)pre_rec_buf,20);
HAL_TIM_Base_Stop_IT(&htim2);
// memset(pre_rec_buf,0,22);
// count=0;
}
HAL_UART_Receive_IT(&huart2,(uint8_t*)pre_rec_buf,22);
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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_TIM2_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart2,(uint8_t*)pre_rec_buf,22);//接收数据
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
key=KEY_Scan(0);
if(key==1)
{
RS485_Ctr_TX;
UserUart1Send((uint8_t*)press_cmd,7);
HAL_TIM_Base_Start_IT(&htim2);
RS485_Ctr_RX;
}
// LED0_ON;
// LED1_OFF;
// HAL_Delay(1000);
// LED0_OFF;
// LED1_ON;
// HAL_Delay(1000);
}
/* USER CODE END 3 */
}