STM32F4VE LCD4x20 HD44780 Keil

Опубликовано stm32 - чт, 01/30/2020 - 12:32

STM32F4VE DS18B20 HD44780 Keil  в этой статье мы подключим и выведем информацию на один из популярный ЖК индикаторов китайского производства LCD 4x20. В этом индикаторе отсутствует таблица русских символов!!!  Есть в одном известном китайским интернет магазине с русской таблицей стоит правда, дороже. Вот ссылка !! Не знаю сколько просуществует магазин, но если нужно пока есть ..  LCD 4x20 на микроконтроллере я кратко описал в статье LCD 1x16, 2x16, 4x20  HD44780 Подключать  LCD 4x20 к плате STM32F4VE будем через расширитель портов PCF8574 статья

Ds18b20

Подключим к STM32F4VE    -  порт  РE 2.

LCD 4x20 

На плате  STM32F4VE  будем использовать I2C как альтернативный

 z23

подключаем проводами к  PCF8574 

 

ss1

Плата с PCF8574                                             STM32F4VE

                GND                       ->                              GND  

                VCC                        ->                              VCC  подключаем на  +   5B!!!!!!

                SDA                        ->                              PB11

                 SCL                         ->                              PB10

 

Подтяжка SDA и SCL у нас есть 4.7 k (см. ниже отметил красным)

z24

Адресация запаяна перемычками на GND!!

g10

Определим сразу адрес микросхемы PCF8574  для "общения"

Из документации на  PCF8574

 

g14

У меня на плате  установлена микросхема  PCF8574T  и A2A1A0 (запаяны на GND) т.е. A2 = 0, A1 = 0, A0 = 0 подставляем 

 S 0100 0000 A  - где 0100 0000 - адрес в BIN переведем в калькуляторе Windows 

z25

Получим в   HEX - 40h - запомним это !!!

На этом все подключения заканчиваются.

Перейдем к написанию программы.

Проект будем создавать в Keil uVision5 версии V5.29.0.0

Проект создать самому, можно взять готовый. Можем создать сами - отлично ! Просто читаем дальше. Для тех у кого пока не получается самостоятельно  - скачиваем архив созданный ранее, с начальными настройками - ссылка. 

Открываем Keil и начинаем ..

Я возьму за основу ранее созданный проект с начальными настройками и дополню его необходимы.

Приступим 

z1

В проект необходимо добавит следующие файлы:

i2c_lcd_HD44780.с

i2c_lcd_HD44780.h

ds18b20.c

ds18b20.h

Начнем создавать и заполнять содержимым

z2

z3

НЕ забываем правильно указывать папку хранения созданных файлов!!!

Содержимое файла 

i2c_lcd_HD44780.c

Начало файла i2c_lcd_HD44780.c

***********************************************************************************

#include "i2c_lcd_HD44780.h"
#include "port_ini.h"

uint8_t backlightState = 1; // подсветка экрана
void I2C2_Init(void)
{
    GPIO_InitTypeDef I2C_user;
      I2C_InitTypeDef i2c;
    
    // Включаем тактирование 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
 
   // I2C использует две ноги микроконтроллера, их тоже нужно настроить
    I2C_user.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
    I2C_user.GPIO_Mode = GPIO_Mode_AF;            
    I2C_user.GPIO_Speed = GPIO_Speed_50MHz;
    I2C_user.GPIO_OType = GPIO_OType_OD;
    I2C_user.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &I2C_user);
 
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2);
 
    // Включаем I2C
    I2C_Cmd(I2C2, ENABLE); 

    // настройка I2C
    i2c.I2C_ClockSpeed = 100000; 
    i2c.I2C_Mode = I2C_Mode_I2C;
    i2c.I2C_DutyCycle = I2C_DutyCycle_2;
    i2c.I2C_OwnAddress1 = 0;
    i2c.I2C_Ack = I2C_Ack_Disable;
    i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Init(I2C2, &i2c);
 
}


void lcd_Goto(uint8_t row, uint8_t col) {  // выбираем строчку для вывода
#ifdef LCD_2004
    switch (row){
        case 1:
            lcd_Command(0x80 + col);
            break;
        case 2:
            lcd_Command(0x80 + col + 0x40);
            break;
        case 3:
            lcd_Command(0x80 + col + 0x14);
            break;
        case 4:
            lcd_Command(0x80 + col + 0x54);
            break;
    }
#endif
}

void lcd_PrintC(const uint8_t *str) {   // Вывод строки
     uint8_t i;
     while (i = *str++){
        lcd_Data(i);
     }
}


void lcd_Init(void) {                  // Инициализация индикатора
    I2C2_Init();
    
    
    
    lcd_Command(0x33);
    delay_ms(30);
    lcd_Command(0x32); // 
    lcd_Command(0x28); // 
    lcd_Command(0x08); // 
    lcd_Command(0x01); // 
    delay_ms(30);
    lcd_Command(0x06); // 
    lcd_Command(0x0C); // 
}

void lcd_Send(uint8_t data) {

    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
    I2C_GenerateSTART(I2C2, ENABLE);

    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));//(0x40+LCD_ADDR) << 1
    I2C_Send7bitAddress(I2C2, LCD_ADDR, I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    I2C_SendData(I2C2, data);
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    I2C_GenerateSTOP(I2C2, ENABLE);
}

void lcd_Command(uint8_t com) {
    uint8_t data = 0;

    data |= (backlightState & 0x01) << BL;

    data |= (((com & 0x10) >> 4) << DB4);
    data |= (((com & 0x20) >> 5) << DB5);
    data |= (((com & 0x40) >> 6) << DB6);
    data |= (((com & 0x80) >> 7) << DB7);
    lcd_Send(data);

    data |= (1 << EN);
    lcd_Send(data);
    delay_us(200);

    data &= ~(1 << EN);
    lcd_Send(data);
    delay_us(200);

    data = 0;

    data |= (backlightState & 0x01) << BL;

    data |= (((com & 0x01) >> 0) << DB4);
    data |= (((com & 0x02) >> 1) << DB5);
    data |= (((com & 0x04) >> 2) << DB6);
    data |= (((com & 0x08) >> 3) << DB7);
    lcd_Send(data);

    data |= (1 << EN);
    lcd_Send(data);
    delay_us(200);

    data &= ~(1 << EN);
    lcd_Send(data);
    delay_us(200);
}

void lcd_Backlight(uint8_t state) {
    backlightState = (state & 0x01) << BL;
    lcd_Send(backlightState);
}

void lcd_Data(uint8_t com) {
    uint8_t data = 0;

    data |= (1 << EN);
    data |= (1 << RS);
    data |= (backlightState & 0x01) << BL;

    data |= (((com & 0x10) >> 4) << DB4);
    data |= (((com & 0x20) >> 5) << DB5);
    data |= (((com & 0x40) >> 6) << DB6);
    data |= (((com & 0x80) >> 7) << DB7);
    lcd_Send(data);
    delay_us(200);

    data &= ~(1 << EN);
    lcd_Send(data);
    delay_us(200);

    data = 0;

    data |= (1 << EN);
    data |= (1 << RS);
    data |= (backlightState & 0x01) << BL;

    data |= (((com & 0x01) >> 0) << DB4);
    data |= (((com & 0x02) >> 1) << DB5);
    data |= (((com & 0x04) >> 2) << DB6);
    data |= (((com & 0x08) >> 3) << DB7);
    lcd_Send(data);
    delay_us(200);

    data &= ~(1 << EN);
    lcd_Send(data);
    delay_us(200);
}

***********************************************************************************

Конец файла i2c_lcd_HD44780.c

Сохраняем 

z4

 

Переходим к следующему файлу 

 

z5

 

Содержимое файла 

i2c_lcd_HD44780.h

Начало файла i2c_lcd_HD44780.h

***********************************************************************************

#ifndef _I2C_LCD_H_
#define _I2C_LCD_H_

#include "stm32f4xx_i2c.h"


// PCF8574
#define LCD_ADDR    0x40 // адрес PCF8574T 

// 
#define LCD_2004        // Выбор 4-х строчного индикатора
//#define LCD_1602      // Выбор 2-х строчного индикатора 
                        //- данной программе отключено
// 
#define PCF_P0    0
#define PCF_P1    1
#define PCF_P2    2
#define PCF_P3    3
#define PCF_P4    4
#define PCF_P5    5
#define PCF_P6    6
#define PCF_P7    7

// 
#define DB4        PCF_P4
#define DB5        PCF_P5
#define DB6        PCF_P6
#define DB7        PCF_P7
#define EN        PCF_P2
#define RW        PCF_P1
#define RS        PCF_P0
#define BL        PCF_P3

// 
extern uint8_t backlightState;

void lcd_Init(void); // 
void lcd_Backlight(uint8_t state); // 
void lcd_Goto(uint8_t row, uint8_t col); // 
void lcd_PrintC(const uint8_t *str); // 


// 
void lcd_Send(uint8_t data); // 
void lcd_Command(uint8_t com); // 
void lcd_Data(uint8_t com);  // 

#endif
 

***********************************************************************************

Конец файла i2c_lcd_HD44780.h

Сохраняем

z6

 

 

Продолжим

z7

 

Содержимое файла 

ds18b20.c

Начало файла ds18b20.c

***********************************************************************************

#include "ds18b20.h"
#include "main.h"

uint8_t status;

void red_ds18b20_init(void)
{
status = ds18b20_init(SKIP_ROM);
}

uint8_t ds18b20_Reset(void)
{

  uint16_t status;
  GPIO_ResetBits(GPIOE, GPIO_Pin_2); // Устанавливаем на ножке PE - "0"
     delay_us(485);// Задерживаемся на 485 микросекунд
    GPIO_SetBits(GPIOE, GPIO_Pin_2); // Устанавливаем на ножке PE1 - "1"
  delay_us(65);// Задерживаемся на 65 микросекунд
    status = GPIOE->IDR & GPIO_IDR_IDR_2;//Проверяем ответила ли DS18b20 на шине
    delay_us(485);// Задерживаемся на 485 микросекунд
  return (status ? 1 : 0);//Возвращаем результат
}

//--------------------------------------------------

uint8_t ds18b20_ReadBit(void)

{
  uint8_t bit = 0;
  GPIO_ResetBits(GPIOE, GPIO_Pin_2); // Устанавливаем на ножке PE1 - "0"
  delay_us(2);// Задерживаемся на 2 микросекунды
    GPIO_SetBits(GPIOE, GPIO_Pin_2); // Устанавливаем на ножке PE1 - "1"
  delay_us(13);// Задерживаемся на 13 микросекунды
    bit = (GPIOE->IDR & GPIO_IDR_IDR_2 ? 1 : 0);//Проверяем ответила ли DS18b20 на шине
  delay_us(45);// Задерживаемся на 45 микросекунд
    return bit;
}

//-----------------------------------------------

uint8_t ds18b20_ReadByte(void)

{
  uint8_t data = 0;
  for (uint8_t i = 0; i <= 7; i++)
  data += ds18b20_ReadBit() << i;
  return data;
}

//-----------------------------------------------

void ds18b20_WriteBit(uint8_t bit)

{

  GPIO_ResetBits(GPIOE, GPIO_Pin_2); // Устанавливаем на ножке PE1 - "0"
  delay_us(bit ? 3 : 65);   ///65
  GPIO_SetBits(GPIOE, GPIO_Pin_2); // Устанавливаем на ножке PE1 - "1"
  delay_us(bit ? 65 : 3);   ///65
 
}

//-----------------------------------------------

void ds18b20_WriteByte(uint8_t dt)

{
  for (uint8_t i = 0; i < 8; i++)
  {
    ds18b20_WriteBit(dt >> i & 1);
    delay_us(5);
  }

}

//----------------------------------------------------------

uint8_t ds18b20_init(uint8_t mode)

{
  if(ds18b20_Reset()) return 1;
  if(mode==SKIP_ROM)
  {
   ds18b20_WriteByte(0xCC);
    //WRITE SCRATCHPAD
   ds18b20_WriteByte(0x4E);
   //TH REGISTER 100 градусов
   ds18b20_WriteByte(0x64);
  //TL REGISTER - 30 градусов
   ds18b20_WriteByte(0x9E);
  //Resolution 12 bit
   ds18b20_WriteByte(RESOLUTION_12BIT); 
    }
  
    
    return 0;
}

//----------------------------------------------------------

void ds18b20_MeasureTemperCmd(uint8_t mode, uint8_t DevNum)

{
  ds18b20_Reset();
  if(mode==SKIP_ROM)
  {
    //SKIP ROM
    ds18b20_WriteByte(0xCC);
  }
  //CONVERT T
  ds18b20_WriteByte(0x44);
}

//----------------------------------------------------------

void ds18b20_ReadStratcpad(uint8_t mode, uint8_t *Data, uint8_t DevNum)

{
  uint8_t i;
  ds18b20_Reset();
  if(mode==SKIP_ROM)
  {
    //SKIP ROM
    ds18b20_WriteByte(0xCC);
  }
    //READ SCRATCHPAD

  ds18b20_WriteByte(0xBE);
  for(i=0;i<8;i++)
  {
    Data[i] = ds18b20_ReadByte();
  }
}

//----------------------------------------------------------
uint8_t ds18b20_GetSign(uint16_t dt)
{
  //Проверяем 11 бит
  if (dt&(1<<11)) return 1;
  else return 0;
}
//----------------------------------------------------------
float ds18b20_Convert(uint16_t dt)
{
  float t;
  t = (float) ((dt&0x07FF)>>4); // Отбросил знаковые и дробные биты
  //Прибавим дробную часть
  t += (float)(dt&0x000F) / 16.0f;
  return t;
}

 

***********************************************************************************

Конец файла ds18b20.c

Сохраняем

z8

Продолжаем 

z9

Содержимое файла 

ds18b20.h

Начало файла ds18b20.h

***********************************************************************************

#ifndef DS18B20_H_
#define DS18B20_H_


#include "stm32f4xx.h"
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#define SKIP_ROM 0
#define NO_SKIP_ROM 1
#define RESOLUTION_9BIT 0x1F
#define RESOLUTION_10BIT 0x3F
#define RESOLUTION_11BIT 0x5F
#define RESOLUTION_12BIT 0x7F

uint8_t ds18b20_init(uint8_t mode);
void ds18b20_MeasureTemperCmd(uint8_t mode, uint8_t DevNum);
void ds18b20_ReadStratcpad(uint8_t mode, uint8_t *Data, uint8_t DevNum);
uint8_t ds18b20_GetSign(uint16_t dt);
float ds18b20_Convert(uint16_t dt);
void red_ds18b20_init(void);
#endif /* DS18B20_H_ */

***********************************************************************************

Конец файла ds18b20.h

Сохраняем

z10

 

Теперь поправим файлы существующие в проекте 

Файл port_ini.с добавим порт для DS18B20

Содержимое файла 

port_ini.с

Начало файла port_ini.с

***********************************************************************************

#include "port_ini.h"


uint16_t delay_count; 


#define    DWT_CYCCNT    *(volatile unsigned long *)0xE0001004
#define    DWT_CONTROL   *(volatile unsigned long *)0xE0001000
#define    SCB_DEMCR     *(volatile unsigned long *)0xE000EDFC

// Прерывание - ЭТО ОБЯЗАТЕЛЬНО!!  
         
void SysTick_Handler(void)
{
if (delay_count > 0)
       {
    delay_count --;
       } 
}         

// Задержка Микро

void delay_us(uint32_t us)   // Микро секунды 10-6
{
    int32_t us_count_tick =  us * (SystemCoreClock/1000000);
    //разрешаем использовать счётчик
    SCB_DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
        //обнуляем значение счётного регистра
    DWT_CYCCNT  = 0;
        //запускаем счётчик
    DWT_CONTROL |= DWT_CTRL_CYCCNTENA_Msk; 
    while(DWT_CYCCNT < us_count_tick);
        //останавливаем счётчик
    DWT_CONTROL &= ~DWT_CTRL_CYCCNTENA_Msk;
    
}
// Задержка МиЛи

void delay_ms(uint32_t ms) // МиЛи секунды 10-3
{
    int32_t ms_count_tick =  ms * (SystemCoreClock/1000);
    //разрешаем использовать счётчик
    SCB_DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
         //обнуляем значение счётного регистра
    DWT_CYCCNT  = 0;
        //запускаем счётчик
    DWT_CONTROL|= DWT_CTRL_CYCCNTENA_Msk; 
    while(DWT_CYCCNT < ms_count_tick);
        //останавливаем счётчик
    DWT_CONTROL &= ~DWT_CTRL_CYCCNTENA_Msk;
    

 void sdelay_ms(uint16_t delay_temp) 
{
    
delay_count = delay_temp;
    while (delay_count)
 {
  };
}


// Конфигурируем порты для управления светодиодами встроенными в плату

void GPIO_init(void)
{
      GPIO_InitTypeDef GPIO_InitStructure;                     // создаем структуру
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);     // включаем тактирования порта В
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);     // включаем тактирование порта А
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);     // включаем тактирование порта E
     //  Настройка порта под сверодиод -> выход PB0 выход PB1  
                      
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; 
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
      GPIO_Init(GPIOB, &GPIO_InitStructure);
        
    // Светодиод на плате подключенный к порту выход РА 6 
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;    
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
        GPIOA->ODR ^= GPIO_Pin_6;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        
  
    // Светодиод на плате подключенный к порту выход РА 7     
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
      GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;    
      GPIOA->ODR ^= GPIO_Pin_7;
            GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // ds18b20 к порту выход РE 2 
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;    
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     
      GPIO_Init(GPIOE, &GPIO_InitStructure); 

       
}

// Конфигурируем порты для управления кнопками встроенными в плату
     void button_ini(void)
         {
       RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);     // включаем тактирование порта А
             
             GPIO_InitTypeDef init_button;  

// Кнопка на плате подключенная к порту РЕ 3 
      init_button.GPIO_Pin = GPIO_Pin_3;    
            init_button.GPIO_Mode = GPIO_Mode_IN; 
      init_button.GPIO_Speed = GPIO_Low_Speed ;  
      init_button.GPIO_PuPd = GPIO_PuPd_UP;    
            GPIO_Init(GPIOE, &init_button); 
             
   // Кнопка на плате подключенная к порту РЕ 4
      init_button.GPIO_Pin = GPIO_Pin_4;
            init_button.GPIO_Mode = GPIO_Mode_IN; 
      init_button.GPIO_Speed = GPIO_Low_Speed ;
      init_button.GPIO_PuPd = GPIO_PuPd_UP;
            GPIO_Init(GPIOE, &init_button);
         }
         
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
// Конфигурируем USART2 

    
void USART2_Configuration(void)

    //  USART2 у которого:
  //  USART2 TX - PA2
  //  USART2 RX - PA3
        GPIO_InitTypeDef  GPIO_InitStructure;   // Создаем структуру порта
      USART_InitTypeDef USART_InitStructure;  // Создаем структуру USART2
    
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //Включаем тактирование порта A
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //Включаем тактирование порта USART2    
    
     // Можно сделать одной строчкой работает и так и так
    //  RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_APB1Periph_USART2,ENABLE);
    
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); //Подключаем PA3 к TX USART2
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); //Подключаем PA2 к RX USART2
    
    //Конфигурируем PA2 как альтернативную функцию -> TX UART2.
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    //Конфигурируем PA3 как альтернативную функцию -> RX UART. 
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
            
            // Конфигурируем настройки USART2 
      USART_InitStructure.USART_BaudRate = 115200; //Скорость обмена 115200 бод
      USART_InitStructure.USART_WordLength = USART_WordLength_8b; //Длина слова 8 бит
      USART_InitStructure.USART_StopBits = USART_StopBits_1; //1 стоп-бит
      USART_InitStructure.USART_Parity = USART_Parity_No ; //Без проверки четности
      USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //Без аппаратного контроля
      USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Включен передатчик и приемник USART2
      // Можно задать настройки по умолчанию строкой
            // USART_StructInit(&USART_InitStructure);

      USART_Init(USART2, &USART_InitStructure);  // Инициализируем структуру
      USART_Cmd(USART2, ENABLE); //Включаем UART
   
}
 

***********************************************************************************

Конец файла  port_ini.с

Далее ...

Дополним port_ini.h добавив в него определение ds18b20

Содержимое файла 

port_ini.h

Начало файла port_ini.h

***********************************************************************************

#ifndef PORT_INI_H
#define PORT_INI_H

#include "stm32f4xx.h" 
#include "ds18b20.h"

void GPIO_init(void); 
void button_ini(void);
void delay_ms(uint32_t ms);
void delay_us(uint32_t us);
void USART2_Configuration(void);

#endif

***********************************************************************************

Конец файла  port_ini.h

 

И наконец поправим main.c

Содержимое файла 

main.c

Начало файла main.c

***********************************************************************************

 

#include "main.h"
#include <stdio.h>
#include <ds18b20.h>
#include <i2c_lcd_HD44780.h>

//*******************************************************
char str3[10];
char pstr[20];
char str4[60];
unsigned char str2[60];
uint8_t dt[8];
uint16_t raw_temper;
float temper;
char c;
uint32_t i=0;
uint32_t set=0;

//*********************************************************
int main(void)
{    
  SysTick_Config(SystemCoreClock / 1000);
    
//  Настраиваем порты
      GPIO_init();
//  Настраиваем кнопки установленные на плате    
       button_ini();
// Настраиваем связь 
       USART2_Configuration();
// ds18b20
      red_ds18b20_init();
 // LCD 4x20.
       lcd_Init();
//
       lcd_Goto(1,2);
       lcd_PrintC("www.stm32res.ru");
       lcd_Goto(2, 1);
       lcd_PrintC("Ds18b20 & PCF8574");
     

        while (1)
     {      
         ds18b20_MeasureTemperCmd(SKIP_ROM, 0); // после этой команды ждут 800 ms 
        // мы просто моргнем светодиодами
        // НЕ просто включаем и выключаем светодиод эта задержка необходима для того

       //  чтобы DS18b20 успела посчитать - если необходимо эти строчки убрать - просто 

       // добавьте delay_ms(800); или используйте любой другой метод!!!!

  
        GPIO_ResetBits(GPIOA, GPIO_Pin_7); //Подаем «0» на PA7
        delay_ms(400);              
        GPIO_SetBits(GPIOA, GPIO_Pin_7); //Подаем «0» на PA7
        delay_ms(400);
      // 
            

         ds18b20_ReadStratcpad(SKIP_ROM, dt, 0);
         raw_temper = ((uint16_t)dt[1]<<8)|dt[0];
         if(ds18b20_GetSign(raw_temper)) c='-';
         else c='+';
         temper = ds18b20_Convert(raw_temper);
         sprintf(str3,"Temperatura  %c%.1f C",c, temper);
         lcd_Goto(4, 0);
         lcd_PrintC(str3);
         }
    }

***********************************************************************************

Конец файла  main.c

Все сохраняем.

z10

 

 

Выбираем 

z13

Ждем и ... получаем ошибки (если вы воспользовались моим проектом в начале статьи)

z26

Ошибки с названием файла и расширением O т.е. например i2с_LCD_hd44700.0 говорит о том,

используется команда из одноименного файла которая не известна.... 

И это правильно!!!  т.к. в проекте который мы дополняем (тот который было предложено скачать в начале статьи) не имеем подключенную библиотеку для работы с I2C!!!! 

Отсутствует библиотеки с названием stm32f4xx_i2c.h и stm32f4xx_i2c.с  - их просто надо добавить именно !! в наш проект

В случае использования моего начального проекта - файлы находятся по адресу  

407\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_i2c.h

407\STM32F4xx_StdPeriph_Driver\scr\stm32f4xx_i2c.с 

Давайте их подключим !! 

Делаем следующую последовательность действий ..

 

z11

 

z14

 

Стрелкой перемещаемся ниже к нужной нам папке

 

z15

 

z16

Все файлы в данном проекте с расширением *с  - в папке src

Все файлы в данном проекте с расширением *h  - в папке inc

Добавляем 

z17

Добавляем командой Add

Переходим в папку inc выбираем тип файла - в нашем случае с расширением *h

z18

Появляются файлы  - выбираем 

z19

 

Все добавили!!

Переходим в проект и жмем 

z20

 

В итоге - ошибок нет !! Предупреждения пока не замечаем ..

z27

 

Прошиваем наш микроконтроллер написанной программой и если все сделано как описано выше на  

LCD 4x20  получим следующую картинку 

G2

Этой же программой можно выводить и  LCD 1x16 и LCD 2x16 как я показал в статье     LCD 1x16, 2x16, 4x20  HD44780

Ура!! Урaaa!!!Ура!!

И если  у вас это тоже получилось - то вы имеете возможность поощрить меня  за мои статьи!!  

 

 

Яндекс.Метрика