123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 |
- /**
- ******************************************************************************
- * @file China AC-meter
- * @author Vladimir N. Shilov <shilow@ukr.net>
- * @version V0.0.1
- * @date 2016.11.09
- * @brief Main program body
- ******************************************************************************
- * @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 "rtos.h"
- /* Private defines -----------------------------------------------------------*/
- // for 1 msek ticks
- #define TIM4_PERIOD (uint8_t)124
- #define ADC_PORT GPIOD
- #define ADC_PINS GPIO_PIN_3
- #define ADC_CHNL ADC1_CHANNEL_4
- #define ADC_SCHT ADC1_SCHMITTTRIG_CHANNEL4
- #define ADC_SMPLS 64
- // Supply voltage in mili volts
- #define ADC_VREF 3335
- // input OA multiplier -- [(3.6/0.68) + 1) * 1000]
- #define ADC_MULT 6294
- // shunt resistance in mili Ohms
- #define ADC_SHUNT 50
- #define BTN_PORT (GPIOA)
- #define BTN_PINS (GPIO_PIN_2)
- /*
- AAA
- F B
- F B
- GGG
- E C
- E C
- DDD P
- */
- #define LED_ANOD1_PORT GPIOA
- #define LED_ANOD1_PIN GPIO_PIN_3
- #define LED_ANOD2_PORT GPIOD
- #define LED_ANOD2_PIN GPIO_PIN_6
- #define LED_ANOD3_PORT GPIOD
- #define LED_ANOD3_PIN GPIO_PIN_4
- #define LED_SEG1_PORT GPIOA
- #define LED_SEG1_PINS GPIO_PIN_1
- #define LED_SEG_F GPIO_PIN_1
- #define LED_SEG2_PORT GPIOB
- #define LED_SEG2_PINS (GPIO_PIN_5 | GPIO_PIN_4)
- #define LED_SEG_A GPIO_PIN_5
- #define LED_SEG_B GPIO_PIN_4
- #define LED_SEG3_PORT GPIOC
- #define LED_SEG3_PINS (GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_3 | GPIO_PIN_5)
- #define LED_SEG_G GPIO_PIN_3
- #define LED_SEG_C GPIO_PIN_4
- #define LED_SEG_P GPIO_PIN_5
- #define LED_SEG_D GPIO_PIN_6
- #define LED_SEG_E GPIO_PIN_7
- #define LED_OUT_OFF {LED_SEG1_PORT->ODR |= LED_SEG1_PINS; LED_SEG2_PORT->ODR |= LED_SEG2_PINS; LED_SEG3_PORT->ODR |= LED_SEG3_PINS;}
- #define LED_OUT_DP GPIOC->ODR &= (~LED_SEG_P);
- #define LED_OUT_MM GPIOC->ODR &= LED_SEG_G;
- #define LED_OUT_0 GPIOA->ODR &= 0xFD; GPIOB->ODR &= 0xCF; GPIOC->ODR &= 0x29;
- #define LED_OUT_1 GPIOB->ODR &= 0xEF; GPIOC->ODR &= 0xE9;
- #define LED_OUT_2 GPIOB->ODR &= 0xCF; GPIOC->ODR &= 0x31;
- #define LED_OUT_3 GPIOB->ODR &= 0xCF; GPIOC->ODR &= 0xA1;
- #define LED_OUT_4 GPIOA->ODR &= 0xFD; GPIOB->ODR &= 0xEF; GPIOC->ODR &= 0xE1;
- #define LED_OUT_5 GPIOA->ODR &= 0xFD; GPIOB->ODR &= 0xDF; GPIOC->ODR &= 0xA1;
- #define LED_OUT_6 GPIOA->ODR &= 0xFD; GPIOB->ODR &= 0xDF; GPIOC->ODR &= 0x21;
- #define LED_OUT_7 GPIOB->ODR &= 0xCF; GPIOC->ODR &= 0xE9;
- #define LED_OUT_8 GPIOA->ODR &= 0xFD; GPIOB->ODR &= 0xCF; GPIOC->ODR &= 0x21;
- #define LED_OUT_9 GPIOA->ODR &= 0xFD; GPIOB->ODR &= 0xCF; GPIOC->ODR &= 0xA1;
- #define LED_ANODE_OFF {LED_ANOD1_PORT->ODR &= ~LED_ANOD1_PIN; GPIOD->ODR &= ~(LED_ANOD2_PIN | LED_ANOD3_PIN);}
- #define LED_ANODE_ON1 LED_ANOD1_PORT->ODR |= LED_ANOD1_PIN;
- #define LED_ANODE_ON2 LED_ANOD2_PORT->ODR |= LED_ANOD2_PIN;
- #define LED_ANODE_ON3 LED_ANOD3_PORT->ODR |= LED_ANOD3_PIN;
- #define SUB_SECOND_CNT 5
- #define LED_ONE_PERIOD 5
- #define ADC_ZERO_EEADDR FLASH_DATA_START_PHYSICAL_ADDRESS
- /* Private function prototypes -----------------------------------------------*/
- static void ADC_CorrectZero(void);
- static void ADC_Config(void);
- static void GPIO_Config(void);
- static void TIM1_Config(void);
- static void TIM4_Config(void);
- static void OutputToLed(void);
- static void PrepareForLed(void);
- //static void CountCapacity(void);
- /* Private functions ---------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- __IO uint16_t ConversionBuffer[ADC_SMPLS];
- __IO uint8_t BufferIndex = 0;
- __IO uint8_t LedCnt = 0;
- static uint16_t Current = 0;
- static uint32_t Capacity = 0;
- static uint8_t LedDigits[3] = {0, 0, 0};
- static uint8_t LedPoint = 3;
- static uint16_t SubSecondBfr = 0;
- static uint8_t SubSecondCnt = SUB_SECOND_CNT;
- static uint16_t ADC_ZeroFix = 0;
- void main(void)
- {
- /* Initialization of the clock to 16MHz */
- CLK->CKDIVR = 0x00;
- /* Disable clock of unused perephireal */
- /* UART, SPI, I2C */
- CLK->PCKENR1 = 0xF0;
- /* CAN */
- CLK->PCKENR2 = 0x0F;
- /* SWIM clock */
- CLK->SWIMCCR = 0x00;
- /* GPIO configuration ------------------------------------------*/
- GPIO_Config();
- /* ADC configuration -------------------------------------------*/
- ADC_Config();
- /* TIM1 configuration -----------------------------------------*/
- TIM1_Config();
- /* Initialize dispatcher */
- //RTOS_Init();
- //RTOS_SetTask(OutputToLed, 0, 5);
- //RTOS_SetTask(PrepareForLed, 210, 200);
- //RTOS_SetTask(CountCapacity, 1005, 1000);
- /* TIM4 configuration -----------------------------------------*/
- TIM4_Config();
- /* enable interrupts */
- enableInterrupts();
- /** If btn pin == 0 -- auto fix adc zero level
- else -- read zero value from eeprom
- Value stored in MSB:LSB
- */
- if((BTN_PORT->IDR & BTN_PINS) == 0){
- ADC_CorrectZero();
- } else {
- ADC_ZeroFix = (uint16_t)(FLASH_ReadByte(ADC_ZERO_EEADDR) << 8);
- ADC_ZeroFix |= FLASH_ReadByte((ADC_ZERO_EEADDR+1));
- }
- /* Infinite loop */
- while (1)
- {
- if (LedCnt >= LED_ONE_PERIOD) {
- LedCnt = 0;
- OutputToLed();
- }
- if (BufferIndex >= ADC_SMPLS) {
- BufferIndex = 0;
- /* Oversampling */
- uint32_t tbuf = 0;
- uint8_t i = 0;
- for(i=0; i<ADC_SMPLS; i++){
- tbuf += ConversionBuffer[i];
- }
- if(tbuf > ADC_ZeroFix){
- tbuf -= ADC_ZeroFix;
- tbuf >>= 3; // ïðåäâàðèòåëüíûé äåëèòåëü îâåðñåìïëèíãà
- tbuf *= ADC_VREF; // Ìíîæèì íà îïîðíîå íàïðÿæåíèå
- tbuf = (tbuf + 4096) / 8191; // get ADC input voltage in mV
- tbuf *= 1000; // êîìïåíñàöèÿ êîýô. óñèëåíèÿ âõîäíîãî ÎÓ
- tbuf *= 1000; // êîìïåíñàöèÿ ñîïðîòèâëåíèÿ øóíòà
- tbuf = (tbuf + (ADC_MULT/2)) / ADC_MULT; // get voltage from shunt
- /* â Current òîê â ìèëèàìïåðàõ */
- Current = (tbuf + (ADC_SHUNT/2)) / ADC_SHUNT;
- SubSecondBfr += Current;
- }
- SubSecondCnt --;
- if(SubSecondCnt == 0){
- Capacity += ( (SubSecondBfr + (SUB_SECOND_CNT/2)) / SUB_SECOND_CNT );
- SubSecondBfr = 0;
- SubSecondCnt = SUB_SECOND_CNT;
- }
- PrepareForLed();
- } // End of if (BufferIndex >= ADC_SMPLS)
- //RTOS_DispatchTask();
- wfi();
- } // End of infinity
- } // End of main()
- /** Êîððåêòèðóåì íàïðÿæåíèå ñìåùåíèÿ íóëÿ ÎÓ íà âõîäå ÀÖÏ */
- static void ADC_CorrectZero(void) {
- /* æä¸ì îêîí÷àíèÿ öèêëà èçìåðåíèé */
- do {
- } while (BufferIndex < ADC_SMPLS);
- BufferIndex = 0;
- /* Ïîëó÷àåì 16-òè áèòíîå çíà÷åíèå îò ÀÖÏ */
- uint8_t i = 0;
- for(i=0; i<ADC_SMPLS; i++){
- ADC_ZeroFix += ConversionBuffer[i];
- }
- /* Ñîõðàíÿåì ïîëó÷åííîå çíà÷åíèå â EEPROM */
- /*Define FLASH programming time*/
- FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_STANDARD);
- /* Unlock Data memory */
- FLASH_Unlock(FLASH_MEMTYPE_DATA);
- /* MSB */
- FLASH_ProgramByte(ADC_ZERO_EEADDR, (uint8_t)(ADC_ZeroFix>>8));
- /* LSB */
- FLASH_ProgramByte((ADC_ZERO_EEADDR+1), (uint8_t)(ADC_ZeroFix));
- /* Lock Data memory */
- FLASH_Lock(FLASH_MEMTYPE_DATA);
- }
- /** Prepare current value for output ot led */
- static void PrepareForLed(void) {
- uint16_t value;
- if((BTN_PORT->IDR & BTN_PINS) == 0){
- value = Capacity / 3600;
- } else {
- value = Current;
- }
- if(value > 9999){
- /* XX.X Amper */
- LedPoint = 1;
- LedDigits[0] = value / 10000;
- value = value % 10000;
- LedDigits[1] = value / 1000;
- LedDigits[2] = (value % 1000) / 100;
- } else if(value > 999){
- /* X.XX Amper */
- LedPoint = 0;
- LedDigits[0] = value / 1000;
- value = value % 1000;
- LedDigits[1] = value / 100;
- LedDigits[2] = (value % 100) / 10;
- } else {
- /* XXX mili Amper */
- LedPoint = 3;
- LedDigits[0] = value / 100;
- value = value % 100;
- LedDigits[1] = value / 10;
- LedDigits[2] = value % 10;
- }
- }
- /** Output current value to next led */
- static void OutputToLed(void) {
- static uint8_t ledn = 0;
- /* íà ïèíå PD2 äîëæåí áûòü ìåàäð ñ ïåðèîäîì 10 ìñåê. */
- GPIOD->ODR ^= GPIO_PIN_2;
- /* all off */
- //LED_ANODE_OFF
- LED_ANOD1_PORT->ODR &= ~LED_ANOD1_PIN;
- LED_ANOD2_PORT->ODR &= ~(LED_ANOD2_PIN | LED_ANOD3_PIN);
- //LED_OUT_OFF
- LED_SEG1_PORT->ODR |= LED_SEG1_PINS;
- LED_SEG2_PORT->ODR |= LED_SEG2_PINS;
- LED_SEG3_PORT->ODR |= LED_SEG3_PINS;
- /* out next value */
- switch(LedDigits[ledn]){
- case 0:
- LED_OUT_0
- break;
- case 1:
- LED_OUT_1
- break;
- case 2:
- LED_OUT_2
- break;
- case 3:
- LED_OUT_3
- break;
- case 4:
- LED_OUT_4
- break;
- case 5:
- LED_OUT_5
- break;
- case 6:
- LED_OUT_6
- break;
- case 7:
- LED_OUT_7
- break;
- case 8:
- LED_OUT_8
- break;
- case 9:
- LED_OUT_9
- break;
- default:
- LED_OUT_MM
- }
- if(ledn == LedPoint) {
- LED_OUT_DP
- }
- /* Fire on nex led */
- switch(ledn){
- case 0:
- LED_ANODE_ON1
- ledn = 1;
- break;
- case 1:
- LED_ANODE_ON2
- ledn = 2;
- break;
- case 2:
- LED_ANODE_ON3
- ledn = 0;
- break;
- default:
- ledn = 0;
- }
- }
- /**
- * @brief Configure GPIO for LEDs and buttons available on the evaluation board
- * @param None
- * @retval None
- */
- static void GPIO_Config(void)
- {
- /* Initialize LEDs */
- GPIO_Init(LED_ANOD1_PORT, (GPIO_Pin_TypeDef)LED_ANOD1_PIN, GPIO_MODE_OUT_PP_LOW_FAST);
- GPIO_Init(LED_ANOD2_PORT, (GPIO_Pin_TypeDef)(LED_ANOD2_PIN | LED_ANOD3_PIN), GPIO_MODE_OUT_PP_LOW_FAST);
- GPIO_Init(LED_SEG1_PORT, (GPIO_Pin_TypeDef)LED_SEG1_PINS, GPIO_MODE_OUT_PP_LOW_FAST);
- GPIO_Init(LED_SEG2_PORT, (GPIO_Pin_TypeDef)LED_SEG2_PINS, GPIO_MODE_OUT_PP_LOW_FAST);
- GPIO_Init(LED_SEG3_PORT, (GPIO_Pin_TypeDef)LED_SEG3_PINS, GPIO_MODE_OUT_PP_LOW_FAST);
- /* Initialize Button pin */
- GPIO_Init(BTN_PORT, (GPIO_Pin_TypeDef)BTN_PINS, GPIO_MODE_IN_PU_NO_IT);
- /* Init GPIO for ADC */
- GPIO_Init(ADC_PORT, (GPIO_Pin_TypeDef)ADC_PINS, GPIO_MODE_IN_FL_NO_IT);
- /* Test output */
- GPIO_Init(GPIOD, (GPIO_Pin_TypeDef)GPIO_PIN_2, GPIO_MODE_OUT_PP_HIGH_FAST);
- }
- /**
- * @brief Configure ADC.
- * @param None
- * @retval None
- */
- static void ADC_Config()
- {
- /* De-Init ADC peripheral*/
- ADC1_DeInit();
- /* Init ADC1 peripheral */
- ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, ADC_CHNL, ADC1_PRESSEL_FCPU_D8, \
- ADC1_EXTTRIG_TIM, ENABLE, ADC1_ALIGN_RIGHT, ADC_SCHT, DISABLE);
- /* Enable EOC interrupt */
- ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE);
- /*Start Conversion */
- //ADC1_StartConversion();
- }
- /**
- * @brief Configure TIM1.
- * @param None
- * @retval None
- */
- static void TIM1_Config(void)
- {
- TIM1_DeInit();
- /* Time Base configuration */
- /*
- Timer period - 3,125 ms
- TIM1_Period = 50
- TIM1_Prescaler = 1000
- TIM1_CounterMode = TIM1_COUNTERMODE_UP
- TIM1_RepetitionCounter = 0
- */
- TIM1_TimeBaseInit(999, TIM1_COUNTERMODE_UP, 49, 0);
- /* Trigrer configuration */
- TIM1_SelectOutputTrigger(TIM1_TRGOSOURCE_UPDATE);
- /* Update Interrupt Enable */
- //TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
- /* Enable TIM1 */
- TIM1_Cmd(ENABLE);
- }
- /**
- * @brief Configure TIM4.
- * @param None
- * @retval None
- */
- static void TIM4_Config(void)
- {
- TIM4_DeInit();
- /*
- 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 */
- TIM4_TimeBaseInit(TIM4_PRESCALER_128, TIM4_PERIOD);
- /* Clear TIM4 update flag */
- TIM4_ClearFlag(TIM4_FLAG_UPDATE);
- /* Enable update interrupt */
- TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
- /* Enable TIM4 */
- TIM4_Cmd(ENABLE);
- }
- #ifdef USE_FULL_ASSERT
- /**
- * @brief Reports the name of the source file and the source line number
- * where the assert_param error has occurred.
- * @param file: pointer to the source file name
- * @param line: assert_param error line source number
- * @retval : None
- */
- void assert_failed(u8* file, u32 line)
- {
- /* User can add his own implementation to report the file name and line number,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* Infinite loop */
- while (1)
- {
- }
- }
- #endif
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|