1 | #include <avr/interrupt.h>
|
2 | #include <avr/pgmspace.h>
|
3 | #include <stdarg.h>
|
4 | #include <ctype.h>
|
5 | #include <string.h>
|
6 | #include <stdlib.h>
|
7 | #include <avr/io.h>
|
8 | #include <util/delay.h>
|
9 |
|
10 | #define DDR_SCK DDRB /*!< DDR fuer Maus-SCLK */
|
11 | #define DDR_SDA DDRB /*!< DDR fuer Maus-SDA */
|
12 |
|
13 | #define PORT_SCK PORTB /*!< PORT fuer Maus-SCK */
|
14 | #define PORT_SDA PORTB /*!< PORT fuer Maus-SDA */
|
15 | #define PIN_SDA PINB /*!< PIN fuer Maus-SDA */
|
16 |
|
17 | #define SCK_PIN (1<<PB1) /*!< PIN nummer fuer Maus-SCK */
|
18 | #define SDA_PIN (1<<PB0) /*!< PIN nummer fuer Maus-SDA */
|
19 |
|
20 | #define ADNS_Produkt_ID 0x00
|
21 | #define ADNS_Revision_ID 0x01
|
22 | #define ADNS_Motion 0x02
|
23 | #define ADNS_DeltaX 0x03
|
24 | #define ADNS_DeltaY 0x04
|
25 | #define SQUAL 0x05
|
26 | #define ADNS_Average_Pixel 0x06
|
27 | #define ADNS_Maximum_Pixel 0x07
|
28 | #define ADNS_Configuration_bits 0x0a
|
29 | #define ADNS_Data_Out_Lower 0x0c
|
30 | #define ADNS_Data_Out_Upper 0x0d
|
31 | #define ADNS_Shutter_Lower 0x0e
|
32 | #define ADNS_Shutter_Upper 0x0f
|
33 | #define ADNS_Frame_Period_Lower 0x10
|
34 | #define ADNS_Frame_Period_Upper 0x11
|
35 |
|
36 |
|
37 | #define FOSC 3686400 // Clock Speed
|
38 | #define BAUD 9600
|
39 | #define UBRR_VAL FOSC/16/BAUD-1
|
40 |
|
41 | #define NOP asm volatile ("nop"::)
|
42 |
|
43 |
|
44 | void uart_init(void);
|
45 | int uart_putc(unsigned char);
|
46 | void uart_puts (char *s);
|
47 | void pan_writeByte(unsigned char);
|
48 | unsigned char pan_readByte(void);
|
49 | void pan_write(unsigned char, unsigned char);
|
50 | unsigned char pan_read(unsigned char);
|
51 | void pan_init(void);
|
52 |
|
53 | volatile uint8_t picture[324];
|
54 | volatile uint8_t temp;
|
55 |
|
56 |
|
57 | /* Start Hauptprogramm------------------------------------------------
|
58 | *
|
59 | -------------------------------------------------------------------*/
|
60 | int main (void)
|
61 | {
|
62 | char Buffer[20];
|
63 | uint8_t i=0;
|
64 | uint16_t framecounter=0;
|
65 | int8_t posx=0,posy=0;
|
66 |
|
67 |
|
68 | pan_init();
|
69 | _delay_ms(100);
|
70 | temp=pan_read(ADNS_Produkt_ID);
|
71 | _delay_ms(100);
|
72 | pan_write(ADNS_Configuration_bits,0b00000001);//LED an
|
73 |
|
74 | uart_init(); // USART initialisieren
|
75 | itoa(temp,Buffer,10);
|
76 | uart_puts(Buffer);
|
77 | i=0;
|
78 | uart_puts("\n\n\r");
|
79 | pan_write(ADNS_Configuration_bits,0b00001001);//Pixel Dump anfordern
|
80 | _delay_ms(100);
|
81 | for(framecounter=0;framecounter<255;)
|
82 | {
|
83 | temp=pan_read(ADNS_Data_Out_Upper);//Pixel Adresse lesen
|
84 | NOP;
|
85 | temp=pan_read(ADNS_Data_Out_Lower);//Pixel Daten lesen
|
86 | NOP;
|
87 | if(!(temp & (1<<7)))//Wenn dass MSB gesetzt ist die Daten nicht ausgeben
|
88 | {
|
89 | i++;
|
90 | picture[framecounter]=temp;
|
91 | NOP;
|
92 | itoa(picture[framecounter],Buffer,10);
|
93 | uart_puts(Buffer);
|
94 | uart_putc('\t');
|
95 | if(i==16)
|
96 | {
|
97 | NOP;
|
98 | uart_puts("\n\r");
|
99 | i=0;
|
100 | }
|
101 | framecounter++;
|
102 | }
|
103 |
|
104 | }
|
105 |
|
106 | return 0;
|
107 | }
|
108 |
|
109 |
|
110 |
|
111 | void uart_init(void)
|
112 | {
|
113 | UCSR0B |= (1<<RXEN0)|(1<<TXEN0); // UART RX, TX und RX Interrupt einschalten
|
114 | UBRR0H = (UBRR_VAL >> 8);
|
115 | UBRR0L = (UBRR_VAL & 0xFF);
|
116 | }
|
117 |
|
118 | // Eine Funktion zum Senden von Zeichen ber Seriellen Port
|
119 | int uart_putc(unsigned char c)
|
120 | {
|
121 | while (!(UCSR0A & (1<<UDRE0))) //warten bis Senden moeglich
|
122 | {
|
123 | }
|
124 |
|
125 | UDR0 = c; // sende Zeichen
|
126 | return 0;
|
127 | }
|
128 |
|
129 | /* puts ist unabhaengig vom Controllertyp */
|
130 | void uart_puts (char *s)
|
131 | {
|
132 | while (*s)
|
133 | { /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
|
134 | uart_putc(*s);
|
135 | s++;
|
136 | }
|
137 | }
|
138 |
|
139 | /*!
|
140 | * Uebertraegt ein Byte an den Sensor
|
141 | * @param data das Byte
|
142 | */
|
143 | void pan_writeByte(unsigned char data)
|
144 | {
|
145 | signed char i;
|
146 |
|
147 | DDR_SDA|= SDA_PIN; // SDA auf Output
|
148 |
|
149 | for (i=7; i>=0; i--){
|
150 |
|
151 | PORT_SCK &= ~SCK_PIN; //SCK auf Low, Daten vorbereiten
|
152 |
|
153 | if(data&(1<<i)){ //Bit rausschieben
|
154 | PORT_SDA|=SDA_PIN;
|
155 | }else{
|
156 | PORT_SDA&=~SDA_PIN;
|
157 | }
|
158 |
|
159 | PORT_SCK |= SCK_PIN; // SCK =1 Sensor uebernimmt auf steigender Flanke
|
160 |
|
161 | _delay_us(1); //Sensor Zeit lassen um Bit zu holen
|
162 | }
|
163 |
|
164 | DDR_SDA &=~ SDA_PIN; //HI-Z state
|
165 | PORT_SDA &=~ SDA_PIN;
|
166 |
|
167 | }
|
168 |
|
169 | /*!
|
170 | * Liest ein Byte vom Sensor
|
171 | * @return das Byte
|
172 | */
|
173 | unsigned char pan_readByte(void)
|
174 | {
|
175 | signed char i;
|
176 | unsigned char data=0;
|
177 |
|
178 | _delay_us(3); //Sensor Zeit lassen um die Daten aus dem Register zu holen
|
179 |
|
180 | for (i=7; i>-1; i--){
|
181 | PORT_SCK &= ~SCK_PIN; // SCK =0 Sensor bereitet Daten auf fallender Flanke vor !
|
182 |
|
183 | _delay_us(1); //Sensor kurz Zeit lassen
|
184 |
|
185 |
|
186 | PORT_SCK |= SCK_PIN; // SCK =1 Daten lesen auf steigender Flanke
|
187 |
|
188 | if(PIN_SDA&SDA_PIN){ //BIT einlesen
|
189 | data |= (1<<i);
|
190 | }else{
|
191 | data &=~ (1<<i);
|
192 | }
|
193 |
|
194 | }
|
195 | return data;
|
196 | }
|
197 |
|
198 | /*!
|
199 | * Uebertraegt ein write-Kommando an den Sensor
|
200 | * @param adr Adresse
|
201 | * @param data zu schreibendes byte
|
202 | */
|
203 | void pan_write(unsigned char adr, unsigned char data)
|
204 | {
|
205 | adr|=(1<<7);
|
206 | pan_writeByte(adr); //rl MSB muss 1 sein f�r Write Operation
|
207 | pan_writeByte(data);
|
208 | }
|
209 |
|
210 |
|
211 |
|
212 | /*!
|
213 | * Schickt ein Lesekommando an den Sensor
|
214 | * und liest ein Byte zurueck
|
215 | * @param adr die Adresse
|
216 | * @return der registerwert
|
217 | */
|
218 | unsigned char pan_read(unsigned char adr)
|
219 | {
|
220 |
|
221 | pan_writeByte(adr);
|
222 | return pan_readByte();
|
223 | }
|
224 |
|
225 |
|
226 | /*!
|
227 | * Initialisiere PAN3101
|
228 |
|
229 | !! Muss unbedingt ganz am ANFANG von main stehen, sonst gibts FEHLER !!
|
230 | (wenn der A2610 sich initialisiert hat, bevor der Controler SCK und
|
231 | SDA auf Output gestellt hat)
|
232 | Deshalb kann es auch sinnvoll sein die Powerup Zeit in den Config Bits
|
233 | auf 4ms zu stellen oder noch besser mit Boden zu arbeiten.
|
234 |
|
235 | */
|
236 | void pan_init(void)
|
237 | {
|
238 |
|
239 | DDR_SCK |= SCK_PIN; // SCK auf Output
|
240 | DDR_SDA |= SDA_PIN; //SDA auf Output
|
241 |
|
242 | PORT_SCK |= SCK_PIN; // SCK auf high
|
243 | PORT_SDA|= SDA_PIN; //SDA auf high
|
244 | }
|