- static uint8_t s_uart1_rxch; 获得的第1个字节数据保存在s_uart1_rxch
- char g_uart1_rxbuf[256]; 将s_uart1_rxch获取到的每个字节保存在g_uart1_rxbuf中
- uint8_t g_uart1_bytes;
就像一个总容量为500ml的杯子(g_uart1_rxbuf[256]),里面实际装了200ml的水(g_uart1_bytes)
串口中断接收回调函数void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart),每次发生中断,就调用这个函数,把接收到1字节数据s_uart1_rxch存储到g_uart1_rxbuf中,并将g_uart1_bytes自加。
串口中断接收处理:在usart.c中,添加串口中断处理函数及接收buffer
/* USER CODE BEGIN 0 */
static uint8_t s_uart1_rxch;
char g_uart1_rxbuf[256]; /*g_是global全局变量*/
uint8_t g_uart1_bytes;
/* USER CODE END 0 */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 2 */
HAL_UART_Receive_IT(&huart1,&s_uart1_rxch,1);//开启接收中断使能
/* USER CODE END USART1_Init 2 */
}
/* USER CODE BEGIN 1 */
/*printf()函数的定义,printf()函数是的重定向实现,下面代码兼容gcc和Keil*/
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *f)
#endif/*__GNUC__*/
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xFFFF);
return ch;
}
/*串口中断接收的回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
if(g_uart1_bytes<sizeof(g_uart1_rxbuf))
{
g_uart1_rxbuf[g_uart1_bytes++] = s_uart1_rxch;
}
HAL_UART_Receive_IT(&huart1,&s_uart1_rxch,1);//使能下一次中断接�???
}
}
/* USER CODE END 1 */
在usart.h中
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>//main.c中要用到snprintf
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
extern char g_uart1_rxbuf[256];//g是global全局变量
extern uint8_t g_uart1_bytes;
#define clear_uart1_rxbuf() do {memset(g_uart1_rxbuf,0,sizeof(g_uart1_rxbuf));\
g_uart1_bytes=0;}while(0)
/* USER CODE END Private defines */
在gpio.c中
/* USER CODE BEGIN 2 */
gpio_t leds[LedMax]=
{
{"BlueLed", GPIOB , GPIO_PIN_2},
{"RedLed", GPIOC, GPIO_PIN_9},
{"GreenLed",GPIOC , GPIO_PIN_6},
};
/*which代表选择哪一个灯,int类型的,每个灯都有一个数字代替,去enum去看;ststus控制灯的亮灭,对应参数是OFF �???? ON*/
void turn_led(int which, int status)
{
GPIO_PinState level;
if( which<0 || which>=LedMax)
{
return ;
}
level = (status == OFF) ? GPIO_PIN_SET : GPIO_PIN_RESET;//SET输入高电平就关灯OFF,RESET输入�????个低电平就开灯ON
HAL_GPIO_WritePin(leds[which].group, leds[which].pin, level);
}
void blink_led(int which, uint32_t interval)
{
if(which>=LedMax || interval<=0)
{
return ;
}
turn_led(which,ON);
HAL_Delay(interval);
turn_led(which,OFF);
HAL_Delay(interval);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(Key1_Pin==GPIO_Pin)
{
blink_led(BlueLed,500);
}
else if(Key2_Pin==GPIO_Pin)
{
blink_led(RedLed,500);
}
else if(Key3_Pin==GPIO_Pin)
{
blink_led(GreenLed,500);
}
}
在gpio.h中
/* USER CODE BEGIN Prototypes */
enum
{
BlueLed,
RedLed,
GreenLed,
LedMax,
};
#define OFF 0
#define ON 1
typedef struct gpio_s
{
const char *name;
GPIO_TypeDef *group;
uint16_t pin;
}gpio_t;
extern gpio_t leds[LedMax];
extern void turn_led(int which, int status);
extern void blink_led(int which, uint32_t interval);
/* USER CODE END Prototypes */
在main.c中,添加串口接收数据JSON解析代码,并控制LED灯
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ds18b20.h"
#include "core_json.h"
#include <string.h>
/* USER CODE END Includes */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
static int report_tempRH2_json(void);
static int parser_led_json(char *json_string,int bytes);//解析led的json
static void proc_uart1_recv(void);//串口1接收
/* USER CODE END 0 */
int main(void)
{
while (1)
{
proc_uart1_recv();//调用这个函数从buf[]中做数据解析
}
}
/* USER CODE BEGIN 4 */
int parser_led_json(char *json_string,int bytes)
{
JSONStatus_t result;
char save;
char *value;
size_t valen;
int i;
printf("DBUG:Start parsar JSON string:%s\r\n",json_string);
result=JSON_Validate(json_string,bytes);/*JSON_Validate()函数用于判断value的�?�是否是有效的JSON数据*/
if(JSONPartial==result)
{
printf("WARN:JSON document is valid so far but incomplete!\r\n");
return 0;
}
if(JSONSuccess!=result)
{
printf("ERROR:JSON document is valid JSON!\r\n");
return -1;
}
for(i=0;i<LedMax;i++)
{
/*通过JSON_Search()函数去解析json数据并且去寻找匹配�?�匹配是根据leds[LedMax]循环匹配查找�????*/
result=JSON_Search(json_string,bytes, leds[i].name,strlen(leds[i].name),&value,&valen);
if(JSONSuccess==result)
{
save = value[valen];
value[valen]="\0";
if(!strncasecmp(value,"on",2))
{
printf("DBUG:turn %s ON \r\n",leds[i].name);
turn_led(i,ON);
}
else if(!strncasecmp(value,"off",3))
{
printf("DBUG:turn %s OFF \r\n",leds[i].name);
turn_led(i,OFF);
}
value[valen]=save;
}
}
return 1;
}
void proc_uart1_recv(void)//串口1接收
{
if(g_uart1_bytes>0)
{
HAL_Delay(200);
if(0!=parser_led_json(g_uart1_rxbuf,g_uart1_bytes))//解析buf的数�?????
{
clear_uart1_rxbuf();//解析完成后buf清零
}
}
}
/* USER CODE END 4 */