febb: (Default)
[personal profile] febb
Вчера доделал еще один OutageLight с простеньким 8-битным микропроцессором PIC12F510.
В корпусе из под старого трансформаторного блока питания.
Туда поместился Ni-MH AA аккумулятор, 4 светодиода, два осветительных 5mm
и два индикаторных заряда - зеленый и красный - 3mm, и кнопка.

Идея в том, что когда отрубается свет он автоматически включается,
а так же кнопкой можно выбирать режимы.
При восстановлении света он выключается и занимается зарядкой аккумулятора.

Поделка несерьезная, но много забавных познавательных электрических сюрпризов.
Под катом если кому интересно вид Си-программы для этого приборчика.
200 строк кода, 400 bytes Flash ROM (из 1К), 14 Bytes RAM включая стек (из 32). :)
4 MHz 8-bits CPU...


/*
 * File:   OutageLight.c
 * Author: 
 *
 * Created on March 29, 2021, 8:01 PM
 */

// PIC12F510 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config OSC = IntRC      // Oscillator Select (INTOSC with 1.125 ms DRT)
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled)
#pragma config CP = OFF         // Code Protect (Code protection off)
#pragma config MCLRE = OFF      // Master Clear Enable bit (GP3/MCLR pin functions as GP3, MCLR internally tied to VDD)
#pragma config IOSCFS = OFF     // Internal Oscillator Frequency Select bit (4 MHz INTOSC Speed)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include xc.h
#include pic12f510.h

//=============================================================================

static const char CopyRight[] = __FILE__ " (C)xxx@gmail.com " __DATE__;

typedef unsigned char byte;

#define BIT_LEDS    0b1u
#define BIT_BAT     0b100u
#define BIT_BUT     0b1000u
#define BIT_POWER   0b10000u
#define BIT_BOOST   0b100000u


#define PIN_LEDS    GPIObits.GP0
#define PIN_BUT     GPIObits.GP3
#define PIN_BAT     GPIObits.GP2
#define PIN_BOOST   GPIObits.GP5
#define PIN_POWER   GPIObits.GP4


#define ADC_OFF     0b00101100u
#define ADC_BAT     0b01101011u
#define ADC_VREF    0b00101111u
#define ADC_SET( adc ) ADCON0 = adc;
#define ADC_WAIT    while( ADCON0 & 2u );

#define COMP_OFF    0b11100001u

#define LED_GREEN   1u
#define LED_RED     0

#define ON  1u
#define OFF 0


const byte TRIS_BASE = BIT_BUT | BIT_POWER;

static bit bit_power, bit_light, bit_light_power,
        bit_but, bit_but_click, bit_bat_full, bit_bat_charge;

static byte Timer;

// ------------------------------ CODE ----------------------------------

#define UPDATE_TIMER( tmr ) if(tmr) --tmr;

static void UpdateTimers(void)
{
    static byte timer;

    byte t = TMR0;
    if(t < timer)
    {
        UPDATE_TIMER(Timer)
    }
    timer = t;
}

static void ADC(byte adc)
{
    byte t = 8u;
    do
    {
        ADC_SET(adc)
        --t;
        ADC_WAIT
    }
    while(t);
}

static void CheckPower(void)
{
    if(PIN_POWER)
    {
        ADC(ADC_VREF);
        bit_power = ADRES < 60u;
        ADC_SET(ADC_OFF);
        return;
    }
    bit_power = OFF;
}

static void CheckBattery(void)
{
    ADC(ADC_VREF);
    byte vref = ADRES; //0.6V

    ADC(ADC_BAT);

    bit_bat_full    = ADRES >= (vref << 1) + (vref >> 1); // 1.5V
    //bit_bat_full    = OFF; // DEBUG
    bit_bat_charge  = ADRES <= (vref << 1) + (vref >> 2); // 1.35V
    //bit_bat_charge  = ON; // DEBUG
    ADC_SET(ADC_OFF)
}

static void CheckButton(void)
{
    if(PIN_BUT)
    {
        bit_but_click = bit_but;
        bit_but = OFF;
        return;
    }
    bit_but = ON;
    bit_but_click = OFF;
}

void InitMCU()
{
    OPTION  = 0b11000111u;
    TRIS = TRIS_BASE | BIT_BAT | BIT_LEDS;
    GPIO = 0;
    CM1CON0 = COMP_OFF;
    ADCON0  = ADC_OFF;
}

static void ChargeOn(void)
{
    PIN_LEDS = LED_RED;
    PIN_BAT = ON;
    TRIS = TRIS_BASE;
}

static void ChargeOff(void)
{
    TRIS = TRIS_BASE | BIT_BAT | BIT_LEDS;
}

static void ChargeDone(void)
{
    PIN_LEDS = LED_GREEN;
    TRIS = TRIS_BASE | BIT_BAT;
}

static void BoostIdle(void)
{
    for(;;)
    {
        ADC(ADC_VREF);
        if(ADRES < 64u) // 2.4V
            break;
        PIN_BOOST = ON;
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
        PIN_BOOST = OFF;
    }
    ADC_SET(ADC_OFF);
}

static void BoostLow(void)
{
    byte p = 4u;
    while(--p)
    {
        PIN_BOOST = ON;
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
        PIN_BOOST = OFF;
    }
}

static void Boost(byte power)
{
    byte i = 8u, p;
    do
    {
        PIN_BOOST = ON;
        p = power;
        while(--p);
        PIN_BOOST = OFF;
    }
    while(--i);
}

/*============================== main() ================================*/
void main(void)
{
    InitMCU();

    for(;;)
    {
        UpdateTimers();
        if(bit_power)
        {
            if(Timer == 0)
            {
                CheckBattery();
                if(bit_bat_full)
                    ChargeDone();
                else
                    if(bit_bat_charge)
                        ChargeOn();
                Timer = 255u;
            }
            CheckPower();
            if(!bit_power)
            {
                ChargeOff();
                bit_light = ON;
                bit_light_power = ON;
            }
        }
        else //if(bit_power)
        {
            CheckPower();
            if(bit_power)
            {
                ChargeOn();
                Timer = 48u;
                bit_light = OFF;
                bit_light_power = OFF;
            }
        }
        CheckButton();
        if(bit_but_click)
        {
            if(bit_light)
            {
                if(bit_light_power)
                    bit_light_power = OFF;
                else
                    bit_light = OFF;
            }
            else
            {
                bit_light = ON;
                bit_light_power = ON;
            }
            bit_but_click = 0; // click consumed
        }
        if(bit_light)
        {
            if(bit_light_power)
                Boost(7u);
            else
                BoostLow();
        }
        else
            BoostIdle();
    }//for(;;)

}/*=========== main() ========*/


This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

febb: (Default)
febb

March 2022

S M T W T F S
  1 2 345
6 7 89 101112
13141516171819
20212223242526
2728293031  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Mar. 10th, 2026 05:50 am
Powered by Dreamwidth Studios