Пн авг 23, 2021 17:36:00
#include "main.h" // < All settings are here
#include <util/delay.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <stdbool.h> // bool in C99
// Яркость нагрузки, 0 - выключен, 255 - максимальная (ШИМ)
u8 rate;
// Направление изменения яркости нагрузки, 1 - прибавить ШИМ, 0 - убавить ШИМ
u8 rate_dir = 0;
// Состояние заднего светодиода LED2
bool led_state = false;
int count = 0;
uint8_t countMode = 0; //????? ?????????? ??????
uint8_t reqChangeMode = 0; //????, ???????????? ????? ????????? ???????? ?????
volatile _Bool direction = 0; // Направление бегущего огонька
u16 x;
void bat_check_low(void) {
u8 adc_raw = bat_getvoltage();
if (adc_raw < BAT_WARNING_BLUE) {
while (adc_raw < BAT_WARNING_BLUE) {
PORTB = 0b00000111;
}
}
if (adc_raw < BAT_WARNING_RED)
{
PORTB = 0b00001011;
}
if (adc_raw > BAT_WARNING_BLUE)
{
PORTB = 0b00001111;
}
if (adc_raw < BAT_SHUTDOWN)
PORTB = 0b00001100;
}
ISR( TIM0_COMPA_vect)
{
}
void knopka_check(void) {
// Проверка заряда батареи
u8 adc_knopki = bat_getvoltage();
u16 bat_time_low = 0;
if (adc_knopki < 150)
{
while (adc_knopki < 150)
{
count++;
if ((count < 250)&&(count > 30))
{
direction = !direction; // Меняем направление
PORTB = 0b00001111;
count = 0;
#ifdef BAT_CHECK_LOW
if (bat_time_low == BAT_CHECK_PERIOD) { // Проверка заряда батареи через определенный интервал
bat_time_low = 0;
bat_check_low();
}
bat_time_low++;
#endif
_delay_ms(1);
}
}
}
}
int main(void) {
setup();
sei ();
u16 bat_time = 0;
while(1) {
knopka_check();
#ifdef BAT_CHECK
if (bat_time == BAT_CHECK_PERIOD) {
bat_time = 0;
bat_check();
}
bat_time++;
#endif
_delay_ms(1);
}
}
ISR(INT0_vect) {}
ISR(ADC_vect) {}
void setup(void){
ADMUX =
(1 << ADLAR) | (1 << REFS0) | (1 << MUX1) | (0 << MUX0);
ACSR |= (1 << ACD);
ADCSRA = (1 << ADIE);
TCCR0B = (0 << CS02) | (1 << CS01) | (0 << CS00 );
TCCR0A = (0 << WGM02) | (1 << WGM01) | (0 << WGM00);
OCR0A = 69;
TCNT0 = 0;
TIMSK0|=(1<<OCIE0A)|(0<<TOIE0);
DDRB = 0b00001111;
PORTB = 0b00001101;
wakeup();
}
void wakeup(void) {
if (led_state)
LED_RED_on
#ifndef RATE_REMEMBER // Если нет памяти яркости
rate = RATE_DEFAULT; // включается сразу на мин. яркость
#endif
OCR0A = rate;
ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN) ;
ADCSRA |= (1 << ADSC);
}
u8 bat_getvoltage(void) {
_delay_us(50);
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC));
return ADCH;
}
void bat_check(void) {
u8 adc_raw = bat_getvoltage();
if (adc_raw < BAT_WARNING_BLUE) {
while (adc_raw < BAT_WARNING_BLUE) {
PORTB = 0b00000101;
}
}
if (adc_raw < BAT_WARNING_RED)
{
PORTB = 0b00001001;
}
if (adc_raw < BAT_SHUTDOWN)
PORTB = 0b00001100;
if (adc_raw > BAT_WARNING_BLUE)
{
PORTB = 0b00001101;
}
}
Пн авг 23, 2021 19:19:19
Ср авг 25, 2021 17:19:56
if (adc_raw < BAT_WARNING_RED)
{
PORTB = 0b00001001;
}
if (adc_raw < BAT_SHUTDOWN)
PORTB = 0b00001100;
Ср авг 25, 2021 20:13:10
Ср авг 25, 2021 21:16:49
Чт авг 26, 2021 08:57:53
Bondosha писал(а):кнопка фиксируемая
А что за кнопка такая интересная?Bondosha писал(а):При полунажатии на кнопку
Чт авг 26, 2021 11:40:29
Чт авг 26, 2021 17:18:08
Чт авг 26, 2021 17:58:16
Пт авг 27, 2021 02:03:33
Пт авг 27, 2021 20:23:17
Пт авг 27, 2021 22:59:06
Сб авг 28, 2021 06:51:14
я так и не добился, что же за кнопка такая? если как на фотоаппарате - так там два контакта.Самсусамыч писал(а):Вы читали первый пост ТС?
Название темы LED Driver, пишите тогда - LED Выключатель.Самсусамыч писал(а):Или Вам не важно какое устройство необходимо ТС?
Сб авг 28, 2021 10:27:37
Акб еще не разредился до такого напряжения, что бы контроллер заряда, встроенный в саму акб, отключил акб, а фонарик светит уже тускло.
За то при полном заряде акб слишком большой ток идет на светодиоды - они имеют свойство быстро выходить из строя.
Название темы LED Driver, пишите тогда - LED Выключатель.
Сб авг 28, 2021 12:31:15
Сб авг 28, 2021 14:01:05
Вт сен 07, 2021 17:38:45
#ifndef MAIN_H_
#define MAIN_H_
// Frequency definition for gcc. Do not forget to set proper fuses.
// Определение частоты для компилятора. Не забудь выставить частоту фьюзами.
#define F_CPU 1200000UL // Attiny13 1.2MHz / PWM 4.6 KHz / CKDIV8 = 0
//#define F_CPU 9600000UL // Attiny13 9.6MHz / PWM 36.8 KHz / CKDIV8 = 1
#include <util/delay.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <stdbool.h> // bool in C99
#define nop __asm__ __volatile__ ("nop");
typedef uint8_t u8;
typedef uint16_t u16;
int main(void);
static void setup(void);
static void wakeup(void);;
static u8 bat_getvoltage(void);
#endif /* MAIN_H_ */
#include <util/delay.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <stdbool.h> // bool in C99
int count = 0;
volatile uint8_t STATUS = 0; //????? ?????????? ??????
volatile uint8_t reqChangeSTATUS = 0; //????, ???????????? ????? ????????? ???????? ?????
volatile uint8_t timer1 = 0;
volatile uint8_t timer2 = 0;
volatile uint8_t timerADC = 0;
volatile uint8_t countMode = 0; //????? ?????????? ??????
volatile uint8_t reqChangeMode = 0; //????, ???????????? ????? ????????? ???????? ?????
u8 adc_raw = 0;
ISR(TIM0_COMPA_vect)
{
}
ISR(TIM0_OVF_vect)
{
timer1++;
timer2++;
timerADC++;
}
ISR(WDT_vect) // Watchdog timeout interrupt service routine// обработка прерыания WDT
{}
void bat_check(void)
{
u8 adc_raw = bat_getvoltage();
if ((adc_raw <= 207)&&(adc_raw > 183))
{
if (countMode == 1)
{
PORTB = 0b00000111;
timer1 = 0;
timer2 = 0;
}
if (countMode == 0)
{
PORTB = 0b00000101;
timer1 = 0;
timer2 = 0;
}
}
if (adc_raw <= 183)//&&(adc_raw >= 130))
{
if (countMode == 1)
{
PORTB = 0b00001011;
if(timer1 == 25)
{
PORTB = 0b00001000;
timer1 = 0;
}
}
if (countMode == 0)
{
PORTB = 0b00001001;
if(timer1 == 25)
{
PORTB = 0b00001000;
timer1 = 0;
}
}
}
if (adc_raw < 150) //(second30 >= 128)
{
if (countMode == 1)
{
PORTB = 0b00001100;
if (timerADC >= 25)
{
PORTB = 0b00001111;
}
if (timerADC >= 27)
{
PORTB = 0b00001100;
timerADC = 0;
}
}
if (countMode == 0)
{
PORTB = 0b00001100; //PORTB = 0b00001101;
if (timerADC >= 25)
{
PORTB = 0b00001101;
}
if (timerADC >= 27)
{
PORTB = 0b00001100;
timerADC = 0;
}
}
}
if (adc_raw > 210)
{
if (countMode == 1)
{
PORTB = 0b00001111;
//timer1 = 0;
}
if (countMode == 0)
{
PORTB = 0b00001101;
//timer1 = 0;
}
}
if (adc_raw < 30)
{
DDRB = 0b00000011;
PORTB = 0b00000000;
}
}
void knopka_check(void) {
u8 adc_knopki = bat_getvoltage();
if (adc_knopki < 90) //adc_knopki 90
{
if (count < 250)
count++;
} else {
if (count > 0)
count--;
if ((count >= 4)&&(count < 50))
{
countMode = (countMode + 1) & 0x1;
reqChangeMode = 1;
count = 0;
}
}
}
int main(void) {
setup();
sei ();
// Main LOOP
while(1) {
knopka_check();
if (reqChangeMode) { //???? ????????? ???????? ?????
reqChangeMode = 0; //???????? ?????????
switch (countMode) { //?????????? ????? ??????
case 0:
{
PORTB = 0b00001101;
}
break;
case 1:
{
PORTB = 0b00001111;
if (timerADC == 50)
{
bat_check();
timerADC = 0;
}
}
break;
}
}
if (timerADC == 50)
{
bat_check();
timerADC = 0;
}
}
}
ISR(INT0_vect) {} // Прерывание ничего не делает, кроме пробуждения МК
ISR(ADC_vect)
{} // Прерывание ничего не делает, кроме пробуждения МК
void setup(void){
// Настройка МК после подачи питания
// Настройка АЦП. Attiny13 datasheet, page 92
ADMUX =
(1 << ADLAR) | // left shift result (for 10-bit values)
(1 << REFS0) | // Sets ref. voltage to internal 1.1V, bit 0
(1 << MUX1) | // use ADC1 for input (PB2), MUX bit 1
(0 << MUX0); // use ADC1 for input (PB2), MUX bit 0
//ACSR |= (1 << ACD); // Отключаем компаратор (по умолчанию включен)
ADCSRA |= (1 << ADEN) // Разрешение АЦП
//|(1 << ADSC) // Запуск преобразования
|(1 << ADPS2)|(1 << ADPS1); // Предделитель на 64 (частота АЦП 125kHz)
//|(1 << ADIE); // Разрешение прерывания от АЦП
// Выключаем аналоговый компаратор
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (1<<ACI) | (0<<ACIE) | (0<<ACIS1) | (0<<ACIS0);
TCCR0B = (0 << CS02) | (1 << CS01) | (1 << CS00 ); // 001 - тактовый генератор CLK/1 (скорость шим = CLK/256 = 4687.5 Гц)
//TCCR0A = (0 << WGM02) | (1 << WGM01) | (0 << WGM00); // 11 - Режим CTC
//OCR0A = 69;
TCNT0 = 0;
//TIMSK0|=(1<<OCIE0A)|(0<<TOIE0);
TIMSK0|= (1 << TOIE0); // Прерывание по переполнению
//WDTCR|=(1<<WDCE)|(1<<WDTIE)|(0 << WDP0); //предделитель на 1 сек. //(1<<WDP1)|(1<<WDP2)|
DDRB = 0b00001111;
PORTB = 0b00001101;
wakeup();
}
void wakeup(void) {
ADCSRA |= (1 << ADSC); // Пробная конверсия (необходимо провести первый раз после включения для стабилизации АЦП)
}
u8 bat_getvoltage(void) {
_delay_us(50); // Стабилизируем напряжение после отключения мощной нагрузки, Занимает 12 байт
ADCSRA |= (1 << ADSC); // Начинаем преобразование
while (ADCSRA & (1 << ADSC)); // ждем окончания преобразования
_delay_ms(3);
return ADCH;
}
Вт сен 07, 2021 18:44:02
void bat_check(void)
{
u8 adc_raw = bat_getvoltage();
if(adc_raw > 210) {
PORTB |= _BV(2) | _BV(3); // для примера
} else if(adc_raw > 183) {
...
} else if(adc_raw > 150) {
...
} else if(adc_raw > 30) {
...
} else { // adc_raw <= 30
...
}
}
Вт сен 07, 2021 18:52:13
Вт сен 07, 2021 18:59:48