Sunteți pe pagina 1din 5

Computer Systems Engineering 3 (EEET2096) Lab 10 James OShannessy S3237461

Preliminary 1) For the ARM System Tick, what is the value in the LOAD Register to give a tick every 100us. State any Assumptions. Assuming we know a clock speed of 8MHz, a value of 800 in the LOAD Register will give a tick every 100us. 2) How must the control register of the system tick be initialised to generate an interrupt? SysTick->LOAD = 800; // Gives a system tick of 100us. SysTick->VAL = 0x3fff; // Any value resets SysTick->CTRL = 4; // Use AHB clock SysTick->CTRL |=2; // Enables the System Tick Interrupts SysTick->CTRL |=1; // Enables the System Tick 3) Briefly explain the difference between the integer operations. The value of X/4096 could generate a decimal remainder, at which point it is discarded before multiplying by Z. (Y=(X/4096)*Z) In the second equation, X and Z are multiplied, before dividing by 4096, which would have the final remainder discarded at the end. (Y=(X*Z)/4096) The second equation is more accurate, and loses less information in the end result. Procedure 1) Create a routine that will be called for the SysemTickISR. Using the default name of SysTick_Handler will work for us here too. //Initialise LEDs RCC->APB2ENR |= 1<<6; GPIOE->CRH = 0x33333333; //configure port E - o/p to LEDs //configure interrupt void InterruptConfig(){ SysTick->LOAD = 90; //will give 1ms from 8Mhz AHB SysTick->VAL = 0x3fff; //any value resets SysTick->CTRL = 4; //Use AHB clock SysTick->CTRL |=2; // enable system tick interrupts SysTick->CTRL |=1; // enable tick } void SysTick_Handler(){ GPIOE->ODR ^= 0xFF00; //toggle LEDs ready = 1; } 2)

RMIT University

Document: 64830417.doc Author: Jidong Wang Save Date: 12/06/2011 Page 1 of 5

3) I initialised the array on startup of the program. Initially, I had the value being calculated and sent to the DAC all in the step routine. However, the time it takes to calculate this alters the results quite dramatically. The frequency of the wave is reduced to approximately 50Hz. Much under what was measured when calculating the values to an array, then using that array as a reference in the step program. See appendix for full implementation. int myRound(double value){ if(value-floor(value)>=ceil(value)-value) return ceil(value); else return floor(value); } int main(){ ... int array[72]; int count =0; for(i=0;i<360;i+=5){ array[count]=myRound((cos(i*(PI/180))*2047)+2048); count++; } 4) The MSO was used to measure the sine wave of the SystemTick. Questions 1) Ready is declared as a volatile variable so that it is not optimized during compilation of the code. If it is not declared this way, the compiler will attempt to optimize it, possibly making it a final variable, and it then cannot be changed. 2) The highest frequency of the wave that could be generated using a SystemTick was 1.215KHz. This was when the LOAD was at the lowest value that still generated a non-distorted sine wave. 3) The system falls over at a LOAD value of approximately 90. I determine this by checking that the lengths of each step. When the step sizes are no longer the same length, I say the system has failed.

RMIT University

Document: 64830417.doc Author: Jidong Wang Save Date: 12/06/2011 Page 2 of 5

Report The SystemTick Interrupt is generated each time the LOAD register has reached 0x00. When this SystemTick register reaches 0, it is reloaded with the LOAD value. I use a loop in the initialisation to setup the array of values from 0 to 4095. This could have been hardcoded in, but it allowed me to have a varying range of values to use. I could change the step, change the range. If the value is negative, it is not able to be converted. This was found when the addition of 4096 was forgotten, and it was only generating half a sine wave.

RMIT University

Document: 64830417.doc Author: Jidong Wang Save Date: 12/06/2011 Page 3 of 5

Appendix Code #include <stm32f10x_cl.h> #include <math.h> #define PI 3.14159265 volatile int ready; void SysTick_Handler(){ GPIOE->ODR ^= 0xFF00; //turn LEDs off ready = 1; } void DAC_GPIO_Config(void){ //prelim 2 & 3 RCC->APB1ENR |= (1<<29); // enable peripheral clock for DAC1 RCC->APB2ENR |= 1; // enable peripheral clock to AFs RCC->APB2ENR |= 1<<2; // enable peripheral clock to GPIOA GPIOA->CRL &= ~0x000F0000; // set PIN4 as analog input DAC->CR |= 1; // } void LEDInit(){ //configure port E - o/p to LEDs } void InterruptConfig(){ SysTick->LOAD = 90; //will give 1ms from 8Mhz AHB SysTick->VAL = 0x3fff; //any value resets SysTick->CTRL = 4; //Use AHB clock SysTick->CTRL |=2; // enable system tick interrupts SysTick->CTRL |=1; // enable tick } void DAC_Config(){ // prelim 4 DAC->CR |= 7<<3; DAC->CR |= 1<<2; } void step(int v){ ready =0; //GPIOE->ODR = 0x0000; //turn LEDs off // load holding register and trigger DAC DAC->DHR12R1 = v; DAC->SWTRIGR |= 1; //software trigger while (DAC->SWTRIGR & 1); //check that last data gone increment data pointer } int myRound(double value){ if(value-floor(value)>=ceil(value)-value) return ceil(value); else return floor(value); } int main(void){ int i, count; int array[72];
Document: 64830417.doc Author: Jidong Wang Save Date: 12/06/2011 Page 4 of 5

RCC->APB2ENR |= 0x40; GPIOE->CRH = 0x33333333;

RMIT University

LEDInit(); DAC_GPIO_Config(); DAC_Config(); InterruptConfig(); GPIOE->ODR = 0x0000; //turn LEDs off //valueStep=1; //v=0; count =0; for(i=0;i<360;i+=5){ array[count]=myRound((cos(i*(PI/180))*2047)+2048); count++; } count=0; while(1){ if(ready){ step(array[count]); count=(count+1)%72; } } }

RMIT University

Document: 64830417.doc Author: Jidong Wang Save Date: 12/06/2011 Page 5 of 5

S-ar putea să vă placă și