PIC16F877的外围功能模块

1. 简单应用实例



该例用于令与PORTD口相连的8个发光二极管前4个点亮,后4个熄灭。在调试程序前,应使与PORTD口相连的8位拔码开关拔向相应的位置。


例5.1 PORTD输出



#include


main()



{


TRISD=0X00; /*TRISD寄存器被赋值,PORTD每一位都为输出*/


while(1); /*循环执行点亮发光二极管的语句*/


{


PORTD=0XF0; /*向PORTD送数据,点亮LED(由实验模板*/


/*的设计决定相应位置低时LED点亮)。*/


}


}





MSSP模块SPI方式功能简介



下面是一段简单的SPI初始化例程,用于利用SPI工作方式输出数据的场合。


例5.2 SPI初始化程序



/*spi初始化子程序*/


void SPIINIT()


{


PIR1=0; /*清除SPI中断标志*/


SSPCON=0x30; /* SSPEN=1;CKP=0 , FOSC/4 */


SSPSTAT=0xC0;


TRISC=0x00; /*SDO引脚为输出,SCK引脚为输出*/


}



程序清单



下面给出已经在实验板上调试通过的一个程序,可作为用户编制其它程序的参考。


#include


/*该程序用于在8个LED上依次显示1~8等8个字符*/


static volatile int table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};


volatile unsigned char data;


#define PORTAIT(adr,bit) ((unsigned)(&adr)*8+(bit)) /*绝对寻址位操作指令*/


static bit PORTA_5 @ PORTAIT(PORTA,5);


/*spi初始化子程序*/


void SPIINIT()


{


PIR1=0;


SSPCON=0x30; /* SSPEN=1;CKP=0 , FOSC/4 */


SSPSTAT=0xC0;


TRISC=0x00; /*SDO引脚为输出,SCK引脚为输出*/


}


/*系统各输入输出口初始化子程序*/


void initial()


{


TRISA=0x00; /*A口设置为输出*/


INTCON=0x00; /*关闭所有中断*/


PORTA_5=0; /*LACK送低电平,为锁存做准备*/


}


/*SPI发送子程序*/


void SPILED(int data)


{


SSPBUF=data; /*启动发送*/


do


{





}while(SSPIF==0); /*等待发送完毕*/


SSPIF=0; /*清除SSPIF标志*/


}


/*主程序*/


main()


{


unsigned I;


initial(); /*系统初始化*/


SPIINIT() ; /*SPI初始化*/


for(i=8;i>0;i--) /*连续发送8个数据*/


{


data=table; /*通过数组的转换获得待显示的段码*/


SPILED(data); /*发送显示段码显示*/


}


PORTA_5=1; /*最后给锁存信号,代表显示任务完成*/


}


程序清单



下面给出已经在实验板上调试通过的程序,可作为用户编制其它程序的参考。有关显示部分的SPI初始化,请读者参考5.2节。


#include


/*该程序用于按下相应的键时,在第一个8段LED上显示相应的1~4的字符*/


#define PORTAIT(adr,bit) ((unsigned)(&adr)*8+(bit)) /*绝对寻址位操作指令*/


static bit PORTA_5 @ PORTAIT(PORTA,5);


#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit)) /*绝对寻址位操作指令*/


static bit PORTB_5 @ PORTBIT(PORTB,5);





static bit PORTB_4 @ PORTBIT(PORTB,4);


static bit PORTB_1 @ PORTBIT(PORTB,1) ;


static bit PORTB_2 @ PORTBIT(PORTB,2) ;


unsigned int I;


unsigned char j;


int data;


/*spi初始化子程序*/


void SPIINIT()


{


PIR1=0;


SSPCON=0x30;


SSPSTAT=0xC0;


TRISC=0xD7; /*SDO引脚为输出,SCK引脚为输出*/


}


/*系统各输入输出口初始化子程序*/


void initial()


{


TRISA=0xDF;


TRISB=0XF0; /*设置与键盘有关的各口的数据方向*/


INTCON=0x00; /*关闭所有中断*/


data=0X00; /*待显示的寄存器赋初值*/


PORTB=0X00; /*RB1 RB2 先送低电平*/


j=0;


}


/*软件延时子程序*/


void DELAY()


{


for(i = 6553; --i ;)


continue;


}


/*键扫描子程序*/


int KEYSCAN()


{


while(1)


{


if ((PORTB_5==0)||(PORTB_4==0))


break;


} /*等待有键按下*/


DELAY(); /*软件延时*/


if ((PORTB_5==0)||(PORTB_4==0))


KEYSERVE(); /*如果仍有键按下,则调用键服务子程序*/


else j=0x00; /*如果为干扰,则令返回值为0*/


return(j);


}


/*键服务子程序*/


int KEYSERVE()


{


PORTB=0XFD ;


if(PORTB_5==0) j=0X01;


if(PORTB_4==0) j=0X03;


PORTB=0XFB;


if(PORTB_5==0) j=0X02;


if(PORTB_4==0) j=0X04;/*以上根据按下的键确定相应的键值*/


PORTB=0X00; /*恢复PORTB的值*/


while(1)


{


if((PORTB_5==1)&&(PORTB_4==1)) break;/*等待键盘松开*/


}


return(j);


}


/*SPI发送子程序*/


void SPILED(int data)


{


SSPBUF=data; /*启动发送*/


do


{





}while(SSPIF==0); /*等待发送完毕


SSPIF=0;


}


/*主程序*/


main()


{


static int table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};


initial();/*系统初始化*/


SPIINIT() ;/*SPI初始化*/


while(1)


{


KEYSCAN();


if(j!=0) /*如果j=0,证明先前的按键为干扰,则不予显示*/


{


data=table[j];


PORTA_5=0; /*LACK信号清0,为锁存做准备*/


SPILED(data);


PORTA_5=1; /*最后给锁存信号,代表显示任务完成*/


}


}


}

相关