SDK中提供了比较多的Demo例程,蓝牙的例程在BLE目录下。
1、devBoardDemo例程之LCD显示
SDK中提供的demo例程devBoardDemo,看起来功能比较强大,只是没有配套LCD显示屏,要实现这个demo就需要外配合适的LCD了。
考虑到使用的都是LCD,就拿合宙官网上买的LCD先测试下
编译下载后居然有显示,能看到XYZ坐标的信息。说明可以驱动,只是屏幕分辨率不同,没能显示全面。
于是,调整显示参数如下
1)、 Project树下的LCD组件中增加Font12字体
由于本人的LCD分辨率是160*128,需要调整显示使用的字体,改成Font12还比较合适
2)、lcd_display.c中所有Font24改成Font12
3)、lcd_display.h中调整显示参数
#define FONT_SIZE (12)
//(24)
#define FONT_WIDTH (7)
//(17)
#define DISP_WIDTH (22)
4)、lcd_drv.h中调整LCD分辨率
#define LCD_HEIGHT 128
//240
#define LCD_WIDTH 160
//240
//下面这个预定义没有用到
#define LCD_WIDTH_Byte 160
驱动的时候,屏幕是横向的
5)、LCD硬件连接
在开发板资料中,可以看到LCD的原理图
接到自己的LCD中,需要调整线序。
6)、开发板跳线,由于用到了ADC、三轴加速器QMA7981、温湿度传感器HDC2010等
需要将J17、J22-J24、J25-J26短接。
7)、显示效果
2、devBoardDemo例程之蓝牙测试
1)、手机端APP
Readme文档中要求手机APP(NS_BlueTooth),不过一致没有找到对应的APP,不知道为何没有放在SDK中。
于是用了前面沁恒的蓝牙APP,BLE调试助手。
2)、蓝牙连接后,能看到灯D11(绿色)常亮,LCD屏幕中BTDisconnect变成BTConnect
3)、蓝牙收发测试
按下开发板上的K05 ,就能收到一条收到数据的信息
if(gKey.key == KEY_SEND)
{
if(bt_connect_flag == 1)
{
log_debug("Key send Press!\r\n");
for (i = 0; i < 10; i++)
{
bt_data_buf[i + 2] = i;
}
bt_data_buf[0] = i;
bt_data_buf[1] = 0;
LED1_ON();
bt_snd_data(bt_data_buf, 12, USER_IDX_WRITE_NOTIFY_VAL);
LED1_OFF();
}
gKey.key = 0;
}
每次接收时,能看到最下方红色LED闪烁一下
而发送测试
则有点蒙圈了,串口log中没有记录
LCD中要发送很多次才能看到接收的数据
每发送一次数据,D10(白色)翻转一次
修改了几行代码后,可以得到发送的数据
3、传感器数据的获取
主要有3个方向的数据
1)三轴加速器QMA7981,I2C方式获取
int qma_i2c_gpio_init(void)
{
I2C_InitType i2c2_master;
GPIO_InitType i2c2_gpio;
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_I2C1, ENABLE);
RCC_EnableAPB2PeriphClk(QMA_I2C_SDA_GPIO_CLK, ENABLE);
GPIO_ConfigPinRemap(GPIO_RMP_I2C1, ENABLE);
/*PB8 -- SCL; PB9 -- SDA*/
i2c2_gpio.Pin = QMA_I2C_SDA_PIN | QMA_I2C_SCL_PIN;
i2c2_gpio.GPIO_Speed = GPIO_Speed_2MHz;
i2c2_gpio.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitPeripheral(QMA_I2C_SDA_PORT, &i2c2_gpio);
I2C_DeInit(QMA_I2C);
i2c2_master.BusMode = I2C_BUSMODE_I2C;
i2c2_master.FmDutyCycle = I2C_FMDUTYCYCLE_2;
i2c2_master.OwnAddr1 = I2C_MASTER_ADDR;
i2c2_master.AckEnable = I2C_ACKEN;
i2c2_master.AddrMode = I2C_ADDR_MODE_7BIT;
i2c2_master.ClkSpeed = QMA_I2C_CLOCK; // 100000 100K
I2C_Init(QMA_I2C, &i2c2_master);
I2C_Enable(QMA_I2C, ENABLE);
return 0;
}
硬件I2C方式读取
qma_i2c_read_ndata(0x01, 6, (uint8_t *)(&(g_sensor_data->x_acc)));
// printf("x=%04x,y=%04x,z=%04x\r\n",g_sensor_data->x_acc,g_sensor_data->y_acc,g_sensor_data->z_acc);
g_sensor_data->x_acc = g_sensor_data->x_acc >> 2; // X轴原始数据
g_sensor_data->y_acc = g_sensor_data->y_acc >> 2; // Y轴原始数据
g_sensor_data->z_acc = g_sensor_data->z_acc >> 2; // Z轴原始数据
显示在LCD屏幕中
2)温湿度传感器HDC2010
同样I2C硬件方式读取
int hdc_i2c_gpio_init(void)
{
I2C_InitType i2c2_master;
GPIO_InitType i2c2_gpio;
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_I2C2, ENABLE);
RCC_EnableAPB2PeriphClk(HDC_I2C_SDA_GPIO_CLK, ENABLE);
/*PB10 -- SCL; PB11 -- SDA*/
i2c2_gpio.Pin = HDC_I2C_SDA_PIN | HDC_I2C_SCL_PIN;
i2c2_gpio.GPIO_Speed = GPIO_Speed_50MHz;
i2c2_gpio.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitPeripheral(HDC_I2C_SDA_PORT, &i2c2_gpio);
I2C_DeInit(HDC_I2C);
i2c2_master.BusMode = I2C_BUSMODE_I2C;
i2c2_master.FmDutyCycle = I2C_FMDUTYCYCLE_2;
i2c2_master.OwnAddr1 = I2C_MASTER_ADDR;
i2c2_master.AckEnable = I2C_ACKEN;
i2c2_master.AddrMode = I2C_ADDR_MODE_7BIT;
i2c2_master.ClkSpeed = HDC_I2C_CLOCK; // 100000 100K
I2C_Init(HDC_I2C, &i2c2_master);
I2C_Enable(HDC_I2C, ENABLE);
return 0;
}
读取温湿度数据
float readTemp(void)
{
// uint8_t byte[2];
uint16_t temp;
/*byte[0] = readReg(TEMP_LOW);
byte[1] = readReg(TEMP_HIGH);
temp = (unsigned int)byte[1] << 8 | byte[0];
*/
readHDC2010_16bitData(TEMP_LOW, &temp);
return ((float)temp)*165 / 65536 - 40;
}
float readHumidity(void)
{
// uint8_t byte[2];
uint16_t humidity;
/* byte[0] = readReg(HUMID_LOW);
byte[1] = readReg(HUMID_HIGH);
humidity = (unsigned int)byte[1] << 8 | byte[0];
*/
readHDC2010_16bitData(HUMID_LOW, &humidity);
return ((float)humidity) / (65536) * 100;
}
3)ADC数据获取
配置方式
/* Configure the ADC1 in continuous mode with a resolution equal to 12 bits */
ADC_InitStructure.WorkMode = ADC_WORKMODE_INDEPENDENT; // ADC工作在独立模式
ADC_InitStructure.MultiChEn = DISABLE; //模数转换工作在单通道模式
ADC_InitStructure.ContinueConvEn = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE; //转换由软件而不是外部触发启动
ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R; // ADC数据右对齐
ADC_InitStructure.ChsNumber = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADCx, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_Enable(ADCx, ENABLE); //使能指定的ADC1
读取的值是通过电位器手动变化的分压值
u16 Get_Adc(ADC_Module *ADCx, adc_sample_ch ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_ConfigRegularChannel(ADCx, ch, 1, ADC_SAMP_TIME_28CYCLES5); // ADC通道,采样时间为239.5周期
ADC_EnableSoftwareStartConv(ADCx, ENABLE); //使能指定的ADC的软件转换启动功能
while (!ADC_GetFlagStatus(ADCx, ADC_FLAG_ENDC))
; //等待转换结束
ADC_ClearFlag(ADCx, ADC_FLAG_ENDC);
ADC_ClearFlag(ADCx, ADC_FLAG_STR);
return ADC_GetDat(ADCx); //返回最近一次ADC规则组的转换结果
}
4、测试视频
BLE及传感器