物联网之蓝牙4.0BLE开发二(基础实验:UART、 LED、 ADC)

OSAL层(操作系统抽象层)工作原理

OSAL相关函数及分析:https://blog.csdn.net/weixin_39148042/article/details/81437042

                                          https://blog.csdn.net/itas109/article/details/12952759

BLE系统架构

OSAL启动流程

OSAL工作原理示意图

事件表和函数表

OSAL层API接口

BLE_UART实验

复制模板,重命名:(关于协议栈的安装,请参考: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=TRUEHAL_UART_USB=FALSE,x掉POWER_SAVING和CC2540_MINIDK以及其他用不上的一些模块(如果不知道哪些模块用不上,那就只x掉POWER_SAVING和CC2540_MINIDK即可)。特别注意:这里一定要设置好,不然串口打印会出现问题。

添加前面两项,修改后面两项:
HAL_UART=TRUE
HAL_UART_USB=FALSE
xPOWER_SAVING
xCC2540_MINIDK

编译烧写程序:

实验结果:

 BLE_LED实验

复制模板并重命名:

所有关于硬件的控制都在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秒翻转一次

ADC实验(开发过程中会经常用到)

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=TRUEHAL_UART_USB=FALSE,x掉POWER_SAVING和CC2540_MINIDK以及其他用不上的一些模块(如果不知道哪些模块用不上,那就只x掉POWER_SAVING和CC2540_MINIDK即可)。特别注意:这里一定要设置好,不然串口打印会出现问题。

添加前面两项,修改后面两项:
HAL_UART=TRUE
HAL_UART_USB=FALSE
xPOWER_SAVING
xCC2540_MINIDK

编译烧写程序:

实验结果:

猜你喜欢

转载自blog.csdn.net/weixin_39148042/article/details/81491048
ADC
今日推荐