/****************************************************************************************
* KF8V系列单片机开发板演示程序
* 标 题: 运算放大器模块实验
* 项 目 名: 16-Operational_Amplifier_TEST
* 开发环境:ChipON IDE
* 版 本: V2.0 (2015/10/10)
* 使用芯片:KF8V216
* 作 者:上海芯旺微电子技术有限公司
* 功能简述: 使能运算放大器模块,运算放大器的输出
*************************************************************************************/
#include<KF8V216.h>
#define uchar unsigned char
#define uint unsigned int
#define NUM1_IO P0LR4
#define NUM2_IO P0LR5
//主函数
uchar num_1,num_2;
uint dis_adc;
void DelayMs (uint Num)
{
uint cnt;
while(Num--)
{
cnt=2000;
while(cnt--);
}
}
void DelayUs (uint Num)
{
while (Num--);
}
void Delay_200us()
{
uchar i = 240;
while(--i);
}
//;***************************************************************
//; 函 数 名:void Delay50Us()
//;功能函数:延时函数,50us
//;入口参数:无
//;返回参数:无
//;***************************************************************
void Delay50Us()
{
char cnt ;
cnt = 30;
while(cnt--);
}
void init (void)
{
OSCCTL = 0x70; //设置为16M
/*********端口初始化***********/
TR0 = 0xcf; //设置P0端口 1100 1111
TR1 = 0x00; //设置P1端口 0000 0000
P0 = 0;
P1 = 0;
P0LR=0;
P1LR=0;
NUM1_IO=1;
NUM2_IO=1;
/*********AD初始化***********/
ANSEL = 0x07; //设置通道2为模拟口 0000 0111
ADCCTL0 = 0x89; //右对齐,通道OPOUT, AD使能打开
ADCCTL1 = 0x17; //8分频,VDD作为参考电压
/*********运放初始化***********/
AMPCTL=0X01; //0000 0001
}
//;***************************************************************
//; 函 数 名:Operational_init()
//;功能函数:运放自校正函数
//;入口参数:无
//;返回参数:无
//;函数 模拟运放口需要先设置为模拟输入,运放校正后,输出失调将降到最低,输出失调可以降低到3mv内左右。
//;***************************************************************
void Operational_init (void)
{
unsigned char val_AMPCALI,first_back_up,i,shift_data;
AMPON = 1; //开启运放
//延迟,给一个输出缓冲时间
Delay50Us();
CALIEN = 1; //开启自校准
//延迟,给一个输出缓冲时间
Delay50Us();
Delay50Us();
Delay50Us();
//读出AMPCTL中的第7位(CALID)放入AMPCALI中的最高位,用于正负失调判断,次高位置1,其它位设置为全0
first_back_up = AMPCTL & 0x80; //保存第一次的值,用于以后判断的标准
val_AMPCALI = first_back_up; //得到AMPCALI的第7位
//bit6-bit2 采用二分法获得最佳值,方法是先把该位 置1,如果和第一次相比翻转了就把该位清0,进行下一位的判断,否则直接进行下一位的判断
shift_data = 0B01000000; //位置1或清0 ,初始值为 bit6
for(i = 0; i < 4; i++) //计数,bit6-bit3 只需要循环4次
{
val_AMPCALI = val_AMPCALI | shift_data; //位置1
AMPDT = val_AMPCALI;
//延迟,给一个输出缓冲时间
Delay50Us();
if(first_back_up != (AMPCTL & 0x80)) //和第一次相比,如果翻转,当前位清0,不翻转直接跳过
{
val_AMPCALI = val_AMPCALI ^ shift_data; //清0
}
shift_data = shift_data >> 1; //右移一位,进行下一位的置1准备
}
//bit2 bit1 bit0 采用累加方式确定临界值,这里只要翻转必定是临界值,校准直接完成
for(i = 0; i < 8; i++)
{
//延迟,给一个输出缓冲时间
AMPDT = val_AMPCALI;
Delay50Us();
if(first_back_up != (AMPCTL & 0x80)) //和第一次相比,如果翻转,当前位清0,不翻转直接跳过
{
CALIEN = 0; //关闭自校准使能,运放2可以进行采样,运放2已经使能,不需要重新打开
return;
}
val_AMPCALI++; //累加判断
}
CALIEN = 0; //关闭自校准使能,运放2可以进行采样,运放2已经使能,不需要重新打开
return;
}
void main()
{
init ();
Operational_init();
while (1);
}
//中断函数0:0X04入口地址
void int_fun0() __interrupt (0)
{
}
//中断函数1:0x14入口地址
void int_fun1() __interrupt (1)
{
}
|