基于STM32驱动CC1101的程序分析 浅谈CC1101调试

发布者:WhisperingWish最新更新时间:2024-05-30 来源: elecfans关键字:STM32 手机看文章 扫描二维码
随时随地手机看文章

首先明确:CC1101是通过SPI与MCU进行通信的。根据从TI官方上获得CC1101驱动,直接先移植SPI部分,STM32F103提供了SPI1和SPI2两条SPI总线,可自行选择,对于SPI的移植,直接参考STM32开发板上关于通过SPI操作Flash示例代码,对于SPI的配置与TI提供的驱动代码里的SPI配置保持一致。SPI移植完成之后,接上CC1101射频模块,测试SPI是否能正常通信,主要通过向CC1101任意可读可写寄存器写一个任意值,然后再读出该寄存器里的值,通过串口打印出该值,通过以上操作判断SPI是否正常通信,SPI移植是否成功。当然,这里使用到了串口,所以需要同时将串口的代码实现,同样参考串口实例。


其次,当STM32与CC1101的SPI通信完成后,果断开始CC1101后续驱动的移植。移植过程中,所有变量名、函数名与TI提供的驱动里的保持一致,当然CC1101寄存器配置也保持移植。对于移植初期,我并没有太多的关心CC1101的时序问题,只关心怎么去移植,这也是自己的一个不好的习惯,所以初期移植的时候,对着TI提供的驱动代码,TI代码里有什么函数,我也移植什么函数;函数里有CS管脚的操作,也对应在操作在STM32下定义的CS管脚;TI里延时多长,我也跟着在STM32下延时相应的时间。整个驱动移植下来,关于CC1101的驱动函数也大多了然在心了。

/*

** CC1101 433MHz无线模块相互通信

** 2014-11-16

*/

#include “stm32f10x.h”

#include “cc1101.h”

#include “led.h”

/*************NVIC控制器配置***************************/

//组号 抢占位数 子优先级数量

// 组0 0 4

// 组1 1 3

// 组2 2 2

// 组3 3 1

// 组4 4 0

#define NVIC_PRIORITY_GROUP_0 (7 - 0)

#define NVIC_PRIORITY_GROUP_1 (7 - 1)

#define NVIC_PRIORITY_GROUP_2 (7 - 2)

#define NVIC_PRIORITY_GROUP_3 (7 - 3)

#define NVIC_PRIORITY_GROUP_4 (7 - 4)

#define NVIC_PRIORITY_GROUP (NVIC_PRIORITY_GROUP_2) /* 设置为组2 */

//#include “RF_Send.h”

//#include “task.h”

//***************更多功率参数设置可详细参考DATACC1100英文文档中第48-49页的参数表******************

//INT8U PaTabel[8] = {0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04}; //-30dBm 功率最小

//INT8U PaTabel[8] = {0x17,0x17 ,0x17 ,0x17 ,0x17 ,0x17,0x17 ,0x17}; //-20dBm

//INT8U PaTabel[8] = {0x1D,0x1D ,0x1D ,0x1D ,0x1D ,0x1D,0x1D ,0x1D}; //-15dBm

//INT8U PaTabel[8] = {0x26,0x26 ,0x26 ,0x26 ,0x26 ,0x26,0x26 ,0x26}; //-10dBm

//INT8U PaTabel[8] = {0x37,0x37 ,0x37 ,0x37 ,0x37 ,0x37,0x37 ,0x37}; //-6dBm

//INT8U PaTabel[8] = {0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60};//0dBm

//INT8U PaTabel[8] = {0x86,0x86 ,0x86 ,0x86 ,0x86 ,0x86,0x86 ,0x86}; //5dBm

const u8 PaTabel[8] = {0xC0 ,0xC0 ,0xC0 ,0xC0 ,0xC0 ,0xC0 ,0xC0 ,0xC0};//12dBm

u8 RF_Read_Buff[64];//接收缓冲区

_RF_Sta RF_Sta;//RF状态

/////////////////////////////////////////////////////////////////

const RF_SETTINGS rfSettings =

{

0x00,

0x08, // FSCTRL1 Frequency synthesizer control.

0x00, // FSCTRL0 Frequency synthesizer control.

0x10, // FREQ2 Frequency control word, high byte.

0xA7, // FREQ1 Frequency control word, middle byte.

0x62, // FREQ0 Frequency control word, low byte.

0x5B, // MDMCFG4 Modem configuration.

0xF8, // MDMCFG3 Modem configuration.

0x03, // MDMCFG2 Modem configuration.

0x22, // MDMCFG1 Modem configuration.

0xF8, // MDMCFG0 Modem configuration.

0x00, // CHANNR Channel number.

0x47, // DEVIATN Modem deviation setting (when FSK modulation is enabled)。

0xB6, // FREND1 Front end RX configuration.

0x10, // FREND0 Front end RX configuration.

0x18, // MCSM0 Main Radio Control State Machine configuration.

// 0x0F, // MCSM1 Main Radio Control State Machine configuration.

0x1D, // FOCCFG Frequency Offset Compensation Configuration.

0x1C, // BSCFG Bit synchronization Configuration.

0xC7, // AGCCTRL2 AGC control.

0x00, // AGCCTRL1 AGC control.

0xB2, // AGCCTRL0 AGC control.

0xEA, // FSCAL3 Frequency synthesizer calibration.

0x2A, // FSCAL2 Frequency synthesizer calibration.

0x00, // FSCAL1 Frequency synthesizer calibration.

0x11, // FSCAL0 Frequency synthesizer calibration.

0x59, // FSTEST Frequency synthesizer calibration.

0x81, // TEST2 Various test settings.

0x35, // TEST1 Various test settings.

0x09, // TEST0 Various test settings.

0x0B, // IOCFG2 GDO2 output pin configuration.

0x06, // IOCFG0D GDO0 output pin configuration. Refer to SmartRF?Studio User Manual for detailed pseudo register explanation.

0x04, // PKTCTRL1 Packet automation control.

0x05, // PKTCTRL0 Packet automation control.

0x00, // ADDR Device address.

RFDATLEN // PKTLEN Packet length.

};

//*****************************************************************************************

//函数名:delayus(unsigned int s)

//输入:时间

//输出:无

//功能描述:普通廷时,内部用

//*****************************************************************************************

void delayus(u16 timeout)

{

u8 i;

do

{

for(i=0; i《20; i++);

}

while (--timeout);

}

/*****************************************************************************************/

//函数名:CC1101_SpiInit()

//输入:无

//输出:无

//功能描述:SPI初始化程序

/*****************************************************************************************/

void CC1101_SpiInit(void)

{

RCC-》APB2ENR|=1《《4; //使能PORTC时钟

GPIOC-》CRL&=0Xff000000;

GPIOC-》CRL|=0X00833388;

GPIOC-》ODR|=0x00000023;

}

void Open_GD0_Interrupt(void)

{

uint32_t priority;

/* 使能io复用时钟 */

RCC-》APB2ENR |= 1 《《 0;

/* 配置为输外部中断5在PC5上 */

AFIO-》EXTICR[1] &= ~(0xF 《《 4);

AFIO-》EXTICR[1] |= (2 《《 4);

/* 开启外部中断5 */

EXTI-》IMR |= (1 《《 5);

/* 上升沿触发 */

EXTI-》RTSR |= (1 《《 5);

EXTI-》FTSR &= ~(1 《《 5);

NVIC_SetPriorityGrouping(NVIC_PRIORITY_GROUP); /* 设置为组2 */

priority = NVIC_EncodePriority (NVIC_PRIORITY_GROUP, 2, 3);

NVIC_SetPriority(EXTI9_5_IRQn,priority); /* EXTIx_IRQn 在stm32f10x.h中有定义 */

NVIC_EnableIRQ(EXTI9_5_IRQn);

}

//*****************************************************************************************

//函数名:SpisendByte(INT8U dat)

//输入:发送的数据

//输出:无

//功能描述:SPI发送一个字节

//*****************************************************************************************

u8 SpiTxRxByte(u8 dat)

{

u8 i,j,temp= 0;

SCK = 0;

for(i=0; i《8; i++)

{

if(dat & 0x80)MOSI = 1;

else MOSI = 0;

j++;j++;

dat 《《= 1;

j++;j++;

SCK = 1;

j++;j++;

temp 《《= 1;

if(MISO)temp++;

SCK = 0;

j++;j++;

}

return temp;

}

//*****************************************************************************************

//函数名:void RESET_CC1100(void)

//输入:无

//输出:无

//功能描述:复位CC1100

//*****************************************************************************************

u8 RESET_CC1100(void)

{

u16 n=0;

CSN = 0;

while(MISO)

{

if(++n》300)return 0;

delayus(5);

}

n=0;

SpiTxRxByte(CCxxx0_SRES); //写入复位命令

while(MISO)

{

if(++n》300)return 0;

delayus(5);

}

CSN = 1;

return 1;

}

//*****************************************************************************************

//函数名:void POWER_UP_RESET_CC1100(void)

//输入:无

//输出:无

//功能描述:上电复位CC1100

//*****************************************************************************************

u8 POWER_UP_RESET_CC1100(void)

{

CSN = 1;

delayus(10);

CSN = 0;

delayus(10);

CSN = 1;

delayus(100);

if(RESET_CC1100())return 1; //复位CC1100

return 0;

}

CC1101调试

关于滤波指令和寄存器配置:

其实这里也TFT配置差不多,玩过TFT的都有同感,TFT可以通过RW引脚控制是读还是写,如果是写寄存器,先写寄存器的地址,然后写数据,数据就到了相应的寄存器里面了;读就是RW引脚设置为读对应的电平,先写寄存器的地址,该寄存器里面的数据就可以读出来了。明白了这些其实理解CC1101就可以很容易理解了。


那么对应CC1101的理解:

寄存器的配置:

CC1101寄存器地址是0~0x3F,也就是BIT0~BIT5

CC1101读写控制是BIT7,BIT7为1时,为读对应的寄存器,BIT7为0时,为写相应的寄存器。

那么还剩下一个BIT6,BIT6是突发访问控制为,BIT6为1为突发访问,BIT6为0为单字节访问。(突发访问下面说)

这样我们就可以很容易理解了,比如配置PKTCTRL0寄存器,其地址0x08,我们突发访问写的话写先数据0x48,再连续写数据,这里明白了突发访问后就很容易知道了,如果单字节读这个寄存器,先写数据0x88,读一下就可以了。

命令滤波:

命令滤波这里和TFT的写0x22是一样的,它就自动跳转到寄存器的出口,cc1101这里也是,只要写一下对应的寄存器的地址,不用写数据,它就内部自动执行相应的指令,比如重启芯片,设置为发送模式,共有14个滤波指令,地址从0x30~0x3D。

关于滤波指令的状态寄存器其实是可读不可写的,

也就是0x30~0x3D的地址加上0xC0,(BIT7 和IBT6为1,前面说过了),比如写数据0xF4,就可以读到相应RSSI状态寄存器里面的值。

CC1101的几个状态:

几个状态分别是,IDLE,TX,RX,FSTXON,校准,迁移,RXFIFO_OVERFLOW,TXFIFO_OVERFLOW,有读的状态字的BIT6~BIT4决定


关键字:STM32 引用地址:基于STM32驱动CC1101的程序分析 浅谈CC1101调试

上一篇:利用STM32F103作为控制器进行设计便携式多道核谱仪
下一篇:浅谈STM32芯片行丝印含义,固件库命名规则及三大结构发展图示

推荐阅读最新更新时间:2026-03-25 10:44

STC89C52单片机驱动CC1101无线模块的发送C语言程序
#include reg52.h #include intrins.h #define INT8U unsigned char #define INT16 Uunsigned int #define WRITE_BURST 0x40//连续写入 #define READ_SINGLE 0x80//读 #define READ_BURST 0xC0//连续读 #define BYTES_IN_RXFIFO 0x7F //接收缓冲区的有效字节数 #define CRC_OK 0x80 //CRC校验通过位标志 //**************CC1100接口********* sbit GDO0=P3^3;
[单片机]
STM32学了两年半,却还是不会做项目
可能你已经学习了很久,但是当Leader抛给你一个STM32项目,你是不是依然手足无措? 有一朋友刚开始学习的51单片机,后来转STM32了。 主要是跟着网上的在线课程学习,自己下边跟着敲代码。 过程中学过各种培训机构出的视频课程,接触过操作系统,开发板上的例程都可以做出来。 后来他又学习了PCB绘制,由于在学校的时候没学到多少东西,而且不是电子类专业,陷入了迷茫,不知道该怎么学了。 记得在上大学的时候,专业课老师曾反复叮嘱我们“ 老师领进门,修行看个人 ”。 这话之后还没完,经常告诫我们要深入学习51单片机。 当时没有完全理解他的意思,直到工作若干年之后才知道。 在嵌入式领域,技术上有所精进,底层的东西
[嵌入式]
如何用 STM32 FLASH 实现等效 100 万次擦写的 EEPROM 功能?
在单片机开发中, 数据存储 是一个绕不开的话题。EEPROM因其非易失性存储特性,常用于保存配置参数等数据。 然而,EEPROM的擦写次数通常有限,以STM32为例,STM32L0、STM32L4自带的EEPROM一般 10万次 左右,而很多单片机并不内置EEPROM,这时候,利用单片机的FLASH存储器来模拟EEPROM就成为了一个高性价比的解决方案,但,FLASH的擦写次数一般在 1万次 左右,这个我们可以通过ST的官方数据手册看到: 1万次,在很多场景下并不够。 今天,老宇哥跟大家一起探讨,如何用单片机FLA
[嵌入式]
如何用 <font color='red'>STM32</font> FLASH 实现等效 100 万次擦写的 EEPROM 功能?
意法半导体中国本地造STM32微控制器启动规模量产
首批完全本地造的STM32微控制器(MCU)正陆续向本地客户交付 STM32微控制器的本地化制造进程以STM32H7高性能系列为开端,逐步扩展至侧重性能与安全的STM32H5系列,以及全新的入门级STM32C5系列 2026年3月23日,中国 – 服务多重电子应用领域、全球排名前列的半导体公司意法半导体 (STMicroelectronics,简称ST;) 宣布, 中国本地制造的STM32通用微控制器现已开启交付。首批由华虹宏力代工的意法半导体STM32晶圆产品已陆续发货给国内客户 。这一里程碑标志着意法半导体全球供应链战略的重大进展。公司计划2026年将有更多STM32产品系列(包括高性能、安全及入门级的微控制器)实现
[单片机]
意法半导体中国本地造<font color='red'>STM32</font>微控制器启动规模量产
基于STM32的矿井作业环境监测系统设计与实现
针对煤矿开采中瓦斯爆炸等严重安全隐患,设计了一套矿井安全系统。该系统实时监测瓦斯浓度、温度、火情、粉尘等环境参数,自动控制除尘、灭火、通风等设备,以保障矿井安全。通过WiFi将数据传输至监控平台,并支持APP远程监控与操作,从而提升应急响应速度和管理效率。 PART 01 系统总体结构 系统实现了对矿井内甲烷气体体积分数、粉尘浓度、火焰及温湿度等关键参数的实时采集与分析;并通过预设的自动控制策略触发联动设备,实现安全隐患的快速响应与主动防控。同时,支持数据远程传输至云端平台,并通过机智云APP提供实时监控、报警及远程操控功能,为矿井安全管理提供高效、可靠的技术支撑。系统总体结构如图1所示。 PART 02 系统详细设计
[单片机]
基于<font color='red'>STM32</font>的矿井作业环境监测系统设计与实现
STM32外设使用中的五个易错技巧与避坑指南
STM32作为嵌入式开发领域的热门微控制器,功能极为丰富,几乎能够完成所有常见控制任务,如GPIO等外设应有尽有。然而,正因为其功能强大,开发过程中也更容易遇到各种陷阱。许多初学者甚至经验丰富的开发者,常在外设配置上浪费大量时间,调试许久仍难以定位问题。本文总结了5个STM32外设使用中最易出错的技巧,旨在帮助你少走弯路、提高开发效率。 1. GPIO 配置别忘了上拉/下拉 很多初学者在读取按键、外部或中断输入时,会发现输入状态总是不稳定,甚至出现抖动或误触发。这通常是因为 GPIO 输入口浮空造成的。 常见坑: 输入引脚未配置上拉/下拉,导致状态随机波动。 上拉/下拉和外部电路冲突,影响可靠性。 输入误
[嵌入式]
STM32外设开发的五个常见陷阱与实战技巧
STM32作为嵌入式开发领域的热门微控制器,功能丰富,几乎能够胜任所有常见控制任务:GPIO、ADC、PWM等外设一应俱全。然而,正因其功能强大,开发中遇到陷阱的机会也随之增多。许多初学者甚至经验丰富的开发者,常在外设配置上浪费大量时间,调试许久仍无法定位问题。本文总结了5个STM32外设使用中最易踩坑的技巧,助你少走弯路,提升开发效率。 1. GPIO 配置别忘了上拉/下拉 很多初学者在读取按键、外部或中断输入时,会发现输入状态总是不稳定,甚至出现抖动或误触发。这通常是因为 GPIO 输入口浮空造成的。 常见坑: 输入引脚未配置上拉/下拉,导致状态随机波动。 上拉/下拉和外部电路冲突,影响可靠性。 输入
[嵌入式]
STM32单片机学习】第12章 GPIO—按键轮询
12.1 关于按键 前面控制LED灯是让GPIO输出高低电平,而获取按键则是读取GPIO电平,从而获知用户是否按下按键。 按键监测一般有两种:按键扫描和按键中断。按键扫描是间隔很短时间反复查询GPIO状态,从而得知是否有按键动作,这种方式代码简单,但比较耗资源。按键中断而是通过按键产生中断信号,从而实现按键的检测,这种方式需要使用到中断机制,需要对MCU了解深入一点,效果是最好的。 本节先介绍按键扫描,理解按键的基本原理,下一章再介绍按键中断,同时了解STM32F103的中断使用方法。 按键一般占用一个GPIO口,通过监测该GPIO的电平变化得知按键操作,典型的电路如图 12.1.1 所示。当所需按键比较多时,则可以采用矩阵按键减
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved