【IAR工程】STM8S基于ST标准库读取DS1302数据

【IAR工程】STM8S基于ST标准库读取DS1302数据


  • ✨申明:本文章仅发表在CSDN网站,任何其他网站,未注明来源,见此内容均为盗链和爬取,请多多尊重和支持原创!
  • 🍁对于文中所提供的相关资源链接将作不定期更换。
  • 🔖基于ST STM8S/A标准外设库:STSW-STM8069,版本号:2.3.1
  • 📌STSW-STM8069官方资源下载地址:https://www.st.com/zh/embedded-software/stsw-stm8069.html
  • 🔧IAR编译器版本:IAR Assembler for STMicroelectronics STM8 3.11.1
  • 📌STM8S207/208RBT6最小系统板:https://oshwhub.com/perseverance51/stm8s207rbt6-kai-fa-ban
  • 🎯本工程使用STM8S208RB+DS1302实物验证没有问题。
🎉基于标准库工程,当然不局限与STM8其他型号的芯片的使用,只要是stm8芯片都可以使用该源文件进行驱动,方便适配移植,减少不必要的重复开发工作。
  • 📜串口打印信息:
    在这里插入图片描述

📑引脚定义

如果是其他型号可以根据自由更换其他引脚。注意修改相关定义。

                TM8S单片机-->DS1302
                  PC2 -->CLK
                  PC3-->DAT
                  PC4 -->RST

📓DS1302驱动

  • 🌿DS1302.h文件
#ifndef __DS1302_H
#define __DS1302_H

/****************************驱动 RTC 芯片 DS1302******************************/

/* Includes ------------------------------------------------------------------*/

#include "stm8s.h"

/* Defines -------------------------------------------------------------------*/
//是否设置时间到DS1302中
#define RTC_RESET_TIME_EN       0u

#define RTC_SCK_PORT            (GPIO_TypeDef *)(GPIOC)
#define RTC_SCK_PIN             (GPIO_PIN_2)            // PC2
#define RTC_SCK_HIGH()          GPIO_WriteHigh(RTC_SCK_PORT, RTC_SCK_PIN)
#define RTC_SCK_LOW()           GPIO_WriteLow (RTC_SCK_PORT, RTC_SCK_PIN)

#define RTC_IO_PORT             (GPIO_TypeDef *)(GPIOC)
#define RTC_IO_PIN              (GPIO_PIN_3)            // PC3

#define RTC_IO_IN()             GPIO_Init(RTC_IO_PORT, RTC_IO_PIN, GPIO_MODE_IN_PU_NO_IT)
#define RTC_IO_STATUS()         GPIO_ReadInputPin(RTC_IO_PORT, RTC_IO_PIN)

#define RTC_IO_OUT()            GPIO_Init(RTC_IO_PORT, RTC_IO_PIN, GPIO_MODE_OUT_PP_HIGH_SLOW)
#define RTC_IO_HIGH()           GPIO_WriteHigh(RTC_IO_PORT, RTC_IO_PIN)
#define RTC_IO_LOW()            GPIO_WriteLow (RTC_IO_PORT, RTC_IO_PIN)

#define RTC_RST_PORT            (GPIO_TypeDef *)(GPIOC)
#define RTC_RST_PIN             (GPIO_PIN_4)            // PC4
#define RTC_RST_HIGH()          GPIO_WriteHigh(RTC_RST_PORT, RTC_RST_PIN)
#define RTC_RST_LOW()           GPIO_WriteLow (RTC_RST_PORT, RTC_RST_PIN)

/* Values --------------------------------------------------------------------*/

typedef struct Time
{
    uint8_t year;         // year       0-99
    uint8_t month;        // month      01-12
    uint8_t day;          // day        01-28,29,30,31
    uint8_t week;         // week       01-07
    uint8_t hour;         // hour       01-12 or 00-23
    uint8_t minute;       // minute     00-59
    uint8_t second;       // second     00-59
} TimeTypeDef;

static TimeTypeDef TimeBuffer;   // 数据缓冲区(8421-BCD码)

/* Functions -----------------------------------------------------------------*/

void DS1302_Init ( void );

static void    DS1302_WriteByte ( uint8_t byte );
static uint8_t DS1302_ReadByte  ( void );
static void    DS1302_WriteData ( uint8_t addr, uint8_t data );
static uint8_t DS1302_ReadData  ( uint8_t addr );

TimeTypeDef DS1302_ReadTime  ( void );
void        DS1302_WriteTime ( TimeTypeDef *TimeDisplay );

static uint8_t DectoBCD ( uint8_t num );
static uint8_t BCDtoDec ( uint8_t num );

//static void DS1302_DLY_ms( uint16_t nCount );
static void DS1302_DLY_us( uint16_t nCount );

#endif /* __DS1302_H */

  • 🌿DS1302.c文件
#include "ds1302.h"

/*************************************************************************
                                初始化
--------------------------------------------------------------------------
无参数
--------------------------------------------------------------------------
无返回值
*************************************************************************/
void DS1302_Init ( void )
{
    GPIO_Init( RTC_SCK_PORT, RTC_SCK_PIN, GPIO_MODE_OUT_PP_HIGH_SLOW );
    GPIO_Init( RTC_RST_PORT, RTC_RST_PIN, GPIO_MODE_OUT_PP_HIGH_SLOW );
    GPIO_Init( RTC_IO_PORT,  RTC_IO_PIN,  GPIO_MODE_OUT_PP_HIGH_SLOW );

    RTC_SCK_LOW();
    RTC_IO_LOW();
    RTC_RST_LOW();
}

/*************************************************************************
                              写一字节数据
--------------------------------------------------------------------------
byte:一字节数据
--------------------------------------------------------------------------
无返回值
*************************************************************************/
static void DS1302_WriteByte ( uint8_t byte )
{
    uint8_t i;
    BitStatus bit;

    RTC_IO_OUT();         // IO 配置为输出模式

    for ( i = 0; i < 8; i++ )
    {
        RTC_SCK_LOW();

        bit = ( BitStatus )( byte & 0x01 );
        if ( bit != RESET )
            RTC_IO_HIGH();
        else
            RTC_IO_LOW();

        RTC_SCK_HIGH();
        byte >>= 1;

        //DS1302_DLY_ms(1);
    }
}

/*************************************************************************
                              读一字节数据
--------------------------------------------------------------------------
addr:地址
--------------------------------------------------------------------------
返回值:一字节数据
*************************************************************************/
static uint8_t DS1302_ReadByte ( void )
{
    uint8_t i;
    uint8_t data = 0;
    BitStatus bit;

    RTC_IO_IN();          // IO 配置为输入模式

    for ( i = 0; i < 8; i++ )
    {
        data >>= 1;
        RTC_SCK_LOW();

        bit = RTC_IO_STATUS();
        if ( bit != RESET )
            data |= 0x80;
        else
            data &= 0x7F;

        RTC_SCK_HIGH();

        //DS1302_DLY_ms(1);
    }

    return data;
}

/*************************************************************************
                      往指定寄存器写入一字节数据
--------------------------------------------------------------------------
addr:地址  data:一字节数据
--------------------------------------------------------------------------
无返回值
*************************************************************************/
static void DS1302_WriteData ( uint8_t addr, uint8_t data )
{
    // 数据传输开始
    RTC_RST_LOW();
    RTC_SCK_LOW();
    RTC_RST_HIGH();

    DS1302_WriteByte ( addr );    // 写入的地址
    DS1302_WriteByte ( data );    // 写入的数据

    // 数据传输结束
    RTC_RST_LOW();
}

/*************************************************************************
                      在指定寄存器读出一字节数据
--------------------------------------------------------------------------
addr:地址
--------------------------------------------------------------------------
返回值:一字节数据
*************************************************************************/
static uint8_t DS1302_ReadData ( uint8_t addr )
{
    uint8_t data;

    // 数据传输开始
    RTC_RST_LOW();
    RTC_SCK_LOW();
    RTC_RST_HIGH();

    DS1302_WriteByte ( addr );    // 要读的地址
    data = DS1302_ReadByte();     // 要读的数据

    // 数据传输结束
    RTC_RST_LOW();

    return data;
}

/*************************************************************************
                                读时间
--------------------------------------------------------------------------
无参数
--------------------------------------------------------------------------
返回值:时间数据
*************************************************************************/
TimeTypeDef DS1302_ReadTime ( void )
{
    TimeTypeDef TimeDisplay;

    // 读出来的数据是 BCD 码
    TimeBuffer.year   = DS1302_ReadData ( 0x8D );
    TimeBuffer.month  = DS1302_ReadData ( 0x89 );
    TimeBuffer.day    = DS1302_ReadData ( 0x87 );
    TimeBuffer.week   = DS1302_ReadData ( 0x8B );
    TimeBuffer.hour   = DS1302_ReadData ( 0x85 );
    TimeBuffer.minute = DS1302_ReadData ( 0x83 );
    TimeBuffer.second = DS1302_ReadData ( 0x81 ); // bit7 定义为时钟暂停标志(CH)

    // BCD 码转换为十进制
    TimeDisplay.year   = BCDtoDec ( TimeBuffer.year );
    TimeDisplay.month  = BCDtoDec ( TimeBuffer.month );
    TimeDisplay.day    = BCDtoDec ( TimeBuffer.day );
    TimeDisplay.week   = BCDtoDec ( TimeBuffer.week );
    TimeDisplay.hour   = BCDtoDec ( TimeBuffer.hour );
    TimeDisplay.minute = BCDtoDec ( TimeBuffer.minute );
    TimeDisplay.second = BCDtoDec ( TimeBuffer.second );

    return TimeDisplay;
}

/*************************************************************************
                                修改时间
--------------------------------------------------------------------------
*TimeDisplay:要显示的时间(十进制)
--------------------------------------------------------------------------
无返回值
*************************************************************************/
void DS1302_WriteTime ( TimeTypeDef *TimeDisplay )
{
    // 十进制转换为 BCD 码
    TimeBuffer.year   = DectoBCD ( TimeDisplay->year );
    TimeBuffer.month  = DectoBCD ( TimeDisplay->month );
    TimeBuffer.day    = DectoBCD ( TimeDisplay->day );
    TimeBuffer.week   = DectoBCD ( TimeDisplay->week );
    TimeBuffer.hour   = DectoBCD ( TimeDisplay->hour );
    TimeBuffer.minute = DectoBCD ( TimeDisplay->minute );
    TimeBuffer.second = DectoBCD ( TimeDisplay->second );

    // 关闭写保护(控制寄存器:8FH、8EH  bit7:保护位)
    DS1302_WriteData ( 0x8E, 0x00 );

    // 写入的数据是 BCD 码
    DS1302_WriteData ( 0x8C, TimeBuffer.year );
    DS1302_WriteData ( 0x88, TimeBuffer.month );
    DS1302_WriteData ( 0x86, TimeBuffer.day );
    DS1302_WriteData ( 0x8A, TimeBuffer.week );
    DS1302_WriteData ( 0x84, TimeBuffer.hour );
    DS1302_WriteData ( 0x82, TimeBuffer.minute );
    DS1302_WriteData ( 0x80, TimeBuffer.second ); // bit7 定义为时钟暂停标志(CH)

    // 开启写保护(控制寄存器:8FH、8EH  bit7:保护位)
    DS1302_WriteData ( 0x8E, 0x80 );
}

/*************************************************************************
                             十进制转BCD码
--------------------------------------------------------------------------
num:十进制数
--------------------------------------------------------------------------
返回值:BCD码
*************************************************************************/
static uint8_t DectoBCD ( uint8_t num )
{
    uint8_t result;
    uint8_t temp1, temp2;

    temp1  = ( num / 10 ) << 4;        // 十位 / 10 * 16
    temp2  =  num % 10;                // 个位 % 10
    result = temp1 + temp2;

    return result;
}

/*************************************************************************
                             BCD码转十进制
--------------------------------------------------------------------------
num:BCD码
--------------------------------------------------------------------------
返回值:十进制
*************************************************************************/
static uint8_t BCDtoDec ( uint8_t num )
{
    uint8_t result;
    uint8_t temp1, temp2;

    temp1 = ( num >> 4 ) * 10;       // 十位 / 16 * 10
    temp2 =  num & 0x0F;             // 个位 % 16
    result = temp1 + temp2;

    return result;
}

/*************************************************************************
                             软件延时(ms级别)
--------------------------------------------------------------------------
nCount:延时长度
--------------------------------------------------------------------------
无返回值
*************************************************************************/
//static void DS1302_DLY_ms( uint16_t nCount )
//{
//    while( nCount-- )
//    {
//        DS1302_DLY_us( 1000 );
//    }
//}

/*************************************************************************
                             软件延时(us级别)
--------------------------------------------------------------------------
nCount:延时长度
--------------------------------------------------------------------------
无返回值
*************************************************************************/
static void DS1302_DLY_us( uint16_t nCount )
{
    nCount *= 2;
    while( --nCount );
}

📝main主程序代码

/**************************************************************************************
实验现象:打开串口调试助手,选择CH340对应串口号,波特率设置9600, 串口助手上会显示
			printf各种数据格式输出信息。

接线说明:	1,STM8S单片机-->LED
		   		PC7-->LED1
                                PC6-->LED2
---------------------------------------------------------
                TM8S单片机-->DS1302
                  PC2 -->CLK
                  PC3-->DAT
                  PC4 -->RST

注意事项:	1、点击“Download active application”按钮,程序下载完成后,即可运行程序。
		2、串口1使用的是PA4和PA5引脚,所以这两个IO口不要被占用
***************************************************************************************/

#include "stm8s.h"      /*  添加库函数头文件 */
#include "delay.h"
#include "led.h"
#include "usart.h"
#include "ds1302.h"
#include <stdio.h>//包含此头文件调用printf函数串口才能有输出


/* 主函数 */
int main( void )
{
    u8 i = 0;
    // 设置初始时间
//    TimeTypeDef Set_Time = {23, 04, 4, 2, 23, 25, 10};
const char *WEEK[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
    TimeTypeDef tm= {0};
    uint8_t TimeSecPre;
    disableInterrupts();    //关闭系统中断
    //内部时钟为1分频 = 16Mhz
    CLK_SYSCLKConfig( CLK_PRESCALER_HSIDIV1 );
    LED_Init();

    USART1_Init( 9600 ); //初始化USART1 , 并设置波特率为9600

    DS1302_Init();
    //是否设置时间到DS1302中
#if RTC_RESET_TIME_EN > 0u
    DS1302_WriteTime( Set_Time );
#endif

    enableInterrupts();     //使能系统中断

    while( 1 )
    {
        i++;
        if( i % 20 == 0 )
        {
            LED1_TOGGLE;
            LED2_TOGGLE;
        }
        tm = DS1302_ReadTime();
        if ( TimeSecPre != tm.second )
        {
            TimeSecPre = tm.second;
            printf( "20%02d年%02d月%02d日 星期:%s %02d:%02d:%02d\r\n", tm.year, tm.month, tm.day,
                    WEEK[tm.week] , tm.hour, tm.minute, tm.second);
        }

        delay_ms( 10 );
    }
}
//是一个宏定义;在固件库中,它的作用就是检测传递给函数的参数是否是有效的参数
void assert_failed( u8* file, u32 line )
{
    while ( 1 )
    {

    }
}

📚程序源码

  • ✨申明:本文章仅发表在CSDN网站,任何其他网站,未注明来源,见此内容均为盗链和爬取,请多多尊重和支持原创!
  • 🍁对于文中所提供的相关资源链接将作不定期更换。
链接: https://pan.baidu.com/s/18drnS5yPTSz79vxTBS7Brw
提取码: thdy
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IAR是一种常见的继电器开发工具,用于开发STM8S单片机。STM8S是意法半导体公司推出的一款低功耗、高性能的8位单片机系列。 在使用IAR开发STM8S时,首先需要安装IAR Embedded Workbench软件。这个软件提供了一个集成的开发环境,包括编译器、调试器和IDE等工具,使得开发者能够方便地进行代码编写、编译、下载和调试等步骤。 在编写代码时,可以使用C语言或汇编语言来进行编程。IAR提供了丰富的库函数和例程,方便开发者使用各种功能和外设。开发人员可以根据自己的需求,调用相应的库函数来控制STM8S的引脚、定时器、串口通信、ADC等外设。 编译完成后,可以使用IAR提供的调试器进行下载和调试。开发者可以通过调试器实时监视程序运行的状态,查看变量的值、寄存器的状态,以及程序执行的流程等。同时,也可以进行单步调试、断点调试等功能,帮助开发者更好地进行程序调试和错误定位。 使用IAR开发STM8S具有良好的兼容性和可移植性。开发者可以使用IAR软件在不同的平台上开发STM8S,例如Windows和Linux等操作系统。同时,IAR提供了针对不同型号的STM8S芯片的编译器和库文件,使得开发者能够方便地移植和调试代码。 总之,使用IAR开发STM8S是一种高效、方便和可靠的方式。通过该开发工具,开发者可以快速开发出满足各种需求的嵌入式应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值