概述
串口通讯是一个很成熟的通讯协议,几乎所有MCU都配有串口,本篇将述在Harmony中如何使用Usart,使用设备为PIC32MZ2048EFH,其他PIC32MZ基本相似。
以下使用的是Harmony的动态驱动,要注意动态驱动的使用规则,动态驱动排序为Driver中配置顺序,即InstanceIndex,而非Usart ID的顺序。
串口使用流程如下,以串口2为例:
1、配置串口驱动
2、配置串口引脚
3、生成代码,使用串口
注意Dynamic的驱动对象都需要有一个Open动作来创建一个Handle,后续所有操作都是用Handle来代表这个驱动对象。所有动态驱动的中断都是采用注册回调函数的方式来使用,无需到system_init中添加,也无需自己清除中断标识,驱动已经自己完成了。
另外要注意的一点是,串口接收一个字节后进入了中断,如果不使用Read接收一下,那么后续就再也无法进入中断,就会出现仅中断一次的现象,因此,也不要在中断中进行耗时操作,避免没有及时接收数据,导致数据残缺不全。
包含头文件之后,第一步要initial(open一个客户端),然后就是调用读写函数,注意读的时候在中断中做简单处理,在APP_Tasks()中循环调用Uart_Task(),以处理接收到的数据。uart_printf支持与printf一样的功能,可打印数字。
uart.h
#ifndef _UART_H
#define _UART_H
#define uartMaxBufferSize 50
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include "system_config.h"
#include "system_definitions.h"
#include <stdio.h>
#include <stdarg.h>
typedef enum
{
Uart_Init,
Uart_Receive
}UART_STATE;
typedef struct
{
/*** uart ******/
DRV_HANDLE drvUartHandle;
UART_STATE uartState;
uint8_t uartBuffer[uartMaxBufferSize];
uint8_t uart_BufferSize;
bool uart_ByteReady; // one command block receive ready flag
}UART_DATA;
UART_DATA uartData;
bool Uart_Initial();
void Uart_Task(void);
void Uart_WriteByte(uint8_t c);
void Uart_WriteString(uint8_t *string);
void Uart_printf(const uint8_t *fmt,...);
void Uart_interrupt(const SYS_MODULE_INDEX index);
#endif
uart.c
#include "uart.h"
uint8_t uartCount;
uint8_t uartTmp;
/**************** uart ***************************/
void Uart_interrupt(const SYS_MODULE_INDEX index)
{
//Uart_WriteByte(UartCommandComeReady);
//if(DRV_USART_ReceiverBufferIsEmpty(uartData.drvUartHandle)) return;
uartTmp = DRV_USART_ReadByte(uartData.drvUartHandle);
if(uartData.uart_ByteReady)
return;
uartData.uartBuffer[uartCount] = uartTmp;
uartCount ++;
}
bool Uart_Initial()
{
uartData.uart_ByteReady = false;
uartData.uart_BufferSize = 0;
uartData.uartState = Uart_Init;
/*********** UART *******************/
uartData.drvUartHandle = DRV_USART_Open( DRV_USART_INDEX_0,DRV_IO_INTENT_EXCLUSIVE );
/* Check the USART1 driver handler */
if (uartData.drvUartHandle == DRV_HANDLE_INVALID )
{
return false;
}
DRV_USART_ByteReceiveCallbackSet(DRV_USART_INDEX_0, (DRV_USART_BYTE_EVENT_HANDLER)Uart_interrupt);
return true;
}
void Uart_Task(void)
{
switch(uartData.uartState)
{
case Uart_Init:
//Uart_Initial();
uartData.uartState = Uart_Receive;
break;
case Uart_Receive:
if(!uartData.uart_ByteReady) return;
uartData.uart_ByteReady = false;
break;
default:
break;
}
}
void Uart_WriteByte(uint8_t c)
{
while ((DRV_USART_TRANSFER_STATUS_TRANSMIT_FULL & DRV_USART_TransferStatus(uartData.drvUartHandle)) ) ;
DRV_USART_WriteByte(uartData.drvUartHandle,c);
}
void Uart_WriteString(uint8_t *string)
{
while(*string!='