#include<pic.h>
#define sda RC1
#define scl RC0
const char table[]={0xde,0x44,0x7a,0x76,0xe4, //0,1,2,3,4
0xb6,0xbe,0x54,0xfe,0xf6, //5,6,7,8,9
0xf8}; //p
__CONFIG(0x09);
void start();
void stop();
void respons();
void sendresponse();
void write_byte(char dat); //寫動作
void read_byte(); //讀動作
void delay1(char x);
void xianshi();
void zuo(int nn);
void you(int nn);
void deng(int mk);
void niu0();
void niu1();
void niu2();
void niu3();
void niu4();
void niu5();
void niu6();
void niu7();
void niu8();
void niu9();
void shumafenpei();
bank2 int dengshuju,ji,read_shu;
bank2 int uu,uy,y,kk;
bank1 int di,di1,tingshan,yu;
bank1 int yi,er,san,si;
void main()
{
char a,b;
TRISA=0;
TRISB=0;
PORTA=0;
PORTB=0;
di=0;
di1=1;
tingshan=1;
yu=0;
dengshuju=1;
while(1)
{
//***********************************************
TRISC =~(1<<0);
TRISC =~(1<<1); //置輸出
sda=1; //數據預置高
ji=0; //--
scl=1; //時鐘預置高
ji=0; //--
start();
write_byte(0xa0); //寫入寫的地址
respons();
write_byte(1); //寫地址
respons();
start();
write_byte(0xa1); //寫入讀的地址和讀動作
respons();
a=read_shu;
sendresponse();
b=read_shu;
stop();
PORTB=a;
//*************************************************
shumafenpei();
xianshi();
if(di1==1)
{
if(di<5)
else
{
RB0=0;
di=0;
di1=0;
}
di++;
}
}
}
void delay1(char x) //長延遲
{
char a,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
void xianshi()
{
zuo(yi); //第壹位數碼
PORTA=0x00;
ji=0;//delay();
niu0();
ji=0;//delay();
PORTA=0x05;
ji=0;//delay();
niu5();
ji=0;//delay();
PORTA=0xff;
you(er); //第二位數碼
PORTA=0x01;
ji=0;//delay();
niu1();
ji=0;//delay();
PORTA=0x06;
ji=0;//delay();
niu6();
ji=0;//delay();
zuo(san); //第三位數碼
PORTA=0x02;
ji=0;//delay();
niu2();
ji=0;//delay();
PORTA=0x07;
ji=0;//delay();
niu7();
ji=0;//delay();
you(si); //第四位數碼
PORTA=0x03;
ji=0;//delay();
niu3();
ji=0;//delay();
PORTA=0x08;
ji=0;//delay();
niu8();
ji=0;//delay();
deng(dengshuju); //指示燈
PORTA=0x04;
ji=0;//delay();
niu4();
ji=0;//delay();
PORTA=0xff;
PORTA=0x09;
ji=0;//delay();
niu9();
ji=0;//delay();
if(tingshan==1)
{
yu++;
if(yu<40)dengshuju=dengshuju|0x30; //0011 0000
if(yu>40&&yu<80)dengshuju=dengshuju&0xcf; //1100 1111
if(yu>80)yu=0;
}
if((dengshuju&0x10)&&(tingshan!=1))
{
dengshuju=dengshuju&0xf0;
dengshuju=dengshuju|0x01;
}
}
void zuo(int nn)
{
int mm=table[nn];
int i;
for(i=0;i<8;i++)
{
RB7=0; //時鐘信號預先置零
RA0=(mm&0x01); //取最邊沿數值
RB7=1;
mm=mm>>1;
}
}
void you(int nn)
{
int nu,nzuo,nyou,i;
nu=table[nn]; //取數
nzuo=(nu&0xaa); //抽1、3、5、7位
nyou=(nu&0x55); //抽2、4、6、8位
nzuo=nzuo>>1; //1、3、5、7變2、4、6、8
nyou=nyou<<1; //2、4、6、8變1、3、5、7
nu=(nzuo|nyou); //合數,賦值給nu
for(i=0;i<8;i++)
{
RB7=0; //時鐘信號預先置零
RA0=(nu&0x01); //取最邊沿數值
RB7=1;
nu=nu>>1;
}
}
void deng(int mk)
{
int i;
for(i=0;i<8;i++)
{
RB7=0; //時鐘信號預先置零
RA0=(mk&0x01); //取最邊沿數值
RB7=1;
mk=mk>>1;
}
}
void niu0()
{
int y0;
kk=dengshuju&0x0f;
if(RC2!=0)
{
uu=uu&0xfe; //1111 1110按鈕標誌位置零
}
y0=uu&0x01; //抽取按鈕標誌位的真假
if(RC2==0)
{
if((y0==0)&&((dengshuju&0x20)||tingshan==1))
{
di1=1;
switch(kk)
{
case 0x01:kk=0x08;break;
case 0x02:kk=0x01;break;
case 0x04:kk=0x02;break;
case 0x08:kk=0x04;break;
}
dengshuju=dengshuju&0xf0; //清除舊記錄
dengshuju=dengshuju|kk; //註入新記錄
}
uu=uu|0x01;
}
}
void niu1()
{
if(RC2!=0)
{
uy=uy&0xfd; //1111 1101按鈕標誌位置零
}
y=uy&0x02; //0000 0010抽取按鈕標誌位的真假
if(RC2==0)
{
if(y==0)
uy=uy|0x02;
}
}
void niu2()
{
if(RC2!=0)
{
uy=uy&0xfe; //1011 1111按鈕標誌位置零
}
y=uy&0x01; //抽取按鈕標誌位的真假
if(RC2==0)
{
if(y==0)
uy=uy|0x01;
}
}
void niu3()
{
if(RC2!=0)
{
uu=uu&0xf7; //1011 1111按鈕標誌位置零
}
y=uu&0x08; //抽取按鈕標誌位的真假
if(RC2==0)
{
if(y==0)
uu=uu|0x08;
}
}
void niu4()
{
kk=dengshuju&0x30; //0x00 0000取燈(單循/自動)狀態
if(RC2!=0)
{
uu=uu&0xfd; //1111 1101按鈕標誌位置零
}
y=uu&0x02; //抽取按鈕標誌位的真假
if(RC2==0)
{
if(y==0)
{
di1=1;
tingshan=0;
switch(kk)
{
case 0x00:kk=0x20;break;
case 0x20:kk=0x10;break;
case 0x10:kk=0x20;break;
case 0x30:kk=0x20;break;
}
dengshuju=dengshuju&0xcf; //1011 1111清除舊記錄
dengshuju=dengshuju|kk; //註入新記錄
}
uu=uu|0x02;
}
}
void niu5()
{
kk=dengshuju&0x40; //0x00 0000取燈(單循/自動)狀態
if(RC2!=0)
{
uu=uu&0xfb; //1111 1011按鈕標誌位置零
}
y=uu&0x04; //抽取按鈕標誌位的真假
if(RC2==0)
{
if(y==0)
{
di1=1;
if(kk==0)kk=0x40;
else kk=0;
dengshuju=dengshuju&0xbf; //1011 1111清除舊記錄
dengshuju=dengshuju|kk; //註入新記錄
}
uu=uu|0x04;
}
}
void niu6()
{
kk=dengshuju&0x80; //x000 0000取燈(圓面/平面)狀態
if(RC2!=0)
{
uu=uu&0xdf; //1101 1111按鈕標誌位置零
}
y=uu&0x20; //抽取按鈕標誌位的真假
if(RC2==0)
{
if(y==0)
{
di1=1;
if(kk==0)kk=0x80;
else kk=0;
dengshuju=dengshuju&0x7f; //0111 1111清除舊記錄
dengshuju=dengshuju|kk; //註入新記錄
}
uu=uu|0x20;
}
}
void niu7()
{
if(RC2!=0)
{
uu=uu&0xbf; //1011 1111按鈕標誌位置零
}
y=uu&0x40; //抽取按鈕標誌位的真假
if(RC2==0)
{
if(y==0)
uu=uu|0x40;
}
}
void niu8()
{
if(RC2!=0)
{
uu=uu&0xef; //1011 1111按鈕標誌位置零
}
y=uu&0x10; //抽取按鈕標誌位的真假
if(RC2==0)
{
if(y==0)
uu=uu|0x10;
}
}
void niu9()
{
if(RC2!=0)
{
uu=uu&0x7f; //1011 1111按鈕標誌位置零
}
y=uu&0x80; //抽取按鈕標誌位的真假
if(RC2==0)
{
if(y==0)
uu=uu|0x80;
}
}
void shumafenpei()
{
int jishu,juanzhi,yayin,tingliu,kk,yu;
jishu=read_shu;
juanzhi=3344;
yayin=5566;
tingliu=7788;
kk=dengshuju&0x0f;
switch(kk)
{
case 0x01:yu=jishu; break;
case 0x02:yu=tingliu; break;
case 0x04:yu=yayin; break;
case 0x08:yu=juanzhi; break;
}
yi=yu/1000;
yu=yu%1000;
er=yu/100;
yu=yu%100;
san=yu/10;
yu=yu%10;
si=yu;
}
//********************************************************
//IIC通訊程序
void start() //開始信號(時鐘高,數據由高變低)
{ //*****************************
TRISC=~(1<<1); //
sda=1; //數據高,準備啟動下沿信號
ji=0; //--
scl=1; //時鐘高
ji=0; //--
sda=0; //數據拉低,開始信號到位
ji=0; //--
}
void stop() //停止信號(時鐘高,數據由低變高)
{ //*****************************
TRISC =~(1<<1); //置輸出
sda=0; //數據低,準備停止上沿信號
ji=0; //--
scl=1; //時鐘高,
ji=0; //
sda=1; //數據拉高,停止信號到位
ji=0; //--
}
void respons() //應答檢測
{
char i;
TRISC=(1<<1); //設置為輸入
scl=1; //時鐘高
ji=0; //--
while((sda==1)&&(i<250)) //如果數據高並且沒循環完畢,i自增
i++;
scl=0; //時鐘高
ji=0; //--
}
void sendresponse() //發送應答
{
TRISC=~(1<<1); //置輸出
sda=0; //數據低
ji=0; //--
scl=1; //時鐘高
ji=0; //--
scl=0; //時鐘低,
ji=0; //--
sda=1; //數據高
}
void write_byte(char dat) //寫動作
{
char i,temp,d;
TRISC =~(1<<1); //置輸出
temp=dat; //函數被賦值轉交temp
for(i=0;i<8;i++) //開始傳輸八位數據
{
if((temp&0x80)==0x80)//如果最左壹位是1
d=1;
else
d=0;
scl=0; //時鐘低
ji=0; //--
sda=d; //數據被賦值
ji=0; //--
scl=1; //接收完,時鐘回復高
ji=0; //--
temp=temp<<1; //最左傳輸完,再左移壹位
}
scl=0; //結束,時鐘低
ji=0; //--
sda=1; //數據高
ji=0; //--
}
void read_byte() //讀動作
{
char i,k;
TRISC =(1<<1); //設置為輸入
scl=0; //時鐘低
ji=0; //--
sda=1; //釋放數據總線
ji=0; //--
for(i=0;i<8;i++)
{
scl=1; //時鐘高
ji=0; //--
k=(k<<1)|sda; //k先騰出位,再灌數據,再刷新k
scl=0; //時鐘低
ji=0; //--
}
read_shu=k; //函數給出讀出數據
}