嵌入式

cc2530学习笔记

CC2530学习笔记

一、硬件资源:

二、功耗模式:

graph LR

Active --> IDLE --> PM1 --> PM2 --> PM3
模式 描述
Active 全速运行,高速时钟(32M、16M)运行
IDLE CPU停止,时钟不停
PM1 高速时钟停下,低速时钟运行
PM2 内部稳压器工作,内存内容全部保留
PM3 内部稳压器不工作,低速时钟停止,内存内容全部保留

进入低功耗:①、确保当前的操作已经完成,如UART发送完成;②IO需要作出处理。

退出低功耗:①、IO重新初始化配置。

三、flash 结构

  • 1 Bank = 16 Pages = 32K
  • Address 0x8000 - 0xFFFF
  • Info 0x7800 - 7FFF(2K)

Flash操作特点:

  • 32-bit Programmable
  • 页擦除(Page)
  • 支持DMA写
  • 页擦除20ms
  • 芯片擦除 20ms
  • 写字(4Byte) 20us

注意事项:

  • 写Flash时时钟不能挺,不能写
  • 不可以进入低功耗模式
  • 时钟不要低于16M(使用stack没有问题)
  • LBF

Flash写流程:

  • 设置地址(FADDRH/L)
  • 置位FCTL.WRITE = 1
  • 写FWDATE,查询FCTL.FULL
  • FCTL.FULL变低后重复写
  • 检查超时,或者FLASH锁定
  • 完成或重复写

计算FADDR:

  • CC2530F256:256K
  • FADDR = Addr >> 2(4字节为1字)
  • FADDRH = (uint8_t)(FADDR >> 8)
  • FADDRL = (uint8_t)(FADDR)

Flash 擦除方法:

  • 关中断
  • 设置擦除页(FADDR) FADDR = addr >> (11-1)
  • 设置FCTL.ERASE
  • 等待结束

测试代码:

#include <ioCC2530.h>

unsigned char erase_page_num = 3;

/* Erase one flash page */
EA = 0;
while( FETL & 0X80 );
FADDRH = erase_page_num << 1;
FCTL |= 0X01;
EA = 1;

四、GPIO

  • 21个IO 都可作为数字输入/输出
  • 有IO之外特定的硬件功能
  • 输入上拉、下拉电阻(P10 P11)除外
  • 都可以接收中断,中断边沿可配置
  • 在休眠状态下PM1、PM2、PM3,配置和状态不变
  • 驱动电流4mA,(P10、P11 20mA)
  • P0口可作为ADC
  • P23、P24外界23K晶体
  • 所有IO都能产生中断,并且能用作唤醒系统使用

五、中断系统

  • 18个中断源
  • 4级中断优先级
  • 6个中断分组

中断优先级分组:

中断源
IPG0 RFERR RF DMA
IPG1 ADC T1 P2INT
IPG2 URX0 T2 UTX0
IPG3 URX1 T3 UTX1
IPG4 ENC T4 P1INT
IPG5 ST P0INT WDT

六、定时器

定时器 用作定时、计数、生成PWM,调制红外等。

CC2530定时器包括:

  • 数量3
  • 8位、16位定时器
  • 模式有 Free / Down / Modulo / Up & Down
  • 可以分配响应IO口,用作计数器、PWM、IR
  • 时钟可以分频
  • 单个定时器支持多通道

七、ADC

  • 14位转换结果,12位有效数字
  • 8个通道
  • 支持DMA不断采样。
  • 支持查分采样
  • 支持内部温度传感器、电压采样
  • 有4种参考电压可供选择
  • 支持自动定时采样、外部触发采样

CC2530中ADC重要参数:

参数 典型值 单位
输入阻抗 197
最高有效位数ENOB 11.5 bits
有效带宽 20 kHz
增益误差 0.68 %
最大转换时间 132 us
内部参考电压 1.15 V
电流消耗 1.2 mA

串口

CC2530拥有2路USART,其中串口还可配置为SPI模式

位数 8
时钟相位 可配置
主从 支持
LSB/MSB 可配置
中断 收 + 发
DMA 收 + 发
波特率 Max:8Mbps
位数 8、 9
校验 ODDEVENNONE
起、停电平 可配置
LSB、MSB 可配置
中断 收 + 发
DMA 收 + 发
校验 支持
流控 支持
波特率 2400 ~ 230400

三、OSAL

OSAL全称是Operating SystemAbstraction Layer

OSAL 特点:

  • TI 开发,在多个协议栈中通用的任务调度和事件处理的操作系统抽象层,它不是完整的操作系统。可以直接运行,也可以运行在RTOS等操作系统进程中。不支持抢占时间片,任务优先级不可以调整。
  • 完全开放源代码
  • 在OSAL上可以运行的对象,对象的时间和状态都在内部进行处理,按照ID从小到大,优先级逐渐降低。
  • OSAL最多支持255个任务;
  • 优先级不可更改;
  • 支持任务间同步;
  • 时间片不可抢占
  • 事件占用连续时间片;

OSAL主要功能:

  1. 静态任务注册、初始化、驱动任务
  2. 信息交换
  3. 任务同步
  4. 中断处理
  5. 时间管理
  6. 内存管理、掉电数据保存;

OSAL注意事项:

  • 相关的事件尽量放在一个任务,不相关的则考虑放在其他任务;
  • 工作流找关键点,并在此设置事件,用事件响应来完成作业;
  • 单个事件处理如果占用CPU时间过长,1ms或者更长的时间,就考虑事件是不是还能分成多个事件;
  • 合理利用事件和中断,将任务设计成“打卡式”执行的作业;
  • 合理的设计驱动,不让驱动占用不必要的时间片;
  • 中断代码简介高效。

OSAL事件:

  • 事件是任务中的触发点,每一个任务都有自己的事件,以及事件处理程序;

  • 事件在OSAL的层面是没有优先级的,取决于编码的位置;

  • 同一个任务中出现多个事件时,只能处理一个,其余返回(未处理任务异或返回);

  • 不同任务中事件的优先级继承任务的优先级;

  • 事件可以跨任务传递(任务同步);

  • 所有的事件一旦产生,必须要有响应的处理程序;

  • 一个任务最多有15个用户事件,1个系统事件。

OSAL定义事件、触发事件:

事件 代码 代号
系统事件 0x8000 SYS_EVENT_MSG
自定1 0x0001 APP_EVENT_1
自定2 0x0002 APP_EVENT_2
自定3 0x0004 APP_EVENT_3
...
自定15 0x4000 APP_EVENT_15

OSAL事件处理方法:事件处理统一入口在tasksArr

if(events & SYS_EVENT_MSG) {

    ...;
    return (events ^ SYS_EVENT_MSG);
}

OSAL优化思想:

  • 事件的处理事件还能不能再短;
  • 事件还能不能再分开;
  • 时间敏感的事件放在前面处理;
  • 一次处理一个事件;
  • 为止事件清零;

OSAL消息机制:

  • 不同任务或者运行环境下交换数据,通过申请OSAL管理的内存,赋予数据并将指针传递给目标任务,完成通信;
  • 发送方申请内存;
  • 接收方申请内存;

OSAL消息收发API:

uint8_t* osal_msg_allocate(uint16_t len)消息申请函数;

uint8_t* osal_msg_deallocate(uint8_t* msg_ptr)消息释放函数;

uint8_t osal_msg_send(uint8_t destination_task, uint8_t* msg_ptr)消息发送函数;

uint8_t* ssal_msg_receive(uint8_t self_task_id)消息接收函数;

OSAL任务同步:

  • 不同任务之间用户事件同步,利用同步可以避免任务等待占用CPU

OSAL同步API:

uin8_t osal_set_event(uint8_t task_id, uint16_t event_flag)同步API

OSAL软件定时器:

  • OSAL 支持软件定时器
  • 最小时间间隔1ms,最大时间间隔65.535s
  • 支持单次、自动重载
  • 可以跨任务调用
  • 定时器不支持回调
uint8_t osal_start_timerEx(uint8_t task_id, uint16_t event_id, uint16_t timeout_value); // 启动定时器
uint8_t osal_start_reload_timer(uint8_t taskID, uint16_t event_id, uint16_t timeout_value); // 定时器重装载
uint8_t osal_stop_timerEx(uint8_t task_id, uint16_t event_id);  // 定时器停止

OSAL内存管理

  • OSAL可以动态管理内存,进行动态分配和回收;
  • OSAL管理的内存大小为2k~3k
void* osal_mem_alloc(uint16 size);  // 动态申请内存
void osal_mem_free(void* ptr);      // 动态释放内存

注意:

  1. 长度较大的内存而且使用频率高的不要用动态内存;
  2. 任务间的消息可以使用动态内存;
  3. 一次分配,一次释放;
  4. 申请的内存,其指针要保存,作为释放的句柄;
OSAL电源管理PM部分:
  • OSAL支持功耗管理,确保设备可以用电池供电;
  • 在不工作期间,CC2530处于PM2;
  • IO中断可以唤醒OSAL;
  • 在低功耗状态下,系统会自动唤醒工作;
  • <= 2uA
  • 如果要进入PM3,需要改写OSAL;
  • POWER_SAVING编译条件要打开;
  • 必要时使用PWRMGR_BATTERY修改设备电源属性;

OSAL电源管理API函数:

void osal_pwrmgr_device(uint8_t pwrmgr_device);                     // 设置是否支持低功耗
uint8_t osal_pwrmgr_task_state(uint8_t task_id, uint8_t state);     // 设置指定任务低功耗状态

OSAL掉电存储:

OSAL Non-Volatile(NV) memory system

  • 系统中必要的数据在断电时要不丢失,需要使用NV
  • NV管理6 Page Flash
  • NV管理的Flash地址 Page 121 - Page 126

回复

This is just a placeholder img.