stm32和lcd1602时间的程序
时间: 2023-11-20 10:05:32 浏览: 93
下面是一个简单的 STM32 和 LCD1602 时间显示程序,使用的是 STM32F103C8T6 开发板和 I2C 接口的 LCD1602 模块。
首先,需要初始化 STM32 的时钟和 I2C 接口。然后,在主循环中,获取当前时间并将其转换为字符串格式,最后将其显示在 LCD1602 屏幕上。
```c
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_i2c.h"
#include "string.h"
#include "stdio.h"
#define I2C1_PORT GPIOB
#define I2C1_SCL GPIO_Pin_6
#define I2C1_SDA GPIO_Pin_7
#define LCD_ADDR 0x27
I2C_InitTypeDef I2C_InitStructure;
void I2C1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitStructure.GPIO_Pin = I2C1_SCL | I2C1_SDA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C1_PORT, &GPIO_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
void I2C1_WriteByte(uint8_t addr, uint8_t data)
{
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, data);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
}
void LCD_Init(void)
{
I2C1_WriteByte(LCD_ADDR, 0x00);
delay_ms(15);
I2C1_WriteByte(LCD_ADDR, 0x30);
delay_ms(5);
I2C1_WriteByte(LCD_ADDR, 0x30);
delay_ms(1);
I2C1_WriteByte(LCD_ADDR, 0x30);
delay_ms(1);
I2C1_WriteByte(LCD_ADDR, 0x20);
delay_ms(1);
I2C1_WriteByte(LCD_ADDR, 0x28);
delay_ms(1);
I2C1_WriteByte(LCD_ADDR, 0x08);
delay_ms(1);
I2C1_WriteByte(LCD_ADDR, 0x01);
delay_ms(2);
I2C1_WriteByte(LCD_ADDR, 0x06);
delay_ms(1);
I2C1_WriteByte(LCD_ADDR, 0x0c);
delay_ms(1);
}
void LCD_WriteChar(uint8_t data)
{
I2C1_WriteByte(LCD_ADDR, (data & 0xf0) | 0x0d);
I2C1_WriteByte(LCD_ADDR, (data << 4) | 0x0d);
}
void LCD_WriteString(char *str)
{
while (*str)
{
LCD_WriteChar(*str++);
}
}
void LCD_SetCursor(uint8_t row, uint8_t col)
{
I2C1_WriteByte(LCD_ADDR, 0x80 | (row << 6) | col);
}
void RTC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_LSEConfig(RCC_LSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_SetPrescaler(32767);
RTC_WaitForLastTask();
RTC_SetCounter(0);
RTC_WaitForLastTask();
}
void RTC_GetTimeString(char *str)
{
RTC_TimeTypeDef RTC_TimeStruct;
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStruct);
sprintf(str, "%02d:%02d:%02d", RTC_TimeStruct.RTC_Hours, RTC_TimeStruct.RTC_Minutes, RTC_TimeStruct.RTC_Seconds);
}
void delay_ms(uint32_t ms)
{
uint32_t i, j;
for (i = 0; i < ms; i++)
{
for (j = 0; j < 7200; j++);
}
}
int main(void)
{
char time_str[9];
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
I2C1_Init();
LCD_Init();
RTC_Init();
while (1)
{
RTC_GetTimeString(time_str);
LCD_SetCursor(0, 0);
LCD_WriteString(time_str);
delay_ms(500);
}
}
```
阅读全文