日志档案

发表于 2007-8-15 23:14:51

0

标签: 无标签

PIC16F877模拟量输入与输出

    

6.1  A/D转换的应用

6.1  A/D转换初始化程序

//A/D转换初始化子程序

void        adinitial( )

{

       ADCON0 = 0x51              //选择A/D通道为RA2,打开A/D转换器

                                             //在工作状态,且使AD转换时钟为8tosc

       ADCON1 = 0X80             //转换结果右移,及ADRESH寄存器的高6位为"0"

                                    //且把RA2口设置为模拟量输入方式

       PIE1 = 0X00

       PIE2 = 0X00

       ADIE = 1                         //A/D转换中断允许

       PEIE = 1                          //外围中断允许

       TRISA2=1                       //设置RA2为输入方式

}

 

6.1.2  程序清单

下面给出一个调试通过的例程,可作为读者编制程序的参考。该程序中用共用体的方式把A/D转换的10位结果组合在一起。有关共用体的详细资料请参考本书相关章节。

# include        <pic.h>

union             adres

{int         y1

unsigned  char  adre[2]

}adresult                                 //定义一个共用体,用于存放A/D转换的结果

unsigned   char    i

unsigned   int       j

//系统各I/O口初始化子程序

void        initial()

{

       TRISD=0X00                   //D口为输出

       i=0x00

}

//A/D转化初始化子程序

void        adinitial()

{

       ADCON0=0x51                //选择A/D通道为RA2,打开A/D转换器

                                             //在工作状态,且使A/D转换时钟为8tosc

       ADCON1=0X80               //转换结果右移,及ADRESH寄存器的高6位为"0"

                                    //且把RA2口设置为模拟量输入方式

       PIE1=0X00

       PIE2=0X00

       ADIE=1                           //A/D转换中断允许

       PEIE=1                            //外围中断允许

       TRISA2=1                       //设置RA2为输入方式

}

//延时子程序

void        delay()

{

       for(j=5535--j) continue

}

//报警子程序

void        alarm()

{

       i=i^0xFF                          //通过异或方式每次把i的各位值取反     

       PORTD=i                         //D口输出i的值

}

//中断服务程序

void        interrupt         adint(void)

{

       ADIF=0                           //清除中断标志

       adresult.adre[0]=ADRESL

       adresult.adre[1]=ADRESH //读取并存储A/D转换结果,A/D转换的结果通过共

                                                 //用体的形式放入了变量y1  

       if(adresult.y1>0x200)

       {

       alarm()                                   //如果输入的模拟量大于2.5V(对应数字量

                                                 //0X200h),则调用报警子程序

       delay()                             //调用延时子程序,使电压检测不要过于频繁

       }

       else  PORTD=0XF0                  //如果输入的模拟量小于2.5V,则与D口相连的

                                                 //8个发光二极管的低4个发亮,表示系统正常

       ADGO=1                         //启动下一次A/D转换

} 

//主程序

main()

{

       adinitial()                          //A/D转换初始化

       initial()                             //系统各I/O口初始化 

       ei()                                  //总中断允许

       ADGO=1                         //启动A/D转换

while(1)

       {

             

       }                                        //等待中断,在中断中循环检测外部电压

}

 

6.2.2  I2C总线工作方式相关子程序

1C语言编写的I2C总线工作方式的初始化子程序

//I2C初始化子程序

void       i2cint()

{

       SSPCON = 0X08                     //初始化SSPCON寄存器

       TRISC3 =1                      //设置SCL为输入口

       TRISC4 =1                      //设置SDA为输入口

       TRISA4 = 0

       SSPSTAT=0X80               //初始化SSPSTAT寄存器

       SSPADD=0X02                //设定I2C时钟频率

       SSPCON2=0X00                     //初始化SSPCON2寄存器

       di()                                  //关闭总中断

       SSPIF=0                          //SSP中断标志

       RA4=0                             //关掉74HC165的移位时钟使能,以免74HC165移位

//数据输出与I2C总线的数据线发生冲突(此操作与该

//实验板的特殊结构有关,不是通用的)

       SSPEN=1                        //SSP模块使能

}

 

2C语言编写的I2C总线工作方式传输数据子程序

需要发送的数据在寄存器j中。

//I2C总线输出数据子程序

i2cout()

{

       SEN=1                                   //产生I2C启动信号

       for(n=0x02--n)      continue//给予一定的延时,保证启动

do    {

              RSEN=1                   //产生I2C重启动信号

       }while(SSPIF==0)            //如果没能启动,则反复启动,直到启动为止

       SSPIF=0                          //SSPIF标志清0

       SSPBUF=0X58                 //I2C总线发送地址字节

do    {

             

       }while(SSPIF==0)            //等待地址发送完毕

       SSPIF=0                          //SSPIF标志清0

       SSPBUF=0X01                 //I2C总线发送命令字节

do    {

             

       }while(SSPIF==0)            //等待命令发送完毕

       SSPIF=0                          //SSPIF标志清0

       SSPBUF=j                        //I2C总线发送数据字节

do    {

             

       }while(SSPIF==0)            //等待数据发送完毕

       SSPIF=0                          //SSPIF标志清0

       PEN=1                                   //产生停止条件

do {

             

       }while(SSPIF==0)            //等待停止条件产生

       SSPIF=0                          //SSPIF标志清0  

}

6.2.4程序清单

      下面给一个例程。该程序利用MAX518进行D/A转换,且从D/A0引脚输出一个正弦波形。可作为读者编制程序的参考。特别注意,在调试该程序时,把模板上的钮子开关S8拔向高电平,以免发生资源冲突。

       #include  <pic.h>

//本程序将通过PIC16F877I2C方式驱动D/A转换器MAX518,使其D/A0通道输出

//一个连续的正弦波形(注:本程序并没对正弦波的频率进行控制)

const  char  table[ ] = {0X800X860X8D 0X930X990X9F0XA50XAB

0XB10XB70XBC0XC20XC70XCC0XD10XD60XDA0XDF0XE30XE70XEA0XEE0XF10XF40XF60XF80XFA0XFC0XFD0XFF0XFF0XFF0XFF0XFF0XFF0XFE0XFD0XFB0XF90XF70XF50XF20XEF0XEC0XE90XE50XE10XDD0XD80XD40XCF0XCA0XC50XBF0XBA0XB40XAE0XA80XA20X9C0X960X900X89