首先添加CC2640R2F串口驱动,驱动添加过程可以自行百度,选择通用的串口驱动添加方式,直接操作业务逻辑层(TI驱动层的上一层)我在这里贴出代码,串口接收采用回调方式加RTOS事件标志组,应用层采用队列方式,串口发送采用阻塞模式(因为我测试采用回调方式会出现问题,但是使用阻塞方式我也测试过不会影响应用层与GAP层连接等),代码如下(
文章中部分代码来源于百度搜索然后更改):
/*这里是C文件*/
#include "cc2640XX_Device.h"
#include
#include
#include
#include
#include "board.h"
#include
#include
#include
#include
#include
#include "Queue.h"
#include "icall.h"
void cc2640UART_readCallBack(UART_Handle handle, void *ptr, size_t size);
void cc2640Task_Fxn(UArg a0, UArg a1);
void cc2640_UART_Send(uint8_t* np_UART_TxBuf, uint16_t n_UART_Len) ;
static void cc2640_UART_Init(void) ;
#define CC2640_UART0_TX_PIN IOID_0
#define CC2640_UART0_RX_PIN IOID_1
#define CC2640_UART0_CTS_PIN IOID_2 /*这里如果不适用RTS/CTS可以关闭,将引脚设置成不可用*/
#define CC2640_UART0_RTS_PIN IOID_3
#define ER_UARTRX_EVT Event_Id_01
#define ER_ALL_EVT Event_Id_01
#define SDITASK_STACK_SIZE 640 /* in order to optimize memory, this value should be a multiple of 8 bytes */
//! \brief Task priority for SDI RTOS task
#define SDITASK_PRIORITY 2
//! \brief Max bytes received from UART send to App
#define DEFAULT_APP_DATA_LENGTH 20
uint8_t cc2640TaskStack[SDITASK_STACK_SIZE];
static uint8_t Rx_buffer[RX_BUFFER_LEN];
static Task_Struct cc2640TaskStruct;
static UartAppCallback cc2640_Uart_Fun;
Event_Struct cc2640uartEvent;
Event_Handle cc2640hUartEvent; //!< Event used to control the UART thread
typedef enum _UARTNUM {
CC2640_UART0 = 0,
CC2640_UARTCOUNT = 1
}UARTNUM;
const UARTCC26XX_HWAttrsV2 CC2640_UART_CC26XXHWAttrs[CC2640_UARTCOUNT] = {
{
.baseAddr = UART0_BASE,
.powerMngrId = PowerCC26XX_PERIPH_UART0,
.intNum = INT_UART0_COMB,
.intPriority = ~0,
.swiPriority = 0,
.txPin = CC2640_UART0_TX_PIN,
.rxPin = CC2640_UART0_RX_PIN,
.ctsPin = CC2640_UART0_CTS_PIN,
.rtsPin = CC2640_UART0_RTS_PIN,
}
};
static UARTCC26XX_Object cc2640_UART_CC26XXObjects[CC2640_UARTCOUNT];
static const UART_Config cc2640_UART_Config[CC2640_UARTCOUNT] = {
{
.fxnTablePtr = &UARTCC26XX_fxnTable,
.object = &cc2640_UART_CC26XXObjects[CC2640_UART0],
.hwAttrs = &CC2640_UART_CC26XXHWAttrs[CC2640_UART0]
}
};
static UART_Handle cc2640_UART_Handle;
static UART_Params cc2640_UART_Params;
void cc2640Task_createTask(void)
{
Task_Params sdiTaskParams;
Task_Params_init(&sdiTaskParams);
sdiTaskParams.stack = cc2640TaskStack;
sdiTaskParams.stackSize = SDITASK_STACK_SIZE;
sdiTaskParams.priority = SDITASK_PRIORITY;
Task_construct(&cc2640TaskStruct, cc2640Task_Fxn, &sdiTaskParams, NULL);
}
void cc2640Task_Fxn(UArg a0, UArg a1)
{
uint32_t SDITask_events;
uint16_t UartRxLen = 0;
uint16_t SendAppLen = 0;
uint8_t appBuf[DEFAULT_APP_DATA_LENGTH];
Event_Params evParams;
Event_Params_init(&evParams);
Event_construct(&cc2640uartEvent, &evParams);
cc2640hUartEvent = Event_handle(&cc2640uartEvent);
cc2640_UART_Init();
QueueInit();
for(;;)
{
SDITask_events = Event_pend(cc2640hUartEvent, Event_Id_NONE, ER_ALL_EVT, BIOS_WAIT_FOREVER);
ICall_CSState key;
key = ICall_enterCriticalSection();
if (SDITask_events & ER_UARTRX_EVT)
{
UartRxLen = lenQueue();
if (UartRxLen > 0)
{
if (UartRxLen >= DEFAULT_APP_DATA_LENGTH)
{
SendAppLen = DEFAULT_APP_DATA_LENGTH;
}
else
{
SendAppLen = UartRxLen;
}
deQueue(appBuf,&SendAppLen);
cc2640_Uart_Fun(UART_DATA_EVT,appBuf,SendAppLen);
if (lenQueue() > 0)
{
Event_post(cc2640hUartEvent,ER_UARTRX_EVT);
}
}
}
ICall_leaveCriticalSection(key);
}
}
static void cc2640_UART_Init(void) {
UART_Params_init(&cc2640_UART_Params);
cc2640_UART_Params.baudRate = 115200;
cc2640_UART_Params.readDataMode = UART_DATA_BINARY;
cc2640_UART_Params.writeDataMode = UART_DATA_BINARY;
cc2640_UART_Params.dataLength = UART_LEN_8;
cc2640_UART_Params.stopBits = UART_STOP_ONE;
cc2640_UART_Params.readMode = UART_MODE_CALLBACK;
cc2640_UART_Params.writeMode = UART_MODE_BLOCKING;
cc2640_UART_Params.readEcho = UART_ECHO_OFF;
cc2640_UART_Params.readCallback = cc2640UART_readCallBack;
cc2640_UART_Params.writeCallback = NULL;
cc2640_UART_Handle = cc2640_UART_Config[0].fxnTablePtr->openFxn((UART_Handle)&cc2640_UART_Config[0],&cc2640_UART_Params);
cc2640_UART_Config[0].fxnTablePtr->controlFxn(cc2640_UART_Handle,UARTCC26XX_CMD_RETURN_PARTIAL_ENABLE,NULL);
cc2640_UART_Config[0].fxnTablePtr->readFxn(cc2640_UART_Handle,Rx_buffer,RX_BUFFER_LEN);
}
void cc2640_UART_Send(uint8_t* np_UART_TxBuf, uint16_t n_UART_Len)
{
cc2640_UART_Config[0].fxnTablePtr->writeFxn(cc2640_UART_Handle, np_UART_TxBuf, n_UART_Len);
}
void cc2640UART_readCallBack(UART_Handle handle, void *ptr, size_t size) {
uint16_t dataLen = 0;
dataLen = size;
ICall_CSState key;
key = ICall_enterCriticalSection();
if(lenQueue() == 0)
{
Event_post(cc2640hUartEvent,ER_UARTRX_EVT);
}
enQueue(ptr,&dataLen);
cc2640_UART_Config[0].fxnTablePtr->readFxn(cc2640_UART_Handle,Rx_buffer,RX_BUFFER_LEN);
ICall_leaveCriticalSection(key);
}
void cc2640XX_APP_UART_Callbanck(UartAppCallback Fun)
{
if (Fun != NULL)
{
cc2640_Uart_Fun = Fun;
}
}
/*这里是H文件*/
#ifndef CC2640XX_DEVICE_H
#define CC2640XX_DEVICE_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "stdint.h"
#define RX_BUFFER_LEN 300
#define UART_DATA_EVT 0x0010
typedef void (*UartAppCallback) (uint8_t event, uint8_t *pMsg, uint8_t len);
extern void cc2640Task_createTask(void);
extern void cc2640XX_APP_UART_Callbanck(UartAppCallback Fun);
extern void cc2640_UART_Send(uint8_t* np_UART_TxBuf, uint16_t n_UART_Len) ;
#ifdef __cplusplus
}
#endif
#endif /* SDI_TL_UART_H */
/*缓冲部分源码,引用百度上面的源码*/
#include "Queue.h"
#include "stdint.h"
static EenQ queue;
void QueueInit(void) {
queue.rear = 0;
queue.front = 0;
memset(queue.data,0x00,sizeof(queue.data));
memset(queue.data,0x00,sizeof(queue.data));
}
/*------------------串口数组队列--------------*/
void enQueue(uint8_t *pElement, uint16_t *len)
{
//队列的尾在队列头的前面一位,或者队尾在最后,队头在第一个也是满的
if ((queue.rear+1)%(MAX_SIZE+1) == queue.front)
{
*len = 0;
return;
}
if (queue.rear+1 < queue.front) //队列尾在队列头前面不止一个的情况下
//长度为queue.front - queue.rear - 1
{
*len = *len <= (queue.front-queue.rear) ? \
*len:queue.front-queue.rear;
memcpy(&queue.data[queue.rear], pElement, *len); /*将数据放到队列中*/
queue.rear += *len; /*队尾指针增加*/
}
else //队列的尾在队列头的后面长度为MAX_SIZE-queue.rear+queue.front
{
*len = *len <= (MAX_SIZE-(queue.rear-queue.front)) ? \
*len : MAX_SIZE-(queue.rear-queue.front);
if (queue.front == 0) //队列的头在第一个元素的情况
{
memcpy(&queue.data[queue.rear], pElement, *len);
queue.rear += *len;
}
else
{
if ((MAX_SIZE-queue.rear) >= *len)
{
memcpy(&queue.data[queue.rear], pElement, *len);
queue.rear = (queue.rear + *len)%(MAX_SIZE);
}
else
{
memcpy(&queue.data[queue.rear], pElement, MAX_SIZE-queue.rear);
queue.rear = *len-(MAX_SIZE-queue.rear);
memcpy(&queue.data[0], pElement+(*len-queue.rear), queue.rear);
}
}
}
}
/*-----------------------------出队列---------------------------*/
void deQueue(uint8_t *pElement, uint16_t *len)
{
if ((*len==0) || (queue.rear==queue.front))
{
*len = 0;
return;
}
if (queue.rear > queue.front)
{
*len = *len <= (queue.rear-queue.front) ? \
*len : (queue.rear-queue.front);
memcpy(pElement, &queue.data[queue.front], *len);
queue.front += *len;
}
else
{
*len = *len <= queue.rear+(MAX_SIZE-queue.front) ? \
*len : queue.rear+(MAX_SIZE-queue.front);
if (*len <= MAX_SIZE-queue.front)
{
memcpy(pElement, &queue.data[queue.front], *len);
queue.front = (queue.front + *len) % (MAX_SIZE);
}
else
{
memcpy(pElement, &queue.data[queue.front], (MAX_SIZE-queue.front));
queue.front = *len-(MAX_SIZE-queue.front);
memcpy(&pElement[*len-queue.front], &queue.data[0], queue.front);
}
}
}
/*----------------------------------计算队列中的元素个数-----------------------*/
uint16_t lenQueue( void ) // MAX_SIZE+1-(queue.rear-queue.front)
{
#if 0
if (queue.rear > queue.front) {
return (queue.rear+MAX_SIZE-queue.front)%(MAX_SIZE+1);
}
#endif
if (queue.front < queue.rear)
return (queue.rear - queue.front);
if (queue.rear < queue.front)
return ( MAX_SIZE - queue.front + queue.rear );
if (queue.rear == queue.front)
return 0;
}
/*H文件*/
#ifndef __QUEUE_H
#define __QUEUE_H
#include "stdlib.h"
#include "stdint.h"
#include "string.h"
/*最大的缓冲数量*/
#define MAX_SIZE 300
/*队列结构*/
typedef struct _EenQ {
uint16_t rear;
uint16_t front;
uint8_t data[MAX_SIZE ];
}EenQ;
extern void QueueInit(void) ;
extern void enQueue(uint8_t *pElement, uint16_t *len);
extern void deQueue(uint8_t *pElement, uint16_t *len);
extern uint16_t lenQueue( void );
#endif //end __QUEUE_H
应用层的源码只需要创建一个队列然后封装成一个函数注册到串口的Event中即可,请各位大牛帮我看一下写数据采用回调方式的问题,然后帮我留个言我在进行改进,小弟新手请各位大牛勿喷小弟!!!!