基于stm32用LCD1602显示时钟,但是在秒的个位向十位跳转的时候 十位总是会提前一位跳转。比如:01 02 03 04
05 06 07 08 19 10 11 12....这样
怎么调才能正常地在节点跳转呢?
变成正常的08 09 10 11...这样子跳
问题代码如下:
main.c
#include "delay.h"
#include "LCDall.h"
int main()
{
Systick_init();
InitLCD();
u32 A;
u32 B;
u32 C;
u32 D;
u32 E;
u32 F;
u32 i=0;
while(1)
{
A=i/3600/10;//时十
B=i/3600%10;//时个
C=i%3600/60/10;//分十
D=i%3600/60%10;//分个
E=i%3600%60/10;//秒十
F=i%3600%60%10;//秒个
i+=1;
NUM (0,0,A);
NUM (1,0,B);
LCD_SHOW (2,0, ":",1 );
NUM (3,0,C);
NUM (4,0,D);
LCD_SHOW (5,0, ":",1);
NUM (6,0,E);
NUM (7,0,F);
if (A==2 && B==4)
{
i=0;
}
delay_ms(1000);
}
}
delay.c
#include "delay.h"
#include "stm32f10x.h" // Device header
uint32_t delay_fac_us;
uint32_t delay_fac_ms;
void Systick_init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
delay_fac_ms = SystemCoreClock / 8000;
delay_fac_us = SystemCoreClock / 8000000;
}
void delay_ms(uint32_t i)
{
uint32_t temp;
SysTick->LOAD=delay_fac_ms*i; //设置重装数值, 72MHZ时
SysTick->CTRL=0X01; //使能,减到零时无动作,采用外部时钟源
SysTick->VAL=0; //清零计数器
do
{
temp=SysTick->CTRL;
}
while((temp&0x01)&&(!(temp&(1<<16)))); //等待时间到达
SysTick->CTRL=0; //关闭计数器
SysTick->VAL=0; //清空计数器
}
void delay_us(uint32_t i)
{
uint32_t temp;
SysTick->LOAD=delay_fac_us*i; //设置重装数值, 72MHZ时
SysTick->CTRL=0X01; //使能,减到零时无动作,采用外部时钟源
SysTick->VAL=0; //清零计数器
do
{
temp=SysTick->CTRL;
}
while((temp&0x01)&&(!(temp&(1<<16)))); //等待时间到达
SysTick->CTRL=0; //关闭计数器
SysTick->VAL=0; //清空计数器
}
delay.h
#ifndef _DELAY_H
#define _DELAY_H
#include "stm32f10x.h"
void Systick_init(void);
void delay_ms(uint32_t i);
void delay_us(uint32_t i);
#endif
LCDall.c
#include "LCDall.h"
#include "stm32f10x.h" // Device header
#include "delay.h" // Device header
#include "string.h "
//static uint8_t delay_fac_us=0;//延时倍乘数
//static uint8_t delay_fac_ms=0;//延时倍乘数
void LCD_WCO(uint8_t cmd)
{
GPIOB->ODR=0x00FF;
delay_ms(2);
LCD_RS_LOW;
LCD_RW_LOW;
LCD_E_LOW;
delay_us(1);
LCD_E_HIGH;
LCD1602_GPIO_PORT->ODR&=(cmd|0xFF00);
LCD_E_LOW;
delay_us(400);
}
void LED_WDA(uint8_t dat)
{
GPIOB->ODR=0x00FF;
delay_ms(2);
LCD_RS_HIGH;
LCD_RW_LOW;
delay_us(30);
LCD_E_HIGH;
LCD1602_GPIO_PORT->ODR &=(dat|0xFF00);
LCD_E_LOW;
delay_us(400);
}
void LCD_SET(uint8_t x, uint8_t y)
{
uint8_t addr;
if (y == 0) //由输入的屏幕坐标计算显示RAM的地址
addr=0x00 + x; //第一行字符地址从 0x00 起始
else
addr=0x40+ x; //第二行字符地址从 0x40 起始
LCD_WCO(addr|0x80); //设置 RAM 地址
}
void LCD_SHOW(uint8_t x, uint8_t y, uint8_t *str, uint8_t len)
{
LCD_SET(x, y); //设置起始地址
while (len--) //连续写入len个字符数据
{
LED_WDA(*str++);
}
}
void LCDI0INIT(void)
{
RCC_APB2PeriphClockCmd(LCD1602_CLK,ENABLE);
GPIO_InitTypeDef LCD1602_GPIOStruct;
LCD1602_GPIOStruct.GPIO_Mode= GPIO_Mode_Out_PP;
LCD1602_GPIOStruct.GPIO_Speed =GPIO_Speed_10MHz;
LCD1602_GPIOStruct.GPIO_Pin=LCD1602_E |LCD1602_RS| LCD1602_RW;
GPIO_Init(LCD1602_GPIO_PORT,&LCD1602_GPIOStruct);
LCD1602_GPIOStruct.GPIO_Mode = GPIO_Mode_Out_OD;
LCD1602_GPIOStruct.GPIO_Pin= DB0|DB1|DB2|DB3|DB4|DB5|DB6|DB7;
GPIO_Init(LCD1602_GPIO_PORT,&LCD1602_GPIOStruct);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
//GPIO_SetBits(GPIOB,GPIO_Pin_3) ;
}
void InitLCD()
{
LCDI0INIT(); //初始化LCD用到的GPIO
LCD_WCO(0x38);//设置为8位总线、2行显示、5×7点阵字体
delay_ms(1);
LCD_WCO(0x01);//清屏,归HOME位
delay_ms(1);
LCD_WCO(0x06);//数据输入为增量方式,显示内容不移动
delay_ms(1);
LCD_WCO(0x0c);//开显示,关闭光标,光标不闪烁
delay_ms(1);
}
void NUM(uint8_t x, uint8_t y, uint8_t num)
{
LCD_SET(x,y);//设置起始地址
LED_WDA(num+'0');
//CHAR(x,y,num+'0'/*没有这个+'0'就不能显示数字*/);
}
LCDall.h
#ifndef _LCDALL_H
#define _LCDALL_H
#include "stm32f10x.h"
#include "delay.h" // Device header
#include "LCDall.h"
#define LCD_RS_LOW GPIO_ResetBits(LCD1602_GPIO_PORT, LCD1602_RS)
#define LCD_RS_HIGH GPIO_SetBits(LCD1602_GPIO_PORT, LCD1602_RS)
#define LCD_RW_LOW GPIO_ResetBits(LCD1602_GPIO_PORT, LCD1602_RW)
#define LCD_RW_HIGH GPIO_SetBits(LCD1602_GPIO_PORT, LCD1602_RW)
#define LCD_E_LOW GPIO_SetBits(LCD1602_GPIO_PORT, LCD1602_E)
#define LCD_E_HIGH GPIO_SetBits(LCD1602_GPIO_PORT, LCD1602_E)
#define LCD1602_CLK RCC_APB2Periph_GPIOB
#define LCD1602_GPIO_PORT GPIOB
#define DB0 GPIO_Pin_0
#define DB1 GPIO_Pin_1
#define DB2 GPIO_Pin_2
#define DB3 GPIO_Pin_3
#define DB4 GPIO_Pin_4
#define DB5 GPIO_Pin_5
#define DB6 GPIO_Pin_6
#define DB7 GPIO_Pin_7
#define LCD1602_E GPIO_Pin_12 //定义使能引脚
#define LCD1602_RW GPIO_Pin_13//定义读写引脚
#define LCD1602_RS GPIO_Pin_14 //定义数据、命名引脚
void LCD_WCO(uint8_t cmd);
void LED_WDA(uint8_t dat);
void LCD_SET(uint8_t x, uint8_t y);
void LCD_SHOW(uint8_t x, uint8_t y, uint8_t *str, uint8_t len);
void LCDI0INIT(void);
void InitLCD();
void NUM(uint8_t x, uint8_t y, uint8_t num);
void CHAR(uint8_t x, uint8_t y, uint8_t dat);
static uint8_t delay_fac_us=0;//延时倍乘数
static uint8_t delay_fac_ms=0;//延时倍乘数
#endif
有熟悉这方面朋友嘛 麻烦大家帮我看一下吧
#include "delay.h"
//ms级别延时
void Delay_ms(uint16_t nCount)
{
while(nCount--)
{
Delay_us(1000);
}
}
//us级别延时
void Delay_us(uint16_t nCount)
{
nCount *= 2;
while(--nCount);
}