#include "stm32f4xx.h" #include "LCD2x16.c" char Results[32768]; int ResultsPointer = 0; void main(void) { // GPIO clock enable, digital pin definitions RCC->AHB1ENR |= 0x00000001; // Enable clock for GPIOA RCC->AHB1ENR |= 0x00000010; // Enable clock for GPIOE GPIOE->MODER |= 0x00010000; // output pin PE08: time mark GPIOE->MODER |= 0x00040000; // output pin PE09: toggle GPIOA->MODER |= 0x00001000; // output pin PA06: LED D390 GPIOA->MODER |= 0x00004000; // output pin PA06: LED D391 GPIOC->MODER |= 0x00900000; // PC10, PC11 => AF mode GPIOC->AFR[0] |= 0x00000010; // select AF1 (TIM2) for PA01 -> TIM2_CH2 //UART4 initialization RCC->APB1ENR |= 0x00080000; // Enable clock for UART4 RCC->AHB1ENR |= 0x00000004; // Enable clock for GPIOC GPIOC->MODER |= 0x00a00000; // PC10, PC11 => AF mode GPIOC->AFR[1] |= 0x00008800; // select AF8 (UART4,5,6) for PA10, PA11 //UART4->BRR = 0x1120; // 9600 baud //UART4->BRR = 0x0890; // 19200 baud //UART4->BRR = 0x0450; // 38400 baud //UART4->BRR = 0x02e0; // 57600 baud UART4->BRR = 0x016d; // 115200 baud UART4->CR1 |= 0x200c; // Enable UART for TX, RX UART4->CR1 |= 0x0020; // Enable RX interrupt // ADC set-up RCC->APB2ENR |= 0x00000100; // clock for ADC1 RCC->APB2ENR |= 0x00000200; // clock for ADC2 ADC->CCR = 0x00000006; // Regular simultaneous mode only ADC1->CR2 = 0x00000001; // ADC1 ON ADC1->SQR3 = 0x00000002; // use PA02 as input ADC2->CR2 = 0x00000001; // ADC1 ON ADC2->SQR3 = 0x00000003; // use PA03 as input GPIOA->MODER |= 0x000000f0; // PA02, PA03 are analog inputs ADC1->CR2 |= 0x06000000; // use TIM2, TRG0 as SC source ADC1->CR2 |= 0x10000000; // Enable external SC, rising edge ADC1->CR1 |= 0x00000020; // Enable ADC Interrupt for EOC // NVIC IRQ enable NVIC_EnableIRQ(ADC_IRQn); // Enable IRQ for ADC in NVIC // Timer 2 set-up RCC->APB1ENR |= 0x0001; // Enable clock for Timer 2 TIM2->ARR = 8400; // Auto Reload value: 8400 == 100us TIM2->CR2 |= 0x0020; // select TRGO to be update event (UE) //TIM2->CR1 |= 0x0001; // Enable Counting // LCD init LCD_init(); // Init LCD //NVIC init NVIC_EnableIRQ(UART4_IRQn); // Enable IRQ for UART4 in NVIC // endless loop while (1) { //if (GPIOE->IDR & 0x0001) GPIOA->ODR |= 0x0040; // LED on //else GPIOA->ODR &= ~0x0040; // else LED off }; } // IRQ function // caution: placing breakpoints in IRQ corrupts the execution! // this happends due to the reading of the DR by the IAR and changes IRQ flags! // I wasted sevaral hours to find this out. Do not step into the same trap. void UART4_IRQHandler(void) { // TX IRQ part if (UART4->SR & 0x0080) { // If TXE flag in SR is on then if (ResultsPointer < 32768) // if not end of string UART4->DR = Results[ResultsPointer++]; // send next byte and increment pointer else { // else UART4->CR1 &= ~0x0080; // disable TX interrupt GPIOA->ODR &= ~0x0040; }; }; // RX IRQ part if (UART4->SR & 0x0020) { // if RXNE flag in SR is on then int RXch = UART4->DR; // save received character & clear flag LCD_uInt16(RXch, 0x05, 1); // show ASCII on LCD if (RXch == 'a') { GPIOA->ODR |= 0x0080; // if 'a' => LED on ResultsPointer = 0; // init pointer to results TIM2->CR1 |= 0x0001; // Enable Counting }; }; } // IRQ function void ADC_IRQHandler(void) // PASS takes approx 400ns of CPU time! { GPIOE->ODR |= 0x0100; // PE08 up if (ResultsPointer < 32767) { int Ra = ADC1->DR; int Rb = ADC2->DR; Results[ResultsPointer++] = (Ra & 0x0f00) >> 8; Results[ResultsPointer++] = (Ra & 0x00ff); Results[ResultsPointer++] = (Rb & 0x0f00) >> 8; Results[ResultsPointer++] = (Rb & 0x00ff); GPIOE->ODR |= 0x0100; GPIOE->ODR &= ~0x0100; } else { GPIOA->ODR &= ~0x0080; // LED off TIM2->CR1 &= ~0x0001; // Disable Counting UART4->CR1 |= 0x0080; // Enable TX IRQ ResultsPointer = 0; GPIOA->ODR |= 0x0040; UART4->DR = Results[ResultsPointer++]; // Send first character }; GPIOE->ODR &= ~0x0100; // PE08 down }