OSAL相关函数及分析:https://blog.csdn.net/weixin_39148042/article/details/81437042
https://blog.csdn.net/itas109/article/details/12952759
BLE系统架构:
OSAL启动流程:
OSAL工作原理示意图:
事件表和函数表:
OSAL层API接口:
复制模板,重命名:(关于协议栈的安装,请参考:https://blog.csdn.net/weixin_39148042/article/details/81490990)
打开工程:
配置串口:
定义一个串口相关的回调函数:
static void NpiSerialReadCB(uint8 port, uint8 event)
{
return;
}
串口初始化:
void NpiSerialReadCB(uint8 port, uint8 event);//对上一步定义的串口回调函数申明,便于串口初始化使用
NPI_InitTransport( NpiSerialReadCB );//串口初始化(使能串口),参数NpiSerialReadCB为串口的回调函数
添加串口打印api:
NPI_WriteTransport( "hello ble word !\n", strlen("hello ble word !\n") );//向串口发送数据
注意添加头文件:
#include "npi.h" //串口初始化函数和向串口写入数据相关函数
#include "string.h" //计算字符串长度的函数strlen()
加入HAL_UART=TRUE和HAL_UART_USB=FALSE,x掉POWER_SAVING和CC2540_MINIDK以及其他用不上的一些模块(如果不知道哪些模块用不上,那就只x掉POWER_SAVING和CC2540_MINIDK即可)。特别注意:这里一定要设置好,不然串口打印会出现问题。
添加前面两项,修改后面两项:
HAL_UART=TRUE
HAL_UART_USB=FALSE
xPOWER_SAVING
xCC2540_MINIDK
编译烧写程序:
实验结果:
复制模板并重命名:
所有关于硬件的控制都在HAL层里面:
控制LED灯使用到的函数和对应参数的可选项:
uint8 HalLedSet( uint8 led, uint8 mode );//控制LED灯的函数
/*函数参数一 LEDS - The LED number is the same as the bit position */
#define HAL_LED_1 0x01
#define HAL_LED_2 0x02
#define HAL_LED_3 0x04
#define HAL_LED_4 0x08
#define HAL_LED_ALL (HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4)
/*函数参数二 Modes 控制LED灯的工作模式,注意实际硬件上LED灯是共阳极还是共阴极,这里必须和实际硬件相一致*/
#define HAL_LED_MODE_OFF 0x00 //关灯(与模块PCB有关)
#define HAL_LED_MODE_ON 0x01 //开灯(与模块PCB有关)
#define HAL_LED_MODE_BLINK 0x02 //闪烁一次
#define HAL_LED_MODE_FLASH 0x04 //不断闪烁(最大闪烁只有255次)
#define HAL_LED_MODE_TOGGLE 0x08 //翻转LED状态
了解控制LED灯的函数之后,在事件中添加控制代码:
HalLedSet( HAL_LED_3, HAL_LED_MODE_TOGGLE );//翻转HAL_LED_3
HalLedSet( HAL_LED_1, HAL_LED_MODE_TOGGLE );//翻转HAL_LED_1
HalLedSet( HAL_LED_2, HAL_LED_MODE_TOGGLE );//翻转HAL_LED_2
x掉POWER_SAVING和CC2540_MINIDK:
xPOWER_SAVING
xCC2540_MINIDK
实验结果:LED灯每隔5秒翻转一次
CC2540相关寄存器(读芯片手册)
ADCCON1(0XB4) ADC控制寄存器1 |
BIT7:EOC ADC结束标志位 0:AD转换进行中 1:AD转换完成 |
BIT6:ST 手动启动AD转换 0:关闭 1:启动AD转换(需要BIT5:BIT4=11) |
|
BIT5:BIT4 AD转换启动方式 00:外部触发 01:全速转换,不需要触发 10:T1通道比较触发 11:手动触发 |
|
BIT3:BIT2 16位随机数发生器控制位 00:普通模式(13x打开) 01:开启LFSR时钟一次(13x打开) 10:保留位 11:关 |
|
ADCC0N2(0XB5) 序列AD转换控制寄存器2 |
BIT7:BIT6 SREF 选择AD转换参考电压 00:内部参考电压(1.25V) 01:外部参考电压AIN7输入 10:模拟电源电压 11:外部参考电压AIN6-AIN7差分输入 |
BIT5:BIT4 设置AD转化分辨率 00:64dec,7位有效 01:128dec,9位有效、 10:256dec,10位有效 11:512dec,12位有效 |
|
BIT3:BIT2:BIT1:BIT0 设置AD转换最末通道,如果置位时ADC正在运行,则在完成序列AD转换后立刻开始,否则置位后AD转换,转换完成后自动清0。 0000:AIN0 0001:AIN1 0010:AIN2 0011:AIN3 0100:AIN4 0101:AIN5 0110:AIN6 0111:AIN7 1000:AIN0-AIN1差分 1001:AIN2-AIN3差分 1010:AIN4-AIN5差分 1011:AIN6-AIN7差分 1100:GND 1101:保留 1110:温度传感器 1111:1/3模拟电源电压 |
|
ADCCON3(0XB5) 单通道AD转换控制寄存器3 |
BIT7:BIT6 SREF 选择单通道AD选择参考电压 00:内部参考电压(1.25V) 01:外部参考电压AIN7输入 10:模拟电源电压 11:外部参考电压AIN6-AIN7差分输入 |
BIT5:BIT4 设置单通道AD转换分辨率 00:64dec,7位有效 01:128dec,9位有效、 10:256dec,10位有效 11:512dec,12位有效 |
|
BIT3:BIT2:BIT1:BIT0 设置AD转换最末通道,如果置位时ADC正在运行,则在完成序列AD转换后立刻开始,否则置位后AD转换,转换完成后自动清0。 0000:AIN0 0001:AIN1 0010:AIN2 0011:AIN3 0100:AIN4 0101:AIN5 0110:AIN6 0111:AIN7 1000:AIN0-AIN1差分 1001:AIN2-AIN3差分 1010:AIN4-AIN5差分 1011:AIN6-AIN7差分 1100:GND 1101:保留 1110:温度传器 1111:1/3模拟电源电压 |
|
TR0(0x624B) | BIT0:置1表示将温度传感器与ADC连接起来 |
ATEST(0x61BD) | BIT0:置1表示将温度传感器启用 |
复制模板并重新命名
配置串口:
定义一个串口相关的回调函数:
static void NpiSerialReadCB(uint8 port, uint8 event)
{
return;
}
串口初始化:
void NpiSerialReadCB(uint8 port, uint8 event);//对上一步定义的串口回调函数申明,便于串口初始化使用
NPI_InitTransport( NpiSerialReadCB );//串口初始化(使能串口),参数NpiSerialReadCB为串口的回调函数
自定义ADC初始化函数
void Temperature_Init(void)
{
TR0 |= 0x01;//选择内部温度传感器
ATEST |= 0x01;
}
调用ADC初始化函数:初始化ADC(注意在使用函数时必须事先声明)
自定义一个函数,将ADC读取的数据转换为实际温度值并通过串口打印至电脑
uint16 Read_Temperature(void)
{
uint16 TempValue;
/*unsigned*/ char buf[10] = {0};
ADCIF = 0; //清除ADC中断标志
//HAL_ADC_DEC_512 = 0x30 //12位有效
ADCCON3 = (HAL_ADC_CHANNEL_TEMP | 0x30 | HAL_ADC_REF_125V);
/*wait for the conversion to finish*/
while(!ADCIF);
//ADCCON3 |=0X0E;//单通道AD转换源位温度传感器
//ADCCON3 &=0X3F;//单通道AD转换参考电压为1.25 内部电压
//ADCCON3 |=0X30;//单通道AD转换分辨率为512DEC,12位有效
//ADCCON1 |=0X30;//ADC启动方式选择为ADCCON1.ST=1事件
//ADCCON1 |=0X40;//ADC启动转换
//
//while(!ADCCON1&0X80);//等待AD转换完成
TempValue = ADCL >> 2; //ADCL寄存器低二位无效
TempValue |=(((uint16)ADCH)<<6); //连接ADCH 和ADCL,并赋值给value
TempValue = (TempValue >> 4) -315; //根据AD值,计算出实际的温度
//sprintf(buf, "%d c\n", TempValue);
//NPI_Printstring(buf);
sprintf(buf, "%d c\n", TempValue);
NPI_WriteTransport((uint8*)buf , strlen(buf));
//set 0c os minimum temprature, and 100c as max
if(TempValue >= 100)
{
return 100;
}
else if(TempValue <= 0)
{
return 0;
}
else
{
return TempValue;
}
}
在事件中添加上面的函数来读取并打印温度值:(注意在调用该函数时应事先声明该函数)
注意在该程序文件中添加相关的头文件:
#include "stdio.h" //把格式化的数据写入某个字符串中sprintf
#include "string.h" //计算字符长度strlen
#include "npi.h" //串口初始化及向串口发送数据
加入HAL_UART=TRUE和HAL_UART_USB=FALSE,x掉POWER_SAVING和CC2540_MINIDK以及其他用不上的一些模块(如果不知道哪些模块用不上,那就只x掉POWER_SAVING和CC2540_MINIDK即可)。特别注意:这里一定要设置好,不然串口打印会出现问题。
添加前面两项,修改后面两项:
HAL_UART=TRUE
HAL_UART_USB=FALSE
xPOWER_SAVING
xCC2540_MINIDK
编译烧写程序:
实验结果: