Hallo erstmal,
Programmierung:
Gcc, AVR Studio, Prozessor ATmega644P
Ziel:
Die Temperatur wird über einen KTY10 eingelesen und soll nun auf den 7
Segmentanzeigen ausgegeben werden.
Den ADC hab ich zuerst alleine ohne Ausgabe geteste: Er gibt die ADC
werte richtig aus (HTerm, UART). Nun wollte ich die drei 7 Segmente dazu
schalten und einfach mal bis 999 zählen lassen umzu kontrolliern ob mein
multiplexing Programm funktioniert. Jedoch tritt hier der Fehler auf:
Compeliern funktioniert wunderbar, jedoch sieht es soaus als würden die
7 Sgmente nun zu wenig Spannung bekommen (?), bzw. es leuchtet nur eines
sehr schwach.
Wenn ich den ADC Init auskommentiere lauft das Programm wieder wunderbar
(7-Segmente zählen bis 999).
An was kann das liegen?
wäre um jede Hilfe sehr dankbar :)
mfg Dominik
1 | #include <avr/io.h>
|
2 | #include <stdint.h>
|
3 | #include <stdlib.h>
|
4 | #include <util/delay.h>
|
5 | #include <avr/interrupt.h>
|
6 | #include <stdio.h>
|
7 |
|
8 | //#include "uart.h"
|
9 | #include "multiplexen.h"
|
10 |
|
11 | uint8_t ADCwert; //globale Variable für ADC wert
|
12 | int i, k, l;
|
13 | void init_Port()
|
14 | {
|
15 | DISPLAY_DDR= 0xFF;
|
16 | SEGMENTS_DDR=0xFF;
|
17 | DISPLAY_PORT=0x00;
|
18 | SEGMENTS_PORT=0x00;
|
19 |
|
20 | }
|
21 |
|
22 | void init_timerA()
|
23 | {
|
24 | TCCR1B |= (1<<WGM12); //CTC mode
|
25 | TCCR1B |= (1<<CS12); // Prescaler - 256 - 62500
|
26 |
|
27 | TIMSK1 |= (1<<OCIE1A);
|
28 | OCR1A = 625; // 16e6/256/1000
|
29 | }
|
30 |
|
31 | void init_timerB()
|
32 | {
|
33 |
|
34 | TCCR2B |= (1<<CS22); //Prescaler 64
|
35 |
|
36 | TIMSK2 |= (1<<TOIE2); //Overflow enable
|
37 | }
|
38 |
|
39 | ISR (TIMER1_COMPA_vect){
|
40 |
|
41 | i++;
|
42 |
|
43 | if(i==1000) i=0;
|
44 |
|
45 | if(i<10)
|
46 | {
|
47 | display_array[0] = i%10;
|
48 | }
|
49 | else if(i>=10 && i<100)
|
50 | {
|
51 | display_array[0] = i%10;
|
52 | display_array[1] = (i%100-i%10)/10; // z.B:
|
53 | }
|
54 | else if(i>=100 && i<1000){
|
55 | display_array[0] = i%10;
|
56 | display_array[1] = (i%100-i%10)/10;
|
57 | display_array[2] = (i%1000-i%100)/100;
|
58 | }
|
59 | else
|
60 | {
|
61 | display_array[0]=0;
|
62 | display_array[1]=0;
|
63 | display_array[2]=0;
|
64 | }
|
65 |
|
66 | }
|
67 |
|
68 | ISR(TIMER2_OVF_vect){
|
69 | refresh_display();
|
70 | }
|
71 |
|
72 | void inti_ADC()
|
73 | {
|
74 | int result; //dient zur Aufwährmung des ADC
|
75 |
|
76 | ADMUX |= (1<<REFS0);
|
77 | ADMUX &= ~ (1<<REFS1); //AVCC wird als Reference eingestellt
|
78 |
|
79 | ADCSRA |= (1<<ADEN); //ADC wird Enabled, kann verwendet werden
|
80 | ADCSRA |= (1<<ADSC); // ADC Start Conversation,
|
81 | //ADCSRA |= (1<<ADATE); //Der ADC arbeitet im FreeRunning Mode,
|
82 | ADCSRA |= (1<<ADIE); //ADC-Interrupt aktiviert
|
83 | ADCSRA |= ((1<<ADPS0) | (1<<ADPS2) | (1<<ADPS1)); //Prescaler 128
|
84 |
|
85 | while ( ADCSRA & (1<<ADSC) ) {}// auf Abschluss der Konvertierung warten}
|
86 | result = ADCW; // ADCW muss einmal gelesen werden,
|
87 | // sonst wird Ergebnis der nächsten Wandlung
|
88 | // nicht übernommen.
|
89 | }
|
90 |
|
91 | uint8_t read_wert(uint8_t channel)
|
92 | {
|
93 | // Kanal waehlen, ohne andere Bits zu beeinflußen
|
94 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
|
95 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
|
96 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
97 | return ADCW; // ADC auslesen und zurückgeben
|
98 | // adc_wert = ADCW;
|
99 | }
|
100 |
|
101 | int main(void)
|
102 | {
|
103 | init_Port();
|
104 | init_timerA();
|
105 | init_timerB();
|
106 | inti_ADC();
|
107 | //uart_init();
|
108 | init_Port();
|
109 |
|
110 | DDRA &=~(1<<PA0); //Input ADC - Temp.Sensor
|
111 |
|
112 | //**************************Varbialen************************************
|
113 | char text [] = "ADC-WERT:_";
|
114 | char wert[20];
|
115 |
|
116 | sei();
|
117 |
|
118 | while(1)
|
119 | {
|
120 | ADCwert = read_wert(0);
|
121 | /*
|
122 | for (i=0;text[i];i++)
|
123 | uart_putchar(text[i]);
|
124 |
|
125 | sprintf (wert, "%3.1d",ADCwert);
|
126 |
|
127 | for (i=0; wert[i];i++)
|
128 | uart_putchar(wert[i]);
|
129 |
|
130 | _delay_ms(1000);
|
131 |
|
132 | //TODO:: Please write your application code
|
133 | */
|
134 | int p=0;
|
135 | p++;
|
136 | }
|
137 | }
|
*****************************************************
multiplexen.h
*****************************************************
1 | #ifndef MULTIPLEXEN_H_
|
2 | #define MULTIPLEXEN_H_
|
3 |
|
4 |
|
5 | unsigned int display_array[3];
|
6 |
|
7 | #define SEGMENTS_DDR DDRB
|
8 | #define SEGMENTS_PORT PORTB
|
9 | #define DISPLAY_DDR DDRD
|
10 | #define DISPLAY_PORT PORTD
|
11 |
|
12 | //****************************_Init_7_Segment_*****************************
|
13 | #define a 0b00000001
|
14 | #define b 0b00000010
|
15 | #define c 0b00000100
|
16 | #define d 0b00001000
|
17 | #define e 0b00010000
|
18 | #define f 0b00100000
|
19 | #define g 0b01000000
|
20 | #define dp 0b10000000
|
21 |
|
22 | #define NULL a|b|c|d|e|f
|
23 | #define EINS b|c
|
24 | #define ZWEI a|b|g|e|d
|
25 | #define DREI a|b|c|d|g
|
26 | #define VIER b|c|f|g
|
27 | #define FUENF a|f|g|c|d
|
28 | #define SECHS a|f|g|e|d|c
|
29 | #define SIEBEN a|b|c
|
30 | #define ACHT a|b|c|d|e|f|g
|
31 | #define NEUN a|b|c|d|f|g
|
32 |
|
33 | //***************************_Init_von_2_Segmente_**************************
|
34 | #define EINER 0b00000001
|
35 | #define ZEHNER 0b00000010
|
36 | #define HUNDERTER 0b00000100
|
37 |
|
38 |
|
39 | void refresh_display();
|
40 |
|
41 |
|
42 |
|
43 |
|
44 | #endif /* MULTIPLEXEN_H_ */
|
***************************************************
multiplexen.c
**************************************************
1 | #include <avr/io.h>
|
2 | #include "multiplexen.h";
|
3 |
|
4 |
|
5 | unsigned int cnt=0;
|
6 |
|
7 | void refresh_display(){
|
8 |
|
9 | //Display disable
|
10 | DISPLAY_PORT = 0x00;
|
11 | SEGMENTS_PORT= 0x00;
|
12 |
|
13 | switch (display_array[cnt]) {
|
14 | case 0: SEGMENTS_PORT |= NULL; break;
|
15 | case 1: SEGMENTS_PORT |= EINS; break;
|
16 | case 2: SEGMENTS_PORT |= ZWEI; break;
|
17 | case 3: SEGMENTS_PORT |= DREI; break;
|
18 | case 4: SEGMENTS_PORT |= VIER; break;
|
19 | case 5: SEGMENTS_PORT |= FUENF; break;
|
20 | case 6: SEGMENTS_PORT |= SECHS; break;
|
21 | case 7: SEGMENTS_PORT |= SIEBEN; break;
|
22 | case 8: SEGMENTS_PORT |= ACHT; break;
|
23 | case 9: SEGMENTS_PORT |= NEUN; break;
|
24 | }
|
25 | switch (cnt) {
|
26 | case 0: DISPLAY_PORT |= EINER; break; //Zuschalten der jeweiligen Anzeige
|
27 | case 1: DISPLAY_PORT |= ZEHNER; break;
|
28 | case 2: DISPLAY_PORT |= HUNDERTER; break;
|
29 | }
|
30 | cnt++; //steter Wechsel zwischen Anzeigen
|
31 | if (cnt == 3)
|
32 | cnt = 0;
|
33 | }
|