• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Программирование ATTINY2313A-PU в среде Arduino IDE 1.8.2

alexlaw

Member
К сожалению пока не получается.
Попробовал в Proteus, то же самое, что и в железе.
Не правильный ход мыслей.
Может у кого получится.
Скетч - Usart_1Wire.
Остальные работают правильно.
 

Вложения

nikolz

Well-known member
К сожалению пока не получается.
Попробовал в Proteus, то же самое, что и в железе.
Не правильный ход мыслей.
Может у кого получится.
Скетч - Usart_1Wire.
Остальные работают правильно.
Подсказка.
суть в том, что вам надо объединить два сигнала туда и обратно так, чтобы выход не закоротил вход при работе 1-wire в сторону UART
Классически это решается созданием на выходе третьего состояния (состояние большого сопротивления фактически разрыв цепи), когда сигнал идет в сторону UART
Если взять диод, то при подаче обратного напряжения его сопротивление станет большим- т е. диод и создаст третье состояние.
Как это сделать? Как включить диод чтобы создать такой режим?
Подумайте над этим.
 

alexlaw

Member
Получилось.
Код:
//http://microsin.net/programming/AVR/avr318-dallas-1-wire-master.html
//https://www.maximintegrated.com/en/app-notes/index.mvp/id/214
unsigned char temp;
unsigned int tmp;
uint8_t WireCRC;
byte Num[10] ={126,48,109,121,51,91,95,112,127,123};
int slaveSelect=14;
int din=6;
int clk=15;
// буфер данных
// 8 байт - CRC
// Если вычисленный CRC совпадает с прочитанным CRC, то
// данные были получены без ошибок
//7 байт - 0x10, 6 байт - 0x0C, 5 байт - 0xFF
byte bufData[9];
byte a,b,n;
void setup() {
  pinMode(slaveSelect, OUTPUT);
  pinMode(din, OUTPUT);
  pinMode(clk, OUTPUT);
  pinMode(12, OUTPUT);
  digitalWrite(12,0);
sendCommand(12,1); //normal mode (default is shutdown mode)
sendCommand (15,0); //Display test off
sendCommand (10,6); //set medium intensity (range is 0-15)
sendCommand (11, 7); //7219 digit scan limit command
sendCommand (9, 0); //decode command, use standard 7-segment digits
clearDisp();
//---------------------
//CodeVisionAVR V2.05.0
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x06;
// USART Baud Rate: 115200
UBRRH=0x00;
UBRRL=0x03;
//---------------------
//digitalWrite(12,DetectPresence());
}

void loop() {
a=0;b=0;n=0; 
DetectPresence();// сброс шины 
Wire_Transmit(0xCC);// пропуск ROM
Wire_Transmit(0x44);//инициализация измерения
delay(900);  // пауза
DetectPresence();// сброс шины
Wire_Transmit(0xCC);// пропуск ROM
Wire_Transmit(0xBE);// чтение памяти датчика
for(int i = 0; i < 72; i++) { //чтение 9 байт памяти датчика      
     if (a==8) {
        bufData[n]=b;
        a=0;
        b=0;
        n++;       
     }
b |= (ReadBit()<<a);
a++;      
}
//вести подсчет CRC по алгоритму для всех байтов,
//включая последний байт контрольной суммы.
//если искажений не было, получится 0.
//для 8 байт crc равно 8 байту буфера 
WireCRC=OneWireCRC (8);
if (bufData[9]==WireCRC)digitalWrite(12,0); //OK
else digitalWrite(12,1);//ошибка crc
    if ((bufData[1]&128) != 0)//'-' отрицательная температура
    {          
      sendCommand (5, 1);
      tmp = ((unsigned char)bufData[1]<<8) | bufData[0];
      tmp = ~tmp + 1;
      bufData[0] = tmp;
      bufData[1] = tmp>>8; 
    }
temp = bufData[0]>>4 | bufData[1]<<4;
sendCommand (4, Num[temp/10]);
sendCommand (3, Num[temp % 10]);
//delay(2000);
////отладка-------------------
//disp(WireCRC,0);//расчетное crc
//delay(2000);
//disp(bufData[9],128); //crc полученное от датчика
delay(2000);
clearDisp();
//отладка-------------------
}
void clearDisp()
{
sendCommand (8, 0);
sendCommand (7, 0);
sendCommand (6, 0);
sendCommand (5, 0);
sendCommand (4, 1);
sendCommand (3, 1);
sendCommand (2, 99);
sendCommand (1, 78);//t*C  --*  
}
void sendCommand(byte cmd, byte data)
{
digitalWrite(slaveSelect, LOW); //chip select is active low
// передать старший байт
shiftOut(din, clk, MSBFIRST, cmd);
// передать младший байт
shiftOut(din, clk, MSBFIRST, data);
digitalWrite(slaveSelect,HIGH);
}
unsigned char TouchBit(unsigned char outValue)
{   
    // Place the output value in the UART transmit buffer, and wait
    // until it is received by the UART receiver.
    UDR = outValue;
    while(!(UCSRA & (1 << RXC)))
    {
    }
    // Set the UART Baud Rate back to 115200kbps when finished.
    // USART Baud Rate: 115200
    UBRRH=0x00;
    UBRRL=0x03;
    return UDR;
}
unsigned char DetectPresence()
{
    // Reset UART receiver to clear RXC register.
    UCSRB &= ~(1 << RXEN);
    UCSRB |= (1 << RXEN);   
    // Set UART Baud Rate to 9600 for Reset/Presence signalling.
    // USART Baud Rate: 9600 
    UBRRH=0x00;
    UBRRL=0x33;   
    // Return 0 if the value received matches the value sent.
    // return 1 else. (Presence detected)
    return (TouchBit(0xF0) != 0xF0);
}
void WriteBit1()
{
    TouchBit(0xff);
}
void WriteBit0()
{
    TouchBit(0x00);
}
void Wire_Transmit(unsigned int data)
{
for(int i = 0; i < 8; i++)
{
   if(data&0x01) WriteBit1();
      else WriteBit0();  
   data = data >> 1; // Следующий бит
}
}
unsigned char ReadBit(){
     // Return 1 if the value received matches the value sent.
     // Return 0 else. (A slave held the bus low).
     return (TouchBit(0xff) == 0xff);
}
uint8_t OneWireCRC (int bytes) {
  uint8_t crc = 0;
  for (int j=0; j<bytes; j++) {
    crc = crc ^ bufData[j];
    for (int i=0; i<8; i++) crc = crc>>1 ^ ((crc & 1) ? 0x8c : 0);
  }
  return crc;
}
//отладка-------------------
//1-lsb-младший бит,8-msb-старший бит
void disp(unsigned char data,unsigned char dot){
for(int i = 1; i < 9; i++) {
  if (i==8) sendCommand (i, Num[data & 0x01] | dot);
  else  sendCommand (i, Num[data & 0x01]);
  data = data >> 1; // Следующий бит 
} 
}
//отладка-------------------
 

alexlaw

Member
Тестирование кнопок
Button.png
Код:
//https://play.google.com/store/apps/details?id=com.peterhohsy.atmega_tutoriallite&hl=ru
#include <util/delay.h>
#define Keypad1_PORT    PORTB
#define Keypad1_DIR     DDRB
#define Keypad1_PIN     PINB

#define Segment1_PORT    PORTD
#define Segment1_DIR     DDRD
#define Segment1_PIN     PIND

#define KEYPAD_NO_PRESS  (unsigned char) 0xFF
#define KEY1_PRESS       (unsigned char) 0 
#define KEY2_PRESS       (unsigned char) 1 
#define KEY3_PRESS       (unsigned char) 2 
#define KEY4_PRESS       (unsigned char) 3 
#define KEY5_PRESS       (unsigned char) 4 
#define KEY6_PRESS       (unsigned char) 5 
#define KEY7_PRESS       (unsigned char) 6 
#define KEY8_PRESS       (unsigned char) 7 
#define KEY9_PRESS       (unsigned char) 8 
#define KEY10_PRESS      (unsigned char) 9 
#define KEY11_PRESS      (unsigned char) 10 
#define KEY12_PRESS      (unsigned char) 11 
#define KEY13_PRESS      (unsigned char) 12 
#define KEY14_PRESS      (unsigned char) 13 
#define KEY15_PRESS      (unsigned char) 14 
#define KEY16_PRESS      (unsigned char) 15

#define KEY_RELEASE   1
#define KEY_PRESS     0

unsigned char segment1[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; // 0~F
unsigned char Keypad1_Data  = 0;       
unsigned char Keypad1_State = KEY_RELEASE;
int key;
void setup() {
// Если  вывод  функционирует  как  вход, то
//при  установке  бита  PORTxn  в  1  подтягивающий  резистор 
//подключается между выводом микроконтроллера и шиной питания.
Keypad1_PORT=0xFF;// pullup
//Бит  DDxn  регистра  DDx  определяет  направление  передачи  данных
//через контакт ввода/вывода. Если этот бит установлен в 1, то nй вывод
//порта является выходом, если же сброшен в 0 — входом.
Keypad1_DIR=0x00;// input

//Если бит установлен в 1, на выводе устанавливается
//напряжение ВЫСОКОГО уровня.
Segment1_PORT=0x00;// low
//Бит  DDxn  регистра  DDxв установлен в 1, то nй вывод
//порта является выходом
//---------------
Segment1_DIR=0x7F;// output
Segment1_off();
}

void loop() {   
       key = Get_Keypad1_Press();   
       if (key !=KEYPAD_NO_PRESS)
       {   
            Segment1_ShowDigit(key & 0x0f);
       }
delay(100);
//Segment1_off();
}
// show hexadecimal 0 ~ F
void Segment1_ShowDigit(unsigned char hexadecimal)
{
      Segment1_PORT = segment1[ hexadecimal & 0x0f];
}
void Segment1_off()
{
      Segment1_PORT = 0x00;
}
// show pattern : 00 ~ FF
//     a
//    --
// f |  | b
//    -- g
// e |  | c
//    --
//    d
//  bit6 bit5 bit4 bit3 bit2 bit1 bit0
//    g   f    e    d    c    b    a
void Segment1_ShowPattern(unsigned char pattern) // 00-FF
{
    Segment1_PORT = pattern;
}
unsigned char Get_Keypad1_Press()
{
    unsigned char temp1 = 0xff;
    if (Keypad1_State == KEY_RELEASE)
    {
        // input | output
        Keypad1_DIR = 0x0F;      
        Keypad1_PORT = 0xF0;   
_delay_loop_2(8);
        switch (Keypad1_PIN & 0xF0)
        {
               case 0xE0 : temp1=0 ; break;
               case 0xD0 : temp1=1 ; break;
               case 0xB0 : temp1=2 ; break;
               case 0x70 : temp1=3; break;
               default : temp1=0xff; break;
         }
         if (temp1==0xff)
         {
             Keypad1_Data = KEYPAD_NO_PRESS;
             return KEYPAD_NO_PRESS;
         }
         Keypad1_Data = temp1 * 4;

        //  output | input
        Keypad1_DIR = 0xF0;      
        Keypad1_PORT = 0x0F;  
_delay_loop_2(8);
        switch (Keypad1_PIN & 0x0F)
        {
               case 0x0E : temp1=0 ; break;
               case 0x0D : temp1=1 ; break;
               case 0x0B : temp1=2 ; break;
               case 0x07 : temp1=3;  break;
               default : temp1=0xff; break;
        }
        if (temp1==0xff)
        {
            Keypad1_Data = KEYPAD_NO_PRESS;
            return KEYPAD_NO_PRESS;
        }
        else
        {
            delay(25);
            Keypad1_Data = Keypad1_Data + temp1;
            Keypad1_State = KEY_PRESS;
            return  KEYPAD_NO_PRESS ;
        }
      }
      else
      {
          Keypad1_DIR = 0x0F;  
          Keypad1_PORT = 0xF0; 
_delay_loop_2(8);
          switch (Keypad1_PIN & 0xF0)
          {
              case 0xE0 : temp1=0 ; break;
              case 0xD0 : temp1=1 ; break;
              case 0xB0 : temp1=2 ; break;
              case 0x70 : temp1=3; break;
              default : temp1=0xff; break;
          }
          if (temp1 != 0xff)
              return KEYPAD_NO_PRESS;
          else
          {
              Keypad1_State = KEY_RELEASE;
              return Keypad1_Data;
          }    
     }
}
 

Вложения

nikolz

Well-known member
Задачка.
Все кнопки можно подключить к одному пину,
если сразу не получится, то максимум к двум.
число кнопок -любое.
подумайте над этим
 

alexlaw

Member
Задачка.
Все кнопки можно подключить к одному пину,
если сразу не получится, то максимум к двум.
число кнопок -любое.
подумайте над этим
У Attiny2313 отсутствует Аналого\цифровой преобразователь.
А с помощью аналогового компаратора, мне кажется слишком трудоемко и не эффективно.
В общем, пока не вижу как подключить много кнопок к одному пину. Если знаете подскажите куда двигаться.
PS Памяти всего 2 кб, поэтому экономить пины мне кажется нецелесообразно.
 

nikolz

Well-known member
я разве указал что это аналоговый пин?
К аналоговому и д... сможет
Задача подключить бесконечное число кнопок к любому пину или двум которые являются бинарными PIO.
Подумайте над этим
 

alexlaw

Member
Здравствуйте.
Кнопки пока решил отложить - не определился с концепцией.
То ли использовать дополнительный сдвиговый регистр, то ли измерять время
зарядки конденсатора. Ну да ладно.
Жду когда придут часы реального времени DS1302. А пока эмулирую в протеусе.
Так вот если подключить виртуальный осциллограф к схеме, то время считывается
правильно, если его отключить, то не правильно.
В чем может быть причина?
PS Меня интересует именно функции shiftOut и shiftIn,
поэтому прошу не переводить вопрос на другие возможности (другая эмуляция SPI и т.п.)
 

Вложения

nikolz

Well-known member
Здравствуйте.
Кнопки пока решил отложить - не определился с концепцией.
То ли использовать дополнительный сдвиговый регистр, то ли измерять время
зарядки конденсатора. Ну да ладно.
Жду когда придут часы реального времени DS1302. А пока эмулирую в протеусе.
Так вот если подключить виртуальный осциллограф к схеме, то время считывается
правильно, если его отключить, то не правильно.
В чем может быть причина?
PS Меня интересует именно функции shiftOut и shiftIn,
поэтому прошу не переводить вопрос на другие возможности (другая эмуляция SPI и т.п.)
вопрос не понятный.
В протеусе подключаете?
Посмотрите какие параметры этого осциллографа
В этом и есть разница - с ним и без него.
 

alexlaw

Member
Поставил диод на линию DIN на max7219 и все заработало.
DS1302_MAX7219.png
Код:
//-----------------------------------------------------------------------------
/*                                   ATTINY2313
                             =========================
                          ATTINY      ARDUINO     ATTINY
                   PA0/XTAL1 || 5 -  3        9 - 12 || PB0/AIN0/PCINT0    
                   PA1/XTAL2 || 4 -  2       10 - 13 || PB1/AIN1/PCINT1
                   PA2/RESET || 1 -  17      11 - 14 || PB2/OC0A/PCINT2
                             ||              12 - 15 || PB3/OC1A/PCINT3   
                     PD0/RXD || 2 -  0       13 - 16 || PB4/OC1B/PCINT4
                     PD1/TXD || 3 -  1       14 - 17 || PB5/MOSI/DI/SDA/PCINT5
          PD2/INT0/XCK/CKOUT || 6 -  4       15 - 18 || PB6/MISO/DO/PCINT6
                    PD3/INT1 || 7 -  5       16 - 19 || PB7/USCK/SCL/PCINT7
                      PD4/T0 || 8 -  6               ||
                 PD5/T1/OC0B || 9 -  7               ||
                     PD6/ICP || 11 - 8               ||
                          ATTINY      ARDUINO     ATTINY                  
                             =========================
                                     ATTINY2313    */
//-----------------------------------------------------------------------------                                    
unsigned char temp;
unsigned char prevtemp=100;
unsigned int tmp;
             //0  1  2   3   4  5  6  7  8   9   A    B  C  D  E  F
byte Num[] ={126,48,109,121,51,91,95,112,127,123,119,31,78,61,79,71};
uint8_t TimeBytes[7];// = {0,0,0,0,0,0,0};
int slaveSelect=14;
int din=6;
int clk=15;
// буфер данных
// 8 байт - CRC
// Если вычисленный CRC совпадает с прочитанным CRC, то
// данные были получены без ошибок
//7 байт - 0x10, 6 байт - 0x0C, 5 байт - 0xFF
byte bufData[9];
byte a,b,n;
void setup() {
  pinMode(slaveSelect, OUTPUT);
  pinMode(din, OUTPUT);
  pinMode(clk, OUTPUT);
sendCommand7219(12,1); //normal mode (default is shutdown mode)
sendCommand7219 (15,0); //Display test off
sendCommand7219 (10,6); //set medium intensity (range is 0-15)
sendCommand7219 (11, 7); //7219 digit scan limit command
sendCommand7219 (9, 0); //decode command, use standard 7-segment digits
  //УСТАНОВИТЬ ВРЕМЯ 30.11.1994 23 часа 45 мин 30 сек
  sendCommand1302(0x86, 0x30);
  sendCommand1302(0x88, 0x11);
  sendCommand1302(0x8C, 0x94);
//  sendCommand1302(0x84, 0x23);
//  sendCommand1302(0x82, 0x45);
//  sendCommand1302(0x80, 0x30);
//  sendCommand1302(0x8A, 0x01);//день пн
//---------------------
//CodeVisionAVR V2.05.0
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x06;
// USART Baud Rate: 115200
UBRRH=0x00;
UBRRL=0x03;
//---------------------
//digitalWrite(12,DetectPresence());
}

void loop() {
a=0;b=0;n=0; 
DetectPresence();// сброс шины 
Wire_Transmit(0xCC);// пропуск ROM
Wire_Transmit(0x44);//инициализация измерения
delay(900);  // пауза
DetectPresence();// сброс шины
Wire_Transmit(0xCC);// пропуск ROM
Wire_Transmit(0xBE);// чтение памяти датчика
for(int i = 0; i < 72; i++) { //чтение 9 байт памяти датчика      
     if (a==8) {
        bufData[n]=b;
        a=0;
        b=0;
        n++;       
     }
b |= (ReadBit()<<a);
a++;      
}

    if ((bufData[1]&128) != 0)//'-'
    {          
      sendCommand7219 (4, 1);
      tmp = ((unsigned char)bufData[1]<<8) | bufData[0];
      tmp = ~tmp + 1;
      bufData[0] = tmp;
      bufData[1] = tmp>>8; 
    } else sendCommand7219 (4, 0);
temp = bufData[0]>>4 | bufData[1]<<4;
sendCommand7219 (3, Num[temp/10]);
sendCommand7219 (2, Num[temp % 10]);
sendCommand7219 (1, 99);
//sendCommand7219 (1, 78);
data1302();
ViewTime(8, TimeBytes[2]);//часы
ViewTime(6, TimeBytes[1]);//минуты
delay(60000);
}

void sendCommand7219(byte cmd, byte data)
{
digitalWrite(slaveSelect, LOW); //chip select is active low
// передать старший байт
shiftOut(din, clk, MSBFIRST, cmd);
// передать младший байт
shiftOut(din, clk, MSBFIRST, data);
digitalWrite(slaveSelect,HIGH);
}
void sendCommand1302(byte cmd, byte data)
{
digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
// передать старший байт
shiftOut(din, clk, LSBFIRST, cmd);
// передать младший байт
shiftOut(din, clk, LSBFIRST, data);
digitalWrite(slaveSelect,LOW);
}
void data1302()
{
//Команда clock burst read с кодом 0xBF считывает текущее состояние часов
//В ответ RTC посылают 7 байт, в которых хранятся соответственно
//секунды, минуты, часы, день, месяц, день недели, год, и кое-какие флаги 
digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
// передать  байт
shiftOut(din, clk, LSBFIRST, 0xBF);
pinMode(din, INPUT);
for(int i = 0; i < 7; i++){
TimeBytes[i]=shiftIn(din, clk, LSBFIRST);
}
digitalWrite(slaveSelect,LOW);
pinMode(din, OUTPUT);
}
unsigned char TouchBit(unsigned char outValue)
{   
    // Place the output value in the UART transmit buffer, and wait
    // until it is received by the UART receiver.
    UDR = outValue;
    while(!(UCSRA & (1 << RXC)))
    {
    }
    // Set the UART Baud Rate back to 115200kbps when finished.
    // USART Baud Rate: 115200
    UBRRH=0x00;
    UBRRL=0x03;
    return UDR;
}
unsigned char DetectPresence()
{
    // Reset UART receiver to clear RXC register.
    UCSRB &= ~(1 << RXEN);
    UCSRB |= (1 << RXEN);   
    // Set UART Baud Rate to 9600 for Reset/Presence signalling.
    // USART Baud Rate: 9600 
    UBRRH=0x00;
    UBRRL=0x33;   
    // Return 0 if the value received matches the value sent.
    // return 1 else. (Presence detected)
    return (TouchBit(0xF0) != 0xF0);
}
void WriteBit1()
{
    TouchBit(0xff);
}
void WriteBit0()
{
    TouchBit(0x00);
}
void Wire_Transmit(unsigned int data)
{
for(int i = 0; i < 8; i++)
{
   if(data&0x01) WriteBit1();
      else WriteBit0();  
   data = data >> 1; // Следующий бит
}
}
unsigned char ReadBit(){
     // Return 1 if the value received matches the value sent.
     // Return 0 else. (A slave held the bus low).
     return (TouchBit(0xff) == 0xff);
}

void ViewTime(byte high_place, byte data)
{
   sendCommand7219 (high_place, Num[(data & 0xF0) >> 4]);
   sendCommand7219 (high_place-1, Num[data & 0x0F]);
}
 

alexlaw

Member
Несколько ссылок для дальнейшего изучения или я бы назвал "используемая литература"

Интересный проект
 

alexlaw

Member
В "железе" с RTC 1302 пришлось немного подкорректировать.
Выкинул диод и SHIFTIN
IMG_20190709_145543.jpg
Схема
DS1302_MAX7219_1.png
Код:
//-----------------------------------------------------------------------------
/*                                   ATTINY2313
                             =========================
                          ATTINY      ARDUINO     ATTINY
                   PA0/XTAL1 || 5 -  3        9 - 12 || PB0/AIN0/PCINT0   
                   PA1/XTAL2 || 4 -  2       10 - 13 || PB1/AIN1/PCINT1
                   PA2/RESET || 1 -  17      11 - 14 || PB2/OC0A/PCINT2
                             ||              12 - 15 || PB3/OC1A/PCINT3  
                     PD0/RXD || 2 -  0       13 - 16 || PB4/OC1B/PCINT4
                     PD1/TXD || 3 -  1       14 - 17 || PB5/MOSI/DI/SDA/PCINT5
          PD2/INT0/XCK/CKOUT || 6 -  4       15 - 18 || PB6/MISO/DO/PCINT6
                    PD3/INT1 || 7 -  5       16 - 19 || PB7/USCK/SCL/PCINT7
                      PD4/T0 || 8 -  6               ||
                 PD5/T1/OC0B || 9 -  7               ||
                     PD6/ICP || 11 - 8               ||
                          ATTINY      ARDUINO     ATTINY                 
                             =========================
                                     ATTINY2313    */
//-----------------------------------------------------------------------------                                   
int slaveSelect=14;//PB5
int din=6;//PD4
int clk=15;//PB6
uint8_t TimeBytes[] ={0x41,0x42,0x43,0x44,'E','\n','\r'};
byte Num[] ={126,48,109,121,51,91,95,112,127,123,119,31,78,61,79,71};

void setup() {
  pinMode(clk, OUTPUT);//7 - 15 PB6 СИНИЙ
  pinMode(din, OUTPUT);//6 - 6 PD4 ЗЕЛЕНЫЙ
  pinMode(slaveSelect, OUTPUT);//5 - 14 PB5 ЖЕЛТЫЙ
sendCommand7219(12,1); //normal mode (default is shutdown mode)
sendCommand7219 (15,0); //Display test off
sendCommand7219 (10,6); //set medium intensity (range is 0-15)
sendCommand7219 (11, 7); //7219 digit scan limit command
sendCommand7219 (9, 0); //decode command, use standard 7-segment digits
sendCommand7219 (8, 0);
sendCommand7219 (7, 61);
sendCommand7219 (6, 91);
sendCommand7219 (5, 1);
sendCommand7219 (4, 48);
sendCommand7219 (3, 121);
sendCommand7219 (2, 126);
sendCommand7219 (1, 109);
delay(1000);
//  //УСТАНОВИТЬ ВРЕМЯ 30.11.94 23 часа 45 мин 00 сек
  sendCommand1302(0x86, 0x30);//день
  sendCommand1302(0x88, 0x11);//месяц
  sendCommand1302(0x8C, 0x94);//год
  sendCommand1302(0x84, 0x23);//час
  sendCommand1302(0x82, 0x45);//мин
  sendCommand1302(0x80, 0x00);//сек
  sendCommand1302(0x8A, 0x01);//день недели пн

}

void loop() {
data1302();
ViewTime(8, TimeBytes[2]);//часы
sendCommand7219 (6, 1);
ViewTime(5, TimeBytes[1]);//минуты
sendCommand7219 (3, 1);
ViewTime(2, TimeBytes[0]);//секунды
delay(800);
}
void sendCommand7219(byte cmd, byte data)
{
digitalWrite(slaveSelect, LOW); //chip select is active low
// передать старший байт
shiftOut(din, clk, MSBFIRST, cmd);
// передать младший байт
shiftOut(din, clk, MSBFIRST, data);
digitalWrite(slaveSelect,HIGH);
}
void sendCommand1302(byte cmd, byte data)
{
digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
// передать старший байт
shiftOut(din, clk, LSBFIRST, cmd);
// передать младший байт
shiftOut(din, clk, LSBFIRST, data);
digitalWrite(slaveSelect,LOW);
}
void data1302()
{
//Команда clock burst read с кодом 0xBF считывает текущее состояние часов
//В ответ RTC посылают 7 байт, в которых хранятся соответственно
//секунды, минуты, часы, день, месяц, день недели, год, и кое-какие флаги
digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
// передать  байт
shiftOut(din, clk, LSBFIRST, 0xBF);
pinMode(din, INPUT);
for(int i = 0; i < 7; i++){
TimeBytes[i]=readByte();
}
digitalWrite(slaveSelect,LOW);
pinMode(din, OUTPUT);
}
uint8_t readByte()
{
  uint8_t value = 0;
  uint8_t currentBit = 0;

  for (int i = 0; i < 8; ++i)
  {
    currentBit = digitalRead(din);
    value |= (currentBit << i);
    digitalWrite(clk, HIGH);
    delayMicroseconds(1);
    digitalWrite(clk, LOW);
  }
  return value;
}
void ViewTime(byte high_place, byte data)
{
   sendCommand7219 (high_place, Num[(data & 0xF0) >> 4]);
   sendCommand7219 (high_place-1, Num[data & 0x0F]);
}
Все работает :)
 

nikolz

Well-known member
В "железе" с RTC 1302 пришлось немного подкорректировать.
Выкинул диод и SHIFTIN
Посмотреть вложение 7620
Все работает :)
А как вам такая схема

--------------------------
теперь для сравнения нарисуйте тоже самое на STM8L151
8-bit ultra-low-power MCU, up to 32 KB Flash, 1 KB Data EEPROM, RTC, LCD, timers, USART, I2C, SPI, ADC, DAC, comparators.
получится и дешевле и проще и меньше кушает и встроенный драйвер индикатора.
 

alexlaw

Member
несомненно лучше. Но ...
ATTINY2313 хорош для начинающих, таких как я.
А STM8L151 это уже следующий этап.
К тому же я хотел использовать для программирования среду Arduino IDE, т.к. код в ней можно менять буквально на лету, что хорошо для наглядности и отладки.
А пока работа с RAM RTC 1302
Код:
//-----------------------------------------------------------------------------
/*                                   ATTINY2313
                             =========================
                          ATTINY      ARDUINO     ATTINY
                   PA0/XTAL1 || 5 -  3        9 - 12 || PB0/AIN0/PCINT0    
                   PA1/XTAL2 || 4 -  2       10 - 13 || PB1/AIN1/PCINT1
                   PA2/RESET || 1 -  17      11 - 14 || PB2/OC0A/PCINT2
                             ||              12 - 15 || PB3/OC1A/PCINT3   
                     PD0/RXD || 2 -  0       13 - 16 || PB4/OC1B/PCINT4
                     PD1/TXD || 3 -  1       14 - 17 || PB5/MOSI/DI/SDA/PCINT5
          PD2/INT0/XCK/CKOUT || 6 -  4       15 - 18 || PB6/MISO/DO/PCINT6
                    PD3/INT1 || 7 -  5       16 - 19 || PB7/USCK/SCL/PCINT7
                      PD4/T0 || 8 -  6               ||
                 PD5/T1/OC0B || 9 -  7               ||
                     PD6/ICP || 11 - 8               ||
                          ATTINY      ARDUINO     ATTINY                  
                             =========================
                                     ATTINY2313    */
//-----------------------------------------------------------------------------                                    
int slaveSelect=14;//PB5
int din=6;//PD4
int clk=15;//PB6
uint8_t TimeBytes[] ={0x41,0x42,0x43,0x44,'E','\n','\r'};
byte Num[] ={126,48,109,121,51,91,95,112,127,123,119,31,78,61,79,71};
byte ds1302[] ={0,61,91,1,48,121,126,109};
uint8_t ReadBytes[8];
void setup() {
  pinMode(clk, OUTPUT);//7 - 15 PB6 СИНИЙ
  pinMode(din, OUTPUT);//6 - 6 PD4 ЗЕЛЕНЫЙ
  pinMode(slaveSelect, OUTPUT);//5 - 14 PB5 ЖЕЛТЫЙ
sendCommand7219(12,1); //normal mode (default is shutdown mode)
sendCommand7219 (15,0); //Display test off
sendCommand7219 (10,6); //set medium intensity (range is 0-15)
sendCommand7219 (11, 7); //7219 digit scan limit command
sendCommand7219 (9, 0); //decode command, use standard 7-segment digits

sendCommand7219 (0x0C,0); //Display  off
delay(100);
//УСТАНОВИТЬ ВРЕМЯ
  sendCommand1302(0x86, 0x10);//день
  sendCommand1302(0x88, 0x07);//месяц
  sendCommand1302(0x8C, 0x19);//год
  sendCommand1302(0x84, 0x12);//час
  sendCommand1302(0x82, 0x25);//мин
  sendCommand1302(0x80, 0x00);//сек
  sendCommand1302(0x8A, 0x03);//день недели
    for (int i = 0; i < 8; ++i)
  {   
    sendCommand1302((i * 2) + 192, ds1302[i]);//запись 8 байт в RAM
  }
  delay(1000);
  //чтение 8 байт из RAM
      for (int i = 0; i < 8; ++i)
  {   
    digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
    shiftOut(din, clk, LSBFIRST, (i * 2) + 193);
    pinMode(din, INPUT);
    ReadBytes[i]=readByte();
    digitalWrite(slaveSelect,LOW);
    pinMode(din, OUTPUT);
  } 
        for (int i = 1; i < 9; ++i)
  {
    sendCommand7219 (i, ReadBytes[8-i]);   
  }
  sendCommand7219 (0x0C,1); //Display  on
  delay(2000);
}

void loop() {
data1302();
ViewTime(8, TimeBytes[2]);//часы
sendCommand7219 (6, TimeBytes[0]&0x01);
ViewTime(5, TimeBytes[1]);//минуты
sendCommand7219 (3, !(TimeBytes[0]&0x01));
ViewTime(2, TimeBytes[0]);//секунды
delay(1000);
}
void sendCommand7219(byte cmd, byte data)
{
digitalWrite(slaveSelect, LOW); //chip select is active low
// передать старший байт
shiftOut(din, clk, MSBFIRST, cmd);
// передать младший байт
shiftOut(din, clk, MSBFIRST, data);
digitalWrite(slaveSelect,HIGH);
}
void sendCommand1302(byte cmd, byte data)
{
digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
// передать старший байт
shiftOut(din, clk, LSBFIRST, cmd);
// передать младший байт
shiftOut(din, clk, LSBFIRST, data);
digitalWrite(slaveSelect,LOW);
}
void data1302()
{
//Команда clock burst read с кодом 0xBF считывает текущее состояние часов
//В ответ RTC посылают 7 байт, в которых хранятся соответственно
//секунды, минуты, часы, день, месяц, день недели, год, и кое-какие флаги 
digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
// передать  байт
shiftOut(din, clk, LSBFIRST, 0xBF);
pinMode(din, INPUT);
for(int i = 0; i < 7; i++){
TimeBytes[i]=readByte();
}
digitalWrite(slaveSelect,LOW);
pinMode(din, OUTPUT);
}
uint8_t readByte()
{
  uint8_t value = 0;
  uint8_t currentBit = 0;

  for (int i = 0; i < 8; ++i)
  {
    currentBit = digitalRead(din);
    value |= (currentBit << i);
    digitalWrite(clk, HIGH);
    delayMicroseconds(1);
    digitalWrite(clk, LOW);
  }
  return value;
}
void ViewTime(byte high_place, byte data)
{
   sendCommand7219 (high_place, Num[(data & 0xF0) >> 4]);
   sendCommand7219 (high_place-1, Num[data & 0x0F]);
}
 

fps

Active member
Задача подключить бесконечное число кнопок к любому пину или двум которые являются бинарными PIO.
Интересная задача.
Надеюсь она не подразумевает дополнительных микросхем и/или RC цепочек?
Тогда не могу придумать. Нужна подсказка.
 

alexlaw

Member
Добавил кнопку для установки часов (время настраивается заранее, кнопка для синхронизации программного и реального времени)
DS1302.png
 

Вложения

nikolz

Well-known member
посмотрите есть ли внутренняя подтяжка
если нет то надо добавить чтобы от помех не синхронизировалось
еще можно ток LED уменьшить
да и зачем он если есть дисплей
 

alexlaw

Member
да и зачем он если есть дисплей
Светодиоды для наглядности.
Сработает прерывание при наж кнопок, светодиод мигнет.
Продолжаю изучать кнопки
DS1302-led.png
Код:
//-----------------------------------------------------------------------------
/*                                   ATTINY2313
                             =========================
                          ATTINY      ARDUINO     ATTINY
                   PA0/XTAL1 || 5 -  3        9 - 12 || PB0/AIN0/PCINT0    
                   PA1/XTAL2 || 4 -  2       10 - 13 || PB1/AIN1/PCINT1
                   PA2/RESET || 1 -  17      11 - 14 || PB2/OC0A/PCINT2
                             ||              12 - 15 || PB3/OC1A/PCINT3   
                     PD0/RXD || 2 -  0       13 - 16 || PB4/OC1B/PCINT4
                     PD1/TXD || 3 -  1       14 - 17 || PB5/MOSI/DI/SDA/PCINT5
          PD2/INT0/XCK/CKOUT || 6 -  4       15 - 18 || PB6/MISO/DO/PCINT6
                    PD3/INT1 || 7 -  5       16 - 19 || PB7/USCK/SCL/PCINT7
                      PD4/T0 || 8 -  6               ||
                 PD5/T1/OC0B || 9 -  7               ||
                     PD6/ICP || 11 - 8               ||
                          ATTINY      ARDUINO     ATTINY                  
                             =========================
                                     ATTINY2313    */
//-----------------------------------------------------------------------------                                    
//https://www.myrobot.ru/stepbystep/pr_mcports.php
int slaveSelect=14;//PB5
int din=6;//PD4
int clk=15;//PB6
uint8_t TimeBytes[] ={0x41,0x42,0x43,0x44,'E','\n','\r'};
byte Num[] ={126,48,109,121,51,91,95,112,127,123,119,31,78,61,79,71};
byte ds1302[] ={0,61,91,1,48,121,126,109};
boolean b = false;
void setup() {
//pb0 pb1 pb2 кнопки
//pb3 pb4 светодиод  
PORTB |= (1 << 0) | (1 << 1 ) | (1 << 2);// Set bits - pullup
DDRB &= ~((1 << 0)  | (1 << 1)  | (1 << 2));// Clear bit - input 
PORTB &= ~((1 << 3)  |  (1 << 4));// Clear bit - low
DDRB |= (1 << 3) | (1 << 4);// Set bits - output
GIMSK |= (1 << PCIE);// Set bits - Разрешение прерывания по изменению состояния выводов 0й группы - PCINT.
//PCMSK Определяют условие генерации прерывания PCI0. Если какойлибо
//бит установлен в 1, то изменение состояния соответствующего вывода
//вызовет генерацию прерывания
PCMSK |= (1 << 0) | (1 << 1) | (1 << 2);// Set bits -прерывание по изменению состояния вывода 0 или 1  или 2 - PCINT

  pinMode(clk, OUTPUT);//7 - 15 PB6 СИНИЙ
  pinMode(din, OUTPUT);//6 - 6 PD4 ЗЕЛЕНЫЙ
  pinMode(slaveSelect, OUTPUT);//5 - 14 PB5 ЖЕЛТЫЙ
sendCommand7219(12,1); //normal mode (default is shutdown mode)
sendCommand7219 (15,0); //Display test off
sendCommand7219 (10,6); //set medium intensity (range is 0-15)
sendCommand7219 (11, 7); //7219 digit scan limit command
sendCommand7219 (9, 0); //decode command, use standard 7-segment digits
        for (int i = 1; i < 9; ++i)
  {
    sendCommand7219 (i, ds1302[8-i]);   
  }
  delay(2000);
}

void loop() {
if (b) SetTime(); 
data1302();
ViewTime(8, TimeBytes[2]);//часы
sendCommand7219 (6, TimeBytes[0]&0x01);
ViewTime(5, TimeBytes[1]);//минуты
sendCommand7219 (3, !(TimeBytes[0]&0x01));
ViewTime(2, TimeBytes[0]);//секунды
delay(1000);
}
void sendCommand7219(byte cmd, byte data)
{
digitalWrite(slaveSelect, LOW); //chip select is active low
// передать старший байт
shiftOut(din, clk, MSBFIRST, cmd);
// передать младший байт
shiftOut(din, clk, MSBFIRST, data);
digitalWrite(slaveSelect,HIGH);
}
void sendCommand1302(byte cmd, byte data)
{
digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
// передать старший байт
shiftOut(din, clk, LSBFIRST, cmd);
// передать младший байт
shiftOut(din, clk, LSBFIRST, data);
digitalWrite(slaveSelect,LOW);
}
void data1302()
{
//Команда clock burst read с кодом 0xBF считывает текущее состояние часов
//В ответ RTC посылают 7 байт, в которых хранятся соответственно
//секунды, минуты, часы, день, месяц, день недели, год, и кое-какие флаги 
digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
// передать  байт
shiftOut(din, clk, LSBFIRST, 0xBF);
pinMode(din, INPUT);
for(int i = 0; i < 7; i++){
TimeBytes[i]=readByte();
}
digitalWrite(slaveSelect,LOW);
pinMode(din, OUTPUT);
}
uint8_t readByte()
{
  uint8_t value = 0;
  uint8_t currentBit = 0;

  for (int i = 0; i < 8; ++i)
  {
    currentBit = digitalRead(din);
    value |= (currentBit << i);
    digitalWrite(clk, HIGH);
    delayMicroseconds(1);
    digitalWrite(clk, LOW);
  }
  return value;
}
void ViewTime(byte high_place, byte data)
{
   sendCommand7219 (high_place, Num[(data & 0xF0) >> 4]);
   sendCommand7219 (high_place-1, Num[data & 0x0F]);
}
void SetTime()
{
//УСТАНОВИТЬ ВРЕМЯ
  sendCommand1302(0x86, 0x10);//день
  sendCommand1302(0x88, 0x07);//месяц
  sendCommand1302(0x8C, 0x19);//год
  sendCommand1302(0x84, 0x12);//час
  sendCommand1302(0x82, 0x25);//мин
  sendCommand1302(0x80, 0x00);//сек
  sendCommand1302(0x8A, 0x03);//день недели
  b = false;
}
ISR(PCINT_vect) {
  //наж кн pb0
  if (!(PINB & 0x01)) PORTB |= (1 << 3);// Set bits - high pb3
  else PORTB &= ~(1 << 3);// Clear bit
  //наж кн pb1
  if (!(PINB>>1 & 0x01)) PORTB |= (1 << 4);// Set bits - high pb4
  else PORTB &= ~(1 << 4);// Clear bit
  //наж кн pb2
  if (!(PINB>>2 & 0x01)) {PORTB |= (1 << 3) | (1 << 4);// Set bits - high pb3 pb4
       b = true;
  }
}
nikolz - вы ничего не рассказали про ваш метод работы с кнопками.
Или это секрет?
 
Сверху Снизу