第12章 與PLC接口的4位LED數字顯示表
12.2 數顯表頭軟件設計思路
12.4 程序清單
static int flag,flag0,flag1,flag3,led_d;
static int data1[5],data2[5];
static int data,data0,data_1,data_2,sdata;
//=====================子程序=========================
//端口初始化子程序
void initport( )
{
PORTA=0;
PORTB=0;
PORTC=0;
PORTD=0;
ADCON1=0x07;
TRISA=0x03; //設RA0,RA1為輸入
TRISB=0xE8; //設RB0,RB1,RB2,RB4為輸出
TRISC=0xFF; //設C口為輸入
TRISD=0; //設D口為輸出
}
//判斷地址是否相同子程序
int adr_jud(int x)
{
int adress,y;
adress=PORTA&0x03;
x&=0x60;
adress=adress<<5;
if (adress==x) y=1;
else y=0;
CLRWDT();
return(y);
}
//顯示初始化子程序
void initdis( )
{
PORTB=0xFE; //選通數碼管1
PORTD=0xC0;
PORTB=0xFD; //選通數碼管2
PORTD=0xC0;
PORTB=0xFB; //選通數碼管3
PORTD&=0x7F; //選通小數位
PORTD=0xC0;
PORTB=0xEF; //選通數碼管4
PORTD=0xC0;
}
//讀5次數據判是否有4次相等
int judge(arry)
int arry[5];
{
int i,j,k;
for(i=0;i<=4;i++){
k=0;
for(j=0;j<=4;j++)
{ if(arry[i]==arry[j]) k++;
if(k>=4) {
flag1=1;
data0=arry[i];
return(flag1);
}
else flag1=0;
}
}
return(flag1);
}
//數據轉換子程序
int convert(int d1,int d2)
{
auto int dd1,dd2;
int i1,j1,k1,i2,j2,m;
dd1=d1;
dd2=d2;
j1=0x10;
k1=2048;
d1=0;
for(i1=1;i1<=5;i1++) {
if(j1==(dd1&j1)) m=1;
else m=0;
d1=d1+mk1;
j1=j1/2;
k1=k1/2;
}
j2=0x40;
d2=0;
for(i2=1;i2<=7;i2++) {
if(j2==(dd2&j2)) m=1;
else m=0;
d2=d2+mk1;
j2=j2/2;
k1=k1/2;
}
data=d1+d2;
return(data);
}
//顯示子程序
int display(int x)
{ int l1,l2,l3,l4;
l1=x/1000;
PORTB=0xFE; //選通數碼管1
PORTD=led[l1];
l2=(x-l11000)/100;
PORTB=0xFD; //選通數碼管2
PORTD=led[l2];
l3=(x-l11000-l2100)/10;
PORTB=0xFB; //選通數碼管3
PORTD=0x7F;
PORTD=led[l3];
l4=x-l11000-l2100-l310;
PORTB=0xEF; //選通數碼管4
PORTD=led[l4];
}
//中斷服務子程序
void interrupt int_serve( )
{
PIR1=0;
TMR1L=0xE5;
TMR1H=0xBE;
di( );
sdata=PORTC&0x80;
ei( );
}
//開中斷子程序
void int_open( )
{
inportc=PORTC&0x80;
if(inportc==1) return;
else data1[0]=~PORTC;
flag=adr_jud(data1[0]);
if(flag==0) return; //地址不同返回
else data1[1]=~PORTC;
data1[2]=~PORTC;
if(data1[0]==data1[1])
if(data1[0]==data1[2]) {
flag3=1;
PIR1=0; //開通總中斷前,清所有中斷標志位
TMR1IE=1; //TMR1溢出中斷使能
PEIE=1;
ei( );
TMR1L=0xE5;
TMR1H=0xBE; //20ms中斷1次
T1CON=0x01; //設TMR1為1分頻,計數器方式工作
}
else return;
}
//讀第1幀子程序
voidread_1( )
{ int j0;
for(j0=1;j0<=4;j0++) data1[j0]=~PORTC;
flag1=judge(data1);
if (flag1==1) {
data_1=data0;
flag0=1;
count1++;
}
flag=adr_jud(data1[0]);
if(flag==1) {
for(j0=1;j0<=4;j0++) data1[j0]=~PORTC;
flag1=judge(data1);
if (flag1==1){
data_1=data0;
flag0=1;
count1++;
}
}
}
// 主程序
main( )
{ int i0,ii,i;
flag0=0; //幀標志位
flag1=0; //讀5次數據判有4次相等標志位
flag3=1; //開中斷標志位
count1=0; //讀第1幀計數單元
count2=0; //讀第2幀計數單元
data_1=0;
data_2=0;
led_d=0;
led[0]=0xc0; //0
led[1]=0xf9;
led[2]=0xa4;
led[3]=0xb0;
led[4]=0x99;
led[5]=0x92;
led[6]=0x82;
led[7]=0xf8;
led[8]=0x80;
led[9]=0x90; //9
initport( );
OPTION=0xFE; //開看門狗
initdis( );
while(1) {
if(flag3==0) int_open();
else{
if(sdata==0x80){ //第二幀數據到
if(flag0==1){
for(i0=0;i0<=4;i0++) data2[i0]=~PORTC;
flag1=judge(data2);
if (flag1==1) {
data_2=data0;
flag0=0;
count2++;
}
}
}
else if(sdata==0) { //第一幀數據到
if(flag0==0) {
data1[0]=~PORTC;
flag=adr_jud(data1[0]);
if(flag==1) {
for(j0=1;j0<=4;j0++) data1[j0]=~PORTC;
flag1=judge(data1);
if (flag1==1) {
data_1=data0;
flag0=1;
count1++;
}
}
}
}
CLRWDT();
if(count1==count2) led_d=convert(data_1,data_2 );
}
display(led_d);
}
}