cc2530入门 与串口中断处理_cc2530串口通信中断

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

在这里只给出单播实现的例子,以SimpleApp为例,其它两个方式原理和这个差不多,读者可自行设置:

参数配置
注:以下代码都需要进行粘贴(在SampleApp.c中)
文件开头定义 afAddrType_t Point_To_Point_DstAddr;
SampleApp_Init中添加参数配置
Point_To_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; //点播
Point_To_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
Point_To_Point_DstAddr.addr.shortAddr = 0x0000; //发给协调器

添加点对点发送函数
文件后面添加:
void SampleApp_SendPointToPointMessage( void )
{
uint8 data[10]={0,1,2,3,4,5,6,7,8,9};
if ( AF_DataRequest( &Point_To_Point_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_Point_To_Point_CLUSTERID,
10,
data,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}

修改参数
 在SampleApp.h中,添加 #define SAMPLEAPP_Point_To_Point_CLUSTERID 5
 SampleApp_ClusterList列表里面添加SAMPLEAPP_Point_To_Point_CLUSTERID,如:
const cId_t SampleApp_ClusterList[SAMPLEAPP_MAX_CLUSTERS] =
{
SAMPLEAPP_PERIODIC_CLUSTERID,
SAMPLEAPP_FLASH_CLUSTERID,
SAMPLEAPP_Point_To_Point_CLUSTERID
};
修改SAMPLEAPP_MAX_CLUSTERS 值为 3
(该部分修改内容可选)
 在if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )中,替换
SampleApp_SendPeriodicMessage()为
SampleApp_SendPointToPointMessage(),后面添加“LED1 闪烁提示”代码
HalLedBlink( HAL_LED_1, 2,50, 500 );

修改参数
 修改SampleApp_MessageMSGCB中簇ID为
SAMPLEAPP_Point_To_Point_CLUSTERID,并添加如下代码:
HalUARTWrite(0,“I get data\n”,11); //提示接收到数据
for(i=0;i<10;i++)
HalUARTWrite(0,&asc_16[pkt->cmd.Data[i]],1);//ASCII码发给PC机
HalUARTWrite(0,“\n”,1); // 回车换行
定义变量:
uint8 asc_16[16]={‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’,‘A’,‘B’,‘C’,‘D’,‘E’,‘F’},i;

修改参数
 屏蔽掉(SampleApp_NwkState == DEV_ZB_COORD),如:
if ( /*(SampleApp_NwkState == DEV_ZB_COORD)|| */(SampleApp_NwkState ==
DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE) )
 找到SampleApp_MessageMSGCB( MSGpkt );
后面添加“LED1 闪烁提示”代码 HalLedBlink( HAL_LED_1, 2,50, 500 );
 在文件开头声明void SampleApp_SendPointToPointMessage(void);
分别以协调器、终端或路由器的方式下载到2-3个设备中,连接串口
注:HalLedBlink( HAL_LED_1, 2,50, 500 ); //LED1 闪烁提示 进行指示
单播通信时,收发双方的端点号必须相同。到这里单播通信方式就实现了。

再此说一下串口:

1.在z_stack中,可以通过预编译和#define来选择是用DMA方式或中断方式进行数据传输。

首先打开hal_board_cfg.h文件,确定有以下语句:

/* Set to TRUE enable DMA usage, FALSE disable it */
#ifndef HAL_DMA
#define HAL_DMA TRUE
#endif

这段语句定义了编译器编译有关DMA的函数

这里引用一下:
任一权,刘童   的 协议栈中的MT包实现UART的发送与接收   
http://www.docin.com/p-658995029.html

Zigbee协议栈已经把使用串口的条件准备好了,从应用角度讲,利用协议栈现有平台即ZStack自带的MT包来实现自己的串口应用,只需对协议栈做一些修改就可以实现URAT发送与接收的功能。

关键函数的解析

MT_UartInit () ①

这是为UART串口传输数据而初始化的MT函数包,在其中定义了串口的波特率,最大接收发送数据量,传输模式等相关配置。在这里的各项参数不需要改变,保持系统默认即可。

MT_UartProcessZToolData() ②

这是MT程序包中URAT接收数据的代码,在这里面需要修改的地方是,在数据接收完毕后需要添加一个回车,便于我们区分不同传输数据,具体的代码为UartRxBuf.RxBuf[count]=‘\n’;此段代码需要添加在count++;后,这里注意一下count,一会还会用到。

hal_board_cfg.h ③

首先说明一下,串口接收发送数据的方式有两种:一种是中断模式,另一种是DMA模式,这里是使用中断模式。而在hal_board_cfg.h中,DMA模式的优先级要高于中断模式的,这里最简单的解决方案就是将DMA的那段预编译注释掉,即仅留一种模式——中断。

void Sampleapp_Init ④

这是应用层函数初始化,即对我们自己的具体应用进行初始化,在这里面需要添加两段代码 MT_UartInit() 和 MT_UartRegisterTaskID(SampleApp_TaskID);这两端代码要添加在Sampl Init()中。

MT_UartInit()

MT_UartRegisterTaskID(SampleApp_TaskID); ⑤

Sampleapp_ProcessEvent ⑥

case SPI_INCOMING_ZTOOL_PORT UartRxComCallBack()

代码功能及执行流程

至此,串口发送接受数据的已经全部修改完毕,可以将程序下载到板子上,利用PC机上的程序调试助手向2530发送数据,在程序调试助手和板子上的液晶屏上分别显示。我们在回顾一下代码的执行顺序

  1. 首先进行各种初始化,这里就不再详解
  2. 程序进去osal_start_system,开始进行轮询有没有要处理的事件
  3. 这时如果从串口发送一个数据,发生中断,(这里我们利用的中断模式)

在OSAL框架中,Hal_ProcessPoll()函数是在一个死循环中,所以每过一定的时间就会执行到。在Z-Stack OSAL中这个时种节奏定义是1ms,Hal_ProcessPoll()的作用是检测中断标志位,由于串口已经接收到数据,所以进入中断处理,具体处理过程如下HalUARTPoll(); ( HalUARTPollISR(); ( static uint16 HalUARTRxAvailISR(void)

(然后就进入了MT_UartProcessZToolData;(详解如下) (数据接收完毕后又进入轮询,由于sampleapp中已经不为空了,所以就会执行sampleapp中的操作,在Sampleapp中的

case SPI_INCOMING_ZTOOL_PORT:

UartRxComCallBack();

break;

这段代码将被执行,UartRxComCallBack();中的代码如上述红字表示,完成我们设定的相应功能。

实验数据

利用程序调试助手测试一下程序的收发速率(波特率为115200)

附:涉及的代码:

① void MT_UartInit ()

{

halUARTCfg_t uartConfig;

/* Initialize APP ID */

App_TaskID = 0;

/* UART Configuration */

uartConfig.configured = TRUE;

uartConfig.baudRate = MT_UART_DEFAULT_BAUDRATE;

uartConfig.flowControl = FALSE;

uartConfig.flowControlThreshold = MT_UART_DEFAULT_THRESHOLD;

uartConfig.rx.maxBufSize = MT_UART_DEFAULT_MAX_RX_BUFF;

uartConfig.tx.maxBufSize = MT_UART_DEFAULT_MAX_TX_BUFF;

uartConfig.idleTimeout = MT_UART_DEFAULT_IDLE_TIMEOUT;

uartConfig.intEnable = TRUE;

#if defined (ZTOOL_P1) || defined (ZTOOL_P2)

uartConfig.callBackFunc = MT_UartProcessZToolData;

#elif defined (ZAPP_P1) || defined (ZAPP_P2)

uartConfig.callBackFunc = MT_UartProcessZAppData;

#else

uartConfig.callBackFunc = NULL;

#endif

/* Start UART */

#if defined (MT_UART_DEFAULT_PORT)

HalUARTOpen (MT_UART_DEFAULT_PORT, uartConfig);

#else

/* Silence IAR compiler warning */

(void)uartConfig;

#endif

/* Initialize for ZApp */

#if defined (ZAPP_P1) || defined (ZAPP_P2)

/* Default max bytes that ZAPP can take */

MT_UartMaxZAppBufLen = 1;

MT_UartZAppRxStatus = MT_UART_ZAPP_RX_READY;

#endif

}

void MT_UartProcessZToolData ( uint8 port, uint8 event )

{

osal_event_hdr_t *msg_ptr;

uint8 ch;

count = 35;

(void)event; // Intentionally unreferenced parameter

while (Hal_UART_RxBufLen(port))

{

HalUARTRead (port, ch, 1);

if((ch == ’ ') (count 31))//帧头

{

UartRxBuf.RxBuf[0] = ch;

count = 1;

}

else if((ch == ‘*’) || (count == 31))//帧尾

{

UartRxBuf.RxBuf[count] = ch;

count++;

UartRxBuf.RxBuf[count]=‘/n’;

msg_ptr = (osal_event_hdr_t *)osal_msg_allocate( 50 );

msg_ptr- event = SPI_INCOMING_ZTOOL_PORT;// 这里会在以后的case中用到,作为一个事件的标致

msg_ptr- status = (byte)state;

osal_msg_send( App_TaskID, (uint8 *)msg_ptr );

这几句是关键,在接收数据完毕后,为时间消息分配缓存,设置事件标志,保存状态,最后一句最重要,将包含该消息的指针发送到App_TaskID任务ID中,使得在下一次轮询时能够检测到此状态的变化,执行相应的后续操作。

}

else if(count 31)//否则接收数据

{

UartRxBuf.RxBuf[count] = ch;

count++;

}

else

{

count++;

}

}

}

//#if HAL_UART

// Always prefer to use DMA over ISR.

/* #if HAL_DMA

#ifndef HAL_UART_DMA

#if (defined ZAPP_P1) || (defined ZTOOL_P1)

#define HAL_UART_DMA 1

#elif (defined ZAPP_P2) || (defined ZTOOL_P2)

#define HAL_UART_DMA 2

#else

#define HAL_UART_DMA 1

#endif

#endif

#define HAL_UART_ISR 0

#else */

// #ifndef HAL_UART_ISR 被注释掉的部分蓝色显示

#if (defined ZAPP_P1) || (defined ZTOOL_P1)

#define HAL_UART_ISR 1

#elif (defined ZAPP_P2) || (defined ZTOOL_P2)

#define HAL_UART_ISR 2

#else

#define HAL_UART_ISR 1

#endif

// #endif

#define HAL_UART_DMA 0

// #endif

// Used to set P2 priority - USART0 over USART1 if both are defined.

#if ((HAL_UART_DMA == 1) || (HAL_UART_ISR == 1))

#define HAL_UART_PRIPO 0x00

#else

#define HAL_UART_PRIPO 0x40

#endif

#else

#define HAL_UART_DMA 0

//#define HAL_UART_ISR 0

#endif

④ void Sampleapp_Init( uint8 task_id )

……

……

MT_UartInit(); //added by kennan

MT_UartRegisterTaskID(widget_TaskID) ; //自己添加

⑤ void MT_UartRegisterTaskID( byte taskID )

{

App_TaskID = taskID;

}

⑥ uint16 Sampleapp_ProcessEvent( uint8 task_id, uint16 events )

……

……

while ( MSGpkt )

switch ( MSGpkt- hdr.event )

……

case SPI_INCOMING_ZTOOL_PORT:

UartRxComCallBack();

……

⑦ UartRxComCallBack();

static uint8 y=0;

P1DIR |= 0x03; // P10、P11定义为输出

RLED = 0;// 这里是红灯和黄灯,如果此处编译有错误的话,在头文件里填

YLED = 0; // 加两个宏定义既可 。

ClearScreen();// 这 是清屏程序,作用是将液晶屏上的所有内容全部删除。

HalUARTWrite(HAL_UART_PORT_0,UartRxBuf.RxBuf,count+1); // 串口显示

Print(y%8, 0,UartRxBuf.RxBuf, 1);// 液晶屏幕显示

y+=2; 液晶可以换行显示

memset(UartRxBuf.RxBuf,NULL,count+1);// 清空UartRxBuf.RxBuf

} 注:在Sampleapp.c文件中还需要在前面添加一个extern uint16 count;外部变量,以便此段程序能够调用。(前面也提到过)

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

上的所有内容全部删除。

HalUARTWrite(HAL_UART_PORT_0,UartRxBuf.RxBuf,count+1); // 串口显示

Print(y%8, 0,UartRxBuf.RxBuf, 1);// 液晶屏幕显示

y+=2; 液晶可以换行显示

memset(UartRxBuf.RxBuf,NULL,count+1);// 清空UartRxBuf.RxBuf

} 注:在Sampleapp.c文件中还需要在前面添加一个extern uint16 count;外部变量,以便此段程序能够调用。(前面也提到过)

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
[外链图片转存中…(img-MiGL3Jsu-1715863770580)]
[外链图片转存中…(img-zkThiqEe-1715863770581)]

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值