Cypress的UART中断以及printf函数重映射调试
Cypress的串口调试
1、根据芯片型号新建一个工程
在TopDesign.cysch原理图中放置串口组件,如下图所示;
2.双击放置的串口组件进行相关参数设置:
串口通讯基本参数,配置接收中断;关于RX/TX buffer size 不知道有什么作用,若勾选了Byte Mode 则RX/TX buffer size必须要大于16;若勾选了DAM下面的配置,则RX/TX buffer size必须要等于8;原因未知,希望有了解的朋友可以赐教。
3.配置绑定引脚
本实验中串口的TX绑定为P4.1,RX绑定为4.0;
4.编译
编译成功后,打开main.c函数进行代码的移植,以及逻辑的编写;
int main(void)
{
/* Flag initialization */
received_character = 0;
error_uart = 0;
/* Start UART operation */
UART_Start();
/* Enable interrupt for UART */
UART_EnableInt();
/* Sets interrupt handler for UART */
UART_SetCustomInterruptHandler(*ISR_UART);
/* Enable global interrupts */
CyGlobalIntEnable;
//
/* Wait for RX fifo not empty interrupt */
for(;;)
{
//printf("sys:%d",bufs[0]);
//if(received_character == 1)
{
//received_character = 0;
/* Characters typed on console are transmitted via UART*/
//UART_UartPutChar(read_character);
printf("datanum=%d\r\n",ring_buffer.buffer[0]);
User_UART_Send((ring_buffer.buffer) ,RING_BUFFER_SIZE);
printf("datanum=%d\r\n",ring_buffer.buffer[RING_BUFFER_SIZE]);
CyDelay(1000);
}
if(error_uart == 1)
{
handle_error();
}
}
UART_Start();函数是串口的基本参数配置,以及串口使能;
UART_EnableInt();为串口中断使能;
UART_SetCustomInterruptHandler(*ISR_UART);该函数是给中断入口重新定义一个自己的名字,ISR_UART为中断入口;
void ISR_UART()
{
/* Returns the status/identity of which enabled RX interrupt source caused interrupt event */
uint32 source = UART_GetRxInterruptSource();
/* Checks for "RX FIFO AND not empty" interrupt */
if(0ul != (UART_INTR_RX_NOT_EMPTY & source))
{
/* Get the character from terminal */
read_character = UART_UartGetChar();
ring_buffer_queue(&ring_buffer, (char) read_character);
/* Clear UART "RX FIFO not empty interrupt" */
UART_ClearRxInterruptSource(UART_INTR_RX_NOT_EMPTY);
/* Sets received_character flag */
if(read_character==0xAA)
received_character = 1;
}
else
{
error_uart = 1;
}
UART_ClearPendingInt();
}
ISR_UART()中断入口函数;当获取的接收中断标志source部位空时,读取数据UART_UartGetChar();
ring_buffer_queue(&ring_buffer, (char) read_character);此处自己定义了一个环形数组,随接收到的数据进行压栈保存;每次进来后都要清一下中断标志位 UART_ClearRxInterruptSource(UART_INTR_RX_NOT_EMPTY);
数据发送函数UART_UartPutChar()每次发送一个字节,若要发送多字节,可按下面进行修改;
void User_UART_Send(uint8_t* databuff ,uint8_t length)
{
uint8_t i=0;
for(i=0;i<length;i++)
{
UART_UartPutChar(databuff[i]);
}
}
printf函数的重映射
在一些场合不方便接仿真工具时,可以用串口将数据打印出来。如:
printf("datanum=%d\r\n",ring_buffer.buffer[0]);
要使用Printf需要进行下列配置,否则程序会陷入死循环中;首先需要包含头文件#include <stdio.h>,然后重写_write()函数,_wite函数如下:
#if defined (__GNUC__)
/* Add an explicit reference to the floating point printf library to allow
use of floating point conversion specifier. */
asm (".global _printf_float");
/* For GCC compiler revise _write() function for printf functionality */
int _write(int file, char *ptr, int len)
{
/* Warning suppression for unused function parameter */
file = file;
int i;
/* Character is sent via UART */
for (i = 0; i < len; i++)
{
UART_UartPutChar(*(ptr++));
}
return(len);
}
#endif /* (__GNUC__) */
最后进行Heap Size大小调整,Heap Size默认值一般较小,若不调整,程序会卡死在Printf函数里出不来,Heap Size在System栏下的Option中,一般设置成0x300;
Cypress配置生成的代码中,有看到RX_buff相关的环形缓冲区的代码,但是没有用起来,自己做了一个环醒缓冲;还有一些配置,不知具体作用,还在探索中;