123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- /**
- ******************************************************************************
- * @file Project/main.c
- * @author "Volodymyr M. Shylov" <shilow@ukr.net>
- * @version v.0.1
- * @date 24-11-2023
- * @brief Main program body. VA-meter from DC/DC XL4005
- ******************************************************************************
- * @attention
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <shilow@ukr.net> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return. Shilov V.N.
- *
- ******************************************************************************
- */
- /* Includes ------------------------------------------------------------------*/
- #include "stm8s.h"
- #include "board.h"
- #include "led.h"
- #include "delay.h"
- /* Private define ------------------------------------------------------------*/
- #define TIM4_PERIOD (uint8_t)124
- /* Private typedef -----------------------------------------------------------*/
- /* Private constants ---------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- __IO uint16_t ConversionBuffer[ADC_SMPLS];
- __IO uint8_t BufferIndex = 0;
- static uint16_t Voltage;
- /* Private function prototypes -----------------------------------------------*/
- static void boardInit(void);
- static void showV(void);
- static void showC(void);
- void main(void)
- {
- /* Board Configuration */
- boardInit();
- Delay(100);
- /* Infinite loop */
- while (1) {
- Delay(100);
- if (BufferIndex >= ADC_SMPLS) {
- BufferIndex = 0;
- int8_t i;
- uint32_t vbuf = 0;
- for (i=0; i<64; i++) {
- vbuf += ConversionBuffer[i];
- }
- vbuf *= ADC_VREF;
- vbuf += 512;
- vbuf /= 1023;
- vbuf *= 45727;
- vbuf += 5000;
- vbuf /= 10000;
- Voltage = vbuf;
- }
- showV();
- showC();
- }
- }
- /* Private functions ---------------------------------------------------------*/
- static void showV(void) {
- uint16_t a = (Voltage + 5) / 10;
- LedDigits[0] = a / 1000;
- uint16_t b = a % 1000;
- LedDigits[1] = b / 100;
- uint8_t c = b % 100;
- LedDigits[2] = c / 10;
- LedDigits[3] = c % 10;
- }
- static void showC(void) {
- LedDigits[4] = 5;
- LedDigits[5] = 6;
- LedDigits[6] = 7;
- LedDigits[7] = 8;
- }
- static void boardInit(void) {
- /* Насколько я понял, для частот выше 16МГц нужно вводить задержку при работе с FLASH:
- - Before using the HSE clock make sure that the "Flash_Wait_States" is set to 1.
- - To do so :
- - with STVD (menu: Debug Instrument -> MCU configuration -> Options)
- - with EWSTM8 (menu: ST-LINK -> Option bytes ->Flash_Wait_States: 1)
- */
- /* Initialization of the clock to 16MHz */
- CLK->CKDIVR = 0x00;
- /* Disable clock of unused peripherial */
- CLK->PCKENR1 = (uint8_t)(~(CLK_PCKENR1_UART1 | CLK_PCKENR1_SPI));
- CLK->PCKENR2 = (uint8_t)(~(CLK_PCKENR2_CAN | CLK_PCKENR2_AWU)); // | CLK_PCKENR2_ADC
- /* SWIM clock */
- CLK->SWIMCCR = 0x00;
- /* SWITCH pin to Push-Pull, High, Fast */
- SWITCH_PORT->ODR |= (uint8_t)(SWITCH_PIN);
- SWITCH_PORT->DDR |= (uint8_t)(SWITCH_PIN);
- SWITCH_PORT->CR1 |= (uint8_t)(SWITCH_PIN);
- SWITCH_PORT->CR2 |= (uint8_t)(SWITCH_PIN);
- SWITCH_OFF;
- /* Configure GPIO used for LED to Push-Pull, High, Fast*/
- GPIOA->ODR |= (uint8_t)LED_SEG_CG;
- GPIOA->DDR |= (uint8_t)LED_SEG_CG;
- GPIOA->CR1 |= (uint8_t)LED_SEG_CG;
- GPIOA->CR2 |= (uint8_t)LED_SEG_CG;
- GPIOB->ODR |= (uint8_t)LED_SEG_DH;
- GPIOB->DDR |= (uint8_t)LED_SEG_DH;
- GPIOB->CR1 |= (uint8_t)LED_SEG_DH;
- GPIOB->CR2 |= (uint8_t)LED_SEG_DH;
- GPIOC->ODR |= (uint8_t)LED_SEG_BE;
- GPIOC->DDR |= (uint8_t)LED_SEG_BE;
- GPIOC->CR1 |= (uint8_t)LED_SEG_BE;
- GPIOC->CR2 |= (uint8_t)LED_SEG_BE;
- GPIOD->ODR |= (uint8_t)LED_SEG_AF;
- GPIOD->DDR |= (uint8_t)LED_SEG_AF;
- GPIOD->CR1 |= (uint8_t)LED_SEG_AF;
- GPIOD->CR2 |= (uint8_t)LED_SEG_AF;
- /* `SPI` pins to Push-Pull, High, Fast */
- SPI_PORT->ODR = (uint8_t)(SPI_SCK|SPI_DATA);
- SPI_PORT->DDR |= (uint8_t)(SPI_SCK|SPI_DATA);
- SPI_PORT->CR1 |= (uint8_t)(SPI_SCK|SPI_DATA);
- SPI_PORT->CR2 |= (uint8_t)(SPI_SCK|SPI_DATA);
- /* I2C GPIO SDA SCL - HiZ, Open drain, Fast */
- //GPIOB->DDR |= (GPIO_PIN_4 | GPIO_PIN_5);
- //GPIOB->ODR |= (GPIO_PIN_4 | GPIO_PIN_5);
- //GPIOB->CR2 |= (GPIO_PIN_4 | GPIO_PIN_5);
- /** Configure ADC1 peripheral */
- /* Configure the data alignment */
- ADC1->CR2 |= (uint8_t)(ADC1_CR2_ALIGN);
- /* Set the single conversion mode */
- ADC1->CR1 &= (uint8_t)(~ADC1_CR1_CONT);
- /* Clear the ADC1 channels */
- ADC1->CSR &= (uint8_t)(~ADC1_CSR_CH);
- /* Select the ADC1 channel */
- ADC1->CSR |= (uint8_t)(ADC_CHNLU);
- /* Clear the SPSEL bits */
- ADC1->CR1 &= (uint8_t)(~ADC1_CR1_SPSEL);
- /* Select the prescaler division factor according to ADC1_PrescalerSelection values */
- ADC1->CR1 |= (uint8_t)(ADC1_PRESSEL_FCPU_D8);
- /* Enable the external Trigger */
- ADC1->CR2 |= (uint8_t)(ADC1_CR2_EXTTRIG);
- /* Set the 'Internal TIM1 TRGO event' as external trigger */
- ADC1->CR2 &= (uint8_t)~(ADC1_CR2_EXTSEL);
- /* disables the ADC1 Schmitt Trigger on a selected channel(s) */
- ADC1->TDRL |= (uint8_t)((uint8_t)0x01 << (uint8_t)ADC_SCHTU);
- /* Enable the ADC1 peripheral */
- ADC1->CR1 |= ADC1_CR1_ADON;
- /* Enable the ADC1 EOC interrupt */
- ADC1->CSR |= (uint8_t)ADC1_IT_EOCIE;
- /*Start Conversion */
- ADC1->CR1 |= ADC1_CR1_ADON;
- /** Configure TIM1 peripheral. Time Base configuration:
- Timer period - 3,125 ms
- TIM1_Period = 50
- TIM1_Prescaler = 1000
- TIM1_CounterMode = TIM1_COUNTERMODE_UP
- TIM1_RepetitionCounter = 0
- */
- /* Set the Autoreload value */
- TIM1->ARRH = (uint8_t)(49 >> 8);
- TIM1->ARRL = (uint8_t)(49);
- /* Set the Prescaler value */
- TIM1->PSCRH = (uint8_t)(999 >> 8);
- TIM1->PSCRL = (uint8_t)(999);
- /* Select the Counter Mode */
- TIM1->CR1 = 0x0;
- /* Set the Repetition Counter value */
- TIM1->RCR = 0;
- /* Trigrer configuration */
- TIM1->CR2 = (uint8_t)TIM1_TRGOSOURCE_UPDATE;
- /* Update Interrupt Enable */
- //TIM1->IER |= (uint8_t)TIM1_IT_UPDATE;
- /* Enable TIM1 */
- TIM1->CR1 |= TIM1_CR1_CEN;
- /**
- TIM4 configuration:
- - TIM4CLK is set to 16 MHz, the TIM4 Prescaler is equal to 128 so the TIM1 counter
- clock used is 16 MHz / 128 = 125 000 Hz
- - With 125 000 Hz we can generate time base:
- max time base is 2.048 ms if TIM4_PERIOD = 255 --> (255 + 1) / 125000 = 2.048 ms
- min time base is 0.016 ms if TIM4_PERIOD = 1 --> ( 1 + 1) / 125000 = 0.016 ms
- - In this example we need to generate a time base equal to 1 ms
- so TIM4_PERIOD = (0.001 * 125000 - 1) = 124
- */
- /* Time base configuration. Set the Prescaler value */
- TIM4->PSCR = (uint8_t)(TIM4_PRESCALER_128);
- /* Set the Autoreload value */
- TIM4->ARR = (uint8_t)(TIM4_PERIOD);
- /* Clear TIM4 update flag */
- TIM4->SR1 = (uint8_t)(~TIM4_FLAG_UPDATE);
- /* Enable update interrupt */
- TIM4->IER |= (uint8_t)TIM4_IT_UPDATE;
- /* enable interrupts */
- enableInterrupts();
- /* Enable TIM4 */
- TIM4->CR1 |= (uint8_t)TIM4_CR1_CEN;
- }
- /************************ (C) COPYRIGHT Shilov V.N. *****END OF FILE****/
|