日志档案

发表于 2007-8-13 19:09:53

0

标签: pic16f877  

PIC16F877的外围功能模块

5.1.2  简单应用实例

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

5.1   PORTD输出

       #include  <pic.h>

main()

{

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

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

       {

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

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

}

}

 

5.2.1  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引脚为输出*/

}

5.2.3  程序清单

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

#include         <pic1687x.h>

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

static volatile int table[20]={0xc00xf90xa40xb00x990x920x820XD80x800x900x880x830xc60xa10x860x8e0x7f0xbf0x890xff}

volatile    unsigned        char       data

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

static       bit PORTA_5 @ PORTAIT(PORTA5)

/*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=8i>0i--)                /*连续发送8个数据*/

      {

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

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

      }

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

}

5.3.3  程序清单

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

#include         <pic.h>

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

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

static       bit  PORTA_5  @  PORTAIT(PORTA5)

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

static       bit  PORTB_5  @  PORTBIT(PORTB5)

 

static      bit  PORTB_4  @  PORTBIT(PORTB4)

static       bit  PORTB_1  @  PORTBIT(PORTB1)   

static       bit  PORTB_2  @  PORTBIT(PORTB2)   

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]={0xc00xf90xa40xb00x990x920x820XD80x800x900x880x830xc60xa10x860x8e0x7f0xbf0x890xff}

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

       SPIINIT()      /*SPI初始化*/         

while(1)

{

       KEYSCAN()

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

{

              data=table[j]

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

              SPILED(data)

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

}

  }

}

5.4.1   PORTB端口“电平变化中断”简介

5.3   PORTB口“电平变化中断”初始化子程序

/*B口“电平变化中断”初始化子程序*/

void              PORTBINT( )

{

       TRISB=0XF0                   /*设置相应口的输入输出方式*/

       OPTION=0x7F                /*B口弱上拉有效*/

       PORTB=0X00                  /*RB1RB2 先送低电平*/

       RBIE=1                           /*B口变位中断允许 */

       PORTB=PORTB               /*B口的值,以锁存旧值,为变位中断创造条件*/

}

5.4.3  程序清单

      下面给出一个调试通过的例程,以供读者参考。有关显示的部分请读者参考前面章节。该程序中寄存器的位都用头文件中定义的位,如RB5表示PORTB的第5位,而不像前面几节那样自己定义。

       #include  <pic.h>

/*该程序用于通过PORTB"电平变化中断"进行键盘的识别。*/

/*程序设置一个键值寄存器j,当按下S9键时j=1,按下S11键时 */

/*j=2,按下S10键时,j=3,按下S12键时j=4*/

unsigned        char        data

unsigned        int           I

unsigned        char        j

const char table[20]={0xc00xf90xa40xb00x990x920x820XD80x800x900x880x830xc60xa10x860x8e0x7f0xbf0x890xff}

/*B口“电平变化中断”初始化子程序*/

void              PORTBINT()

{

       TRISB=0XF0                   /*设置相应口的输入输出方式*/

       OPTION=0x7F

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

       RBIE=1                           /*B