如何使用SX1278的中断控制发送和接收

中断寄存器

在SX1278中,中断寄存器的地址是0x12, 在数据手册中称为RegIrqFlag. 是一个非常重要的寄存器,利用这个寄存器可以控制芯片读取接收到的信息。

首先要介绍这个寄存器各个位的含义:

Name(Address)BitsVariable NameModeResetLoRa Description
RegIrqFlag7RxTimeoutrc0x00Timeout interrupt, write a 1 clears the IRQ
6RxDonerc0x00Packet receive complete interrupt, write a 1 clears the IRQ
5PayloadCrcErrorrc0x00Payload CRC error interrupt, write a 1 clears the IRQ
4ValidHeaderrc0x00Valid header received in RX: write a 1 clears the IRQ
3TxDonerc0x00FIFO payload transmission complete interrupt: write a 1 clears the IRQ
2CadDonerc0x00CAD complete: write a 1 clears the IRQ
1FhhsChangeChannelrc0x00FHHS change channel interrupt: write a 1 clears the IRQ
0CadDetectedrc0x00Valid LoRa signal detected during CAD operation: write a 1 clears the IRQ

第7位:
RxTimeout接收超时中断,要在接收状态等待,接收超过(博客中文章提及)定义的时间,产生超时中断。写入该位为1清除该中断位。
第六位:
RxDone接收完成产生中断:写1清除该中断位。
第五位:
发送数据CRC错误中断。写1清除中断位。
第四位:
Rx接收到正确的头数据中断。写1清除中断位。
第三位:
Tx发送完成中断。FIFO中的数据发送完成中断。写1清除中断位。
第二位:
CAD完成中断。写1清除该中断位。
第一位:
FHHS变换通道中断。写1清除该中断位。
第零位:
在CAD期间检测到正确的LoRa信号中断,写1清除该中断位。

中断寄存器在程序中使用

在运行过程中,如果没有编写回调函数,要在程序中不断用程序来检测这个中断寄存器的数值,当数值大于1时,需要判断是哪个位被置1了。发送一组数据,然后等待应答的例子程序程序如下:


	SX1278WriteBuffer(REG_LR_IRQFLAGS, 0xFF);
	// 清除所有的中断
	FUN_RF_SENDPACKET(“my Message", 10);
	// 延时,等待发送完成,并清除中断
	delayMS(1000);
	SX1278WriteBuffer(REG_LR_IRQFLAGS, 0xFF);
	sxStep = 1;
	if (sxStep == 1)
	{
		RF_EX0_STATUS = SX1278ReadBuffer(REG_LR_IRQFLAGS);
		if ( !bUnCnt  && RF_EX0_STATUS > 0 )
		{
			bUnCnt = true;
			if (( RF_EX0_STATUS & 0x08 ) == 0x08)
			{	
				SX1278LoRaSetOpMode( Stdby_Mode );	// 设置standby mode
				SX1278WriteBuffer(REG_LR_IRQFLAGSMASK, IRQN_RXSIG_Value);
				// IRQN_RXSIG_Value = 0x1F
				// 屏蔽0-4位中断,打开5-7
				// bit 7: RXTimeoutMask
				// bit 6: RxDoneMask
				// bit 5: PayloadCrcErrorMask
				SX1278WriteBuffer(REG_LR_HOPPERIOD, 0xFF);
				SX1278LoRaSetOpMode( receive_single);
				// 本次接收到TxDone中断,不再执行对发送中断的判断
			}
		}
		if (RF_EX0_STATUS > 0)
		{
			if ( (RF_EX0_STATUS & 0x40 ) == 0x40)			// RxDone 中断发生
			{
				SX1278WriteBuffer(REG_LR_FIFOADDRPTR, 0x00);		// 确定起始指针
				SX1278_RLEN = SX1278ReadBuffer(REG_LR_NBRXBYTES);	// 获取接收的字节数量
				FUN_RF_READPACKET(RECV, SX1278_RLEN);
				// 接收应答完毕
			}
			if (( RF_EX0_STATUS & 0x80 ) == 0x80 ) 		// RxTimeout 中断发生
			{
				SX1278LoRaSetOpMode(Stdby_mode);
				SX1278WriteBuffer(REG_LR_IRQFLAGSMASK, 0xFF); // 屏蔽所有中断
				SX1276LoRaSetOpMode(Sleep_mode);			// 进入休眠状态
			}
			sxStep = 0}
	}

中断程序说明

简单总结发送和接收的过程即,当发送完一个信息后,如果是要等待应答的话,需要在接到了TxDone后进入接收等待的状态,在规定的时间内接收到回答信号就开始接收,如果发生了超时接收中断信号,就放弃。进入下一次的发送过程。

在程序中,使用0x08 即第3位,TxDone发送完成中断;0x40即第六位,RxDone接收完成中断;RxTimeout中断;通过这些中断位,控制发送和接收,在超时时退出接收过程。

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
我可以提供一个基于STM32平台的SX1278无线模块的带DIO的发送接收程序的参考代码。请注意,这只是一个参考代码,具体的实现可能会因为硬件平台的不同而有所差异。 发送程序代码: ``` #include "stm32f10x.h" #include "sx1278.h" #define DIO0_Pin GPIO_Pin_0 #define DIO0_Port GPIOA void SX1278_Init(void) { // 初始化SX1278模块 } void SX1278_SendPacket(uint8_t* buffer, uint8_t size) { // 设置SX1278发送模式 SX1278_SetMode(SX1278_MODE_TX); // 等待发送准备就绪 while(!SX1278_IsTxDone()); // 清除中断标志 SX1278_ClearInterrupt(SX1278_IRQ_TX_DONE); // 发送数据包 SX1278_WriteBuffer(buffer, size); // 等待发送完成 while(!SX1278_IsInterruptAsserted(SX1278_IRQ_TX_DONE)); // 重新设置SX1278接收模式 SX1278_SetMode(SX1278_MODE_RX_CONTINUOUS); } int main(void) { // 初始化GPIO和SPI接口 // ... // 初始化SX1278模块 SX1278_Init(); while(1) { uint8_t buffer[] = "Hello, World!"; uint8_t size = sizeof(buffer); // 发送数据包 SX1278_SendPacket(buffer, size); } } ``` 接收程序代码: ``` #include "stm32f10x.h" #include "sx1278.h" #define DIO0_Pin GPIO_Pin_0 #define DIO0_Port GPIOA void SX1278_Init(void) { // 初始化SX1278模块 } void SX1278_OnDio0Interrupt(void) { // 中断处理函数 if(SX1278_IsInterruptAsserted(SX1278_IRQ_RX_DONE)) { // 数据包已经接收完成 uint8_t buffer[256]; uint8_t size = SX1278_ReadBuffer(buffer, sizeof(buffer)); // 处理接收到的数据包 if(size > 0) { // ... } // 清除中断标志 SX1278_ClearInterrupt(SX1278_IRQ_RX_DONE); } } int main(void) { // 初始化GPIO和SPI接口 // ... // 初始化SX1278模块 SX1278_Init(); // 配置DIO0为中断引脚 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = DIO0_Pin; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DIO0_Port, &GPIO_InitStruct); // 配置DIO0中断 EXTI_InitTypeDef EXTI_InitStruct; EXTI_InitStruct.EXTI_Line = EXTI_Line0; EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStruct.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStruct); // 开启DIO0中断 NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); // 进入接收模式 SX1278_SetMode(SX1278_MODE_RX_CONTINUOUS); while(1) { // 等待中断 __WFI(); } } void EXTI0_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line0) != RESET) { // 处理DIO0中断 SX1278_OnDio0Interrupt(); EXTI_ClearITPendingBit(EXTI_Line0); } } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值