前言
沁恒蓝牙芯片CH58x系列学习与应用:
在前人的基础上补充一个沁恒CH85x系列蓝牙central例程的记录
注:我是用的是沁恒的CH582M芯片,IDE是Mounriver Studio
因作者能力有限,文中难免存在错误,请不吝指正!
沁恒的外设从机例程Peripheral原文:
沁恒蓝牙芯片CH57x系列学习与应用
头文件包含:
#include "CONFIG.h"
#include "hal.h"
#include "central.h"
全局
//GLOBAL TYPEDEFS
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4]; // 4字节对齐
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE) // 不启用
const uint8_t MacAddr[6] = {
0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
#endif
循环
/*********************************************************************
* @fn Main_Circulation
*
* @brief 循环
*
* @return none
*/
__HIGH_CODE // 将作用的函数或数据放入指定名为"section_name"输入段(没搞明白)
__attribute__((noinline)) // 声明为非内联函数
void Main_Circulation()
{
while(1)
{
TMOS_SystemProcess(); // 执行系统处理
}
}
Central例程的主函数如下所示:
int main(void)
{
#if(defined(DCDC_ENABLE)) && (DCDC_ENABLE == TRUE)
PWR_DCDCCfg(ENABLE);
#endif
SetSysClock(CLK_SOURCE_PLL_60MHz);
#if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
#endif
#ifdef DEBUG
GPIOA_SetBits(bTXD1);
GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA);
UART1_DefInit();
#endif
PRINT("%s\n", VER_LIB);
CH58X_BLEInit(); // BLE库初始化
HAL_Init(); // 硬件初始化
GAPRole_CentralInit();
Central_Init();
Main_Circulation();
}
一、CH58X_BLEInit
首先来看蓝牙的库初始化配置:
void CH58X_BLEInit(void)
{
uint8_t i;
bleConfig_t cfg;
if(tmos_memcmp(VER_LIB, VER_FILE, strlen(VER_FILE)) == FALSE) // 其中函数是对利用变量实现对当前芯片与库文件的是否匹配
{
PRINT("head file error...\n");
while(1);
}
SysTick_Config(SysTick_LOAD_RELOAD_Msk); // 系统时钟的配置
PFIC_DisableIRQ(SysTick_IRQn); // 中断不使能
tmos_memset(&cfg, 0, sizeof(bleConfig_t)); // 设置清0 通过配置参数bleConfig_t配置库的内存,时钟,发射功率等参数
cfg.MEMAddr = (uint32_t)MEM_BUF;
cfg.MEMLen = (uint32_t)BLE_MEMHEAP_SIZE;
cfg.BufMaxLen = (uint32_t)BLE_BUFF_MAX_LEN;
cfg.BufNumber = (uint32_t)BLE_BUFF_NUM;
cfg.TxNumEvent = (uint32_t)BLE_TX_NUM_EVENT;
cfg.TxPower = (uint32_t)BLE_TX_POWER;
#if(defined(BLE_SNV)) && (BLE_SNV == TRUE)
cfg.SNVAddr = (uint32_t)BLE_SNV_ADDR;
cfg.readFlashCB = Lib_Read_Flash;
cfg.writeFlashCB = Lib_Write_Flash;
#endif
#if(CLK_OSC32K)
cfg.SelRTCClock = (uint32_t)CLK_OSC32K;
#endif
cfg.ConnectNumber = (PERIPHERAL_MAX_CONNECTION & 3) | (CENTRAL_MAX_CONNECTION << 2);
cfg.srandCB = SYS_GetSysTickCnt;
#if(defined TEM_SAMPLE) && (TEM_SAMPLE == TRUE)
cfg.tsCB = HAL_GetInterTempValue; // 根据温度变化校准RF和内部RC( 大于7摄氏度 )
#if(CLK_OSC32K)
cfg.rcCB = Lib_Calibration_LSI; // 内部32K时钟校准
#endif
#endif
#if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
cfg.WakeUpTime = WAKE_UP_RTC_MAX_TIME;
cfg.sleepCB = CH58X_LowPower; // 启用睡眠
#endif
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
for(i = 0; i < 6; i++)
{
cfg.MacAddr[i] = MacAddr[5 - i];
}
#else
{
uint8_t MacAddr[6];
GetMACAddress(MacAddr);
for(i = 0; i < 6; i++)
{
cfg.MacAddr[i] = MacAddr[i]; // 使用芯片mac地址
}
}
#endif
if(!cfg.MEMAddr || cfg.MEMLen < 4 * 1024) // 蓝牙地址是否成功配置,否则进去空循环
{
while(1);
}
i = BLE_LibInit(&cfg); // 通过BLE_LibInit()函数将配置参数传入库中
if(i) // 对总体的库配置是否完成进行判断,当配置成功,则返回0值。反之则返回1,通过串口报错,并陷入空循环之中。
{
PRINT("LIB init error code: %x ...\n", i);
while(1);
}
}
其中函数是对利用变量实现对当前芯片与库文件的是否匹配的检查,如果不匹配,则执行空循环,并打印“head file error…”,通过串口进行通报:
tmos_memcmp( VER_LIB, VER_FILE, strlen( VER_FILE ) )
后续两个函数分别是对系统时钟的配置和中断的不使能:
SysTick_Config( SysTick_LOAD_RELOAD_Msk );
PFIC_DisableIRQ( SysTick_IRQn );
之后再对BLE的库进行配置。
先是对所有变量进行清零,然后重新配置:
tmos_memset(&cfg, 0,