Jak to jak udało mi się w końcu zbudować, termometr na układzie DS18B20 i STM32F103. Przy temperaturze dodatniej wszystko pięknie działa od 0 - 125 stopnie wynik jest pięknie wyświetlany, natomiast przy ujemnej temperaturze otrzymuję 4095,12 stopni. Taktowanie procesora 8MHz.
Kod: Zaznacz cały
#include "stm32f1xx_it.h"
#include "stm32f10x.h"
#include <stdio.h>
uint8_t Reset, Temperature_MSB, Temperature_LSB;
char String_Temperature[10];
float Temperature;
#define D4_SET (GPIOB -> ODR |= GPIO_ODR_ODR15);
#define D5_SET (GPIOB -> ODR |= GPIO_ODR_ODR14);
#define D6_SET (GPIOB -> ODR |= GPIO_ODR_ODR13);
#define D7_SET (GPIOB -> ODR |= GPIO_ODR_ODR12);
#define E_SET (GPIOA -> ODR |= GPIO_ODR_ODR9);
#define RS_SET (GPIOA -> ODR |= GPIO_ODR_ODR8);
#define D4_RESET (GPIOB -> ODR &= ~GPIO_ODR_ODR15);
#define D5_RESET (GPIOB -> ODR &= ~GPIO_ODR_ODR14);
#define D6_RESET (GPIOB -> ODR &= ~GPIO_ODR_ODR13);
#define D7_RESET (GPIOB -> ODR &= ~GPIO_ODR_ODR12);
#define E_RESET (GPIOA -> ODR &= ~GPIO_ODR_ODR9);
#define RS_RESET (GPIOA ->ODR &= ~GPIO_ODR_ODR8);
#define SIO_SET (GPIOA -> ODR |= GPIO_ODR_ODR10);
#define SIO_RESET (GPIOA -> ODR &= ~GPIO_ODR_ODR10);
void Lcd_Send_Half_Byte(uint8_t Data)
{
if (Data & 0x01) D4_SET else D4_RESET;
if (Data & 0x02) D5_SET else D5_RESET;
if (Data & 0x04) D6_SET else D6_RESET;
if (Data & 0x08) D7_SET else D7_RESET;
}
void Lcd_Write_Byte(uint8_t Data)
{
E_SET;
Lcd_Send_Half_Byte(Data >> 4);
E_RESET;
E_SET;
Lcd_Send_Half_Byte(Data);
E_RESET;
Delay_ms(5);
}
void Lcd_Write_Command(uint8_t Command)
{
RS_RESET;
Lcd_Write_Byte(Command);
}
void Lcd_Write_Data(uint8_t Data)
{
RS_SET;
Lcd_Write_Byte(Data);
}
void Lcd_Init(void)
{
RS_SET;
E_SET;
Delay_ms(45);
E_RESET;
RS_RESET;
E_SET;
Lcd_Send_Half_Byte(0x03);
E_RESET;
Delay_ms(5);
E_SET;
Lcd_Send_Half_Byte(0x03);
E_RESET;
Delay_ms(5);
E_SET;
Lcd_Send_Half_Byte(0x03);
E_RESET;
Delay_ms(5);
E_SET;
Lcd_Send_Half_Byte(0x02);
E_RESET;
Delay_ms(5);
Lcd_Write_Command(0x28); // Function SET // OFF DISPLAY // DISPLAY TWO-LINE // MATRIX CHARACTER 5 * 7 POINTS
Lcd_Write_Command(0x01); // CLEAR DISPLAY /
Lcd_Write_Command(0x06); // ENTRY MODE SET //
Lcd_Write_Command(0x0C); // DISPLAY ON //
Delay_ms(5);
}
void Lcd_Char(char c)
{
Lcd_Write_Data(c);
}
void Lcd_Send_String (char * String)
{
while(*String) Lcd_Char(*String++);
}
void Lcd_Int(int val)
{
char bufor[17];
sprintf(bufor,"%d",val);
Lcd_Send_String(bufor);
}
void Lcd_XY(uint8_t Y, uint16_t X)
{
switch (Y)
{
case 0: Y = 0x00; break;
case 1: Y = 0x40; break;
}
Lcd_Write_Command((0x80 + Y + X));
Delay_ms(5);
}
inline __attribute__((always_inline)) inline void SET_SIO_OUTPUT(void)
{
GPIOA -> CRH &= ~GPIO_CRH_CNF10_1;
GPIOA -> CRH |= GPIO_CRH_MODE10_1;
GPIOA -> CRH &= ~GPIO_CRH_CNF10_0;
}
inline __attribute__((always_inline)) inline void SET_SIO_INPUT(void)
{
GPIOA -> CRH &= ~GPIO_CRH_MODE10_1;
GPIOA -> CRH &= ~GPIO_CRH_CNF10_0;
GPIOA -> CRH |= GPIO_CRH_CNF10_1;
GPIOA -> ODR &= ~GPIO_ODR_ODR10;
}
inline __attribute__((always_inline)) inline void Delay_us(uint16_t Time)
{
TIM1 -> CNT = 0;
while((TIM1 -> CNT) <= Time);
}
uint8_t One_Wire_Reset_Pulse(void)
{
uint8_t Presence_Impulse = 0;
SET_SIO_OUTPUT();
SIO_RESET;
Delay_us(480);
SET_SIO_INPUT();
Delay_us(37);
if(!(GPIOA ->IDR & GPIO_IDR_IDR10))
{
Presence_Impulse ++;
}
Delay_us(443);
if(GPIOA ->IDR & GPIO_IDR_IDR10)
{
Presence_Impulse ++;
}
if(Presence_Impulse == 2)
{
return Presence_Impulse = 1;
}
else
{
return Presence_Impulse = 0;
}
}
void One_Wire_Send_Bit(uint8_t Bit)
{
SET_SIO_OUTPUT();
if(Bit == 0)
{
SIO_RESET;
Delay_us(60);
SIO_SET;
Delay_us(1);
}
else
{
SIO_RESET;
Delay_us(1);
SIO_SET;
Delay_us(60);
}
}
void One_Wire_Send_Byte (uint8_t Byte)
{
uint8_t Cnt = 0x01;
while(1)
{
if(Byte & Cnt)
{
One_Wire_Send_Bit(1);
}
else
{
One_Wire_Send_Bit(0);
}
Cnt <<= 1;
if(!Cnt) break;
}
}
uint8_t One_Wire_Read_Bit(void)
{
uint8_t Bit = 0;
SET_SIO_OUTPUT();
SIO_RESET;
Delay_us(5);
SET_SIO_INPUT();
Delay_us(5);
if(GPIOA ->IDR & GPIO_IDR_IDR10)
{
Bit = 1;
}
else
{
Bit = 0;
}
Delay_us(45);
return Bit;
}
uint8_t One_Wire_Read_Byte(void)
{
uint8_t Read_Byte = 0;
uint8_t Cnt = 0;
while(1)
{
if(One_Wire_Read_Bit())
{
Read_Byte |= 0x01 << Cnt;
}
Cnt ++;
if(Cnt > 7) break;
}
return Read_Byte;
}
int main (void)
{
RCC -> APB2ENR = RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_TIM1EN;
GPIOB -> CRH |= GPIO_CRH_MODE15_1;
GPIOB -> CRH &= ~GPIO_CRH_CNF15_0;
GPIOB -> CRH |= GPIO_CRH_MODE14_1;
GPIOB -> CRH &= ~GPIO_CRH_CNF14_0;
GPIOB -> CRH |= GPIO_CRH_MODE13_1;
GPIOB -> CRH &= ~GPIO_CRH_CNF13_0;
GPIOB -> CRH |= GPIO_CRH_MODE12_1;
GPIOB -> CRH &= ~GPIO_CRH_CNF12_0;
GPIOA -> CRH |= GPIO_CRH_MODE9_1;
GPIOA -> CRH &= ~GPIO_CRH_CNF9_0;
GPIOA -> CRH |= GPIO_CRH_MODE8_1;
GPIOA -> CRH &= ~GPIO_CRH_CNF8_0;
TIM1 -> PSC = 8;
TIM1 -> ARR = 65535;
TIM1 -> CR1 = TIM_CR1_CEN;
SysTick_Config(8000000/1000);
Lcd_Init();
Lcd_XY(0,0);
Lcd_Send_String("TERMOMETR MY LIB");
Lcd_XY(1,5);
Lcd_Send_String("DS18B20");
Delay_ms(2000);
Lcd_Write_Command(0x01);
Lcd_XY(0,5);
Lcd_Send_String("DS18B20");
while(1)
{
Reset = One_Wire_Reset_Pulse();
if(Reset == 1)
{
One_Wire_Send_Byte(0xCC);
One_Wire_Send_Byte(0x44);
Delay_ms(750);
Reset = One_Wire_Reset_Pulse();
One_Wire_Send_Byte(0xCC);
One_Wire_Send_Byte(0xBE);
Temperature_LSB = One_Wire_Read_Byte();
Temperature_MSB = One_Wire_Read_Byte();
Reset = One_Wire_Reset_Pulse();
Temperature = (float)(Temperature_LSB + (Temperature_MSB << 8)) * 0.0625;
sprintf(String_Temperature, "%.2f", Temperature);
Lcd_XY(1, 0);
Lcd_Send_String(" ");
Lcd_XY(1, 0);
Lcd_Send_String("TEMP: ");
Lcd_Send_String(String_Temperature);
Lcd_Send_String(" *C");
}
else
{
Lcd_XY(1, 0);
Lcd_Send_String(" BRAK CZUJNIKA");
}
}
}