Kód: Vybrat vše
// Na I2C displeji bude teplota ve stupních Celsia s přesností na jedno desetinné místo. Pro
// zápornou teplotu zobrazte znaménko -. Program musí využívat CCP modul a přerušení pro měření z
// teplotního čídla SMT160-30.
// 33/RB0 vstupni port cidla
#include <pic.h>
#define CrystalFreq 18432000
#define Misto PORTA
#define Display PORTD
#define SCL RC3
#define SDA RC4
#define TSCL TRISC3
#define TSDA TRISC4
#define W_TEMP 0x7F
#define STATUS_TEMP 0x7E
unsigned char DispPos,DisData[4];
unsigned char abc[20];
char Cekani, Count, Bity, Cas, I2CHodn;
bit I2CStarted, I2CError;
float rofl=0.0;
int a=0,b=0,c=0,d=0;
float t1=0.0, t2=0.0, t3=0.0, W=0.0, T=0.0, temp=0.0, Duty=0.0;
int j=0, x,pocet=0;
float PICrlz=0.0;
void Delay()
{
unsigned char Cas;
while(Cas--);
}
void DelayUs(unsigned char time) // Funguje docela dobře pro krystal 20MHz
{
if(!time--) return;
if(!time--) return;
while(time--)
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
}
void I2CSetup(void)
{
char i;
SSPCON=0x38; // I2C master mode
I2CStarted=0; // Zatím se nic neděje
I2CError=0;
SSPSTAT=0x80; // 100 kHz sběrnice (no slew rate control)
SSPCON2=0; // Vynulovat informační bity
SSPADD=1.0*CrystalFreq/(400000.0); // 100 kHz sběrnice, SSPADD = fosc/(4.100kHz)-1
if(SDA) return; // Pokud bez chyby, tak konec
PORTC&=0xE7; // Nastavení SDA a SCL na nulu
SSPEN=0; // Zákaz I2C
for(i=9;i!=0;i--) // Maximálně 9 impulsů,pak už chyba nejde opravit
{
TSCL=0; // Hodiny dolů
DelayUs(40); // Chvilku čekej (40us)
TSCL=1; // Hodiny nahodu
DelayUs(40); // Chvilku čekej (40us)
if(SDA) break;
}
SSPEN=1; // Povol I2C
}
void I2CWait()
{
while(!SSPIF);
SSPIF=0;
}
void I2CSta03()
{
I2CError=1;
return;
}
void I2CSta02()
{
I2CStarted=1;
I2CWait();
}
void I2CSta01()
{
if(SDA==1)
{
if(SCL==1)
{
SEN=1;
I2CSta02();
}
I2CSta03();
}
I2CSta03();
}
void I2CStart()
{
if(I2CStarted==1)
{
RSEN=0;
I2CSta02();
}
I2CSta01();
}
void I2COut(char Znak)
{
SSPBUF=Znak;
I2CWait();
return;
}
void I2CStop()
{
PEN=1;
I2CStarted=0;
I2CWait();
}
void ConfSAA1064()
{
I2CStart();
I2COut(0x70);
I2COut(0x00);
I2COut(0x77);
I2CStop();
}
const unsigned char PrevodZnaky[10]=
{0b00000000,
0b00000110,
0b01011011,
0b01001111,
0b01100110,
0b01101101,
0b01111100,
0b00000111,
0b01111111,
0b01100111};
const unsigned char PrevodZnakyTecka[10]=
{0b10000000,
0b10000110,
0b11011011,
0b11001111,
0b11100110,
0b11101101,
0b11111100,
0b10000111,
0b11111111,
0b11100111};
char n, number;
void Numero() // prepis pole na display
{
if(n<4)
{
n++;
return;
}
}
void WrDis() // sem to dostane hodnotu z mainu
{
I2CStart();
I2COut(0x70); // adresa SAA1064
I2COut(0x01); // subadresa
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
n=0;
if(n==0)
{
number=PrevodZnaky[d];
Numero();
I2COut(number);
}
if(n==1)
{
number=PrevodZnakyTecka[c];
Numero();
I2COut(number);
}
if(n==2)
{
number=PrevodZnaky[b];
Numero();
I2COut(number);
}
if(n==3)
{
if(rofl<0)
{
Numero();
number = 0b01000000;
I2COut(number);
}
}
I2CStop();
return;
}
void Prevod(float rofl)
{
asm("NOP");
PICrlz=rofl*10.0;
asm("NOP");
a=(int)PICrlz;
asm("NOP");
if(a>100) // kladne >100
{
b=a/100;
c=(a-(100*b))/10;
d=(a-100*b-10*c);
}
else if(a<100 && a>10) // kladne 10 ~ 100
{
b=0;
c=(a-(100*b))/10;
d=(a-100*b-10*c);
}
else if(a<10 && a>0) // kladne 0 ~ 10
{
b=0;
c=0;
d=(a-100*b-10*c);
}
else if(a<0 && a>-10) // zapor 0 ~ -10
{
a=-1*a;
b=0;
c=0;
d=(a-100*b-10*c);
}
else if(a<0 && a>-100) // zapor -10 ~ -100
{
a=-1*a;
b=0;
c=(a-(100*b))/10;
d=(a-100*b-10*c);
}
else if(a<-100) // zapor <100
{
a=-1*a;
b=a/100;
c=(a-(100*b))/10;
d=(a-100*b-10*c);
}
else if(a==0) // 0
{
b=0;
c=0;
d=0;
}
WrDis();
}
char CountandShow()
{
rofl=(Duty-0.320)/0.00470;
Prevod(rofl); //vypocet teploty
}
void interrupt CCPpreruseni()
{
CCP1IF=0;
if(CCP1CON==0b00000101)
{
t1=TMR1; //zapis hodnoty TMR1 do t1
CCP1CON=0b00000100; //zachytavani sestupne hrany
if(j==1)
{
T=t1-temp;
Duty=W/T;
j=0;
CountandShow();
return;
}
}
if(CCP1CON==0b00000100)
{
j=1;
temp=0;
temp=t1;
t2=TMR1;
W=t2-t1;
CCP1CON=0b00000101;
return;
}
}
//----------------------------------------------------------------------------
void main()
{
PORTD=0xFF; // Výstupy PORTu D budou v jedničce
TRISD=0x00; // Vývody budou výstupní
TRISD0=1;
ADCON1=0x07;
TRISA=0b11000011; // Výstupní piny pro display
PORTA=0xFF;
PORTE=0;
TRISE2=0;
TRISB=0b11111111;
TRISC=0b11111111; //RC3 - SCL; RC4 - SDA
RB0=1;
I2CSetup();
ConfSAA1064();
PORTC = 0;
CCP1CON=0b00000101; //zachytavani vzestupne hrany
T1CON=0b00110001; //preddelicka 1:8
CCP1IE=1; //zapnuti CCP preruseni
GIE=1;
// TMR1IE=1; // nechat zakomentovane
PEIE=1;
/*
t1=22124;
t2=29499;
t3=51622;
W=t2-t1;
T=t3-t1;
Duty=W/T;
a=0;
b=0;
c=0;
*/
while(1)
{
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
WrDis();
}
}