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

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

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

  1. nikolz

    nikolz Гуру

    Сообщения:
    5.092
    Симпатии:
    465
    Один из методов раза два уже рассказывал на форуме.
    Поэтому рассказывать надцатый раз нет интереса.
    ===============
    можно это написать иначе
    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 Новичок

    Сообщения:
    105
    Симпатии:
    2
    Отслеживаем нажатие 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 Новичок

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

    alexlaw Новичок

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

    alexlaw Новичок

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

    nikolz Гуру

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

    alexlaw Новичок

    Сообщения:
    105
    Симпатии:
    2
    Финальный аккорд. Ради чего все затевалось, а именно разгрузить основной МК.
    Тинька спит, при этом контролирует кнопки. При нажатии кнопок - просыпается,
    отсылает на основной МК какой-то код, соответствующий нажатым кнопкам и
    снова засыпает.
    скетч (раскрыть)
    Код (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 Гуру

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

    alexlaw Новичок

    Сообщения:
    105
    Симпатии:
    2
    скетч (раскрыть)
    Код (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 Гуру

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

    alexlaw Новичок

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

    nikolz Гуру

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

    alexlaw Новичок

    Сообщения:
    105
    Симпатии:
    2
    Недавно перечитал эту ветку и увидел, что забыл важную деталь.
    Попробовать i2c.
    Попробовал на на часах ds3231.
    attini2313_ds3231 (раскрыть)
    Код (Text):
    1. /*                 DS3231
    2. /                 ___________  
    3. /        32kHz   | 1      16 | SCL
    4. /         Vcc    | 2      15 | SDA
    5. /       INT/SOW  | 3      14 | Vbat
    6. /         RST    | 4      13 | GND
    7. /                | 5      12 |
    8. /                | 6      11 |
    9. /                | 7      10 |
    10. /                | 8      9  |
    11. /                |___________|
    12. / SCL,SDA,INT/SOW,32kHz подтянуть к + через резистор 4,7к
    13. //-----------------------------------------------------------------------------
    14.                                     ATTINY2313
    15.                              =========================
    16.                           ATTINY      ARDUINO     ATTINY
    17.                    PA0/XTAL1 || 5 -  3        9 - 12 || PB0/AIN0/PCINT0  
    18.                    PA1/XTAL2 || 4 -  2       10 - 13 || PB1/AIN1/PCINT1
    19.                    PA2/RESET || 1 -  17      11 - 14 || PB2/OC0A/PCINT2
    20.                              ||              12 - 15 || PB3/OC1A/PCINT3  
    21.                      PD0/RXD || 2 -  0       13 - 16 || PB4/OC1B/PCINT4
    22.                      PD1/TXD || 3 -  1       14 - 17 || PB5/MOSI/DI/ SDA /PCINT5
    23.           PD2/INT0/XCK/CKOUT || 6 -  4       15 - 18 || PB6/MISO/DO/PCINT6
    24.                     PD3/INT1 || 7 -  5       16 - 19 || PB7/USCK/ SCL /PCINT7
    25.                       PD4/T0 || 8 -  6               ||
    26.                  PD5/T1/OC0B || 9 -  7               ||
    27.                      PD6/ICP || 11 - 8               ||
    28.                           ATTINY      ARDUINO     ATTINY                
    29.                              =========================
    30.                                      ATTINY2313  
    31. //-----------------------------------------------------------------------------
    32. */
    33.  
    34. //http://www.technoblogy.com/show?24R7
    35. //https://github.com/technoblogy/tiny-i2c
    36. #include <TinyI2CMaster.h>
    37. const int RTCaddress = 0x68;
    38. const int clock1 = 6;
    39. const int data1 = 7;
    40.                  /*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/ /*8*/ /*9*/
    41. //uint8_t digits1[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
    42. uint8_t digits1[] = { 0x3f, 0x30, 0x5b, 0x79, 0x74, 0x6d, 0x6F, 0x38, 0x7f, 0x7D, 0x7E, 0x67, 0x0F, 0x73, 0x4F, 0x4E};
    43. //byte second, minute, hour, date, month, year;
    44. uint8_t TimeBytes[] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    45. byte dot = 128;//двоеточие на дисплее индикатора
    46. uint8_t temp;
    47. boolean viewTemperature;
    48. uint8_t _reg_status;
    49. void setup() {
    50. TinyI2C.init();
    51. pinMode(clock1, OUTPUT);
    52. pinMode(data1, OUTPUT);
    53. start(clock1,data1);
    54. writeValue(clock1,data1,0x8c);
    55. stop(clock1,data1);
    56. // clear display
    57. write(clock1,data1,0x00, 0x00, 0x00, 0x00);
    58. //SetTime_ds3231();
    59. resetAlarm();
    60. }
    61.  
    62. void loop() {
    63. GetTime_ds3231();
    64. uint8_t h = TimeBytes[2];
    65. uint8_t m = TimeBytes[1];
    66. if (TimeBytes[0]&0x01) dot=0; else dot=128;
    67. // write(clock1,data1,digits1[(h & 0xF0) >> 4],digits1 [h & 0x0F] | dot,digits1[(m & 0xF0) >> 4],digits1 [m & 0x0F]);
    68. if (viewTemperature){
    69. write(clock1,data1,0x0F,0x5C,digits1 [temp % 10],digits1[(temp / 10)]);
    70. } else {
    71. write(clock1,data1,digits1 [m & 0x0F],digits1[(m & 0xF0) >> 4] | dot,digits1 [h & 0x0F],digits1[(h & 0xF0) >> 4]);
    72. }
    73. delay(1000);
    74. }
    75.  
    76. void GetTime_ds3231() {
    77.     TinyI2C.start(RTCaddress, 0);                // Start I2C protocol with DS3231 address
    78.     TinyI2C.write(0);                            // Send register address
    79.     TinyI2C.restart(RTCaddress, 7);               // Request 7 bytes from DS3231 and release I2C bus at end of reading
    80. //    second = TinyI2C.read();                         // Read seconds from register 0
    81. //    minute = TinyI2C.read();                         // Read minuts from register 1
    82. //    hour   = TinyI2C.read();                         // Read hour from register 2
    83. //    TinyI2C.read();                                  // Read day from register 3 (not used)
    84. //    date   = TinyI2C.read();                         // Read date from register 4
    85. //    month  = TinyI2C.read();                         // Read month from register 5
    86. //    year   = TinyI2C.read();                         // Read year from register 6
    87.     for(int i = 0; i < 7; i++){
    88.       TimeBytes[i]=TinyI2C.read();
    89.     }
    90.     TinyI2C.stop();
    91.       if ((int)(TimeBytes[0] & 0x0F) % 10 == 0){//каждые 10 сек показ температуру
    92.          viewTemperature=true;
    93.         getTemperture();
    94.       } else viewTemperature=false;
    95. }
    96. void SetTime_ds3231() {
    97.         // Write data to DS3231 RTC
    98.       TinyI2C.start(RTCaddress, 0);                  // Start I2C protocol with DS3231 address
    99.       TinyI2C.write(0);                              // Send register address    
    100.       TinyI2C.write(0);                              // Reset sesonds and start oscillator
    101.       TinyI2C.write(0x48);                           // Write minute
    102.       TinyI2C.write(0x21);                           // Write hour
    103.       TinyI2C.write(0x06);                           // Write day (not used)
    104.       TinyI2C.write(0x31);                           // Write date
    105.       TinyI2C.write(0x08);                           // Write month
    106.       TinyI2C.write(0x19);                           // Write year
    107.       TinyI2C.stop();                                // Stop transmission and release the I2C bus
    108. }
    109. void getTemperture()
    110. {
    111.   TinyI2C.start(RTCaddress, 0);                 // Start I2C protocol with DS3231 address
    112.   TinyI2C.write(0x11);                        // Send register address
    113.   TinyI2C.restart(RTCaddress, 2);                    // Request 2 bytes from DS3231 and release I2C bus at end of reading
    114.   uint8_t _msb = TinyI2C.read();
    115.   uint8_t _lsb = TinyI2C.read();
    116. //  float temp = (float)_msb + ((_lsb >> 6) * 0.25f);
    117.   TinyI2C.stop();
    118.             temp = _msb;
    119. }
    120. //Поскольку при первом включении питания бит INTCN устанавливается в логическую единицу,
    121. //на выводе по умолчанию выводится прерывание с отключенными тревогами.
    122. void resetAlarm()//
    123. {
    124. readStatus();
    125. //сброс флагов Alarm1 и Alarm2
    126. _reg_status &= ~((1 << 0) | (1 << 1));// Clear bit 0(Alarm1), bit 1(Alarm2)
    127.       TinyI2C.start(RTCaddress, 0);                  // Start I2C protocol with DS3231 address
    128.       TinyI2C.write(0x0F);                           // Send register address  Status Register (0Fh)        
    129.       TinyI2C.write(_reg_status);                    // сброс флагов Alarm1 и Alarm2
    130.       TinyI2C.stop();
    131. //Alarm1    
    132.       TinyI2C.start(RTCaddress, 0);                  // Start I2C protocol with DS3231 address
    133.       TinyI2C.write(0x07);                           // Send register address  Alarm 1          
    134.       TinyI2C.write(0x00);                           // Alarm 1
    135.       TinyI2C.write(0x00);                        
    136.       TinyI2C.write(0x00);
    137.       TinyI2C.write(0x00);
    138.       TinyI2C.stop();                               // Stop transmission and release the I2C bus  
    139. //Alarm1
    140. //Alarm2    
    141.       TinyI2C.start(RTCaddress, 0);                  // Start I2C protocol with DS3231 address
    142.       TinyI2C.write(0x0B);                           // Send register address  Alarm 2          
    143.       TinyI2C.write(0x00);                        
    144.       TinyI2C.write(0x00);                  
    145.       TinyI2C.write(0x00);
    146.       TinyI2C.stop();                     // Stop transmission and release the I2C bus  
    147. //Alarm2
    148.       TinyI2C.start(RTCaddress, 0);                   // Start I2C protocol with DS3231 address
    149.       TinyI2C.write(0x0E);                           // Send register address - Control Register (0Eh)
    150. //Bit 2: Interrupt Control (INTCN). This bit controls the
    151. //INT/SQW signal. When the INTCN bit is set to logic 0, a
    152. //square wave is output on the INT/SQW pin        
    153.       TinyI2C.write(0x04);                           // Alarm  Interrupt desable
    154.       TinyI2C.stop();                               // Stop transmission and release the I2C bus
    155.      
    156. }
    157. void readStatus(){
    158.   TinyI2C.start(RTCaddress, 0);                    // Start I2C protocol with DS3231 address
    159.   TinyI2C.write(0x0F);                             // Send register address REG_STATUS
    160.   TinyI2C.restart(RTCaddress, 1);                  // Request 1 bytes from DS3231 and release I2C bus at end of reading                
    161.   _reg_status = TinyI2C.read();
    162.   TinyI2C.stop();  
    163. }
    164. void write(int clock,int data,uint8_t first, uint8_t second, uint8_t third, uint8_t fourth)
    165. {
    166. start(clock,data);
    167. writeValue(clock,data,0x40);
    168. stop(clock,data);
    169. start(clock,data);
    170. writeValue(clock,data,0xc0);
    171. writeValue(clock,data,first);
    172. writeValue(clock,data,second);
    173. writeValue(clock,data,third);
    174. writeValue(clock,data,fourth);
    175. stop(clock,data);
    176. }
    177.  
    178. void start(int clock,int data)
    179. {
    180. digitalWrite(clock,HIGH);//send start signal to TM1637
    181. digitalWrite(data,HIGH);
    182. delayMicroseconds(5);
    183. digitalWrite(data,LOW);
    184. digitalWrite(clock,LOW);
    185. delayMicroseconds(5);
    186. }
    187.  
    188.  
    189. void stop(int clock,int data)
    190. {
    191. digitalWrite(clock,LOW);
    192. digitalWrite(data,LOW);
    193. delayMicroseconds(5);
    194. digitalWrite(clock,HIGH);
    195. digitalWrite(data,HIGH);
    196. delayMicroseconds(5);
    197. }
    198.  
    199. bool writeValue(int clock,int data,uint8_t value)
    200. {
    201. for(uint8_t i = 0; i < 8; i++)
    202. {
    203. digitalWrite(clock, LOW);
    204. delayMicroseconds(5);
    205. digitalWrite(data, (value & (1 << i)) >> i);
    206. delayMicroseconds(5);
    207. digitalWrite(clock, HIGH);
    208. delayMicroseconds(5);
    209. }
    210. // wait for ACK
    211. digitalWrite(clock,LOW);
    212. delayMicroseconds(5);
    213. pinMode(data,INPUT);
    214. digitalWrite(clock,HIGH);
    215. delayMicroseconds(5);
    216. bool ack = digitalRead(data) == 0;
    217. pinMode(data,OUTPUT);
    218. return ack;
    219. }
     
  14. alexlaw

    alexlaw Новичок

    Сообщения:
    105
    Симпатии:
    2
    А перед этим попробовал RTC с ардуино нано
     

    Вложения:

  15. alexlaw

    alexlaw Новичок

    Сообщения:
    105
    Симпатии:
    2
    Удалось подключить дисплей lcd1602 по I2C к Attiny2313.
    Правда библиотеку LiquidCrystal_I2C до конца не допилил,
    чтобы одновременно работала и для Attiny и для Ардуино.
    С Attiny2313 - работает.
     

    Вложения:

  16. alexlaw

    alexlaw Новичок

    Сообщения:
    105
    Симпатии:
    2
    Удалось подключить дисплей lcd1602 по I2C к Attiny2313.
    Правда библиотеку LiquidCrystal_I2C до конца не допилил,
    чтобы одновременно работала и для Attiny и для Ардуино.
    С Attiny2313 - работает.
     

    Вложения:

  17. alexlaw

    alexlaw Новичок

    Сообщения:
    105
    Симпатии:
    2
    Удалось подключить дисплей lcd1602 по I2C к Attiny2313.
    Правда библиотеку LiquidCrystal_I2C до конца не допилил,
    чтобы одновременно работала и для Attiny и для Ардуино.
    С Attiny2313 - работает.
     
  18. alexlaw

    alexlaw Новичок

    Сообщения:
    105
    Симпатии:
    2
    Пожалуйста удалите лишние посты.
    Случайно продублировались.
     
  19. alexlaw

    alexlaw Новичок

    Сообщения:
    105
    Симпатии:
    2
  20. alexlaw

    alexlaw Новичок

    Сообщения:
    105
    Симпатии:
    2
    Решил сделать выносной терминал на Attiny2313.
    Technoblogy - Tiny Terminal - оригинальный проект на ATtiny85.
    1-й этап - подключение дисплея ssd1306.
    attini2313_Terminal_v01 (раскрыть)
    Код (Text):
    1. int const clk = 0;//9; //D0,SCL,CLK,SCK - Clock - PB0
    2. int const data = 1;//10;//D1,SDA,MOSI - Data - PB1
    3. int const res = 2;//11,RES - Reset - PB2//можно сразу к +
    4. int const dc = 3;//12;DC - Data/Command - PB3
    5. int const cs = 4;//13;CS - Chip Select - PB4
    6.  
    7. // Initialisation sequence for OLED module
    8. int const InitLen = 23;
    9. unsigned char Init[InitLen] = {
    10.   0xAE, // Display off
    11.   0xD5, // Set display clock
    12.   0x80, // Recommended value
    13.   0xA8, // Set multiplex
    14.   0x3F,
    15.   0xD3, // Set display offset
    16.   0x00,
    17.   0x40, // Zero start line
    18.   0x8D, // Charge pump
    19.   0x14,
    20.   0x20, // Memory mode
    21.   0x02, // Page addressing
    22.   0xA1, // 0xA0/0xA1 flip horizontally
    23.   0xC8, // 0xC0/0xC8 flip vertically
    24.   0xDA, // Set comp ins
    25.   0x12,
    26.   0x81, // Set contrast
    27.   0x7F,
    28.   0xD9, // Set pre charge
    29.   0xF1,
    30.   0xDB, // Set vcom detect
    31.   0x40,
    32.   0xA6  // Normal (0xA7=Inverse)
    33. };
    34. // Character set - stored in program memory
    35. const uint8_t CharMap[96][6] PROGMEM = {
    36. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
    37. { 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00 },
    38. { 0x00, 0x07, 0x00, 0x07, 0x00, 0x00 },
    39. { 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00 },
    40. { 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00 },
    41. { 0x23, 0x13, 0x08, 0x64, 0x62, 0x00 },
    42. { 0x36, 0x49, 0x56, 0x20, 0x50, 0x00 },
    43. { 0x00, 0x08, 0x07, 0x03, 0x00, 0x00 },
    44. { 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00 },
    45. { 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00 },
    46. { 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00 },
    47. { 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00 },
    48. { 0x00, 0x80, 0x70, 0x30, 0x00, 0x00 },
    49. { 0x08, 0x08, 0x08, 0x08, 0x08, 0x00 },
    50. { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 },
    51. { 0x20, 0x10, 0x08, 0x04, 0x02, 0x00 },
    52. { 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00 },
    53. { 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00 },
    54. { 0x72, 0x49, 0x49, 0x49, 0x46, 0x00 },
    55. { 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00 },
    56. { 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00 },
    57. { 0x27, 0x45, 0x45, 0x45, 0x39, 0x00 },
    58. { 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00 },
    59. { 0x41, 0x21, 0x11, 0x09, 0x07, 0x00 },
    60. { 0x36, 0x49, 0x49, 0x49, 0x36, 0x00 },
    61. { 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00 },
    62. { 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 },
    63. { 0x00, 0x40, 0x34, 0x00, 0x00, 0x00 },
    64. { 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 },
    65. { 0x14, 0x14, 0x14, 0x14, 0x14, 0x00 },
    66. { 0x00, 0x41, 0x22, 0x14, 0x08, 0x00 },
    67. { 0x02, 0x01, 0x59, 0x09, 0x06, 0x00 },
    68. { 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00 },
    69. { 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00 },
    70. { 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00 },
    71. { 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00 },
    72. { 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00 },
    73. { 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00 },
    74. { 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00 },
    75. { 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00 },
    76. { 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00 },
    77. { 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00 },
    78. { 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00 },
    79. { 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00 },
    80. { 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00 },
    81. { 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00 },
    82. { 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00 },
    83. { 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00 },
    84. { 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00 },
    85. { 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00 },
    86. { 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00 },
    87. { 0x26, 0x49, 0x49, 0x49, 0x32, 0x00 },
    88. { 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00 },
    89. { 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00 },
    90. { 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00 },
    91. { 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00 },
    92. { 0x63, 0x14, 0x08, 0x14, 0x63, 0x00 },
    93. { 0x03, 0x04, 0x78, 0x04, 0x03, 0x00 },
    94. { 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00 },
    95. { 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00 },
    96. { 0x02, 0x04, 0x08, 0x10, 0x20, 0x00 },
    97. { 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00 },
    98. { 0x04, 0x02, 0x01, 0x02, 0x04, 0x00 },
    99. { 0x40, 0x40, 0x40, 0x40, 0x40, 0x00 },
    100. { 0x00, 0x03, 0x07, 0x08, 0x00, 0x00 },
    101. { 0x20, 0x54, 0x54, 0x78, 0x40, 0x00 },
    102. { 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00 },
    103. { 0x38, 0x44, 0x44, 0x44, 0x28, 0x00 },
    104. { 0x38, 0x44, 0x44, 0x28, 0x7F, 0x00 },
    105. { 0x38, 0x54, 0x54, 0x54, 0x18, 0x00 },
    106. { 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00 },
    107. { 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00 },
    108. { 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00 },
    109. { 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00 },
    110. { 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00 },
    111. { 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00 },
    112. { 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00 },
    113. { 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00 },
    114. { 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00 },
    115. { 0x38, 0x44, 0x44, 0x44, 0x38, 0x00 },
    116. { 0xFC, 0x18, 0x24, 0x24, 0x18, 0x00 },
    117. { 0x18, 0x24, 0x24, 0x18, 0xFC, 0x00 },
    118. { 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00 },
    119. { 0x48, 0x54, 0x54, 0x54, 0x24, 0x00 },
    120. { 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00 },
    121. { 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00 },
    122. { 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00 },
    123. { 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00 },
    124. { 0x44, 0x28, 0x10, 0x28, 0x44, 0x00 },
    125. { 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00 },
    126. { 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00 },
    127. { 0x00, 0x08, 0x36, 0x41, 0x00, 0x00 },
    128. { 0x00, 0x00, 0x77, 0x00, 0x00, 0x00 },
    129. { 0x00, 0x41, 0x36, 0x08, 0x00, 0x00 },
    130. { 0x02, 0x01, 0x02, 0x04, 0x02, 0x00 },
    131. { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 }
    132. };
    133. int Line, Column, Scroll;
    134. int thisByte = 33;
    135. void setup() {
    136. //clk = 0;//9; //D0,SCL,CLK,SCK - Clock - PB0
    137. //data = 1;//10;//D1,SDA,MOSI - Data - PB1
    138. //res = 2;//11 - PB2
    139. //dc = 3;//12; //-Data/Command - PB3
    140. //cs = 4;//13;//-Chip Select - PB4
    141.   // Define pins
    142. //  pinMode(11, OUTPUT); digitalWrite(11,HIGH);//res
    143. //  pinMode(12, OUTPUT); digitalWrite(12,HIGH);//dc
    144. //  pinMode(9, OUTPUT); digitalWrite(9,HIGH);//clk
    145. //  pinMode(10, OUTPUT);//data
    146. //  pinMode(13, OUTPUT); digitalWrite(13,HIGH);//cs
    147.   PORTB |= (1 << res);/// Set bits - high
    148.   DDRB |= (1 << res);// Set bits - output
    149.   PORTB &= ~(1 << data);// Clear bit - low
    150.   PORTB |= (1 << cs) | (1 << dc) | (1 << clk);/// Set bits - high
    151.   DDRB |= (1 << data) | (1 << cs) | (1 << dc) | (1 << clk);// Set bits - output
    152.  
    153.   InitDisplay();
    154.   ClearDisplay();
    155.   Command(0xAF);  // Display on
    156. //  Print('q');Print('w');Print('e');Print('r');Print('t');Print('y');
    157. }
    158.  
    159. void loop() {
    160.   //"ASCII Table"
    161.   if (thisByte < 126){
    162.     Print(thisByte);Print(' ');
    163.     thisByte++;
    164.   }
    165.   delay(1000);
    166. }
    167.  
    168. // Write a data byte to the display
    169. void Data(uint8_t d) {
    170.   PINB = 1<<cs; // cs low
    171.   for (uint8_t bit = 0x80; bit; bit >>= 1) {
    172.     PINB = 1<<clk; // clk low
    173.     if (d & bit) PORTB = PORTB | (1<<data); else PORTB = PORTB & ~(1<<data);
    174.     PINB = 1<<clk; // clk high
    175.   }
    176.   PINB = 1<<cs; // cs high
    177. }
    178.  
    179. // Write a command byte to the display
    180. void Command(uint8_t c) {
    181.   PINB = 1<<dc; // dc low
    182.  
    183.   Data(c);
    184.   PINB = 1<<dc; // dc high
    185. }
    186.  
    187. void InitDisplay () {
    188.   for (uint8_t c=0; c<InitLen; c++) Command(Init[c]);
    189.  
    190. }
    191. // Character terminal **********************************************
    192. void Clear256() {
    193.   uint8_t b = 0;
    194.   do {
    195.     PINB = 1<<clk; // clk low
    196.     b++;
    197.     PINB = 1<<clk; // clk high
    198.   } while (b != 0);
    199. }
    200.  
    201. // Optimised for fast scrolling
    202. void ClearLine (int line) {
    203.   Command(0xB0 + line);
    204.   Command(0x00); // Column start low
    205.   Command(0x00); // Column start high
    206.   PINB = 1<<cs; // cs low
    207.   PORTB = PORTB & ~(1<<data); // data low
    208.   Clear256(); Clear256(); Clear256(); Clear256();
    209.   PINB = 1<<cs; // cs high
    210. }
    211.  
    212. void ClearDisplay () {
    213.   for (uint8_t p=0; p < 8; p++) ClearLine(p);
    214.   Line = Scroll;
    215.   Column = 0;
    216. }
    217.  
    218. // Clears the top line, then scrolls the display up by one line
    219. void ScrollDisplay () {
    220.   ClearLine(Scroll);
    221.   Scroll = (Scroll + 1) & 0x07;
    222.   Command(0xD3);
    223.   Command(Scroll << 3);
    224. }
    225.  
    226. // Plots a character; line = 0 to 7; column = 0 to 20
    227. void PlotChar(char c, int line, int column) {
    228.   column = column*6;
    229.   Command(0xB0 + ((line + Scroll) & 0x07));
    230.   Command(0x00 + (column & 0x0F)); // Column start low
    231.   Command(0x10 + (column >> 4));   // Column start high
    232.   for (uint8_t col = 0 ; col < 6; col++) {
    233.     Data(pgm_read_byte(&CharMap[c-32][col]));
    234.   }
    235. }
    236.  
    237. // Prints a character, handling control characters
    238. void Print(char c) {
    239.   c = c & 0x7F; // Ignore top bit
    240.   if (c >= 32) {
    241.     PlotChar(c, Line, Column++);
    242.     if (Column > 20) {
    243.       Column = 0;
    244.       if (Line == 7) ScrollDisplay(); else Line++;
    245.     }
    246.   }
    247.   // Return character
    248.   else if (c == 13) {
    249.     Column = 0;
    250.     if (Line == 7) ScrollDisplay(); else Line++;
    251.   }
    252. }
    253.  

    ssd1306_terminal.png
     

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