十年专注单片机方案开发的方案公司英锐恩,分享PIC16F877 单片机A/D转化的C的源程序。英锐恩现提供服务产品涉及主控芯片:8位单片机、16位单片机、32位单片机及各类运算放大器等。
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
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总线工作方式相关子程序
1.C语言编写的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模块使能
}
2.C语言编写的I2C总线工作方式传输数据子程序
需要发送的数据在寄存器j中。
//I2C总线输出数据子程序
i2cout()
{
SEN=1; //产生I2C启动信号
for(n=0x02;--n;) continue;//给予一定的延时,保证启动
do {
RSEN=1; //产生I2C重启动信号
}while(SSPIF==0); //等待数据发送完毕
SSPIF=0; //SSPIF标志清0
PEN=1; //产生停止条件
do {
;
}while(SSPIF==0); //等待停止条件产生
SSPIF=0; //SSPIF标志清0
}
//主程序
main ()
{
i2cint(); //I2C初始化
while(1){
for(i=0x00;i<=127;++i)
{
j=table[i]; //从数组中得到需要传输的数据量
i2cout(); //利用I2C总线方式送出数据
}
}
}