Hallo, ich möchte gerne die Position eines Motors mittels HCTL-2022 auf einen AVR32 auslesen. Dazu habe ich eine Funktion geschrieben die den Wert aus dem HCTL-2022 ausliest. Diese wird in einem Task (freeRTOS) alle 5ms aufgerufen, und der Aufruf befindet sich in einer "critical section". Jedoch habe ich beim auslesen höchstwahrscheinlich ein Timing Problem. Der HCTL-2022 reseted sich manchmal von selbst. Also die Funktion liefert mir manchmal Werte bis ca 30, dann beginnt es wieder bei 0, manchmal wird aber auch nur bis 3 gezählt. Hat jemand eine Ahnung warum dies ist? Handbuch Motor: http://www.faulhaber.com/uploadpk/DE_2619_SR_IE2-16_DFF.pdf Handbuch HCTL-2022: http://www.avagotech.com/docs/AV02-0096EN AVR32: AT32UC3A0512 mit 60MHz getaktet. Code von Task:
1 | void vMotorPosTask( void * pvParameters ) { |
2 | |
3 | // Initialize the xLastWakeTime variable with the current time.
|
4 | portTickType xLastWakeTime = xTaskGetTickCount(); |
5 | |
6 | |
7 | |
8 | for( ;; ) { |
9 | taskENTER_CRITICAL(); |
10 | pos = HCTL2022_get_position(); |
11 | |
12 | if (pos != motor[0].position) { |
13 | |
14 | // save the last element (pointer)
|
15 | struct Motor last = motor[MOTOR_BUFFER_LENGTH-1]; |
16 | |
17 | for (int i = MOTOR_BUFFER_LENGTH-1; i>0; i--) { |
18 | motor[i] = motor[i-1]; |
19 | }
|
20 | |
21 | // set the pointer of the last element to the first element => ring buffer
|
22 | motor[0] = last; |
23 | |
24 | motor[0].time = time; |
25 | timeDiff = time - motor[1].time; |
26 | motor[0].position = pos; |
27 | motor[0].velocity = ((motor[0].position - motor[1].position) * 2*M_PI / DECODER_PULSE_PER_ROUND) * 1000 / timeDiff; |
28 | motor[0].acceleration = (motor[0].velocity - motor[1].velocity) * 1000 / timeDiff; |
29 | |
30 | }
|
31 | taskEXIT_CRITICAL(); |
32 | |
33 | time += MOTOR_POSITION_DELAY_TIME_MS; |
34 | // Wait for the next cycle.
|
35 | |
36 | vTaskDelayUntil( &xLastWakeTime, MOTOR_POSITION_DELAY_TICKS); |
37 | }
|
38 | }
|
Code vom auslesen des HCTL-2022:
1 | inline uint32_t HCTL2022_read_data_byte( void ) { |
2 | return AVR32_GPIO.port[HCTL2022_DATA_PORT].pvr & HCTL2022_DATA_MASK; |
3 | }
|
4 | |
5 | |
6 | // ************************************************
|
7 | // Read-out current position
|
8 | // Precaution: Init_ and Reset_ have been invoked
|
9 | // Status: (Beginning and end) -RST = High; -OE = High; SEL1 = Low; SEL2 = High
|
10 | // ************************************************
|
11 | int32_t HCTL2022_get_position ( void ) { |
12 | uint32_t temp; |
13 | uint32_t pos; |
14 | |
15 | // -OE = High; SEL2 = High; SEL1 = Low
|
16 | // Set -OE = Low (Inhibit=1)
|
17 | gpio_set_pin_low(HCTL2022_OE_N); |
18 | |
19 | // Do nothing - Delay time, SEL1~SEL2 (tSDV) = 29 ns
|
20 | asm("nop"); |
21 | asm("nop"); |
22 | |
23 | // Read byte 4
|
24 | pos = HCTL2022_read_data_byte(); |
25 | |
26 | // -OE = Low; SEL2 = High; SEL1 = High
|
27 | gpio_set_pin_high(HCTL2022_SEL1); |
28 | |
29 | |
30 | // Read byte 3
|
31 | temp = HCTL2022_read_data_byte(); |
32 | |
33 | // -OE = Low; SEL2 = Low; SEL1 = Low
|
34 | gpio_set_pin_low(HCTL2022_SEL1); |
35 | gpio_set_pin_low(HCTL2022_SEL2); |
36 | |
37 | // [ Byte 4 ] or ( Byte 3 >> 8 )
|
38 | pos |= ( temp >> 8 ); |
39 | |
40 | // Read byte 2
|
41 | temp = HCTL2022_read_data_byte(); |
42 | |
43 | |
44 | // -OE = Low; SEL2 = Low; SEL1 = High
|
45 | gpio_set_pin_high(HCTL2022_SEL1); |
46 | pos |= ( temp >> 16 ); |
47 | asm("nop"); |
48 | |
49 | // Read byte 1
|
50 | temp = HCTL2022_read_data_byte(); |
51 | // [ Byte 4 or ( Byte 3 >> 8 ) or ( Byte 2 >> 16 ) ] or ( Byte 1 >> 24 )
|
52 | pos |= ( temp >> 24 ); |
53 | |
54 | |
55 | // -OE = High; SEL2 = High (Inhibit=0)
|
56 | gpio_set_pin_high(HCTL2022_OE_N); |
57 | gpio_set_pin_high(HCTL2022_SEL2); |
58 | // SEL1 = Low
|
59 | gpio_set_pin_low(HCTL2022_SEL1); |
60 | return pos; |
61 | }
|
godi