技术热线: 4007-888-234

PIC单片机C语言编程实例八

更新时间: 2019-01-05
阅读量:2763

第12章 与PLC接口的4位LED数字显示表
12.2 数显表头软件设计思路
12.4 程序清单

include

include “mydefine.h”

include

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+m
k1;
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-l1
1000-l2100)/10;
PORTB=0xFB; //选通数码管3
PORTD=0x7F;
PORTD=led[l3];
l4=x-l1
1000-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);
}
}