串口通信算是非常基础且实用的功能了,哪款单片机没有串口,那还好意思称自己为单片机么。当然,对于蓝牙SOC也不例外,这个神奇的功能也是必须要支持的。 本文简单讲一下在高通的蓝牙平台上如何实现串口通信功能。例子是基于QCC300x系列讲解的,同样也适用于老的芯片CSR867x,对于新平台QCC51xx经过微调也适用。 首先,贴上一段例子代码,如下:
#include <stream.h>
#include <sink.h>
#include <source.h>
#include <string.h>
#include <panic.h>
#include <message.h>
#include <app/uart/uart_if.h>
typedef struct
{
TaskData task;
Sink uart_sink;
Source uart_source;
} UARTStreamTaskData;
UARTStreamTaskData theUARTStreamTask;
static void UARTStreamMessageHandler (Task pTask, MessageId pId, Message pMessage);
static void uart_data_stream_rx_data(Source src);
static void uart_data_stream_tx_data(const uint8 *data, uint16 length);
static void uart_data_stream_init(void);
int main(void)
{
uart_data_stream_init();
/* Start the message scheduler loop */
MessageLoop();
/* Never get here...*/
return 0;
}
void uart_data_stream_init(void)
{
/* Assign task message handler */
theUARTStreamTask.task.handler = UARTStreamMessageHandler;
/* Configure uart settings */
StreamUartConfigure(VM_UART_RATE_38K4, VM_UART_STOP_ONE, VM_UART_PARITY_NONE);
/* Get the sink for the uart */
theUARTStreamTask.uart_sink = StreamUartSink();
PanicNull(theUARTStreamTask.uart_sink);
/* Get the source for the uart */
theUARTStreamTask.uart_source = StreamUartSource();
PanicNull(theUARTStreamTask.uart_source);
/* Register uart source with task */
MessageSinkTask(StreamSinkFromSource(theUARTStreamTask.uart_source),
&theUARTStreamTask.task);
}
void uart_data_stream_tx_data(const uint8 *data, uint16 length)
{
uint16 offset = 0;
uint8 *dest = NULL;
/* Claim space in the sink, getting the offset to it */
offset = SinkClaim(theUARTStreamTask.uart_sink, length);
if(offset == 0xFFFF) Panic();
/* Map the sink into memory space */
dest = SinkMap(theUARTStreamTask.uart_sink);
PanicNull(dest);
/* Copy data into the claimed space */
memcpy(dest+offset, data, length);
/* Flush the data out to the uart */
PanicZero(SinkFlush(theUARTStreamTask.uart_sink, length));
}
void uart_data_stream_rx_data(Source src)
{
uint16 length = 0;
const uint8 *data = NULL;
/* Get the number of bytes in the specified source before the next packet
boundary */
if(!(length = SourceBoundary(src)))
return;
/* Maps the specified source into the address map */
data = SourceMap(src);
PanicNull((void*)data);
/* Transmit the received data */
uart_data_stream_tx_data(data, length);
/* Discards the specified amount of bytes from the front of the specified
source */
SourceDrop(src, length);
}
void UARTStreamMessageHandler (Task pTask, MessageId pId, Message pMessage)
{
switch (pId)
{
case MESSAGE_MORE_DATA:
uart_data_stream_rx_data(((MessageMoreData *)pMessage)->source);
break;
default:
break;
}
} 以上代码是官方提供的,主要也就那么几个函数:
int main(void)
void uart_data_stream_init(void)
void uart_data_stream_tx_data(const uint8 *data, uint16 length)
void uart_data_stream_rx_data(Source src)
void UARTStreamMessageHandler (Task pTask, MessageId pId, Message pMessage)
看名称也知道这几个函数是啥意思,程序实现的功能也简单,从外部(如PC)发送数据给芯片(如QCC300x),芯片收到后将数据回发给外部芯片。没几行代码,稍微看一下就懂了,不多解释~ 当然,如果是要在sink上运行程序,你所要做的工作是把这段代码移植到sink工程中,不过,仅仅代码还是不够的,需要做一些修改。这里以QCC300x为例,其余芯片类似,但不绝对一样。 修改工程属性的Transport为Raw: 
在pstool中修改以下pskey:

最后用pc串口助手测试结果: 
看来收发一切正常~
来源:https://mp.weixin.qq.com/s/dD2jfaeNDEdZl5twcmGEBQ 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
|