本帖最后由 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.jpg (36.05 KB, 下載次數: 67)
下載附件
2020-8-21 21:00 上傳
圖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.jpg (37.41 KB, 下載次數: 62)
下載附件
2020-8-21 21:09 上傳
圖2 BH1750檢測結果
|