AVR--ATMega16A__将ADC数值显示在数码管上

1.数码管显示原理: http://m.elecfans.com/article/1088588.html 

LED的发光原理,稍有电子技术基础的人士都很清楚,我们不想作过多的介绍,七段LED数码管,则在一定形状的绝缘材料上,

利用单只LED组合排列成“8”字型的数码管,分别引出它们的电极,点亮相应的点划来显示出0-9的数字。

LED数码管根据LED的接法不同分为共阴和共阳两类,了解LED的这些特性,对编程是很重要的,因为不同类型的数码管,

除了它们的硬件电路有差异外,编程方法也是不同的。右图是共阴和共阳极数码管的内部电路,它们的发光原理是一样的,

只是它们的电源极性不同而已。将多只LED的阴极连在一起即为共阴式,而将多只LED的阳极连在一起即为共阳式。以共

阴式为例,如把阴极接地,在相应段的阳极接上正电源,该段即会发光。当然,LED的电流通常较小,一般均需在回路中

接上限流电阻。假如我们将“b”和“c”段接上正电源,其它端接地或悬空,那么“b”和“c”段发光,此时,数码管显示将显示数

字“1”。而将“a”、“b”、“d”、“e”和“g”段都接上正电源,其它引脚悬空,此时数码管将显示“2”。其它字符的显示原理类同,

读者自行分析即可。

2. 数码管的静态显示与动态显示

 3.硬件原理图:

 由原理图可以看出:

数码管采用动态扫描方式,ADC的精度是10Bit,数码管只用到前4个,显示0~1023

ADC管脚为PA7,外接电位器,如下图,跳帽插上后。可以通过调节电位器来改变PA7上的采集电压。

 4.软件的实现:

  1 #include <avr/io.h>
  2 #include <avr/interrupt.h>
  3 #define F_CPU  8000000UL
  4 
  5 #include <util/delay.h>
  6 #include <stdio.h>
  7 //bit definition
  8 #define BIT0    0x01
  9 #define BIT1    0x02
 10 #define BIT2    0x04
 11 #define BIT3    0x08
 12 #define BIT4    0x10
 13 #define BIT5    0x20
 14 #define BIT6    0x40
 15 #define BIT7    0x80
 16 
 17 #define FALSE    0
 18 #define TRUE    1
 19 
 20 //bit operation
 21 #define BIT(X)            (1<<X)
 22 #define SETBIT(x,y)        (x |= (y))
 23 #define CLEARBIT(x,y)    (x &= (~y))
 24 #define CHECKBIT(x,y)    (x & y)
 25 
 26 //function 
 27 unsigned int read_adc_val(void);
 28 void adc_to_disbuffer(unsigned int adc);
 29 void display(void);
 30 void display_seg(unsigned char num, unsigned char wei);
 31 
 32 //Numeric Display
 33 unsigned char  dis[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};  //0~9  BCD code
 34 const unsigned char sec[8] ={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
 35 unsigned char dis_buff[4] = {0};
 36 unsigned char ptr,i;
 37 volatile unsigned int cnt, adc_val;
 38 unsigned int  flag = 0;
 39 int main(void)
 40 {
 41     //Display ADC value on 7-section digital tube
 42     
 43     //1.GPIO initialize
 44     DDRA = 0x7F;   //set PA7 input  ,PA0~PA6 output
 45     DDRC = 0xFF;   //set PCx output
 46     PORTA = 0x7F;  //set PA7 tri-state ,PA0~PA6 output 1
 47     
 48     //2.ADC initialize
 49     ADMUX = 0x07;  //select ADC channel 7 (PA7)  MUX4:0 --> 00111 
 50     ADMUX &= (~BIT7);
 51     ADMUX &= (~BIT6);                //REFS0: 0 REFS1: 0 AREF, Internal VREF turned off
 52     //SFIOR |= (0<<ADTS0) | (0<<ADTS1) | (0<<ADTS2);  //default :Free running mode  ADTS[0:2]= 0;
 53     ADCSRA |= (1<< ADEN) ;            //Enable ADC module
 54     ADCSRA |= (1<< ADPS2);            //Enable ADC with clock prescaled by 16   8M/16 = 500KHZ
 55     ADCSRA |= (1<< ADSC);            //Start a single convert
 56     
 57     //3.TIMER0 initialize
 58     TCCR0 = (0 << WGM01) | (0 << WGM00); //8bit Timer0 Normal mode
 59     TCCR0 |= (1<< CS02);     //clock by 256   8M/256 = 31.25khz  cycle : 32us
 60     TCNT0 = 0X64;                         //5ms --> 5000/32 = 156.25  TCNT0 = 100;
 61     TIMSK = (1<< TOIE0);                //Overflow interrupt enable
 62     
 63     sei();                                //enable global interrupt
 64     
 65     while (1) 
 66     {
 67         if(cnt == 60)                    //sample ADC vale every 300ms,lock the data to display
 68         {
 69             adc_val = read_adc_val();
 70             adc_to_disbuffer(adc_val);
 71             cnt = 0;
 72         }
 73         display();
 74     }
 75 }
 76 
 77 
 78 ISR(TIMER0_OVF_vect)
 79 {
 80     TCNT0 = 0x64;                //reload the TCNT0 initial val
 81     cnt++;
 82 }
 83 
 84 
 85 unsigned int read_adc_val(void)
 86 {
 87     unsigned int adc_result;
 88     while(!(ADCSRA & (1<<ADIF)));
 89     
 90     adc_result = ADCL;
 91     adc_result |= (unsigned int)ADCH << 8;
 92     ADCSRA |= (1 << ADIF);          // clean interrupt flag
 93     ADCSRA |= (1 << ADSC);            // Start the conversion
 94     return adc_result;
 95 }
 96 
 97 
 98 void adc_to_disbuffer(unsigned int adc)
 99 {
100     unsigned char i;
101     for(i = 0; i <=3; i++)
102     {
103         dis_buff[i] = adc % 10;
104         adc /= 10; 
105     }
106     
107 }
108 
109 void display(void)
110 {
111     for(ptr = 0; ptr < 4; ptr++)
112     {
113         display_seg(dis_buff[ptr], ptr);
114         _delay_ms(1);            
115     }
116     PORTC = 0xFF;
117 
118 }
119 
120 
121 
122 
123 void display_seg(unsigned char num, unsigned char wei)
124 {
125     
126     switch(wei)
127     {
128         case 0: PORTC = ~sec[0]; break;
129         case 1: PORTC = ~sec[1]; break;
130         case 2: PORTC = ~sec[2]; break;
131         case 3: PORTC = ~sec[3]; break;
132         case 4: PORTC = ~sec[4]; break;
133         case 5: PORTC = ~sec[5]; break;
134         case 6: PORTC = ~sec[6]; break;
135         case 7: PORTC = ~sec[7]; break;
136         case 8: PORTC = ~sec[8]; break;
137         case 9: PORTC = ~sec[9]; break;
138         default : break;
139     }
140     
141     switch(num)
142     {
143         case 0:PORTA = dis[0];break;
144         case 1:PORTA = dis[1];break;
145         case 2:PORTA = dis[2];break;
146         case 3:PORTA = dis[3];break;
147         case 4:PORTA = dis[4];break;
148         case 5:PORTA = dis[5];break;
149         case 6:PORTA = dis[6];break;
150         case 7:PORTA = dis[7];break;
151         case 8:PORTA = dis[8];break;
152         case 9:PORTA = dis[9];break;
153         default : break;
154     }
155 }
View Code
原文地址:https://www.cnblogs.com/mickey-double/p/12411691.html