суббота, 16 сентября 2017 г.

Отображаем температуру на индикаторе

Снимать данные с ADC () мы научились в примере: https://le2x.blogspot.com/2017/09/blog-post_56.html
Отображать информацию на семисегментном индикаторе научились в примере:
Осталось совместить оба примера чтобы отобразить на индикаторе температуру с внутреннего термометра STM32

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_gpio.h"

// Общие выводы индикатора
#define D0 0x100 //индикатор 1 GPIO_Pin_7
#define D1 0x200 //индикатор 2 GPIO_Pin_8
#define D2 0x400 //индикатор 3 GPIO_Pin_9

//0 0x3F 00111111
//1 0x06 00000110
//2 0x5B 01011011
//3 0x4F 01001111
//4 0x66 01100110
//5 0x6D 01101101
//6 0x7D 01111101
//7 0x07 00000111
//8 0x7F 01111111
//9 0x6F 01101111
//c 0x58 01011000

// массив со значениями чисел от 0 до 9
int number[11] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x58};
int t=101;

void delay (uint32_t time_delay) //функция задержки
{
    uint32_t i;
    for (i=0;i<time_delay;i++);
}

int main(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    ADC_InitTypeDef term;
    term.ADC_Mode = ADC_Mode_Independent;
    term.ADC_ScanConvMode = DISABLE;
    term.ADC_ContinuousConvMode = ENABLE;
    term.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    term.ADC_DataAlign = ADC_DataAlign_Right;
    term.ADC_NbrOfChannel = 1;

    ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, ADC_SampleTime_239Cycles5);
    ADC_Init (ADC1, &term);

    ADC_TempSensorVrefintCmd(ENABLE);
    ADC_Cmd (ADC1, ENABLE);

    ADC_ResetCalibration(ADC1);    //Сброс калибровочных данных
    while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);    //Новая калибровка
    while(ADC_GetCalibrationStatus(ADC1));

    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    ADC_Cmd (ADC1, ENABLE);


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    //настройка портов под сегменты
    GPIO_InitTypeDef SEG;
    SEG.GPIO_Speed = GPIO_Speed_2MHz;
    SEG.GPIO_Mode  = GPIO_Mode_Out_PP;
    SEG.GPIO_Pin   = GPIO_Pin_0| GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_6;
    GPIO_Init(GPIOA, &SEG);

    //настройка портов под индикаторы
    GPIO_InitTypeDef DIG;
    DIG.GPIO_Speed = GPIO_Speed_2MHz;
    DIG.GPIO_Mode  = GPIO_Mode_Out_OD; //настраиваем выходы на режим open drain
    DIG.GPIO_Pin   = GPIO_Pin_7| GPIO_Pin_8| GPIO_Pin_9;
    GPIO_Init(GPIOA, &DIG);

    int value;
    int temperature;


    while(1)
    {
       if (t > 100) { // для того чтобы слишком часто не менять цифры на индикаторе
          temperature = (1750 - ADC_GetConversionValue(ADC1)) / 4.3 + 25; // результат в градусах Цельсия
          t=0;
       }

       value = temperature/10; //получаем значение первого знакоместа
       GPIO_Write(GPIOA, number[value]);
       GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_SET);
       GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);
       delay (10000);

       value = temperature - (temperature/10)*10; //получаем значение второго знакоместа
       GPIO_Write(GPIOA, number[value]);
       GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_SET);
       GPIO_WriteBit(GPIOA, GPIO_Pin_9, Bit_SET);
       delay (10000);

       value = 10;
       GPIO_Write(GPIOA, number[value]); // значение третьего знакоместа - значок градусов Цельсия
       GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);
       GPIO_WriteBit(GPIOA, GPIO_Pin_9, Bit_SET);
       delay (10000);

       t++;
    }
}