本帖最后由 jinglixixi 于 2020-8-21 21:16 编辑
传感器测量离不开3件事,输入输出、延时及时序控制。 1. 延时函数 鉴于ESK32-360开发板在SYSTICK程序中只提供了ms级的延时函数,而未提供us级的延时函数,使得程序设计时极为不便,为此添加了us级延时函数。 - void Delayus(u32 nTime)
- {
- /* Enable the SysTick Counter */
- SYSTICK_CounterCmd(SYSTICK_COUNTER_ENABLE);
- DelayTime = nTime;
- while(DelayTime != 0);
- /* Disable SysTick Counter */
- SYSTICK_CounterCmd(SYSTICK_COUNTER_DISABLE);
- /* Clear SysTick Counter */
- SYSTICK_CounterCmd(SYSTICK_COUNTER_CLEAR);
- }
复制代码
在使用时,因为ms级和us级延时函数是基于同一个基准时钟,故在使用前需调整基准时钟。 在ms级延时时,使用下列语句: SYSTICK_IntConfig(DISABLE); SYSTICK_SetReloadValue(SystemCoreClock / 8 / 1000); SYSTICK_IntConfig(ENABLE); 在us级延时时,使用如下语句: SYSTICK_IntConfig(DISABLE); SYSTICK_SetReloadValue(SystemCoreClock / 8 / 1000000); SYSTICK_IntConfig(ENABLE);
ms级延时的验证主程序如下: - int main(void)
- {
- SYSTICK_ClockSourceConfig(SYSTICK_SRC_STCLK);
- SYSTICK_SetReloadValue(SystemCoreClock / 8 / 1000);
- SYSTICK_IntConfig(ENABLE);
- /* Initialize LEDs */
- HT32F_DVB_LEDInit(HT_LED1);
- HT32F_DVB_LEDInit(HT_LED2);
- HT32F_DVB_LEDInit(HT_LED3);
- /* Infinite loop */
- while(1)
- {
- /* Toggle LEDs */
- HT32F_DVB_LEDToggle(HT_LED1);
- HT32F_DVB_LEDToggle(HT_LED2);
- HT32F_DVB_LEDToggle(HT_LED3);
- Delay(500);
- }
- }
复制代码
2. GPIO口输入输出 鉴于SD卡接口处于空置状态,故可用做GPIO来使用并进行功能扩展,从而化解资源的紧张的情况。 1)GPIO口输出 为便于输出口的配置,特定义了一个专用的函数,其内容为: - void HT32F_DVB_OUT_Init(void)
- {
- HT32F_DVB_ClockConfig();
- // PD0 、 PC12
- HT32F_DVB_GPxConfig(GPIO_PD, GPIO_PIN_0, 0);
- HT32F_DVB_GPxConfig(GPIO_PC, GPIO_PIN_12, 0);
- HT_GPIOD->SRR = GPIO_PIN_0;
- HT_GPIOC->SRR = GPIO_PIN_12;
- GPIO_PullResistorConfig(HT_GPIOD, GPIO_PIN_0, GPIO_PR_DISABLE);
- GPIO_DriveConfig(HT_GPIOD, GPIO_PIN_0, GPIO_DV_8MA);
- GPIO_DirectionConfig(HT_GPIOD, GPIO_PIN_0, GPIO_DIR_OUT);
- GPIO_PullResistorConfig(HT_GPIOC, GPIO_PIN_12, GPIO_PR_DISABLE);
- GPIO_DriveConfig(HT_GPIOC, GPIO_PIN_12, GPIO_DV_8MA);
- GPIO_DirectionConfig(HT_GPIOC, GPIO_PIN_12, GPIO_DIR_OUT);
- }
复制代码此外,还定义了一个GPIO口的时钟启动函数,其内容为: - void HT32F_DVB_ClockConfig(void)
- {
- CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
- u8 RegCK[5] = {0};
- RegCK[3] = 1; // 启动PD口
- RegCK[2] = 1; // 启动PC口
- CKCUClock.Bit.PA = RegCK[0];
- CKCUClock.Bit.PB = RegCK[1];
- CKCUClock.Bit.PC = RegCK[2];
- CKCUClock.Bit.PD = RegCK[3];
- CKCUClock.Bit.AFIO = 1;
- CKCU_PeripClockConfig(CKCUClock, ENABLE);
- }
复制代码
验证函数功能的主程序为: - int main(void)
- {
- SYSTICK_ClockSourceConfig(SYSTICK_SRC_STCLK);
- SYSTICK_SetReloadValue(SystemCoreClock / 8 / 1000);
- SYSTICK_IntConfig(ENABLE);
- // LED1 & PC12
- HT32F_DVB_OUT_Init();
- while(1)
- {
- /* Toggle LEDs */
- HT_GPIOD->SRR = GPIO_PIN_0;
- HT_GPIOC->RR = GPIO_PIN_12;
- Delay(1000);
- HT_GPIOD->RR = GPIO_PIN_0;
- HT_GPIOC->SRR = GPIO_PIN_12;
- Delay(1000);
- }
- }
复制代码
经程序的下载验证,可实现指定GPIO口的输出功能。 2)GPIO口输入 为便于输入口的配置,所定义得专用函数为: - void HT32F_DVB_IN_Init(void)
- {
- AFIO_GPxConfig(GPIO_PC, GPIO_PIN_12, 0);
- GPIO_PullResistorConfig(HT_GPIOC, GPIO_PIN_12, GPIO_PR_UP); // down ?
- GPIO_InputConfig(HT_GPIOC, GPIO_PIN_12, ENABLE);
- }
复制代码
注:为配置相应的时钟,需在HT32F_DVB_ClockConfig()函数中添加语句: RegCK[2] = 1; // 启动PC口
验证函数功能的主程序为: - int main(void)
- {
- SYSTICK_ClockSourceConfig(SYSTICK_SRC_STCLK);
- SYSTICK_SetReloadValue(SystemCoreClock / 8 / 1000);
- SYSTICK_IntConfig(ENABLE);
- HT32F_DVB_OUT_Init();
- while(1)
- {
- // PC12=KEY
- if(GPIO_ReadInBit(HT_GPIOC, GPIO_PIN_12)==0)
- {
- HT_GPIOD->SRR = GPIO_PIN_0;
- }
- else
- {
- HT_GPIOD->RR = GPIO_PIN_0;
- }
- Delay(1000);
- }
- }
复制代码
经程序下载,当按下连接PC12的按键时,可见到LED1发生变化,说明指定GPIO口的输入功能正确。 3. 串行通讯输出信息 除了使用LED显示按键状态外,还可以使用串行通讯来输出按键状态,它可以反映出比LED更丰富的信息。 实现按键状态输出的主程序如下: - int main(void)
- {
- SYSTICK_ClockSourceConfig(SYSTICK_SRC_STCLK);
- SYSTICK_SetReloadValue(SystemCoreClock / 8 / 1000);
- SYSTICK_IntConfig(ENABLE);
- HT32F_DVB_OUT_Init();
- UxART_Configuration();
- while(1)
- {
- if(GPIO_ReadInBit(HT_GPIOD, GPIO_PIN_1)==0)
- {
- HT_GPIOD->SRR = GPIO_PIN_0;
- gHelloString[3] ='0';
- UxART_TxTest();
- }
- else
- {
- HT_GPIOD->RR = GPIO_PIN_0;
- gHelloString[3] = '1';
- UxART_TxTest();
- }
- Delay(1000);
- }
- }
复制代码
图1 按键状态输出
4. I2C总线模拟与BH1750光强检测 BH1750是一款基于I2C接口的数字式光强传感器,我们可利用SD卡接口空出的引脚来模拟I2C接口以驱动该传感器,从而进行光强检测。 BH1750与MCU的连接关系如下: SCL --- PC11 SDA --- PC12
定义相关引脚输出高低电平的引脚为: #define SCL_Set() HT_GPIOC->SRR = GPIO_PIN_11 #define SCL_Clr() HT_GPIOC->RR = GPIO_PIN_11
#define SDA_Set() HT_GPIOC->SRR = GPIO_PIN_12 #defineSDA_Clr() HT_GPIOC->RR =GPIO_PIN_12
BH1750的初始化函数为:
- void IIC_Init(void)
- {
- HT32F_DVB_ClockConfig();
-
- GPIO_PullResistorConfig(HT_GPIOC, GPIO_PIN_12, GPIO_PR_DISABLE);
- GPIO_DriveConfig(HT_GPIOC, GPIO_PIN_12, GPIO_DV_8MA);
- GPIO_DirectionConfig(HT_GPIOC, GPIO_PIN_12, GPIO_DIR_OUT);
-
- GPIO_PullResistorConfig(HT_GPIOC, GPIO_PIN_11, GPIO_PR_DISABLE);
- GPIO_DriveConfig(HT_GPIOC, GPIO_PIN_11, GPIO_DV_8MA);
- GPIO_DirectionConfig(HT_GPIOC, GPIO_PIN_11, GPIO_DIR_OUT);
- }
复制代码 BH1750的读取函数为:
- void Get_Sunlight_Value()
- {
- int dis_data=0;
- float temp;
- char i=0;
- unsigned int sd;
- Single_Write_BH1750(0x01); // power on
- Single_Write_BH1750(0x10); // H- resolution mode
- Delayms(180);
- Multiple_Read_BH1750();
- for(i=0;i<3;i++)
- dis_data=gHelloString[0];
- dis_data=(dis_data<<8)+gHelloString[1];
- temp=(float)dis_data/1.2;
- sd=temp;
- gHelloString[0] = sd/10000+'0';
- gHelloString[1] = sd% 10000/1000+'0';
- gHelloString[2] = sd % 1000/100+'0';
- gHelloString[3] = sd % 100/10+'0';
- gHelloString[4] = sd % 10+'0';
- UxART_TxTest();
- }
复制代码
光强检测的主函数为: - int main(void)
- {
- SYSTICK_ClockSourceConfig(SYSTICK_SRC_STCLK);
- SYSTICK_SetReloadValue(SystemCoreClock / 8 / 1000);
- SYSTICK_IntConfig(ENABLE);
- UxART_Configuration();
- IIC_Init();
- while(1)
- {
- Get_Sunlight_Value();
- Delayms(1000);
- }
- }
复制代码
经程序下载后,其运行结果如图所示。 图2 BH1750检测结果
|