|
话不多说,程序如下:
/*系统时钟采用内部8M时钟,编译环境为GCC*/
#include <avr/io.h>
#include <avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define SegAddrPort PORTD //数码管位选接口
#define SegDataPort PORTC //数码管端选接口
#define GPInterruptON() (SREG |= (1 << 7))
#define GPInterruptOFF() (SREG &= ~(1 << 7))
#define ADCON() (ADCSRA |= (1 << ADEN))
#define ADCOFF() (ADCSRA &= ~(1 << ADEN))
const uchar SegTab[] = {0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};
enum Row
{Row0 = 0,Row1,Row2,Row3,Row4,Row5,Row6,Row7}; //定义8个输入通道
enum Row CurrentRow,NextRow;
uchar ShowRow;
uchar ScanCnt;
uint ADCData[8];
void GPIOInit(void);
void Timer0Init(void);
void INT0Init(void);
void ADCInit(void);
void DisplayData(void);
void SystemRun(void);
int main(void)
{
GPIOInit();
Timer0Init();
INT0Init();
ADCInit();
GPInterruptON();
while(1)
{
SystemRun();
}
}
void GPIOInit(void) //IO口初始化函数
{
DDRA = 0X00;
PORTA = 0X00;
DDRB = 0XFF;
PORTB = 0X00;
DDRC = 0XFF;
PORTC = 0X00;
DDRD |= 0XF0;
PORTD &= 0X0F;
}
void Timer0Init(void) //定时器0初始化函数
{
OCR0 = 0XF9; //比较TOP值
TIMSK |= 0X02; //开中断
TCCR0 = 0X0B; //CTC模式,64分频
}
void INT0Init(void) //外部中断0初始化函数,下降沿触发
{
MCUCR |= 0X02; //下降沿触发
GICR |= 0X40; //开中断
}
void ADCInit(void) //ADC初始化函数
{
ADMUX = 0X40; //参考电压为AVCC=5V,转换结果默认右对齐
ADCSRA = 0XEE; //ADC时钟源为8M/64=125K
SFIOR = 0X60; //ADC的转换触发源选择定时器0比较匹配
}
void DisplayData(void) //数码管显示函数
{
uint ADCDataTemp;
ADCDataTemp = ADCData[ShowRow];
if((ADCDataTemp % 10) >= 5) //转换结果4舍5入,精度为0.01
ADCDataTemp = ADCDataTemp / 10 +1;
else
ADCDataTemp = ADCDataTemp / 10;
switch(ScanCnt)
{
case 0: SegAddrPort = (1 << 4);
SegDataPort = SegTab[ShowRow]; //显示通道号,为0--7
break;
case 1: SegAddrPort = (1 << 5);
SegDataPort = SegTab[ADCDataTemp / 100] & 0X7F; //显示个位及小数点
break;
case 2: SegAddrPort = (1 << 6);
SegDataPort = SegTab[(ADCDataTemp % 100) / 10]; //显示十分位
break;
case 3: SegAddrPort = (1 << 7);
SegDataPort = SegTab[ADCDataTemp % 10]; //显示百分位
break;
}
}
void SystemRun(void)
{
switch(CurrentRow)
{
case Row0: NextRow = Row1;
break;
case Row1: NextRow = Row2;
break;
case Row2: NextRow = Row3;
break;
case Row3: NextRow = Row4;
break;
case Row4: NextRow = Row5;
break;
case Row5: NextRow = Row6;
break;
case Row6: NextRow = Row7;
break;
case Row7: NextRow = Row0;
break;
}
DisplayData();
}
ISR(TIMER0_COMP_vect) //定时器0,2ms比较匹配中断函数,产生数码管的扫描信号
{
if(ScanCnt >= 3)
ScanCnt = 0;
else
ScanCnt ++;
}
ISR(INT0_vect) //外部中断0函数,切换显示值
{
if(ShowRow >= 7)
ShowRow = 0;
else
ShowRow ++;
}
ISR(ADC_vect) //ADC转换完成中断函数,读取转换值,更新输入通道
{
ADCOFF();
ADCData[CurrentRow] = ADC * 4.883;
ADMUX = ((ADMUX & 0XE0) | NextRow);
CurrentRow = NextRow;
ADCON();
}
![](http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_606958G5PE0B.jpg)
仿真图 (原文件名:ADC.jpg) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|