冰楓論壇

標題: STM8S103F3P6製作4 位數字時鐘 [打印本頁]

作者: 洪嵐峰    時間: 2023-3-31 19:52
標題: STM8S103F3P6製作4 位數字時鐘
STM8S103F3P6製作4 位數字時鐘
需要以下材料:

STM8S103F3P6微控制器
4位共陰極數碼管
DS1302實時時鐘模塊
20MHz晶振
電容:2 x 22pF,1 x 100nF
電阻:1 x 10kΩ,1 x 330Ω
2個按鈕開關
面包板
杜邦線
接線方式如下:


PA1 -> 時鐘的SCLK
PA2 -> 時鐘的DAT
PA3 -> 時鐘的CE
PB0-PB3 -> 4位共陰極數碼管的控制端
PA4, PA5 -> 按鈕開關的控制端
PC3 -> 晶振的X1
PC4 -> 晶振的X2
其中,按鈕開關用於設置時間和調整時鐘的時間。

程式碼如下:


#include <stdio.h>
#include <stdlib.h>
#include "stm8s.h"
#include "stm8s_gpio.h"
#include "stm8s_tim1.h"
#include "stm8s_clk.h"
#include "stm8s_spi.h"

#define DIGIT1 GPIO_PIN_0
#define DIGIT2 GPIO_PIN_1
#define DIGIT3 GPIO_PIN_2
#define DIGIT4 GPIO_PIN_3

#define CE_PIN GPIO_PIN_3
#define SCLK_PIN GPIO_PIN_1
#define DAT_PIN GPIO_PIN_2

#define BTN1_PIN GPIO_PIN_4
#define BTN2_PIN GPIO_PIN_5

#define RTC_WRITE_MODE 0x8E
#define RTC_READ_MODE 0x8F

static const uint8_t DIGITS[] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 };

uint8_t hour = 12;
uint8_t minute = 0;

void GPIO_Config(void);
void TIM1_Config(void);
void SPI_Config(void);
void RTC_Init(void);
void RTC_ReadTime(void);
void RTC_WriteTime(void);

void main()
{
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
  GPIO_Config();
  TIM1_Config();
  SPI_Config();
  RTC_Init();
  
  enableInterrupts();
  
  while(1)
  {
    RTC_ReadTime();
   
    GPIO_WriteLow(GPIOB, DIGIT1);
    GPIO_Write(GPIOB, DIGITS[hour / 10]);
    TIM1_Cmd(ENABLE);
    while(!TIM1_GetFlagStatus(TIM1_FLAG_UPDATE));
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
   
    GPIO_WriteHigh(GPIOB, DIGIT1);
    GPIO_WriteLow(GPIOB, DIGIT2);
    GPIO_Write(GPIOB, DIGITS[hour % 10]);
    TIM1_Cmd(ENABLE);
    while(!TIM1_GetFlagStatus(TIM1_FLAG_UPDATE));
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
   
    GPIO_WriteHigh(GPIOB, DIGIT2);
    GPIO_Write

#include <stdio.h>
#include <stdlib.h>
#include "stm8s.h"
#include "stm8s_gpio.h"
#include "stm8s_tim1.h"
#include "stm8s_clk.h"
#include "stm8s_spi.h"

#define DIGIT1 GPIO_PIN_0
#define DIGIT2 GPIO_PIN_1
#define DIGIT3 GPIO_PIN_2
#define DIGIT4 GPIO_PIN_3

#define CE_PIN GPIO_PIN_3
#define SCLK_PIN GPIO_PIN_1
#define DAT_PIN GPIO_PIN_2

#define BTN1_PIN GPIO_PIN_4
#define BTN2_PIN GPIO_PIN_5

#define RTC_WRITE_MODE 0x8E
#define RTC_READ_MODE 0x8F

static const uint8_t DIGITS[] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 };

uint8_t hour = 12;
uint8_t minute = 0;

void GPIO_Config(void);
void TIM1_Config(void);
void SPI_Config(void);
void RTC_Init(void);
void RTC_ReadTime(void);
void RTC_WriteTime(void);

void main()
{
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
  GPIO_Config();
  TIM1_Config();
  SPI_Config();
  RTC_Init();
  
  enableInterrupts();
  
  while(1)
  {
    RTC_ReadTime();
   
    GPIO_WriteLow(GPIOB, DIGIT1);
    GPIO_Write(GPIOB, DIGITS[hour / 10]);
    TIM1_Cmd(ENABLE);
    while(!TIM1_GetFlagStatus(TIM1_FLAG_UPDATE));
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
   
    GPIO_WriteHigh(GPIOB, DIGIT1);
    GPIO_WriteLow(GPIOB, DIGIT2);
    GPIO_Write(GPIOB, DIGITS[hour % 10]);
    TIM1_Cmd(ENABLE);
    while(!TIM1_GetFlagStatus(TIM1_FLAG_UPDATE));
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
   
    GPIO_WriteHigh(GPIOB, DIGIT2);
    GPIO_WriteLow(GPIOB, DIGIT3);
    GPIO_Write(GPIOB, DIGITS[minute / 10]);
    TIM1_Cmd(ENABLE);
    while(!TIM1_GetFlagStatus(TIM1_FLAG_UPDATE));
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
   
    GPIO_WriteHigh(GPIOB, DIGIT3);
    GPIO_WriteLow(GPIOB, DIGIT4);
    GPIO_Write(GPIOB, DIGITS[minute % 10]);
    TIM1_Cmd(ENABLE);
    while(!TIM1_GetFlagStatus(TIM1_FLAG_UPDATE));
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
   
    GPIO_WriteHigh(GPIOB, DIGIT4);
  }
}

void GPIO_Config()
{
  GPIO_DeInit(GPIOA);
  GPIO_DeInit(GPIOB);
  GPIO_DeInit(GPIOC);
  
  GPIO_Init(GPIOB, DIGIT1|DIGIT2|DIGIT3|DIGIT4, GPIO_MODE_OUT_PP_LOW_FAST);
  
  GPIO_Init(GPIOA, SCLK_PIN|DAT_PIN|CE_PIN|BTN1_PIN|BTN2_PIN, GPIO_MODE_IN_PU_NO_IT);
  
  GPIO_Init(GPIOC, GPIO_PIN_3|GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);
}

void TIM1_Config()
{
  TIM1_DeInit();
  TIM1_TimeBaseInit(0, TIM

#include <stdio.h>
#include <stdlib.h>
#include "stm8s.h"
#include "stm8s_gpio.h"
#include "stm8s_tim1.h"
#include "stm8s_clk.h"
#include "stm8s_spi.h"

#define DIGIT1 GPIO_PIN_0
#define DIGIT2 GPIO_PIN_1
#define DIGIT3 GPIO_PIN_2
#define DIGIT4 GPIO_PIN_3

#define CE_PIN GPIO_PIN_3
#define SCLK_PIN GPIO_PIN_1
#define DAT_PIN GPIO_PIN_2

#define BTN1_PIN GPIO_PIN_4
#define BTN2_PIN GPIO_PIN_5

#define RTC_WRITE_MODE 0x8E
#define RTC_READ_MODE 0x8F

static const uint8_t DIGITS[] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 };

uint8_t hour = 12;
uint8_t minute = 0;

void GPIO_Config(void);
void TIM1_Config(void);
void SPI_Config(void);
void RTC_Init(void);
void RTC_ReadTime(void);
void RTC_WriteTime(void);

void main()
{
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
  GPIO_Config();
  TIM1_Config();
  SPI_Config();
  RTC_Init();
  
  enableInterrupts();
  
  while(1)
  {
    RTC_ReadTime();
   
    GPIO_WriteLow(GPIOB, DIGIT1);
    GPIO_Write(GPIOB, DIGITS[hour / 10]);
    TIM1_Cmd(ENABLE);
    while(!TIM1_GetFlagStatus(TIM1_FLAG_UPDATE));
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
   
    GPIO_WriteHigh(GPIOB, DIGIT1);
    GPIO_WriteLow(GPIOB, DIGIT2);
    GPIO_Write(GPIOB, DIGITS[hour % 10]);
    TIM1_Cmd(ENABLE);
    while(!TIM1_GetFlagStatus(TIM1_FLAG_UPDATE));
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
   
    GPIO_WriteHigh(GPIOB, DIGIT2);
    GPIO_WriteLow(GPIOB, DIGIT3);
    GPIO_Write(GPIOB, DIGITS[minute / 10]);
    TIM1_Cmd(ENABLE);
    while(!TIM1_GetFlagStatus(TIM1_FLAG_UPDATE));
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
   
    GPIO_WriteHigh(GPIOB, DIGIT3);
    GPIO_WriteLow(GPIOB, DIGIT4);
    GPIO_Write(GPIOB, DIGITS[minute % 10]);
    TIM1_Cmd(ENABLE);
    while(!TIM1_GetFlagStatus(TIM1_FLAG_UPDATE));
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
   
    GPIO_WriteHigh(GPIOB, DIGIT4);
  }
}

void GPIO_Config()
{
  GPIO_DeInit(GPIOA);
  GPIO_DeInit(GPIOB);
  GPIO_DeInit(GPIOC);
  
  GPIO_Init(GPIOB, DIGIT1|DIGIT2|DIGIT3|DIGIT4, GPIO_MODE_OUT_PP_LOW_FAST);
  
  GPIO_Init(GPIOA, SCLK_PIN|DAT_PIN|CE_PIN|BTN1_PIN|BTN2_PIN, GPIO_MODE_IN_PU_NO_IT);
  
  GPIO_Init(GPIOC, GPIO_PIN_3|GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);
}

void TIM1_Config()
{
  TIM1_DeInit();
  TIM1_TimeBaseInit(0, TIM

  TIM1_OC1Init(TIM1_OCMODE_PWM1, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_DISABLE,
               500, TIM1_OCPOLARITY_HIGH, TIM1_OCNPOLARITY_LOW, TIM1_OCIDLESTATE_RESET,
               TIM1_OCNIDLESTATE_RESET);
  
  TIM1_Cmd(DISABLE);
  TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
}

void SPI_Config()
{
  SPI_DeInit();
  SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_MASTER, SPI_CLOCKPOLARITY_LOW,
           SPI_CLOCKPHASE_1EDGE, SPI_DATADIRECTION_1LINE_TX, SPI_NSS_SOFT, 0x07);
  SPI_Cmd(ENABLE);
}

void RTC_Init()
{
  SPI_Write(GPIOC, CE_PIN, RTC_WRITE_MODE);
  SPI_Write(GPIOC, DAT_PIN, 0x00);
  SPI_Write(GPIOC, DAT_PIN, 0x80);
  SPI_Write(GPIOC, DAT_PIN, 0x86);
  SPI_Write(GPIOC, CE_PIN, RTC_READ_MODE);
}

void RTC_ReadTime()
{
  uint8_t hour_bcd, min_bcd;
  
  SPI_Write(GPIOC, CE_PIN, RTC_READ_MODE);
  
  hour_bcd = SPI_Read(GPIOC, DAT_PIN);
  min_bcd = SPI_Read(GPIOC, DAT_PIN);
  
  hour = ((hour_bcd & 0x30) >> 4) * 10 + (hour_bcd & 0x0F);
  minute = ((min_bcd & 0x70) >> 4) * 10 + (min_bcd & 0x0F);
}

void RTC_WriteTime()
{
  uint8_t hour_bcd, min_bcd;
  
  hour_bcd = ((hour / 10) << 4) | (hour % 10);
  min_bcd = ((minute / 10) << 4) | (minute % 10);
  
  SPI_Write(GPIOC, CE_PIN, RTC_WRITE_MODE);
  SPI_Write(GPIOC, DAT_PIN, 0x00);
  SPI_Write(GPIOC, DAT_PIN, hour_bcd);
  SPI_Write(GPIOC, DAT_PIN, min_bcd);
}

INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11)
{
  TIM1_ClearITPendingBit(TIM1_IT_UPDATE);
  
  if(!GPIO_ReadInputPin(GPIOA, BTN1_PIN))
  {
    hour++;
    if(hour > 23) hour = 0;
    RTC_WriteTime();
  }
  
  if(!GPIO_ReadInputPin(GPIOA, BTN2_PIN))
  {
    minute++;
    if(minute > 59) minute = 0;
    RTC_WriteTime();
  }
}
這段程式碼使用SPI通訊與RTC進行溝通,並使用定時器和GPIO驅動4位7段顯示器。還有兩個按鈕用於調整時間。您需要將此代碼編譯並燒錄到您的STM8S103F3P6單片機上,才能使用它來製作4位數字時鐘。




歡迎光臨 冰楓論壇 (https://bingfong.com/) Powered by 冰楓