Вт сен 11, 2018 09:34:21
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/twi.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define data_port PORTD
#define data_ddr DDRD
#define cmd_port PORTB
#define cmd_ddr DDRB
#define DCS1 0
#define DCS2 1
#define DI 2
#define RW 3
#define E 4
#define RST 5
#define I2C_ADDR 0x30
void I2C_init(uint8_t address);
void I2C_stop(void);
void I2C_setCallbacks(void (*recv)(uint8_t), void (*req)());
inline void __attribute__((always_inline)) I2C_transmitByte(uint8_t data)
{
TWDR = data;
}
static void (*I2C_recv)(uint8_t);
static void (*I2C_req)();
void I2C_setCallbacks(void (*recv)(uint8_t), void (*req)())
{
I2C_recv = recv;
I2C_req = req;
}
void I2C_init(uint8_t address)
{
cli();
// load address into TWI address register
TWAR = address << 1;
// set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt
TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
sei();
}
void I2C_stop(void)
{
// clear acknowledge and enable bits
cli();
TWCR = 0;
TWAR = 0;
sei();
}
ISR(TWI_vect)
{
switch(TW_STATUS)
{
case TW_SR_DATA_ACK:
// received data from master, call the receive callback
I2C_recv(TWDR);
TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
break;
case TW_ST_SLA_ACK:
// master is requesting data, call the request callback
I2C_req();
TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
break;
case TW_ST_DATA_ACK:
// master is requesting data, call the request callback
I2C_req();
TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
break;
case TW_BUS_ERROR:
// some sort of erroneous state, prepare TWI to be readdressed
TWCR = 0;
TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
break;
default:
TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
break;
}
}
volatile uint8_t data1=0;
volatile uint8_t data[6][3]={0};
volatile uint8_t flagStepFF=1;
volatile uint8_t flagJump=0;
volatile uint8_t flagCompleteReceiv=0;
volatile uint8_t FlagCompleteFill=0;
void I2C_received(uint8_t received_data)
{
switch (flagStepFF)
{
case 1: if(received_data==0xFF) flagStepFF=2;break;
case 2: if(received_data==0xFF) flagStepFF=3;break;
case 3:
if(received_data==0x00) {data[0][0]=received_data; flagStepFF=4;}
if(received_data==0x01) {data[1][0]=received_data; flagStepFF=5;}
if(received_data==0x02) {data[2][0]=received_data; flagStepFF=6;}
if(received_data==0x03) {data[3][0]=received_data; flagStepFF=7;}
if(received_data==0x04) {data[4][0]=received_data; flagStepFF=8;}
if(received_data==0x05) {data[5][0]=received_data; flagStepFF=9;}
flagJump=1;
break;
case 4:
if(flagJump==0) {data[flagStepFF-4][2]=received_data;flagStepFF=1;break;}
data[0][1]=received_data;
flagJump=0;
break;
case 5:
if(flagJump==0) {data[flagStepFF-4][2]=received_data;flagStepFF=1;break;}
data[1][1]=received_data;
flagJump=0;
break;
case 6:
if(flagJump==0) {data[flagStepFF-4][2]=received_data;flagStepFF=1;break;}
data[2][1]=received_data;
flagJump=0;
break;
case 7:
if(flagJump==0) {data[flagStepFF-4][2]=received_data;flagStepFF=1;break;}
data[3][1]=received_data;
flagJump=0;
break;
case 8:
if(flagJump==0) {data[flagStepFF-4][2]=received_data;flagStepFF=1;break;}
data[4][1]=received_data;
flagJump=0;
break;
case 9:
if(flagJump==0) {data[flagStepFF-4][2]=received_data;flagStepFF=1;flagCompleteReceiv=1;break;}
data[5][1]=received_data;
flagJump=0;
break;
}
}
void I2C_requested()
{
I2C_transmitByte(data1);
}
void setup()
{
// set received/requested callbacks
I2C_setCallbacks(I2C_received, I2C_requested);
// init I2C
I2C_init(I2C_ADDR);
}
PROGMEM const unsigned char FONTNUMBERS[10][32] = {
//0
{0x00,0x00,0xE0,0xF0,0x38,0x38,0x38,0x38,
0x38,0x38,0x38,0x38,0xF0,0xE0,0x00,0xFE,
0x00,0x00,0x07,0x0F,0x1C,0x1C,0x1C,0x1C,
0x1C,0x1C,0x1C,0x1C,0x0F,0x07,0x00,0x7F},
//1
{0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xF0,0xF0,0x00,0xFE,
0x00,0x00,0x03,0x07,0x0F,0x1D,0x19,0x01,
0x01,0x01,0x01,0x01,0x07,0x07,0x00,0x7F},
//2
{0x00,0x00,0xE0,0xF0,0x78,0x38,0x78,0xF0,
0xC0,0x80,0x00,0x00,0xF8,0xF8,0x00,0xFE,
0x00,0x00,0x03,0x07,0x0E,0x1C,0x00,0x00,
0x01,0x03,0x07,0x0E,0x1F,0x1F,0x00,0x7F},
//3
{0x00,0x00,0xE0,0xF0,0x78,0x38,0x38,0xF0,
0xF0,0x38,0x38,0x78,0xF0,0xE0,0x00,0xFE,
0x00,0x00,0x0F,0x1F,0x1C,0x00,0x00,0x0F,
0x0F,0x00,0x00,0x1C,0x1F,0x0F,0x00,0x7F},
//4
{0x00,0x00,0xE0,0xE0,0xE0,0x60,0x60,0x60,
0xF8,0xF8,0x60,0x60,0x60,0x60,0x00,0xFE,
0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x18,
0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x7F},
//5
{0x00,0x00,0xF8,0xF8,0x00,0x00,0xC0,0xF0,
0x78,0x38,0x38,0x70,0xE0,0xC0,0x00,0xFE,
0x00,0x00,0x1F,0x1F,0x18,0x18,0x1F,0x1F,
0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x7F},
//6
{0x00,0x00,0xE0,0xF8,0x38,0x18,0x00,0xE0,
0xF0,0x38,0x18,0x38,0xF0,0xE0,0x00,0xFE,
0x00,0x00,0x0F,0x0F,0x1C,0x18,0x18,0x1B,
0x1F,0x1C,0x18,0x1C,0x0F,0x07,0x00,0x7F},
//7
{0x00,0x00,0xF8,0xF8,0x38,0x38,0x38,0x70,
0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0xFE,
0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,
0x00,0x01,0x03,0x07,0x0E,0x1C,0x00,0x7F},
//8
{0x00,0x00,0xE0,0xF0,0x38,0x18,0x38,0xF0,
0xF0,0x38,0x18,0x38,0xF0,0xE0,0x00,0xFC,
0x00,0x00,0x07,0x0F,0x1C,0x18,0x1C,0x0F,
0x0F,0x1C,0x18,0x1C,0x0F,0x07,0x00,0x7F},
//9
{0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x38,
0xF8,0xD8,0x18,0x38,0xF0,0xE0,0x00,0xFE,
0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x1C,
0x0F,0x03,0x00,0x18,0x1F,0x0F,0x00,0x7F},
};
//uint8_t Nuber[6][3];
uint8_t BufferChar[6][4]={0};
/************************************************************************/
/* Функция отправки команды дисплею. ( lcd_cmd ) */
/************************************************************************/
void lcd_cmd(unsigned char cmd)
{
_delay_us(2);
data_port = cmd;
_delay_us(1);
cmd_port |= (1<<E);
_delay_us(12);
cmd_port &= ~(1<<E);
_delay_us(2);
}
/************************************************************************/
/* Функция отправки данных дисплею. ( lcd_data ) */
/************************************************************************/
void lcd_data(unsigned char data,uint8_t FlagInvert)
{
_delay_us(2);
cmd_port |= (1<<DI);
_delay_us(2);
if(FlagInvert)
data_port = data;
else
data_port = ~data;
_delay_us(2);
cmd_port |= (1<<E);
_delay_us(12);
cmd_port &= ~(1<<E);
_delay_us(2);
cmd_port &= ~(1<<DI);
_delay_us(2);
}
/************************************************************************/
/* Функция инициализации дисплея. ( lcd_init ) */
/************************************************************************/
void lcd_init()
{
data_ddr = 0xFF;
cmd_ddr |= (1<<DI)|(1<<RW)|(1<<E)|(1<<DCS1)|(1<<DCS2)|(1<<RST);
cmd_port |= (1<<RST);
cmd_port &=~((1<<DCS2)|(1<<DCS1));
cmd_port |= (1<<DCS1);
lcd_cmd(0x3F);
cmd_port &=~((1<<DCS2)|(1<<DCS1));
cmd_port |= (1<<DCS2);
lcd_cmd(0x3F);
}
/************************************************************************/
/* Установка курсора на дисплее, ось X. (Верх/Низ) ( set_x ) */
/************************************************************************/
void set_x(unsigned char pos_x)
{
data_port = pos_x|0xB8;
_delay_us(2);
cmd_port |= (1<<E);
_delay_us(12);
cmd_port &= ~(1<<E);
_delay_us(2);
}
/************************************************************************/
/* Установка курсора на дисплее, ось Y. (Лево/Право) ( set_y ) */
/************************************************************************/
void set_y(unsigned char pos_y)
{
data_port = pos_y|0x40;
_delay_us(2);
cmd_port |= (1<<E);
_delay_us(12);
cmd_port &= ~(1<<E);
_delay_us(2);
}
uint8_t lcd_send_block(uint8_t x,uint8_t y, uint8_t len, uint16_t addr,uint8_t FlagInvert)
{
uint8_t i,col;
if(y>63)
{
cmd_port &= ~(1<<DCS1);
cmd_port |= (1<<DCS2);
col = y-64;
}
else
{
cmd_port &= ~(1<<DCS2);
cmd_port |= (1<<DCS1);
col = y;
}
set_x(x);
set_y(col);
for(i=0;i!=len;i++,addr++,col++)
{
if(64==col)
{
if(cmd_port == (1<<DCS2))
{
return 128;
}
col=0;
cmd_port &= ~(1<<DCS1);
cmd_port |= (1<<DCS2);
set_x(x);
set_y(col);
}
lcd_data(pgm_read_byte(addr),FlagInvert);
}
return y+len;
}
void lcd_big_number(unsigned char Chip, uint8_t x, uint8_t y, uint16_t number,uint8_t FlagInvert)
{
x=x*2;
y=y*16;
uint8_t i,col;
uint16_t addr;
addr= number*32;
if(Chip == 2)
{
cmd_port &= ~(1<<DCS1);
cmd_port |= (1<<DCS2);
col = y;
}
else
{
cmd_port &= ~(1<<DCS2);
cmd_port |= (1<<DCS1);
col = y;
}
set_x(x);
set_y(col);
for(i=0;i<32;i++,addr++,col++)
{
if (i == 16)
{
col=y;
x= x+1;
set_x(x);
set_y(col);
}else{
set_y(col);
}
lcd_data(pgm_read_byte((uint16_t)FONTNUMBERS+addr),FlagInvert);
}
}
void avr_init()
{
DDRC = 0x00;
sei();
}
void FillBuffer()
{
uint8_t Value[6];
for (uint8_t tX = 0; tX < 6; tX++ )
{
Value[tX]=data[tX][2];
}
for (uint8_t tX = 0; tX < 6; tX++ )
{
uint8_t TempResult=0;
for (uint8_t i = 0; i < 3; i++)
{
TempResult =Value[tX] % 10;
Value[tX] =Value[tX] / 10;
BufferChar[tX][i] =TempResult;
}
}
for (uint8_t tX = 0; tX < 6; tX++ )
{
BufferChar[tX][3]=data[tX][1];
}
FlagCompleteFill=1;
flagCompleteReceiv=0;
}
void UpdateLCD()
{
for (uint8_t tX = 0; tX < 6 ; tX++ )
{
for (uint8_t tY = 0; tY < 3; tY++ )
{
if(tX<3)
lcd_big_number(1,tY,tX+1,BufferChar[tX][tY],1);
else
lcd_big_number(2,tY,tX-3,BufferChar[tX][tY],0);
}
}
}
int main(void)
{
avr_init();
lcd_init();
lcd_cmd(0xC0);
setup();
sei();
while(1)
{
if(flagCompleteReceiv) FillBuffer();
if(FlagCompleteFill) UpdateLCD();
}
return 0;
}
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <stdint.h>
#include <util/twi.h>
#define F_SCL 100000UL // SCL frequency
#define Prescaler 1
#define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2)
//General Master staus codes
#define START 0x08 //START has been transmitted
#define REP_START 0x10
#define MT_DATA_ACK 0x28
#define MT_SLA_ACK 0x18
//Master Transmitter staus codes
#define MT_ADR_ACK 0x18 //SLA+W has been tramsmitted and ACK received
#define MT_ADR_NACK 0x20 //SLA+W has been tramsmitted and NACK received
#define MT_DATA_ACK 0x28 //Data byte has been tramsmitted and ACK received
#define MT_DATA_NACK 0x30 //Data byte has been tramsmitted and NACK received
#define MT_ARB_LOST 0x38 //Arbitration lost in SLA+W or data bytes
#define WRITE 0x00
#define READ 0x01
#define READ_END 0x01
#define READ_NOEND 0x00
#define ERROR 0x01
#define SUCCESS 0x00
#define I2C_ADR_SLAVE 0x30
// I2C
static uint8_t send_i2c(uint8_t value);
static uint8_t start_i2c(uint8_t d_adr);
static inline void stop_i2c();
static uint8_t write_i2c(uint8_t ADR, uint8_t value);
void i2c_init(void)
{
TWBR = (uint8_t)TWBR_val;
}
//----------///init_pwm///----------//
void init_pwm()
{
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (0<<CS00);
OCR0A=0x00;
OCR0B=0x00;
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10);
OCR1AL=0x00;
OCR1BL=0x00;
TCCR2A=(1<<COM2A1) | (0<<COM2A0) | (1<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (1<<WGM20);
TCCR2B=(0<<WGM22) | (0<<CS22) | (1<<CS21) | (0<<CS20);
OCR2A=0x00;
OCR2B=0x00;
}
//----------//
void init_int0()
{
//настраиваем на срабатывание INT0 по переднему фронту
EICRA |= (1<<ISC01)|(0<<ISC00);
//разрешаем внешнее прерывание INT0
EIMSK |= (1<<INT0);
}
//----------//
void init_io()
{
DDRB=(0<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(0<<PB5)|(0<<PB6)|(0<<PB7);
PORTB=0x00;
DDRC=(1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5)|(1<<PC6);
PORTC=0x00;
DDRD=(1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
PORTD=0x00;
}
//----------//
//настройка параметров работы функций
#define BTN_LOCK_TIME 30 /*время обработки дребезга в милисекундах (10-100)*/
#define BTN_LONG_TIME 1000 /*время фиксации длинного нажатия в милисекундах (1000 - 2500)*/
//настройки портов
/*порт чтения кнопок*/
#define BTN_PORT PORTB
#define BTN_DDR DDRB
#define BTN_PIN PINB
/*пины чтения кнопок*/
#define BTN_LINE_UP (1<<5)
#define BTN_LINE_DN (1<<0)
//#define BTN_LINE_POWER (1<<5)
//#define BTN_LINE_SW (1<<0)
//глобальные переменные
volatile uint8_t BtnFlags; //байт флагов нажатия кнопки
#define BTN_SHRT_UP (1<<0) /*бит короткого нажатия кнопки up*/
#define BTN_SHRT_DN (1<<1) /*бит короткого нажатия кнопки dn*/
#define BTN_SHRT_POWER (1<<2) /*бит короткого нажатия кнопки POWER */
#define BTN_SHRT_SW (1<<3) /*бит короткого нажатия кнопки SW*/
#define BTN_LONG_UP (1<<4) /*бит длинного нажатия кнопки up*/
#define BTN_LONG_DN (1<<5) /*бит длинного нажатия кнопки dn*/
#define BTN_LONG_SW (1<<6) /*бит короткого нажатия кнопки SW*/
//----------
//Функция настройки библиотеки работы с кнопками
void BtnInit (void)
{
BTN_DDR &= ~(BTN_LINE_UP| BTN_LINE_DN);//на ввод
BTN_PORT |= (BTN_LINE_UP| BTN_LINE_DN);//подтяжка вкл
}
//----------
//Функция чтения данных о нажатии кнопок
char BtnGet (void)
{
cli();
char temp = BtnFlags;
BtnFlags = 0;
sei();
return temp;
}
//----------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании с частотой 100 Гц)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
void BtnExe (void)
{
static unsigned char BtnLockBit; //защелка (защита от дребезга)
static unsigned char BtnLockCoun; //счетчик защелки (защита от дребезга)
static unsigned char BtnLongCoun; //счетчик длинного нажатия
static unsigned char BtnLastState; //последнее состояние кнопок перед отпусканием
char mask = 0;
if (! (BTN_PIN & BTN_LINE_UP)) mask = BTN_SHRT_UP;
if (! (BTN_PIN & BTN_LINE_DN)) mask = BTN_SHRT_DN;
//if (! (BTN_PIN & BTN_LINE_POWER)) mask = BTN_SHRT_POWER;
//if (! (BTN_PIN & BTN_LINE_SW)) mask = BTN_SHRT_SW;
if (mask){ //опрос состояния кнопки
if (BtnLockCoun < (BTN_LOCK_TIME/10)){ //клавиша нажата
BtnLockCoun++;
return; //защелка еще не дощитала - возврат
}
BtnLastState = mask;
BtnLockBit =1; //нажатие зафиксировано
if (BtnLongCoun >= (BTN_LONG_TIME/10))
return; //возврат, т.к. счетчик длинн нажат досчитал до максимума еще раньше
if (++BtnLongCoun >= (BTN_LONG_TIME/10))
BtnFlags |= (BtnLastState<<4); //счетчик досчитал до максимума - устанавливаем биты длинного нажатия
}
else{ //клавиша отжата
if (BtnLockCoun){
BtnLockCoun --;
return; //защелка еще не обнулилась - возврат
}
if (! BtnLockBit) //СТАТИЧЕСКИЙ ВОЗВРАТ
return;
BtnLockBit =0; //отжатие зафиксировано
if (BtnLongCoun < (BTN_LONG_TIME/10))
BtnFlags |= BtnLastState; //установка бита короткого нажатия
BtnLongCoun = 0; //сброс счетчика длительности нажатия
}
}
#define CONFIG_AMOUNT 6
typedef struct
{
char FlagPower;
char ValuePWM;
}ConfigurationLamp;
EEMEM ConfigurationLamp E_ConfigLamp[CONFIG_AMOUNT];
ConfigurationLamp ConfigLamp[CONFIG_AMOUNT];
unsigned char ValuePWM[CONFIG_AMOUNT];
unsigned char FlagPower[CONFIG_AMOUNT];
//----------
void LoadingEEPROM()
{
eeprom_read_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));
/*
for (static unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
{
FlagPower[ValueCount]=ConfigLamp[ValueCount].FlagPower;
ValuePWM[ValueCount]=ConfigLamp[ValueCount].ValuePWM;
}
*/
for (static unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
{
FlagPower[ValueCount]=1;
ValuePWM[ValueCount]=ValueCount*20+15;
}
ValuePWM[5]=0xFF;
}
void SaveEEPROM()
{
for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
{
ConfigLamp[ValueCount].FlagPower=(FlagPower[ValueCount]);
ConfigLamp[ValueCount].ValuePWM=(ValuePWM[ValueCount]);
}
eeprom_update_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));
}
//----------
unsigned char data1 = 0;
unsigned char data2 = 0;
unsigned char count = 0;
unsigned char ZoneNumber=0;
/*
void WriteSeg(unsigned char Number)
{
data1=ValuePWM[Number]%10;
data2=ValuePWM[Number]/10;
PORTB |=(1<<ANOD1);
PORTD |=(1<<ANOD2);
PORTD |=(1<<ANOD3);
segchar(99);
if(FlagPower[Number]==1)
{
count++;
if (count==1){
PORTB &= ~(1<<ANOD1);
segchar(data1);
PORTD |=(1<<ANOD2);
PORTD |=(1<<ANOD3);
}
if (count==2){
PORTD &= ~(1<<ANOD2);
segchar(data2);
PORTB |=(1<<ANOD1);
PORTD |=(1<<ANOD3);
}
if (count==3){
PORTD &= ~(1<<ANOD3);
segchar(Number+1);
PORTB |=(1<<ANOD1);
PORTD|=(1<<ANOD2);
}
if (count==3){count=0;}
}
}
*/
void UpdateValue(void)
{
for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
{
unsigned char TempValue=0;
switch (ValueCount)
{
case 0:
TempValue=OCR0A*2.56;
if (FlagPower[ValueCount]==1)
{
if ((TempValue==0)&(!(ValuePWM[ValueCount]==0)))
{
while ((TempValue<ValuePWM[ValueCount])& (ValuePWM[ValueCount] < 99))
{
//WriteSeg(ZoneNumber);
TempValue++;
_delay_ms(100);
OCR0A=TempValue;
}
}
OCR0A=ValuePWM[ValueCount]*2.56;
}
else{
OCR0A=0;
}break;
case 1:
if (FlagPower[ValueCount]==1)
{
OCR0B=ValuePWM[ValueCount]*2.56;
}
else{
OCR0B=0;}break;
case 2:
if (FlagPower[ValueCount]==1)
{
OCR1AL=ValuePWM[ValueCount]*2.56;
}
else{
OCR1AL=0;
}break;
case 3:
if (FlagPower[ValueCount]==1)
{
OCR1BL=ValuePWM[ValueCount]*2.56;
}
else{
OCR1BL=0;
}break;
case 4:
if (FlagPower[ValueCount]==1)
{
OCR2A=ValuePWM[ValueCount]*2.56;
}
else{
OCR2A=0;
}break;
case 5:
if (FlagPower[ValueCount]==1)
{
OCR2B=ValuePWM[ValueCount]*2.56;
}
else{
OCR2B=0;
}break;
}
}
}
ISR(INT0_vect)
{
//WriteSeg(ZoneNumber);
BtnExe();
}
unsigned char fBtnPower=0;
void BtnUpdate(void)
{
char BtnMask = BtnGet ();
if (BtnMask == BTN_SHRT_POWER)
{
FlagPower[ZoneNumber]++;
if (FlagPower[ZoneNumber]>1)
{
FlagPower[ZoneNumber]=0;
}
SaveEEPROM();
}
if ((BtnMask == BTN_SHRT_SW))
{
ZoneNumber++;
if (ZoneNumber==6)
{
ZoneNumber=0;
}
}
//одиночное нажатие +
if ((BtnMask == BTN_SHRT_UP)& (ValuePWM[ZoneNumber] < 99))
{
ValuePWM[ZoneNumber]++;
SaveEEPROM();
}
//одиночное нажатие -
if ((BtnMask == BTN_SHRT_DN)& (ValuePWM[ZoneNumber] > 0))
{
ValuePWM[ZoneNumber]--;
SaveEEPROM();
}
//Удержание +
if ((BtnMask == BTN_LONG_UP) & (ValuePWM[ZoneNumber] < 99))
{
while ((!(PINB&0b10000000))& (ValuePWM[ZoneNumber] < 99))
{
ValuePWM[ZoneNumber]++;
_delay_ms(50);
}
SaveEEPROM();
}
//Удержание -
if ((BtnMask == BTN_LONG_DN) & (ValuePWM[ZoneNumber] > 0))
{
while ((!(PINB&0b01000000))& (ValuePWM[ZoneNumber] > 0))
{
ValuePWM[ZoneNumber]--;
_delay_ms(50);
}
SaveEEPROM();
}
}
static uint8_t SendByte_i2c(uint8_t value)
{
write_i2c((I2C_ADR_SLAVE<<1), value);
asm("NOP");
return 0;
}
uint8_t SendDataPack()
{
for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
{
SendByte_i2c(0xFF);
SendByte_i2c(0xFF);
SendByte_i2c(ValueCount);
SendByte_i2c(FlagPower[ValueCount]);
SendByte_i2c(ValuePWM[ValueCount]);
}
return 0;
}
//char i=0;
int main(void)
{
LoadingEEPROM();
_delay_ms(50);
init_io();
init_int0();
BtnInit();
i2c_init();
init_pwm();
sei();
while(1)
{
BtnUpdate();
UpdateValue();
SendDataPack();
}
return 0;
}
// I2C ////////////////////////////////////////
static uint8_t write_i2c(uint8_t ADR, uint8_t value) {
uint8_t ret;
if (start_i2c(ADR) != ERROR)
{
ret=send_i2c(value);
stop_i2c();
} else {
stop_i2c();
ret=ERROR;
}
return ret;
}
uint8_t send_i2c(uint8_t value)
{
TWDR = value;
TWCR = (1<<TWINT) | (1<<TWEN);
// wail until transmission completed and ACK/NACK has been received
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
value = TWSR & 0xF8;
return (value == MT_SLA_ACK || value == MT_DATA_ACK) ? SUCCESS : ERROR;
}
static uint8_t start_i2c(uint8_t d_adr)
{
TWCR=(1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // START
while (!(TWCR & (1<<TWINT)));
uint8_t twst = (TWSR & 0xF8); // check value of TWI Status Register. Mask prescaler bits.
return ((twst != START) && (twst != REP_START)) ? ERROR : send_i2c(d_adr);
};
static inline void stop_i2c()
{
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
}
// END OF FILE ///////////////////////////////
Вт сен 11, 2018 12:33:27
Ср сен 12, 2018 02:52:12