上篇博客介绍了UART2的LOG打印,但是用的查询发送,没有用中断,也没有接收处理,这篇博客就用UART4的回环测试来学习下串口中断接收和发送。
一、RAM配置
我调试时候,定义了一个xdata数组,发现程序乱了,查看数据寄存器章节:
mdk配置如下:
在进行编译,下载,程序正常。
二、UART4寄存器
IO口说明:
特定端口,不需要配置。
三、驱动
/**************************************UART4***********************************/
#define UART4_ENABLE_RX() T5LIB_ATOM_CODE(SCON2R= SCON2R | 0x80;)
#define UART4_DISENABLE_RX() T5LIB_ATOM_CODE(SCON2R= SCON2R & 0x7F;)
#define UART4_ENABLE_TX() T5LIB_ATOM_CODE(SCON2T= SCON2T | 0x80;)
#define UART4_DISENABLE_TX() T5LIB_ATOM_CODE(SCON2T= SCON2T & 0x7F;)
#define UART4_ENABLE_RX_INT() T5LIB_ATOM_CODE(ES2R = 0x01;)
#define UART4_DISENABLE_RX_INT() T5LIB_ATOM_CODE(ES2R = 0x00;)
#define UART4_ENABLE_TX_INT() T5LIB_ATOM_CODE(ES2T = 0x01;)
#define UART4_DISENABLE_TX_INT() T5LIB_ATOM_CODE(ES2T = 0x00;)
#define UART4_CLEAR_RX_FLAG() T5LIB_ATOM_CODE(SCON2R= SCON2R & 0xFE;)
#define UART4_READ_RX_FLAG() (SCON2R & 0xFE)
#define UART4_CLEAR_TX_FLAG() T5LIB_ATOM_CODE(SCON2T= SCON2T & 0xFE;)
#define UART4_READ_TX_FLAG() (SCON2T & 0xFE)
bool uart4_set_baudrate(uint32_t baudrate)
{
union _union_uint32_t tTemp = {0};
bool bResult = false;
if(!baudrate){
return false;
}
T5LIB_ATOM_CODE(
SCON2T = SCON2T & 0xBF; //选择8位模式
tTemp.wTemp = (CPU_SYSCLK)/(baudrate*8l);
BODE2_DIV_H = tTemp.chTemp[2];
BODE2_DIV_L = tTemp.chTemp[3];
)
return true;
}
初始化:
static void uart4_init(void)
{
UART4_DISENABLE_TX_INT();
UART4_DISENABLE_RX_INT();
UART4_DISENABLE_TX();
UART4_DISENABLE_RX();
UART4_CLEAR_TX_FLAG();
UART4_CLEAR_RX_FLAG();
uart4_set_baudrate(115200);
UART4_ENABLE_RX();
UART4_ENABLE_TX();
UART4_ENABLE_RX_INT();
//UART4_ENABLE_TX_INT();
}
四、中断
static uint8_t xdata s_chBuffer[100] = {0};
static uint8_t s_chSize = 0;
static void uart4_init(void)
{
UART4_DISENABLE_TX_INT();
UART4_DISENABLE_RX_INT();
UART4_DISENABLE_TX();
UART4_DISENABLE_RX();
UART4_CLEAR_TX_FLAG();
UART4_CLEAR_RX_FLAG();
uart4_set_baudrate(115200);
UART4_ENABLE_RX();
UART4_ENABLE_TX();
UART4_ENABLE_RX_INT();
//UART4_ENABLE_TX_INT();
}
void uart4_rx_irq(void)
{
UART4_CLEAR_RX_FLAG();
if(s_chSize < sizeof(s_chBuffer)){
s_chBuffer[s_chSize] = SBUF2_RX;
s_chSize++;
}
}
void uart4_tx_irq(void)
{
static uint8_t i=1;
UART4_CLEAR_TX_FLAG();
if(i<s_chSize){
SBUF2_TX = s_chBuffer[i];
i++;
}else{
i=1;
s_chSize = 0;
UART4_DISENABLE_TX_INT();
}
}
void uart4_tx_start(void)
{
UART4_CLEAR_TX_FLAG();
UART4_ENABLE_TX_INT();
SBUF2_TX = s_chBuffer[0];
}
//中断处理
void UART4_T_ISR(void) interrupt 10
{
SAFE_ATOM_CODE(
extern void uart4_tx_irq(void);
uart4_tx_irq();
)
}
void UART4_R_ISR(void) interrupt 11
{
SAFE_ATOM_CODE(
extern void uart4_rx_irq(void);
uart4_rx_irq();
)
}
五、测试函数
void test_uart4(void)
{
static enum{
FSM_UART4_STATE_START = 0,
FSM_UART4_STATE_WAIT,
FSM_UART4_STATE_SEND,
FSM_UART4_STATE_CPL,
}s_tUart4State = FSM_UART4_STATE_START;
static uint8_t s_chSizeOld = 0;
static struct timer s_tUart4Timer = {0};
switch(s_tUart4State){
case FSM_UART4_STATE_START:
//s_chSizeOld = 0;
timer_set(&s_tUart4Timer,DELAY_TIMERS(20));
s_tUart4State = FSM_UART4_STATE_WAIT;
//break;
case FSM_UART4_STATE_WAIT:
if(!timer_expired(&s_tUart4Timer)){
break;
}
if(s_chSizeOld != s_chSize){
s_chSizeOld = s_chSize;
s_tUart4State = FSM_UART4_STATE_START;
}else{
if(s_chSize){
{
int8_t cData[10];
int i = 0;
i = sprintf(cData,"%bd",s_chSize);
write_dgusii_vp(0x500A,cData,10);
}
s_tUart4State = FSM_UART4_STATE_SEND;
}else{
s_tUart4State = FSM_UART4_STATE_START;
}
}
break;
case FSM_UART4_STATE_SEND:
uart4_tx_start();
timer_set(&s_tUart4Timer,DELAY_TIMERS(3000));
s_tUart4State = FSM_UART4_STATE_CPL;
//break;
case FSM_UART4_STATE_CPL:
if(!s_chSize || timer_expired(&s_tUart4Timer)){
s_tUart4State = FSM_UART4_STATE_START;
}
break;
default:
FSM_DEFAULT_ACTION();
}
}
结果: