具有高波特率循环缓冲器的 PIC 中断驱动 UART
Posted
技术标签:
【中文标题】具有高波特率循环缓冲器的 PIC 中断驱动 UART【英文标题】:PIC Interrupt driven UART with circular buffer at high baud rate 【发布时间】:2013-01-23 20:10:19 【问题描述】:我正在尝试从具有 PIC 18f4550 的传感器以波特率 = 38400 读取数据。使用 FIFO 循环缓冲区,我可以将传感器中的数据存储到数组中。
传感器将响应请求命令并返回 15 个字节的测量值(与我创建的循环缓冲区相同)。我必须抓取所有 15 个字节 并将 \r\n 放在末尾以分隔每个测量值,因为没有分隔符。
所以我使用了两个指针,inputpointer 和 outputpointer 来存储字节和传输字节。因为18f4550只有一个硬UART,所以我用它来读取数据并向传感器发送命令,同时使用软件UART通过RS232输出到笔记本电脑。
当缓冲区被读取并发送到串行端口时,我请求重新测量。
它工作得很好,但我只是想知道当头指针超出尾指针时,是否有更好的方法来避免 FIFO 溢出,即当有大量数据被缓冲但它们无法及时输出时。
这里是代码:16MHZ PIC 18f4550 mikroC 编译器
char dataRx[15];
char unsigned inputpointer=0;
char unsigned outputpointer=0;
// initialize pointers and buffer.
void main()
ADCON1=0x0F; //turn analog off
UART1_Init(115200); //initialize hardware UART @baudrate=115200, the same setting for the sensor
Soft_UART_Init(&PORTD,7,6,38400,0); //Initialize soft UART to commnuicate with a laptop
Delay_ms(100); //let them stablize
PIE1.RCIE = 1; //enable interrupt source
INTCON.PEIE = 1;
INTCON.GIE = 1;
UART1_Write(0x00); //request a measurement.
UART1_Write(0xE1); //each request is 2 bytes
while(1)
Soft_UART_Write(dataRx[outputpointer]); //output one byte from the buffer to laptop
outputpointer++; //increment output pointer
if(outputpointer==0x0F) //reset pointer if it's at the end of the array
outputpointer=0x00;
Soft_UART_Write(0x0D); //if it's at the end, that means the buffer is filled with exactly one measurement and it has been output to the laptop. So I can request another measurement.
Soft_UART_Write(0x0A); //add \r\n
UART1_Write(0x00); //request another measurement
UART1_Write(0xE1);
void interrupt(void) //interrupt routine when a byte arrives
dataRx[inputpointer]=UART1_Read(); //put a byte to a buffer
inputpointer++;
if (inputpointer==0x0F)inputpointer=0; //reset pointer.
【问题讨论】:
FIFO 溢出?您的代码中有一个 FIFO 欠载错误:在发送第一个字节之前,您没有检查是否有实际数据。它可能只是工作,因为你的软 uart 很慢。 @TurboJ 我正在购买带有 2 个 UART 模块的 dsPIC30f4011,它正在开发中。但我不认为它可以解决问题。发送数据的代码多于接收数据的代码,接收具有高优先级(中断驱动),因此最终会出现溢出,除非我停止请求,直到所有字节都发送出去。 有什么理由不使用单独的缓冲区进行传输和接收吗?从技术上讲,它们应该是单独的缓冲区。 【参考方案1】:也许您可以在传输传感器读数时禁用中断,然后在完成传输数据后重新启用它?
它可能不会产生重大影响,但它可能会阻止您提到的 FIFO 溢出?
【讨论】:
我想过这个问题,但是如果在我禁用中断之后有一个字节进入但我仍然在中断例程中怎么办?我会丢失那个字节对吗? 是的,当然,你会丢失字节。我很抱歉,我曾认为您的代码块是另一种方式,在 INTERRUPT 中,您将缓冲区数据导出到笔记本电脑(每隔一段时间(定时或缓冲区已满)),并在 MAIN 循环中缓冲传感器读数。以上是关于具有高波特率循环缓冲器的 PIC 中断驱动 UART的主要内容,如果未能解决你的问题,请参考以下文章