【发布时间】:2015-12-23 10:43:23
【问题描述】:
- 微控制器:
dsPIC33EP512MU810 - 编译器:
MikroC
我正在尝试通过UART 从远程设备请求多个字节。
要获取所需的信息,您发送一个请求字节以接收单个数据字节。
请求多个字节时,我无法识别数据字节。
UART接收通过中断处理:
void UART2RXInterrupt() iv IVT_ADDR_U2RXINTERRUPT
{
uart_rd2[LoopVar0] = UART2_Read(); //Read into buffer
LoopVar0++;
if (LoopVar0 >= 1)
{
LoopVar0 = 0;
ready0 = 1;
}
U2RXIF_bit = 0; //Reset interrupt flag
}
我的单个数据字节的代码如下所示:
UART2_Write(0x11); //Request byte
if (ready0 == 1) //Data received and ready
{
//Parse data byte
ready0 = 0; //Reset data received bit
}
这很好用。
如果我需要更多,那么我只需要一个数据字节,如下所示
UART2_Write(0x11); //Request byte 11h
if (ready0 == 1) //Data received and ready
{
//Parse data byte
ready0 = 0; //Reset data received bit
}
UART2_Write(0x14); //Request byte 14h
if (ready0 == 1) //Data received and ready
{
//Parse data byte
ready0 = 0; //Reset data received bit
}
这种方法的问题是下一个请求字节可能已经被传输,而不能确定最后一个数据字节是否被正确接收。
这会导致数据“乱码”。这意味着可以在当前请求中解析来自最后一个请求的数据字节,依此类推。
我似乎找不到合适的解决方案。任何建议都会很棒!
循环缓冲区实现:
UART中断:
void UART2RXInterrupt() iv IVT_ADDR_U2RXINTERRUPT
{
uart_rcv[write_buffer_pointer0] = UART2_Read(); // put received char in circular buffer
write_buffer_pointer0++; // increment pointer
if (write_buffer_pointer0 > 511) {
write_buffer_pointer0 = 0; // reset pointer
}
U2RXIF_bit = 0;
}
主循环处理:
void service_UART()
{
UART_send(0x14); //MAP request
UART_send(0x1D); //ECT request
if (read_buffer_pointer0 != write_buffer_pointer0) { // new data in circular buffer
ser_in(); // handle incoming serial data
}
}
UART 发送例程:
void UART_send(volatile char data0)
{
uart_snd[write_buffer_pointer1] = data0;
write_buffer_pointer1++; // increment pointer
if (write_buffer_pointer1 > 511) {
write_buffer_pointer1 = 0; // reset pointer
}
UART2_Write(data0);
}
处理收到的数据:
void ser_in()
{
volatile char rqst;
volatile char resp;
resp = uart_rcv[read_buffer_pointer0]; // read next character from buffer
read_buffer_pointer0++; // increment read buffer pointer
if (read_buffer_pointer0 > 511) { // if pointer past end of buffer
read_buffer_pointer0 = 0; // reset pointer
}
rqst = uart_snd[read_buffer_pointer1];
read_buffer_pointer1++;
if (read_buffer_pointer1 > 511) {
read_buffer_pointer1 = 0;
}
// do something with the data here.
if (rqst == 0x14) //If MAP request
{
//Handle MAP Data
}
if (rqst == 0x1D) //If ECT request
{
//Handle ECT Data
}
}
【问题讨论】:
-
你是什么平台?您的框架/SDK 是什么?如何以及在何处管理
ready0?我们需要更多信息和代码来帮助您。 -
我添加了信息。谢谢!
-
为什么每次收到一个字节就重置缓冲区索引?
-
我没有得到你。我想您应该将
if (ready0 == 1)更改为while (ready0 == 0)。这允许您在单个请求后等待每个单个字符。 -
如果你想增加缓冲区大小,你必须实现一个假脱机程序。然后是中断中的输入索引和消费者的输出索引。在这种情况下,你的缓冲区变成了一个循环队列。
标签: c communication microcontroller uart dspic