Нагревалка батарей для рыси. Работает про принципу гистерезиса. Если на любой из ячеек температура падает ниже 10 градусов то включается нагрев, пока температура на любой из ячеек не станет выше 20 градусов.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

274 lines
7.5 KiB

/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.0.0
* Date : 2022/08/08
* Description : Main program body.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/*
*@Note
*Multiprocessor communication mode routine:
*Master:USART1_Tx(PD5)\USART1_Rx(PD6).
*This routine demonstrates that USART1 receives the data sent by CH341 and inverts
*it and sends it (baud rate 115200).
*
*Hardware connection:PD5 -- Tx
* PD6 -- Rx
* PD4 -- A_in
* PD1 -- SWIO
* PC0 -- heater on
* PC4 -- S0
* PC5 -- S1
* PC6 -- S2
*/
#include "debug.h"
/* Global define */
const uint16_t Grad20 = 860; //ADC value for 20 grad C
const uint16_t Grad10 = 920;
u_int8_t channel = 0;
u_int8_t heater_enable = 0;
uint16_t ADC_NTC[8];
#define GPIO_HEATER_On_Off GPIO_Pin_0;
/* Global Variable */
vu8 val;
/*********************************************************************
* @fn USARTx_CFG
*
* @brief Initializes the USART2 & USART3 peripheral.
*
* @return none
*/
//void USARTx_CFG(void)
//{
// GPIO_InitTypeDef GPIO_InitStructure = {0};
// USART_InitTypeDef USART_InitStructure = {0};
//
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
//
// /* USART1 TX-->D.5 */
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_Init(GPIOD, &GPIO_InitStructure);
//
//
// USART_InitStructure.USART_BaudRate = 9600;
// USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// USART_InitStructure.USART_StopBits = USART_StopBits_1;
// USART_InitStructure.USART_Parity = USART_Parity_No;
// USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// USART_InitStructure.USART_Mode = USART_Mode_Tx;
//
// USART_Init(USART1, &USART_InitStructure);
// USART_Cmd(USART1, ENABLE);
//}
void Tim1_CFG(void){ //для периодических прерываний через 100мс
printf("Timer CFG start\r\n");
TIM_TimeBaseInitTypeDef TIMBase_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
NVIC_EnableIRQ(TIM1_UP_IRQn);
TIMBase_InitStruct.TIM_Period = 10000-1; //T=1s
TIMBase_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIMBase_InitStruct.TIM_Prescaler = 2400-1; //F=10KHz
TIMBase_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM1, &TIMBase_InitStruct);
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = TIM1_UP_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM1->CTLR1 |= TIM_CEN; //включаем таймер
}
void ADC_CFG(void){
ADC_InitTypeDef ADC_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_241Cycles);
ADC_Calibration_Vol(ADC1, ADC_CALVOL_50PERCENT);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0}; //structure variable used for the GPIO configuration
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6; //PC0 - heatet_on, PC4,5,6 - S0,1,2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // Defines which Pin to configure
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Defines Output Type
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; // Defines speed
GPIO_Init(GPIOD, &GPIO_InitStructure);
//AFIO->PCFR1 &= ~(1<<15); //PA12RM set 0
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // PD4 ADC in
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
uint16_t Get_ADC_Val(void){
uint16_t val;
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
val = ADC_GetConversionValue(ADC1);
return val;
}
void Heater_On(void) {
GPIOC->OUTDR |= GPIO_HEATER_On_Off;
heater_enable = 0xFF;
printf("Heater On\n\r");
}
void Heater_Off(void) {
GPIOC->OUTDR &= ~GPIO_HEATER_On_Off;
heater_enable = 0;
printf("Heater Off\n\r");
}
/*********************************************************************
* @fn main
*
* @brief Main program.
*
* @return none
*/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
SystemCoreClockUpdate();
Delay_Init();
USART_Printf_Init(9600);
printf("SystemClk:%d\r\n",SystemCoreClock);
//USARTx_CFG();
GPIO_Config();
ADC_CFG();
Tim1_CFG();
Delay_Ms(100);
Heater_Off();
__enable_irq();
// while(1) {
// GPIOC->OUTDR |= GPIO_HEATER_On_Off;
// Delay_Us(10);
// GPIOC->OUTDR &= ~GPIO_HEATER_On_Off;
// Delay_Us(10);
//
// }
while(1)
{
}
}
__attribute__((interrupt("WCH-Interrupt-fast")))
void TIM1_UP_IRQHandler(void){
printf("Timer interrupt\r\n");
uint32_t temp;
if (TIM_GetITStatus(TIM1, TIM_IT_Update) == SET)
{
Delay_Ms(100);
channel++;
if (channel == 3) {
channel = 0;
}
temp = GPIOC->OUTDR & 0b10001111;
GPIOC->OUTDR = (temp | (channel << 4));
ADC_NTC[channel] = Get_ADC_Val();
printf("ADC channel %d = %d\r\n", channel, ADC_NTC[channel]);
//////////HEATER WORK ALGHORITHM////////////
if (heater_enable == 0) {
if (ADC_NTC[channel] >= Grad10) { //Temperature < 10 grad
Heater_On();
}
} else {
if (ADC_NTC[channel] <= Grad20) {
Heater_Off();
}
}
// this can be replaced with your code of flag so that in main's that flag can be handled
//ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
}
TIM_ClearITPendingBit(TIM1, TIM_IT_Update); //
}