本文的话主要练习串口的收发,包括串口发送,接收数据的处理,我们还是简单的实现一个小例子,题目如下:
设计一个有8个车位的停车场装置,通过串口来分辨车辆的进出和待de1时间,如果车辆出去,就用串口发送收费情况(一小时2块,未满一个小时按照一个小时算)和时间,例子如下:
A01202203191500 表明编号为A01的车辆在2022年3月19日下午15时进入停车场。
A01202203191800 表明编号为A01的车辆在2022年3月19日下午18时出去停车场。
其收费应该是3*2=6元。
此节涉及到对于字符串的处理,以及一些结构体,所以我们分为 C语言基础、STM32串口操作简单使用和例题实现。
定义:
struct Postion
{
int num1[8];
int num2[8];
};
struct Postion car_postion;
调用:
int main()
{
car_postion.num1[0] = 1;
printf("%d",car_postion.num1[0]);
}
函数1: int strcmp(*num1,*num2);
头文件#include <string.h>
如果返回值小于 0,则表示 str1 小于 str2。
如果返回值大于 0,则表示 str1 大于 str2。
如果返回值等于 0,则表示 str1 等于 str2。
用法:
char num1[4] = "A01";
char num2[4] = "A01";
int main()
{
if (strcmp(num1, num2) == 0) //若他俩相等
{
printf("1");
}
}
函数2: atoi(*str)
头文件#include <stdlib.h>
将字符串中的char类型数字转化成int类型
用法: char date[16] = "A01202203191500";
char year[5];
int year_num;
int main()
{
year[4] = '\0';
for(int i=3;i<7;i++)
{
year[i - 3] = date[i];
}
year_num = atoi(year);
printf("year_num is %d\n", year_num);
}
我们实现一个小例子:用串口助手发送长度为10个字节的数据,并发送后5位
由于上节已经演示过,故不在演示,直接进入代码部分。
串口的收发都需要提供一个缓存地址
uint8_t rx_buff[255];
uint8_t tx_buff[255];
HAL_UART_Receive_IT(&huart1,(uint8_t *)rx_buff,10);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
for(int i=5;i<10;i++)
{
tx_buff[i-4] = rx_buff[i];
}
HAL_UART_Transmit(&huart1,tx_buff,6,1000);
HAL_UART_Receive_IT(&huart1,(uint8_t *)rx_buff,10); //注意,要在回调函数里再次开启接收中断
}
这个停车场项目的实现比较考察逻辑,首先如果是我的话,我会先设置一个车位结构体,里面包括的变量有车位编号,车位状态,起始占用时间,末尾离开时间,以及已经在其中的车辆的编号。
struct Postion
{
int num[8];
int state[8];
uint8_t id[25];
int StartTimeYear[8];
int StartTimeMonth[8];
int StartTimeDay[8];
int StartTimeHour[8];
int StartTimeMin[8];
int ExitTimeYear[8];
int ExitTimeMonth[8];
int ExitTimeDay[8];
int ExitTimeHour[8];
int ExitTimeMin[8];
};
struct Postion car_postion;
具体逻辑的话,我们先判断这辆车在不在停车场内,如果已经在的话,我们直接解算费用,把车位标志位置0;如果不在的话,我们判断停车场内有没有车位,有车位,计入信息,标志位置1,如果没有,我们告诉他已无车位,请离开。
逻辑分析完了,我们来分析程序的具体实现,首先车辆信息是通过串口发送的,我们就在串口中断函数里完成车辆id的判断和数据的解析存储。
整体逻辑如下:
uint8_t rx_buff[255];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //rx_buff里存储这车辆的信息
{
static int i;
static uint8_t id_check[4];
id_check[3] = '\0';
for(int i=0;i<3;i++) //解析车辆id
{
id_check[i] = rx_buff[i];
}
id_flag = check_id(id_check);
if(id_flag != 1)
{
if((postion_flag = check_state())== 0)
{
printf("There is no postion in here,please exit");
}
else //有车位的话,将信息存入结构体
{
for(i=0;i<8;i++)
{
if(car_postion.state[i] == 0)
{
printf("your car in %d postion",i);
get_date_start(i);
break;
}
}
}
}
HAL_UART_Receive_IT(&huart1,(uint8_t *)rx_buff,15);
}
检查汽车是否在停车场内,如果在,计入末尾数据,解算费用,如果不在,返回0
int check_id(uint8_t * id_check) //判断汽车现在在不在停车场内,在的话返回1,反之0
{
static uint8_t id[4];
static int money;
static int i;
static int j;
id[3] = '\0';
for(i=0;i<8;i++) //对比各车位ID
{
for(int j=0;j<3;j++) //读取已有车位车位ID
{
id[j] = car_postion.id[i*3+j];
}
printf("%s",id);
if(strcmp((char *)id,(char *)id_check) == 0)
{
get_date_end(i);
money = get_money(i);
printf("you need pay %d yuan",money);
printf("the car in %d postion is exit",i);
return 1;
}
}
}
如果在停车场内,获取结束数据
void get_date_end(int k)
{
static uint8_t Year[5];
static uint8_t Month[3];
static uint8_t Day[3];
static uint8_t Hour[3];
static uint8_t Min[3];
static int i;
Year[4] = '\0';
Month[2] = '\0';
Day[2] = '\0';
Hour[2] = '\0';
Min[2] = '\0';
for(i=0;i<3;i++) //销毁对应ID
{
car_postion.id[k*3+i] = '9';
}
for(i=3;i<7;i++) //采集年份信息
{
Year[i-3] = rx_buff[i];
}
for(i=7;i<9;i++) //采集月份信息
{
Month[i-7] = rx_buff[i];
}
for(i=9;i<11;i++) //采集日信息
{
Day[i-9] = rx_buff[i];
}
for(i=11;i<13;i++) //采集小时信息
{
Hour[i-11] = rx_buff[i];
}
for(i=13;i<15;i++) //采集分钟信息
{
Min[i-13] = rx_buff[i];
}
// 写入结构体:
car_postion.ExitTimeYear[k] = atoi((char *)Year);
car_postion.ExitTimeMonth[k] = atoi((char *)Month);
car_postion.ExitTimeDay[k] = atoi((char *)Day);
car_postion.ExitTimeHour[k] = atoi((char *)Hour);
car_postion.ExitTimeMin[k] = atoi((char *)Min);
car_postion.state[k] = 0; //标志位
}
检查车位状态函数:
int check_state() //检查是否有车位
{
static int sum=0;
static int i;
static int k;
for(k=0;k<8;k++)
{
sum += car_postion.state[k];
}
if(sum == 8)
{
return 0; //无车位返回 0
}
else
{
return 1; //有车位返回 1
}
}
如果有车位,停入,获取起始数据:
void get_date_start(int k) //获取汽车进入时的数据
{
static uint8_t Year[5];
static uint8_t Month[3];
static uint8_t Day[3];
static uint8_t Hour[3];
static uint8_t Min[3];
static int i;
Year[4] = '\0';
Month[2] = '\0';
Day[2] = '\0';
Hour[2] = '\0';
Min[2] = '\0';
for(i=0;i<3;i++) //读入ID
{
car_postion.id[k*3+i] = rx_buff[i];
}
for(i=3;i<7;i++) //采集年份信息
{
Year[i-3] = rx_buff[i];
}
for(i=7;i<9;i++) //采集月份信息
{
Month[i-7] = rx_buff[i];
}
for(i=9;i<11;i++) //采集日信息
{
Day[i-9] = rx_buff[i];
}
for(i=11;i<13;i++) //采集小时信息
{
Hour[i-11] = rx_buff[i];
}
for(i=13;i<15;i++) //采集分钟信息
{
Min[i-11] = rx_buff[i];
}
// 写入结构体:
car_postion.StartTimeYear[k] = atoi((char *)Year);
car_postion.StartTimeMonth[k] = atoi((char *)Month);
car_postion.StartTimeDay[k] = atoi((char *)Day);
car_postion.StartTimeHour[k] = atoi((char *)Hour);
car_postion.StartTimeMin[k] = atoi((char *)Min);
car_postion.state[k] = 1; //已被占用
}
解算费用函数:
int get_money(int i)
{
static int money_year;
static int money_month;
static int money_day;
static int money_hour;
static int money_min;
int money_sum;
money_year = (car_postion.ExitTimeYear[i] - car_postion.StartTimeYear[i])*365*24*2;
money_month = (car_postion.ExitTimeMonth[i] - car_postion.StartTimeMonth[i])*30*24*2;
money_day = (car_postion.ExitTimeDay[i] - car_postion.StartTimeDay[i])*24*2;
money_hour = (car_postion.ExitTimeHour[i] - car_postion.StartTimeHour[i])*2;
money_min = (car_postion.ExitTimeMin[i] - car_postion.StartTimeMin[i]);
if(money_min <= 0)
{
money_sum = money_year + money_month + money_day + money_hour;
return money_sum;
}
if(money_min > 0)
{
money_sum = money_year + money_month + money_day + money_hour + 2;
return money_sum;
}
}
main函数里记得初始化
int main(void)
{
int v;
/* 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_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1,(uint8_t *)rx_buff,15);
for(v=0;v<24;v++)
{
car_postion.id[v] = '9';
}
for(v=0;v<8;v++)
{
car_postion.state[v] = 0;
}
/*gure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1,(uint8_t *)rx_buff,15);
for(v=0;v<24;v++)
{
car_postion.id[v] = '9';
}
for(v=0;v<8;v++)
{
car_postion.state[v] = 0;
}
}