洪嵐峰 發表於 2023-4-8 17:24:05

STM8S001J3 定時+紅外線清新劑自動噴霧器

以下是使用STM8S001J3控制定時和紅外線傳感器的清新劑自動噴霧器的基本示例:


#include <iostm8s001j3.h>

// 紅外線接收器引腳定義
#define IR_PIN  GPIOB_PIN_4

// 噴霧器引腳定義
#define SPRAY_PIN GPIOB_PIN_5

// 噴霧時間(毫秒)
#define SPRAY_TIME 1000

// 定時器中斷計數器
volatile uint32_t counter = 0;

// 定時器中斷服務程序
void TIM4_IRQHandler() __interrupt(TIM4_ISR)
{
    // 增加計數器
    counter++;
}

// 初始化函數
void init()
{
    // 配置定時器
    TIM4_PSCR = 3;   // 設置預分頻器,使計數器頻率為2MHz
    TIM4_ARR = 2000; // 設置計數器最大值,使定時器中斷頻率為1kHz
    TIM4_IER |= 1;   // 啟用計數器中斷
    TIM4_CR1 |= 1;   // 啟動計數器

    // 配置紅外線接收器引腳
    GPIOB_CR1 |= IR_PIN;  // 啟用引腳
    GPIOB_CR2 |= IR_PIN;  // 啟用中斷
    EXTI_CR1 &= 0xF0;     // 將引腳分配給EXTI4
    EXTI_CR1 |= 0x04;
    EXTI_CR2 |= 0x04;     // 啟用下降沿觸發

    // 配置噴霧器引腳
    GPIOB_DDR |= SPRAY_PIN;  // 設置引腳為輸出
    GPIOB_CR1 |= SPRAY_PIN;  // 啟用引腳
}

// 噴霧函數
void spray()
{
    GPIOB_ODR |= SPRAY_PIN;  // 啟動噴霧器
    delay(SPRAY_TIME);       // 等待一段時間
    GPIOB_ODR &= ~SPRAY_PIN; // 停止噴霧器
}

// 主函數
void main()
{
    init();

    while(1)
    {
        // 檢查是否有紅外線信號
        if(GPIOB_IDR & IR_PIN)
        {
            // 噴霧
            spray();
        }

        // 檢查是否達到定時時間
        if(counter >= 1000) // 1000毫秒
        {
            // 重置計數器
            counter = 0;

            // 噴霧
            spray();
        }
    }
}
在上面的代碼中,我們首先定義了紅外線接收器和噴霧器的引腳。



以下是基於上述功能描述所擬定的STM8S001J3定時+紅外線清新劑自動噴霧器的零件規格、連接腳位和程式碼:

零件規格
MCU: STM8S001J3
紅外線傳感器:HC-SR501
電磁閥:12V DC電磁閥
驅動電路:ULN2003
時鐘晶振:12MHz
電源:12V DC供電
連接腳位
PB4 - 電磁閥控制信號輸出
PC4 - 紅外線傳感器信號輸入
PD4 - 12MHz晶振接收腳
VDD - 12V DC供電正極
GND - 12V DC供電負極
程式碼

#include <stm8s.h>

#define IR_SENSOR_PIN   GPIO_PIN_4
#define SOLENOID_PIN    GPIO_PIN_4

uint8_t onTime = 5; // 噴霧器開啟時間(單位:秒)
uint8_t offTime = 60; // 噴霧器關閉時間(單位:秒)
uint16_t count = 0; // 計數器

void delay_ms(uint16_t ms) {
    uint16_t i;
    while (ms--) {
        i = 2000;
        while (i--) {
            __asm__("nop");
        }
    }
}

void init_GPIO(void) {
    GPIO_Init(SOLENOID_PIN, GPIO_MODE_OUT_PP_LOW_FAST);
    GPIO_Init(IR_SENSOR_PIN, GPIO_MODE_IN_FL_NO_IT);
}

void init_Timer4(void) {
    TIM4_TimeBaseInit(TIM4_PRESCALER_128, 93); // 設置計時器分頻和計數值
    TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE); // 啟用更新中斷
    TIM4_Cmd(ENABLE); // 啟用計時器
}

INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23) {
    TIM4_ClearITPendingBit(TIM4_IT_UPDATE); // 清除中斷標誌
    count++;
    if (count >= onTime) { // 開啟噴霧器
        GPIO_WriteHigh(SOLENOID_PIN);
    }
    if (count >= onTime + offTime) { // 關閉噴霧器
        GPIO_WriteLow(SOLENOID_PIN);
        count = 0; // 重新計數
    }
}

int main() {
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); // 設置HSI時鐘頻率
    init_GPIO();
    init_Timer4();
    enableInterrupts(); // 啟用全局中斷
    while (1) {
        if (GPIO_ReadInputPin(IR_SENSOR_PIN) == SET) { // 紅外線傳感器偵


以下是基本程式碼,可以進行修改以符合你的具體需求:


#include "stm8s.h"

#define PERIOD 31250  // 1秒,以31250計數器單位計算

volatile uint16_t counter = 0;
volatile uint8_t infrared_triggered = 0;

void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void) __interrupt(TIM1_UPD_OVF_TRG_BRK_IRQHANDLER)
{
    counter++;
    if (counter == PERIOD) {
        counter = 0;
        if (infrared_triggered) {
            // 在此添加噴霧器觸發代碼
            infrared_triggered = 0; // 清除紅外線觸發標誌位
        }
    }
}

void EXTI_PORTB_IRQHandler(void) __interrupt(EXTI_PORTB_IRQHANDLER)
{
    if (GPIO_ReadInputPin(GPIOB, GPIO_PIN_4) == RESET) {
        infrared_triggered = 1; // 設置紅外線觸發標誌位
    }
    EXTI_ClearITPendingBit(EXTI_IT_PORTB);
}

void main(void)
{
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
    TIM1_TimeBaseInit(0, TIM1_COUNTERMODE_UP, PERIOD, 0);
    TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
    TIM1_Cmd(ENABLE);

    EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOB, EXTI_SENSITIVITY_FALL_ONLY);
    enableInterrupts();

    while (1) {
        // 在此添加其他需要執行的代碼
    }
}
此代碼利用STM8S001J3的計數器模塊和外部中斷模塊,實現定時和紅外線觸發噴霧器的功能。

在主循環中,你可以添加其他需要執行的代碼,如清新劑的補充等。
頁: [1]
查看完整版本: STM8S001J3 定時+紅外線清新劑自動噴霧器