|
我使用ATmega16功能小板,在PC口上连了4个数码管,用来显示AD转换后的结果,用PD4-PD7来控制数码管的片选,使用ADC0单通道输入,使用内部RC振荡.用ICC语言编写,用JTAG仿真,程序如下:
/****************************************
project: A/D转换
chip type: ATmega16
Clock frequency: 内部RC(INT) 8.000000MHZ
****************************************/
#include<iom16v.h>
#include<macros.h>
#define osccal 0xb7 //内部RC校正常数
#define Vref 500 //参考电压值
unsigned int adc_rel; //AD转换结果
unsigned char adc_mux; //AD通道
unsigned char led_buff[4]={0,0,0,0};
#pragma data:code //设置数据区为程序存储器
const unsigned char seg_table[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
#pragma data:data //设置数据区回到数据存储器
void delay_us(int time) //微秒级延时程序
{
do
time--;
while(time>1);
}
void delay_ms(unsigned int time) //毫秒级延时程序
{
while(time!=0)
{
delay_us(1000);
time--;
}
}
void display(void)
{
unsigned char i;
DDRC=0xff; //PC口设置为段码输出
PORTC=0xff;
DDRD|=0xf0; //PD口设置为片选输出
PORTD|=0xf0;
for(i=0;i<4;i++)
{
PORTC=led_buff; //将显示缓冲区数据送到PORTC口
PORTD&=~(1<<(i+4)); //显示第i位
delay_ms(1);
PORTD|=0xf0;
}
}
void adc_init(void) //ADC初始化
{
DDRA=0x00; //设置为高阻态输入
PORTA=0x00;
ADCSRA=0x00;
ADMUX=0xC0|(1<<ADLAR); //2.56v 片内基准电压 /select adc input 0 /
ACSR=(1<<ACD); //关闭模拟比较器
ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1); //64分频
}
#pragma interrupt_handler adc_isr:15 //ADC完成中断
void adc_isr(void)
{
adc_rel=ADC&0x3ff; //读取ADC结果
ADMUX=0xC0|(1<<ADLAR); //2.56v 片内基准电压 /select adc input 0 /
ADCSRA|=(1<<ADSC); //启动AD转换
}
void ADCtoBCD(unsigned int temp) //ADC结果转换成电压值
{
unsigned char i;
temp=(unsigned int)(((unsigned long)((unsigned long)temp*Vref))/0x3ff);
for(i=0;i<4;i++) //刷新LED缓冲区
{
led_buff=seg_table[temp%10];
temp=temp/10;
}
led_buff[2]&=0x7f; //设置小数点
}
//main()
void main(void)
{
unsigned char i;
unsigned int adc_old;
DDRD=0xf0;
PORTD=0xff;
OSCCAL=osccal; //校正内部RC振荡频率
adc_mux=0; //设置为0通道
adc_init(); //ADC初始化
SEI(); //打开全局中断允许位
for(i=0;i<4;i++) //复位后显示一段时间8888
led_buff=seg_table[8];
for(i=0;i<200;i++)
display();
adc_old=0;
adc_rel=0;
while(1)
{
if(adc_old!=adc_rel) //如果AD转换的结果有改变,则刷新显示缓冲区
{
adc_old=adc_rel;
ADCtoBCD(adc_old);
}
display();
i=PIND&0x0c; //读取按键状态
if(i!=0x0c) //判断按键
{
display(); //按键消抖,用显示函数代延时函数
if(i==(PIND&0x0c))
{
CLI(); //关闭全局中断
adc_rel=0;
adc_old=0;
if(i==0x08) //INT0键按下
{
if(adc_mux<3)
adc_mux++; //ADC通道递增
else
adc_mux=0;
}
if(i==0x04) //INT1键按下
{
if(adc_mux>0)
adc_mux--; //ADC通道递减
else
adc_mux=3;
}
led_buff[0]=seg_table[adc_mux]; //显示ADC通道号码
led_buff[1]=0xbf; //-
led_buff[2]=0b10001001; //h
led_buff[3]=0b11000110; //c
while((PIND&0x0c)!=0x0c); //检查按键释放
display();
SEI(); 开放全局中断
}
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|