#include "misc.h" #include "stm32f10x_adc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x_tim.h" #include "stm32f10x_usart.h" // A - PA7 #define SEG_A 0x40 // B - PA5 #define SEG_B 0x10 // C - PA2 #define SEG_C 0x02 // D - PA3 #define SEG_D 0x04 // E - PA4 #define SEG_E 0x08 // F - PA6 #define SEG_F 0x20 // G - PA1 #define SEG_G 0x01 static const uint8_t SYMBOLS[12] = { /* 0 */ SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, /* 1 */ SEG_B | SEG_C, /* 2 */ SEG_A | SEG_B | SEG_G | SEG_E | SEG_D, /* 3 */ SEG_A | SEG_B | SEG_G | SEG_C | SEG_D, /* 4 */ SEG_F | SEG_G | SEG_B | SEG_C, /* 5 */ SEG_A | SEG_F | SEG_G | SEG_C | SEG_D, /* 6 */ SEG_A | SEG_F | SEG_E | SEG_D | SEG_C | SEG_G, /* 7 */ SEG_A | SEG_B | SEG_C, /* 8 */ SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G, /* 9 */ SEG_G | SEG_F | SEG_A | SEG_B | SEG_C | SEG_D, /* E */ SEG_A | SEG_F | SEG_G | SEG_E | SEG_D, /* r */ SEG_E | SEG_G }; /* A1 - PC13 A2 - PC14 A3 - PC15 */ static inline void SelectSymbol(uint32_t sym) { uint32_t mask; mask = GPIOC->ODR & 0x1FFF; switch(sym) { case 0: mask |= 0xC000; break; case 1: mask |= 0xA000; break; case 2: mask |= 0x6000; break; } GPIOC->ODR = mask; } static inline void SetSymbol(uint32_t sym) { GPIOA->ODR = (GPIOA->ODR & 0xFF01) | (SYMBOLS[sym % 12] << 1); } uint32_t DispState; uint8_t DisplayDigits[4]; void TIM1_UP_IRQHandler (void) { TIM_ClearITPendingBit(TIM1,TIM_FLAG_Update); // Clear update interrupt bit SelectSymbol(DispState); SetSymbol(DisplayDigits[DispState]); DispState++; if(DispState >= 3) DispState = 0; } static const ADC_InitTypeDef ADC_InitStructure = { .ADC_Mode = ADC_Mode_Independent, .ADC_ScanConvMode = ENABLE, .ADC_ContinuousConvMode = ENABLE, .ADC_ExternalTrigConv = ADC_ExternalTrigConv_None, .ADC_DataAlign = ADC_DataAlign_Right, .ADC_NbrOfChannel = 1 }; static const USART_InitTypeDef USART_InitStructure = { .USART_BaudRate = 19200, .USART_WordLength = USART_WordLength_8b, .USART_StopBits = USART_StopBits_1, .USART_Parity = USART_Parity_No, .USART_HardwareFlowControl = USART_HardwareFlowControl_None, .USART_Mode = USART_Mode_Rx | USART_Mode_Tx }; static const NVIC_InitTypeDef NVIC_InitStructure = { .NVIC_IRQChannel = TIM1_UP_IRQn, .NVIC_IRQChannelPreemptionPriority = 7, .NVIC_IRQChannelSubPriority = 0, .NVIC_IRQChannelCmd = ENABLE }; static const TIM_TimeBaseInitTypeDef TIM1_TimeBaseInitStruct = { .TIM_Prescaler = 80, // 8Mhz / 80 = 100khz .TIM_CounterMode = TIM_CounterMode_Up, .TIM_Period = 500, // 100Khz / 500 = 200Hz .TIM_ClockDivision = TIM_CKD_DIV1, .TIM_RepetitionCounter = 0 }; int main() { /* работает на 8MHz RC, нам достаточно, PLL натачивать не будем */ // SystemInit(); uint32_t AdcData; GPIO_InitTypeDef GPIO_InitStructure; __disable_interrupt(); // ставим таблицу прерываний #ifndef EMB_FLASH NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); // Set the Vector Table base location at 0x20000000 #else NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); // Set the Vector Table base location at 0x08000000 #endif NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // включаем нужное нам оборудование RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_TIM1 | RCC_APB2Periph_ADC1 | RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_TIM1 | RCC_APB2Periph_ADC1 | RCC_APB2Periph_USART1, DISABLE); // инитим ноги GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Init PA0 as Analog input GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Init PA1..PA7 as Push/Pull output GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOA, &GPIO_InitStructure); // Init PC13..PC15 as Push/Pull output GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure USART1 Tx (PA9) push-pull */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure USART1 Rx (PA10) as input floating */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA, &GPIO_InitStructure); // настраиваем таймер period 5ms (200Hz) TIM_TimeBaseInit(TIM1, (TIM_TimeBaseInitTypeDef *) &TIM1_TimeBaseInitStruct); TIM_ClearITPendingBit(TIM1,TIM_FLAG_Update); // Clear update interrupt bit TIM_ITConfig(TIM1,TIM_FLAG_Update,ENABLE); // Enable update interrupt NVIC_Init((NVIC_InitTypeDef *) &NVIC_InitStructure); // Enable IRQ for Timer1 TIM_Cmd(TIM1,ENABLE); // Enable timer counting // Настраиваем ADC ADC_Init(ADC1, (ADC_InitTypeDef *)&ADC_InitStructure); // ADC1 configuration ADC_RegularChannelConfig(ADC1, 0, 1, ADC_SampleTime_55Cycles5); // ADC1 channel0 configuration ADC_DMACmd(ADC1, DISABLE); // Disable ADC1 DMA ADC_Cmd(ADC1, ENABLE); // Enable ADC1 ADC_ResetCalibration(ADC1); // Enable ADC1 reset calibaration register while(ADC_GetResetCalibrationStatus(ADC1)); // Check the end of ADC1 reset calibration register ADC_StartCalibration(ADC1); // Start ADC1 calibaration while(ADC_GetCalibrationStatus(ADC1)); // Check the end of ADC1 calibration // Настраиваем USART1 USART_Init(USART1, (USART_InitTypeDef*) &USART_InitStructure); USART_Cmd(USART1, ENABLE); // Enable the USART1 __enable_interrupt(); // App cycle begin DisplayDigits[3] = 218; // = '\n' - '0' ADC_SoftwareStartConvCmd(ADC1, ENABLE); // Start ADC1 Software Conversion while(1) { AdcData = ADC_GetConversionValue(ADC1); ADC_SoftwareStartConvCmd(ADC1, ENABLE); AdcData = AdcData * 1000 / 4096; DisplayDigits[0] = AdcData / 100; DisplayDigits[1] = (AdcData / 10) % 10; DisplayDigits[2] = AdcData % 10; for(int i =0; i < 4; i++) { USART_SendData(USART1, '0' + DisplayDigits[i]); while(!(USART1->SR & USART_FLAG_TXE)) ; } } }