Термометр 0/999 градусов на Attiny13

Ввиду того, что у многих проблемы с TM1650, сделал вариант для TM1637. Схема та-же. Должна работать и на тиньке13 и на UNO и подобных. На тиньке занимает 432 байта на УНО 574. Проверить не смог т.к. нет MAX6675, а подпаиваться к мелкой платке программатором лень.

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#define miso     PB0 //MAX6675           
#define cs       PB1 //--
#define clk      PB2 //--
//#define clk    PB3 //TM1637
//#define DIO    PB4 //--
#define miso_In()   (PINB & 0B00000001)

#define DIO_H()    (PORTB |=  _BV(PB4))
#define DIO_L()    (PORTB &= ~_BV(PB4))
#define DIO_OUT()  (DDRB  |=  _BV(PB4))
#define DIO_IN()   (DDRB  &= ~_BV(PB4))
#define DIO_RD()   (((PINB  & _BV(PB4)) > 0) ? 1 : 0)
#define CLK_H()    (PORTB |=  _BV(PB3))
#define CLK_L()    (PORTB &= ~_BV(PB3))

PROGMEM const uint8_t _digit2segments[] =
{
  0x3F, // 0
  0x06, // 1
  0x5B, // 2
  0x4F, // 3
  0x66, // 4
  0x6D, // 5
  0x7D, // 6
  0x07, // 7
  0x7F, // 8
  0x6F, // 9
  0x00, // пусто
  0x63  // градус
};
 
//********************************************************************************************************
int main(void) {
		/* setup */
	 //  Serial.begin(9600);

	  TM1637_init();
    
	 _delay_ms(300);
//********************************************************************************************************
	while(1) {

int t= spiRead();//Читаем данные из модуля термопары  MAX6675
byte ks=0;
byte kd=0;
  while(t>=100){t-=100;ks++;} ;
  while(t>=10){t-=10;kd++;}
        //************ выводим число на индикатор *******************   

if (ks==0)ks=10;
           //СОТНИ
          TM1637_dig (0, ks); 
          //ДЕСЯТКИ
          TM1637_dig (1, kd); 
          //ЕДИНИЦЫ
          TM1637_dig (2, t);   
          //знак градуса
          TM1637_dig (3, 11);//градус 
    
_delay_ms(500);
}

}


//    ******************** Чтение данных из модуля термопары  MAX6675 ******************************
//https://arduinodiy.wordpress.com/2019/12/06/using-a-max6675-temperature-sensor-without-a-library/
int spiRead() {
 DDRB = DDRB | 0B00000110;
 int rawTmp = 0;
PORTB &= ~(1<<cs);   //  cs,LOW
      _delay_ms(2);     //  задержка 2 миллисекунды
PORTB |= (1<<cs);    //  cs,HIGH
      _delay_ms(200);   //  задержка 200 миллисекунд
PORTB &= ~(1<<cs);   //  cs,LOW Опускаем CS для старта преобразования

//Считываем 11 из 14 бит из MAX6675 (больше мне не нужно)и сохраняем в rawTmp

for (int i=10; i>=0; i--) {
PORTB |= (1<<clk); //clk,HIGH

byte r=0;if(PINB & (1<<miso))r=1;//Чтение пина MISO
rawTmp +=r << i;
PORTB &= ~(1<<clk); // clk,LOW
}
//rawTmp=24;
return rawTmp;
}


//***********************************************************************************


void
TM1637_dig(const uint8_t position, const uint8_t digit)
{ uint8_t segments = (digit < 12 ? pgm_read_byte_near((uint8_t *)&_digit2segments + digit) : 0x00);
  TM1637_display_segments(position, segments);}

void
TM1637_display_segments(const uint8_t position, const uint8_t segments)
{ send_cmd(0x40 | 0x04);
  TM1637_start();
  TM1637_write_byte(0xC0 | (position & (4 - 1)));
  TM1637_write_byte(segments);
  TM1637_stop();}

//  Serial.println((0x80 | _config),HEX);

uint8_t TM1637_write_byte(uint8_t value)
{ uint8_t i, ack;
  for (i = 0; i < 8; ++i, value >>= 1) {
  CLK_L(); _delay_us(5);
    if (value & 0x01) {DIO_H();}
    else {DIO_L();}
  CLK_H(); _delay_us(5);}
  CLK_L();
  DIO_IN();
  DIO_H(); _delay_us(5);
  ack = DIO_RD();
  if (ack) { DIO_OUT();DIO_L();} _delay_us(5);
  CLK_H(); _delay_us(5);
  CLK_L(); _delay_us(5);
  DIO_OUT();
  return ack;}

void send_cmd(const uint8_t value)
{ TM1637_start(); TM1637_write_byte(value); TM1637_stop();}  

void TM1637_start()
{ DIO_H();CLK_H(); _delay_us(5); DIO_L();}

void TM1637_stop()
{ CLK_L(); _delay_us(5); DIO_L(); _delay_us(5); CLK_H(); _delay_us(5); DIO_H();}

void
TM1637_init()
{ DDRB |= (_BV(PB4)|_BV(PB3));
  PORTB &= ~(_BV(PB4)|_BV(PB3));
  send_cmd(0x8B);}
1 лайк