原创 PIC16F877模拟量输入与输出

2007-8-15 23:14 4852 4 4 分类: 汽车电子
    

<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />6.1  A/D转换的应用<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


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


0XB10XB70XBC0XC20XC70XCC0XD10XD60XDA0XDF0XE30XE70XEA0XEE0XF10XF40XF60XF80XFA0XFC0XFD0XFF0XFF0XFF0XFF0XFF0XFF0XFE0XFD0XFB0XF90XF70XF50XF20XEF0XEC0XE90XE50XE10XDD0XD80XD40XCF0XCA0XC50XBF0XBA0XB40XAE0XA80XA20X9C0X960X900X890X830X800X790X720X6C0X660X600X5A0X550X4E0X480X430X3D0X380X330X2E0X290X250X200X1C0X180X150X110X0E0X0B0X090X070X050X030X020X000X000X000X000X000X000X010X020X040X060X080X0A0X0D0X100X130X160X1A0X1E0X220X270X2B0X300X350X3A0X400X450X4C0X510X570X5D0X630X690X6F0X760X7C}


//以上的数组用于存放正弦表,在定义数组时,前面应该加上 const


//以使数组存放于ROM中,而不至于占用太多的RAM


unsigned       char  i


unsigned               char       j


unsigned               char       n


//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模块使能


}


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


void        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  


}


//主程序


main ()


{


       i2cint()                                   //I2C初始化


while(1){


              for(i=0x00i<=127++i)


              {    


                     j=table            //从数组中得到需要传输的数据量


                     i2cout()             //利用I2C总线方式送出数据


              }


       }


}

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /2 下一条