Advertisement
Guest User

Untitled

a guest
May 20th, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.95 KB | None | 0 0
  1. #include "stm32f4xx.h"
  2. #include "system_stm32f4xx.h"
  3. #include "stdio.h"
  4. /**
  5. ******************************************************************************
  6. * @file Src/main.c
  7. * @author Hemant Nile
  8. * @version V1
  9. * @date 04-Feb-2017
  10. * @brief Simple implementation of accessing LIS3DSH accelerometer on STM32F4
  11. Discovery board using SPI interface. Four LEDs present on the board
  12. lit up when board is tilted in their direction.
  13.  
  14. ******************************************************************************
  15. */
  16.  
  17. int PLL_M = 8;
  18. int PLL_N = 336;
  19. int PLL_P = 2;
  20. int PLL_Q = 7;
  21. static void Configure_LEDS(void);
  22. static void Configure_SPI1(void);
  23. void SPI_Tx(uint8_t address, uint8_t data);
  24. uint8_t SPI_Rx(uint8_t address);
  25. void ResetPin(GPIO_TypeDef * GPIO, uint32_t pin);
  26. void SetPin(GPIO_TypeDef * GPIO, uint32_t pin);
  27. void SystemInit2(void);
  28.  
  29. int8_t x, y, z;
  30. int main(void)
  31. {
  32. SystemInit2();
  33.  
  34. // Configure peripherals
  35. Configure_LEDS();
  36. Configure_SPI1();
  37.  
  38. // Initiating accelerometer LIS3DSH
  39. SPI_Tx(0x20U, 0x67U); // CTRL_REG4: output data rate = 100Hz, continuous update, x,y,z enable
  40. SPI_Tx(0x24U, 0x48U); // CTRL_REG5: Anti-aliasing filter bandwidth=200Hz, full scale = 4g
  41.  
  42. // Infinite loop
  43. while (1)
  44. {
  45. x = SPI_Rx((uint8_t) 0x29U);
  46. y = SPI_Rx((uint8_t) 0x2BU);
  47. z = SPI_Rx((uint8_t) 0x2DU);
  48. if (x < -20) SetPin(GPIOD, GPIO_ODR_ODR_12);
  49. else ResetPin(GPIOD, GPIO_ODR_ODR_12);
  50. if (x > 20) SetPin(GPIOD, GPIO_ODR_ODR_14);
  51. else ResetPin(GPIOD, GPIO_ODR_ODR_14);
  52. if (y < -20) SetPin(GPIOD, GPIO_ODR_ODR_15);
  53. else ResetPin(GPIOD, GPIO_ODR_ODR_15);
  54. if (y > 20) SetPin(GPIOD, GPIO_ODR_ODR_13);
  55. else ResetPin(GPIOD, GPIO_ODR_ODR_13);
  56. }
  57. }
  58.  
  59. /**
  60. * System Clock Configuration
  61. * The system Clock is configured as follows in MAIN.H :
  62. *
  63. * System Clock source = PLL (HSE)
  64. * SYSCLK(Hz) = 168000000
  65. * HCLK(Hz) = 168000000
  66. * AHB Prescaler = 1
  67. * APB1 Prescaler = 4
  68. * APB2 Prescaler = 2
  69. * HSE Frequency(Hz) = 8000000
  70. * PLL_M = 8
  71. * PLL_N = 336
  72. * PLL_P = 2
  73. * PLL_Q = 7
  74. * VDD(V) = 3.3
  75. * Main regulator output voltage = Scale1 mode
  76. * Flash Latency(WS) = 5
  77. */
  78. void SystemInit2(void)
  79. {
  80. // FPU settings
  81. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  82. SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
  83. #endif
  84.  
  85. // Configure the Vector Table location add offset address
  86. #ifdef VECT_TAB_SRAM
  87. SCB->VTOR = SRAM_BASE; /* Vector Table Relocation in Internal SRAM */
  88. #else
  89. SCB->VTOR = FLASH_BASE; /* Vector Table Relocation in Internal FLASH */
  90. #endif
  91.  
  92. #define UNUSED(x) ((void)(x))
  93.  
  94. #define CLK_ENABLE(REGISTERWA, BITWA) do { \
  95. __IO uint32_t tmpreg = 0x00U; \
  96. SET_BIT(REGISTERWA, BITWA);\
  97. tmpreg = READ_BIT(REGISTERWA, BITWA);\
  98. UNUSED(tmpreg); \
  99. } while(0)
  100. // Enable PWR CLK and set voltage scale 1
  101. CLK_ENABLE(RCC->APB1ENR, RCC_APB1ENR_PWREN);
  102. SET_BIT(PWR->CR, PWR_CR_VOS);
  103.  
  104. // Flash latency, prefech, instruction cache , data cache
  105. MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_5WS);
  106. SET_BIT(FLASH->ACR, FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN);
  107.  
  108. // Enable HSE and wait for it
  109. SET_BIT(RCC->CR, RCC_CR_HSEON);
  110. while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RCC_CR_HSERDY)
  111. {
  112. }
  113.  
  114. WRITE_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC_HSE | PLL_M | PLL_N << 6 | ((PLL_P >> 1U) - 1U) << 16 | PLL_Q << 24);
  115. // Enable PLL and wait for it
  116. SET_BIT(RCC->CR, RCC_CR_PLLON);
  117. while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RCC_CR_PLLRDY)
  118. {
  119. }
  120. #define AHB_PRE RCC_CFGR_HPRE_DIV1
  121. #define APB1_PRE RCC_CFGR_PPRE1_DIV4
  122. #define APB2_PRE RCC_CFGR_PPRE2_DIV2
  123. MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2 | RCC_CFGR_PPRE1 | RCC_CFGR_HPRE | RCC_CFGR_SW_PLL,
  124. APB2_PRE | APB1_PRE | AHB_PRE | RCC_CFGR_SW_PLL);
  125. while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
  126. {
  127. }
  128. // Disable HSI
  129. CLEAR_BIT(RCC->CR, RCC_CR_HSION);
  130. }
  131.  
  132. static void Configure_LEDS(void)
  133. {
  134. CLK_ENABLE(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
  135. MODIFY_REG(GPIOD->MODER, (uint32_t) 0xFF000000U, (uint32_t) 0x55000000U); // pins 12,13,14,15 as output
  136. MODIFY_REG(GPIOD->OTYPER, (uint32_t) 0xFF000000U, (uint32_t) 0x00000000U); // GPIOD->OTYPER - PUSH PULL
  137. MODIFY_REG(GPIOD->OSPEEDR, (uint32_t) 0xFF000000U, (uint32_t) 0xFF000000U); // pins 12,13,14,15 very high speed
  138. MODIFY_REG(GPIOD->PUPDR, (uint32_t) 0xFF000000U, (uint32_t) 0x00000000U); // GPIOD->PUPDR - NO PULL
  139. }
  140.  
  141. static void Configure_SPI1(void)
  142. {
  143. CLK_ENABLE(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
  144. CLK_ENABLE(RCC->AHB1ENR, RCC_AHB1ENR_GPIOEEN);
  145.  
  146. MODIFY_REG(GPIOA->MODER, (uint32_t) 0x0000FC00U, (uint32_t) 0x0000A800U);
  147. MODIFY_REG(GPIOA->OTYPER, (uint32_t) 0x000000E0U, (uint32_t) 0x00000000U);
  148. MODIFY_REG(GPIOA->OSPEEDR, (uint32_t) 0x0000FC00U, (uint32_t) 0x00005400U);
  149. MODIFY_REG(GPIOA->PUPDR, (uint32_t) 0x0000FC00U, (uint32_t) 0x00005400U);
  150. MODIFY_REG(GPIOA->AFR[0], (uint32_t) 0xFFF00000U, (uint32_t) 0x55500000U);
  151.  
  152. MODIFY_REG(GPIOE->MODER, (uint32_t) 0x000000C0U, (uint32_t) 0x00000040U);
  153. MODIFY_REG(GPIOE->OTYPER, (uint32_t) 0x00000008U, (uint32_t) 0x00000000U);
  154. MODIFY_REG(GPIOE->OSPEEDR, (uint32_t) 0x000000C0U, (uint32_t) 0x00000080U);
  155. MODIFY_REG(GPIOE->PUPDR, (uint32_t) 0x000000C0U, (uint32_t) 0x00000040U);
  156.  
  157. CLK_ENABLE(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);
  158.  
  159. WRITE_REG(SPI1->CR1, SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_MSTR | SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_1);
  160. WRITE_REG(SPI1->CR2, SPI_CR2_ERRIE);
  161.  
  162. NVIC_SetPriority(SPI1_IRQn, 0);
  163. NVIC_EnableIRQ(SPI1_IRQn);
  164.  
  165. SetPin(GPIOE, GPIO_ODR_ODR_3);
  166. SET_BIT(SPI1->CR1, SPI_CR1_SPE);
  167. }
  168.  
  169. uint8_t temp;
  170. void SPI_Tx(uint8_t address, uint8_t data)
  171. {
  172. ResetPin(GPIOE, GPIO_ODR_ODR_3);
  173. while (READ_BIT(SPI1->SR, SPI_SR_TXE) == 0)
  174. {
  175. }
  176. *((__IO uint8_t *)&(SPI1->DR)) = address;
  177. while (READ_BIT(SPI1->SR, SPI_SR_RXNE) == 0)
  178. {
  179. }
  180. temp = *((__IO uint8_t *)&(SPI1->DR)); // useless read
  181. while (READ_BIT(SPI1->SR, SPI_SR_TXE) == 0)
  182. {
  183. }
  184. *((__IO uint8_t *)&(SPI1->DR)) = data;
  185. while (READ_BIT(SPI1->SR, SPI_SR_RXNE) == 0)
  186. {
  187. }
  188. temp = *((__IO uint8_t *)&(SPI1->DR)); // useless read
  189. while (READ_BIT(SPI1->SR, SPI_SR_BSY) == SPI_SR_BSY)
  190. {
  191. }
  192. SetPin(GPIOE, GPIO_ODR_ODR_3);
  193. }
  194.  
  195. uint8_t SPI_Rx(uint8_t address)
  196. {
  197. uint8_t temp;
  198. ResetPin(GPIOE, GPIO_ODR_ODR_3);
  199. address |= (uint8_t) 0x80U;
  200. while (READ_BIT(SPI1->SR, SPI_SR_TXE) == 0)
  201. {
  202. }
  203. *((__IO uint8_t *)&(SPI1->DR)) = address;
  204. while (READ_BIT(SPI1->SR, SPI_SR_RXNE) == 0)
  205. {
  206. }
  207. temp = *((__IO uint8_t *)&(SPI1->DR)); // useless read
  208. while (READ_BIT(SPI1->SR, SPI_SR_TXE) == 0)
  209. {
  210. }
  211. *((__IO uint8_t *)&(SPI1->DR)) = (uint8_t)0x00U;
  212. while (READ_BIT(SPI1->SR, SPI_SR_RXNE) == 0)
  213. {
  214. }
  215. temp = *((__IO uint8_t *)&(SPI1->DR));
  216. while (READ_BIT(SPI1->SR, SPI_SR_BSY) == SPI_SR_BSY)
  217. {
  218. }
  219. SetPin(GPIOE, GPIO_ODR_ODR_3);
  220. return temp;
  221. }
  222.  
  223. void SPI1_TransferError_Callback(void)
  224. {
  225. // Disable RXNE Interrupt
  226. CLEAR_BIT(SPI1->CR2, SPI_CR2_RXNEIE);
  227.  
  228. // Disable TXE Interrupt
  229. CLEAR_BIT(SPI1->CR2, SPI_CR2_TXEIE);
  230.  
  231. // All LEDs ON to indicate error occurs
  232. SetPin(GPIOD, GPIO_ODR_ODR_12);
  233. SetPin(GPIOD, GPIO_ODR_ODR_13);
  234. SetPin(GPIOD, GPIO_ODR_ODR_14);
  235. SetPin(GPIOD, GPIO_ODR_ODR_15);
  236. }
  237.  
  238. void ResetPin(GPIO_TypeDef * GPIO, uint32_t pin){
  239. GPIO->ODR &= ~ pin;
  240. }
  241.  
  242. void SetPin(GPIO_TypeDef * GPIO, uint32_t pin){
  243. GPIO->ODR |= pin;
  244. }
  245. void Error_Handler(void)
  246. {
  247. // User may add here some code to deal with this error
  248. while (1)
  249. {
  250. }
  251. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement