Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

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

Тема в разделе "Общие вопросы по электронике", создана пользователем alexlaw, 23 май 2019.

  1. nikolz

    nikolz Гуру

    Сообщения:
    4.489
    Симпатии:
    443
    Один из методов раза два уже рассказывал на форуме.
    Поэтому рассказывать надцатый раз нет интереса.
    ===============
    можно это написать иначе
    PORTB |= (1 << 0) | (1 << 1 ) | (1 << 2);// Set bits - pullup
    DDRB &= ~((1 << 0) | (1 << 1) | (1 << 2));// Clear bit - input
    PCMSK |= (1 << 0) | (1 << 1) | (1 << 2);// Set bits
    ---------------------
    так:
    ----------------------
    #define mask (1 << 0) | (1 << 1 ) | (1 << 2)
    PORTB |= mask;// Set bits - pullup
    DDRB &= ~mask;// Clear bit - input
    PCMSK |=mask;// Set bits
    т е PCMSK равен PORTB верно ?
    ==============
    #define mask (1 << 0) | (1 << 1 ) | (1 << 2)
    так:
    #define mask 0x7
    =================
    а сброс маски
    DDRB &= ~mask;// Clear bit - input
    так:
    DDRB^=mask;// Clear bit - input
     
  2. alexlaw

    alexlaw Новичок

    Сообщения:
    79
    Симпатии:
    1
    Отслеживаем нажатие 3 кнопок в любом сочетании
    вектор прерывания (раскрыть)
    Код (Text):
    1. ISR(PCINT_vect) {
    2.   PORTB &= ~((1 << 7)  | (1 <<4)  | (1 <<3));// Clear bit - выкл все светодиоды
    3.   switch(PINB & 0x07){
    4.     case 6:PORTB |= (1 << 3);break;//наж кн pb0 - high pb3
    5.     case 5:PORTB |= (1 << 4);break;//наж кн pb1 - high pb4
    6.     case 4:PORTB |= (1 << 4) | (1 <<3);break;//наж кн pb0 pb1 - high pb4 pb3
    7.     case 3:PORTB |= (1 << 7);break;//наж кн pb2 - high pb7
    8.     case 2:PORTB |= (1 << 7) | (1 <<3);break;//наж кн pb2 pb0 - high pb7 pb3
    9.     case 1:PORTB |= (1 << 7) | (1 <<4);break;//наж кн pb2 pb1 - high pb7 pb4
    10.   }
    11. }
     
  3. alexlaw

    alexlaw Новичок

    Сообщения:
    79
    Симпатии:
    1
    Я конечно не смог, но используя метод
    и задействовав все 8 портов, можно получить 8!+1=40321 различных состояний порта "B", что практически является бесконечностью.
    Вместо кнопок лучше использовать переключатели.
    Хотя программно обработать такое кол-во состояний вряд ли возможно.
     
  4. alexlaw

    alexlaw Новичок

    Сообщения:
    79
    Симпатии:
    1
    Например с помощью переключателей можно выставить время в RTC.
     
  5. alexlaw

    alexlaw Новичок

    Сообщения:
    79
    Симпатии:
    1
    Я конечно перегнул палку.
    Всего 255 различных состояний порта "B".
    Бывает.
     
  6. nikolz

    nikolz Гуру

    Сообщения:
    4.489
    Симпатии:
    443
    подсказка
    В общем случае подобные задачи я решаю методом измерения времени разряда ( заряда) емкостей.
    В частности это могут быть поверхностные , межслойные , слой и палец.
     
  7. alexlaw

    alexlaw Новичок

    Сообщения:
    79
    Симпатии:
    1
    Финальный аккорд. Ради чего все затевалось, а именно разгрузить основной МК.
    Тинька спит, при этом контролирует кнопки. При нажатии кнопок - просыпается,
    отсылает на основной МК какой-то код, соответствующий нажатым кнопкам и
    снова засыпает.
    скетч (раскрыть)
    Код (Text):
    1. char but;
    2. void setup() {
    3. initButton();
    4. initUSART();
    5. }
    6. void loop() {
    7.   sleepNow();
    8.   USART_Transmit(but);
    9.   delay(500);
    10. }
    11. ISR(PCINT_vect) {
    12.   PORTB &= ~((1 <<4)  | (1 <<3));// Clear bit - выкл все светодиоды
    13.   switch(PINB & 0x03){  
    14.     case 2:{PORTB |= (1 <<3);
    15.     but=0x41;//A
    16.     break;}// - high  pb3
    17.     case 1:{PORTB |= (1 <<4);
    18.     but=0x42;//B
    19.     break;}// - high  pb4
    20.     case 0:{PORTB |=(1 <<4) | (1 <<3);
    21.     but=0x43;//C
    22.     break;}// - high pb4 pb3
    23.   }
    24. }
    25. void sleepNow() {
    26. /*
    27. * Idle  (режим холостого хода)
    28. * В этом режиме прекращается формирование тактовых сигналов clk CPU и  clk FLASH .
    29. * При  этом  ЦПУ  микроконтроллера  останавливается,  а  все остальные  периферийные  устройства
    30. * (интерфейсные  модули,  таймеры/счетчики,  аналоговый  компаратор,  АЦП,  сторожевой  таймер),
    31. * а также  подсистема  прерываний  продолжают  функционировать.
    32. */
    33. /*Если компаратор не используется, то при переводе микроконтроллера в
    34. * режим Idle или ADC Noise Reduction его необходимо отключить. В других
    35. * «спящих» режимах модуль аналогового компаратора отключается автома
    36. * тически. */
    37. DIDR |= (1 << AIN1D)  | (1 << AIN0D ); // Set bits - отключения  входных  цифровых буферов
    38. ACSR |= (1 << ACD);// Set bits - Выключение компаратора
    39. /*
    40. *Аналогоцифровой преобразователь
    41. * Если функционирование АЦП разрешено, то он будет работать во всех
    42. * «спящих»  режимах.  Соответственно,  для  снижения  потребляемого  тока
    43. * модуль АЦП необходимо отключать перед переводом микроконтроллера в
    44. * любой из энергосберегающих режимов.
    45. */
    46. //Режим энергосбережения
    47. MCUCR |= (1 << SM0);// Set bits - Power Down
    48. MCUCR |= (1 << SE);// Set bits -  sleep_enable
    49. asm ("sleep");
    50. MCUCR &= ~(1 << SE);// Clear bit - sleep_disable
    51. }
    52. void initButton() {
    53. //pb0 pb1  кнопки
    54. //pb3 pb4 светодиод  
    55. PORTB |= (1 << 0) | (1 << 1 );// Set bits - pullup
    56. DDRB &= ~((1 << 0)  | (1 << 1));// Clear bit - input
    57. PORTB &= ~((1 << 3)  |  (1 << 4));// Clear bit - low
    58. DDRB |= (1 << 3) | (1 << 4);// Set bits - output
    59. GIMSK |= (1 << PCIE);// Set bits - Разрешение прерывания по изменению состояния выводов 0й группы - PCINT.
    60. //PCMSK Определяют условие генерации прерывания PCI0. Если какойлибо
    61. //бит установлен в 1, то изменение состояния соответствующего вывода
    62. //вызовет генерацию прерывания
    63. PCMSK |= (1 << 0) | (1 << 1);// Set bits -прерывание по изменению состояния вывода 0 или 1 - PCINT
    64. }
    65. void initUSART() {
    66. //UCSRB &= ~((1 << TXEN) | (1 << RXEN)); // Clear bit
    67. //запретить прнерывания от передатчика
    68. UCSRB &= ~((1 << RXCIE) | (1 << TXCIE) | (1 << UDRIE)); // Clear bit
    69. //Если бит UMSEL сброшен в 0, то модуль работает в асинхронном режиме
    70. //USBS Количество стопбитов. Если бит сброшен в 0, то передатчик посылает 1 стопбит,
    71. //если установлен в 1, то 2 стопбита.
    72. //UCPOL  При работе в асинхронном режиме он должен быть сброшен в 0. USART Mode: Asynchronous
    73. //UPM1 UPM0 - Управление схемой контроля четности - 0 0 Выключена
    74. UCSRC &= ~((1 << UMSEL) | (1 << USBS) | (1 << UCPOL) | (1 << UPM1) | (1 << UPM0)); // Clear bit
    75. //Определение размера слова данных - 8 бит
    76. UCSRC |= (1<<UCSZ1) | (1<<UCSZ0); // Set bits
    77. UCSRA &= ~(1 << UCSZ2); // Clear bit
    78. //UCSRC &= ~(1 << U2X); // Clear bit  обычная скорость
    79. // Speed = 9600
    80. UBRRH = 0;
    81. UBRRL = 51;
    82. //Разрешение передачи
    83. UCSRB |=(1<<TXEN); // Set bits
    84. }
    85. void USART_Transmit(unsigned int data)
    86. {
    87.    /* Ждать очистки буфера передатчика */
    88.    while ( !( UCSRA & (1<<UDRE))) {  
    89.    };
    90.    UDR = data;    
    91. }

    com_3.png
    Светодиоды нужны только для наглядности.
    IMG_20190715_074705.jpg
     
  8. nikolz

    nikolz Гуру

    Сообщения:
    4.489
    Симпатии:
    443
    Если это и есть цель, то вот простейшее решение
    кнопки подключаются на RST или CH_ED
    ESP спит либо вооще в дауне
    нажимаем кнопки и ESP просыпается и делает по нужде и снова спит
    и не надо ничего довешивать кроме кнопок на один пин
     
  9. alexlaw

    alexlaw Новичок

    Сообщения:
    79
    Симпатии:
    1
    скетч (раскрыть)
    Код (Text):
    1. //-----------------------------------------------------------------------------
    2. /*                                   ATTINY2313
    3.                              =========================
    4.                           ATTINY      ARDUINO     ATTINY
    5.                    PA0/XTAL1 || 5 -  3        9 - 12 || PB0/AIN0/PCINT0    
    6.                    PA1/XTAL2 || 4 -  2       10 - 13 || PB1/AIN1/PCINT1
    7.                    PA2/RESET || 1 -  17      11 - 14 || PB2/OC0A/PCINT2
    8.                              ||              12 - 15 || PB3/OC1A/PCINT3  
    9.                      PD0/RXD || 2 -  0       13 - 16 || PB4/OC1B/PCINT4
    10.                      PD1/TXD || 3 -  1       14 - 17 || PB5/MOSI/DI/SDA/PCINT5
    11.           PD2/INT0/XCK/CKOUT || 6 -  4       15 - 18 || PB6/MISO/DO/PCINT6
    12.                     PD3/INT1 || 7 -  5       16 - 19 || PB7/USCK/SCL/PCINT7
    13.                       PD4/T0 || 8 -  6               ||
    14.                  PD5/T1/OC0B || 9 -  7               ||
    15.                      PD6/ICP || 11 - 8               ||
    16.                           ATTINY      ARDUINO     ATTINY                  
    17.                              =========================
    18.                                      ATTINY2313    */
    19. //-----------------------------------------------------------------------------                                    
    20. const int clock1 = 3;
    21. const int data1 = 2;
    22.                  /*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/ /*8*/ /*9*/
    23. uint8_t digits1[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
    24. //uint8_t digits1[] = { 0x3f, 0x30, 0x5b, 0x79, 0x74, 0x6d, 0x6F, 0x38, 0x7f, 0x7D };
    25. int slaveSelect=14;//PB5
    26. int din=16;//PB7
    27. int clk=15;//PB6
    28. uint8_t TimeBytes[] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    29. boolean b = false;
    30. byte dot = 128;//двоеточие на дисплее индикатора
    31. void setup() {
    32. PORTB |= (1 << 4);// Set bits - pullup
    33. DDRB &= ~(1 << 4);// Clear bit - input
    34. PORTB &= ~(1 << 3);// Clear bit - low
    35. DDRB |= (1 << 3) | (1 << 5) | (1 << 6) | (1 << 7) ;// Set bits - output
    36. GIMSK |= (1 << PCIE);// Set bits - Разрешение прерывания по изменению состояния выводов 0й группы - PCINT.
    37. //PCMSK Определяют условие генерации прерывания PCI0. Если какойлибо
    38. //бит установлен в 1, то изменение состояния соответствующего вывода
    39. //вызовет генерацию прерывания
    40. PCMSK |= (1 << 4);// Set bits -прерывание по изменению состояния вывода 4
    41. pinMode(clock1, OUTPUT);
    42. pinMode(data1, OUTPUT);
    43. start(clock1,data1);
    44. writeValue(clock1,data1,0x8c);
    45. stop(clock1,data1);
    46. // clear display
    47. write(clock1,data1,0x00, 0x00, 0x00, 0x00);
    48. watch_dog_ext();
    49. }
    50. void loop() {
    51. if (b) SetTime();
    52. data1302();
    53. uint8_t h = TimeBytes[2];
    54. uint8_t m = TimeBytes[1];
    55. if (TimeBytes[0]&0x01) dot=0; else dot=128;
    56. write(clock1,data1,digits1[(h & 0xF0) >> 4],digits1 [h & 0x0F] | dot,digits1[(m & 0xF0) >> 4],digits1 [m & 0x0F]);
    57. //delay(1000);
    58. sleepNow();
    59. }
    60. void sendCommand1302(byte cmd, byte data)
    61. {
    62. digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
    63. // передать старший байт
    64. shiftOut(din, clk, LSBFIRST, cmd);
    65. // передать младший байт
    66. shiftOut(din, clk, LSBFIRST, data);
    67. digitalWrite(slaveSelect,LOW);
    68. }
    69. void data1302()
    70. {
    71. //Команда clock burst read с кодом 0xBF считывает текущее состояние часов
    72. //В ответ RTC посылают 7 байт, в которых хранятся соответственно
    73. //секунды, минуты, часы, день, месяц, день недели, год, и кое-какие флаги
    74. digitalWrite(slaveSelect,HIGH); //chip select is active HIGH
    75. // передать  байт
    76. shiftOut(din, clk, LSBFIRST, 0xBF);
    77. pinMode(din, INPUT);
    78. for(int i = 0; i < 7; i++){
    79. TimeBytes[i]=readByte();
    80. }
    81. digitalWrite(slaveSelect,LOW);
    82. pinMode(din, OUTPUT);
    83. }
    84. uint8_t readByte()
    85. {
    86.   uint8_t value = 0;
    87.   uint8_t currentBit = 0;
    88.  
    89.   for (int i = 0; i < 8; ++i)
    90.   {
    91.     currentBit = digitalRead(din);
    92.     value |= (currentBit << i);
    93.     digitalWrite(clk, HIGH);
    94.     delayMicroseconds(1);
    95.     digitalWrite(clk, LOW);
    96.   }
    97.   return value;
    98. }
    99. void SetTime()
    100. {
    101. //УСТАНОВИТЬ ВРЕМЯ
    102.   sendCommand1302(0x86, 0x24);//день
    103.   sendCommand1302(0x88, 0x07);//месяц
    104.   sendCommand1302(0x8C, 0x19);//год
    105.   sendCommand1302(0x84, 0x21);//час
    106.   sendCommand1302(0x82, 0x00);//мин
    107.   sendCommand1302(0x80, 0x00);//сек
    108.   sendCommand1302(0x8A, 0x03);//день недели
    109.   b = false;
    110. }
    111. ISR(PCINT_vect) {
    112.   if (PINB>>4 & 0x01) PORTB &= ~(1 << 3);// Clear bit - low
    113.   else PORTB |= (1 << 3);// Set bits - high
    114.   b = true;
    115. }
    116. void write(int clock,int data,uint8_t first, uint8_t second, uint8_t third, uint8_t fourth)
    117. {
    118. start(clock,data);
    119. writeValue(clock,data,0x40);
    120. stop(clock,data);
    121. start(clock,data);
    122. writeValue(clock,data,0xc0);
    123. writeValue(clock,data,first);
    124. writeValue(clock,data,second);
    125. writeValue(clock,data,third);
    126. writeValue(clock,data,fourth);
    127. stop(clock,data);
    128. }
    129.  
    130. void start(int clock,int data)
    131. {
    132. digitalWrite(clock,HIGH);//send start signal to TM1637
    133. digitalWrite(data,HIGH);
    134. delayMicroseconds(5);
    135. digitalWrite(data,LOW);
    136. digitalWrite(clock,LOW);
    137. delayMicroseconds(5);
    138. }
    139. void stop(int clock,int data)
    140. {
    141. digitalWrite(clock,LOW);
    142. digitalWrite(data,LOW);
    143. delayMicroseconds(5);
    144. digitalWrite(clock,HIGH);
    145. digitalWrite(data,HIGH);
    146. delayMicroseconds(5);
    147. }
    148. bool writeValue(int clock,int data,uint8_t value)
    149. {
    150. for(uint8_t i = 0; i < 8; i++)
    151. {
    152. digitalWrite(clock, LOW);
    153. delayMicroseconds(5);
    154. digitalWrite(data, (value & (1 << i)) >> i);
    155. delayMicroseconds(5);
    156. digitalWrite(clock, HIGH);
    157. delayMicroseconds(5);
    158. }
    159. // wait for ACK
    160. digitalWrite(clock,LOW);
    161. delayMicroseconds(5);
    162. pinMode(data,INPUT);
    163. digitalWrite(clock,HIGH);
    164. delayMicroseconds(5);
    165. bool ack = digitalRead(data) == 0;
    166. pinMode(data,OUTPUT);
    167. return ack;
    168. }
    169. void sleepNow() {
    170. /*
    171. * Idle  (режим холостого хода)
    172. * В этом режиме прекращается формирование тактовых сигналов clk CPU и  clk FLASH .
    173. * При  этом  ЦПУ  микроконтроллера  останавливается,  а  все остальные  периферийные  устройства
    174. * (интерфейсные  модули,  таймеры/счетчики,  аналоговый  компаратор,  АЦП,  сторожевой  таймер),
    175. * а также  подсистема  прерываний  продолжают  функционировать.
    176. */
    177. /*Если компаратор не используется, то при переводе микроконтроллера в
    178. * режим Idle или ADC Noise Reduction его необходимо отключить. В других
    179. * «спящих» режимах модуль аналогового компаратора отключается автома
    180. * тически. */
    181. DIDR |= (1 << AIN1D)  | (1 << AIN0D ); // Set bits - отключения  входных  цифровых буферов
    182. ACSR |= (1 << ACD);// Set bits - Выключение компаратора
    183. /*
    184. *Аналогоцифровой преобразователь
    185. * Если функционирование АЦП разрешено, то он будет работать во всех
    186. * «спящих»  режимах.  Соответственно,  для  снижения  потребляемого  тока
    187. * модуль АЦП необходимо отключать перед переводом микроконтроллера в
    188. * любой из энергосберегающих режимов.
    189. */
    190. //Режим энергосбережения
    191. //MCUCR &= ~((1 << SM1) | (1 << SM0));// Clear bit  - Idle -не у меня не работает?
    192. MCUCR |= (1 << SM0);// Set bits - Power Down
    193. MCUCR |= (1 << SE);// Set bits -  sleep_enable
    194. asm ("sleep");
    195. MCUCR &= ~(1 << SE);// Clear bit - sleep_disable
    196. }
    197. void watch_dog_ext(){
    198. //расширенный  сторожевой  таймер
    199. /*
    200. * для выключения таймера (сброса бита WDE) необходимо выполнить следующие действия:
    201. * 1. Одной командой записать 1 в биты WDE и WDCE.
    202. * 2. В течение следующих четырех тактов записать 0 в бит WDE.
    203. */
    204. /*
    205. * Обратите внимание на то, что состояние флага сброса WDRF регистра MCUSR отменяет состояние бита WDE. Это означает, что бит WDE уста
    206. * новлен всегда, когда установлен флаг WDRF, поэтому перед сбросом WDE необходимо также сбросить WDRF.
    207. */
    208. //MCUSR &= ~(1 << WDRF);// Clear bit
    209. //WDTCSR |= (1 << WDE)  | (1 << WDCE); // Set bits
    210. //WDTCSR &= ~(1 << WDE);// Clear bit
    211. /*
    212. * Для изменения периода таймаута необходимо выполнить следующие действия:
    213. * 1. Одной командой записать 1 в биты WDE и WDCE.
    214. * 2. В течение следующих четырех тактов записать требуемое значение в биты WDP3:0 и WDE, одновременно сбрасывая бит WDCE.
    215. * Перед  изменением  битов  WDP3:0  сторожевой  таймер  рекомендуется сбрасывать.
    216. * Сброс сторожевого таймера осуществляется командой WDR.
    217. */
    218. asm ("WDR");
    219. WDTCSR |= (1 << WDE)  | (1 << WDCE); // Set bits
    220. //1 сек
    221. WDTCSR |= (1 << WDP1  | (1 << WDP2)); // Set bits
    222. WDTCSR &= ~((1 << WDP0)  | (1 << WDP3));// Clear bit
    223. WDTCSR &= ~(1 << WDCE);// Clear bit
    224.  
    225. MCUSR &= ~(1 << WDRF);// Clear bit
    226. WDTCSR |= (1 << WDE)  | (1 << WDCE); // Set bits
    227. WDTCSR &= ~(1 << WDE);// Clear bit
    228.  
    229. WDTCSR |= (1 << WDIE);// Set bits - Разрешение прерывания от сторожевого таймера (сбрасывается после сраб тайм аута)
    230. }
    231. ISR(WDT_OVERFLOW_vect) { //1 сек
    232. dot = 128;
    233. }

    На досуге собрал часы (на дальнем плане).
    Работают на CR2032.
    IMG_20190722_141009.jpg
    Может кому пригодится.
    ds1302_tm1637.png
     
  10. nikolz

    nikolz Гуру

    Сообщения:
    4.489
    Симпатии:
    443
    мощные.
    Но индикатор почему-то меньше платы.
    Наверное поверхностный монтаж ?
    На руси так всегда
    вроде нормальная идея - а воплощение - ужас какой-то.
     
  11. alexlaw

    alexlaw Новичок

    Сообщения:
    79
    Симпатии:
    1
    Макетная плата.
     
  12. nikolz

    nikolz Гуру

    Сообщения:
    4.489
    Симпатии:
    443
    попробуйте сделать объемное устройство без платы вообще
    все сможете поместить в спичечный коробок и сверху дисплей
     

Поделиться этой страницей