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 }