找回密码
 立即注册
查看: 44|回复: 6

AI8H RTC启动后再关闭RTC使能就会卡死有解决办法吗?

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-06-11 11:48:30

3

主题

6

回帖

37

积分

新手上路

积分
37
发表于 5 天前 | 显示全部楼层 |阅读模式
各位大神,如标题所述,应用中需要根据场合开启RTC计时和关闭RTC计时功能。在初始化调用void RTC_config(void) 后,RTC可以正常工作,但通过 RCT运行控制寄存器 RTCCR = 0x01;     //RTC使能 , 再次控制RTCCR = 0x00后,系统就会死机状态,想通过禁止32K内部时钟, IRC32KCR = 0x00;   //关闭内部32K晶振,但是感觉没用,晶振启动后关闭不了?各位有没好的办法?

void RTC_EN(bit s)
{
        if(s){
        
        RTCCR = 0x01;     //RTC使能
        delay1ms(300) ;   //更新到 SEC 需要时间
        Tim_go=1;}
    else{        
        RTCCR &= ~0x01;     //RTC关闭
    delay1ms(100) ;   //更新到 SEC 需要时间
        Tim_go=0;}
}

回复

使用道具 举报 送花

3

主题

726

回帖

163

积分

等待验证会员

积分
163
发表于 5 天前 | 显示全部楼层
在解决您提到的问题时,首先需要确保在初始化调用void RTCconfig(void)时,内部时钟和晶振的状态是正确的。具体来说:

1. 内部时钟和晶振的配置:确保在运行 RTC时,内部时钟和晶振的状态被正确配置为不可用或开启状态,以防止它们在运行时导致系统卡死。

2. 系统资源检查:检查系统中是否还存在未被正确配置的其他资源,如内存、 timer资源等,这些可能会影响系统运行。

3. 系统日志分析:检查系统日志,了解是否有其他异常或错误信息出现,以进一步定位问题。

4. 系统状态确认:确认系统是否处于稳定运行状态,是否有异常或错误信息提示系统有问题。

如果以上步骤未解决问题,建议重新启动系统并确认配置是否正确。如有其他问题,建议联系官方支持或社区寻求进一步帮助。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

3

主题

726

回帖

163

积分

等待验证会员

积分
163
发表于 5 天前 | 显示全部楼层
根据您的问题,可以提供以下专业解决方案:

问题分析:
1.  RTC计时与停止功能设置:
通常, RTC计时功能需要一个计时位(如bit 0)设置为1,以启动计时;停止功能需要一个停止位(如bit 1)设置为0,以阻止计时。
您的设置中,计时位可能未正确设置,导致系统无法正确启动计时,进而导致计时和停止功能无法正常工作。

2. 内部32K晶振的设置问题:
内部32K晶振的频率和停止位的设置可能影响 RTC的计时精度和稳定。
如果停止位设置为1,可能会导致计时无法停止,从而引发系统卡死。

3. 系统环境因素:
系统环境因素如温度、电源电压、电源频率等可能对 RTC的性能产生影响。
需要确保系统处于稳定且适宜的环境,以避免因外部因素导致的系统异常。

解决方案:
1. 重新配置计时和停止功能:
确保计时位(bit 0)设置为1,以启动计时;停止位(bit 1)设置为0,以阻止计时。
检查并调整停止位的设置,确保停止功能正确关闭。

2. 优化内部32K晶振设置:
确保内部32K晶振的频率设置为正确的值(如1 MHz)。
检查停止位设置为0,以阻止晶振停止计时。

3. 检查系统定时器配置:
确保系统中使用了正确的定时器和定时器频率。
检查系统中使用的是正确类型的定时器(如RS-74型)。

4. 验证系统状态:
确保系统处于稳定状态,没有异常事件。
检查系统中是否有其他潜在的异常源,如定时器的频率设置不正确。

5. 环境因素的测试:
在不同环境条件下测试系统性能,确保系统在高温、低电压或变化电源频率下仍能正常工作。

实施步骤:
1. 重新配置 RTC参数:
确保计时位(bit 0)设置为1,停止位(bit 1)设置为0。
检查停止位的设置,确保其正确关闭。

2. 验证内部32K晶振设置:
检查内部32K晶振的频率设置为正确的值(如1 MHz)。
检查停止位设置为0,以阻止晶振停止计时。

3. 检查系统定时器配置:
确保系统中使用了正确的定时器和定时器频率。
检查系统中使用的是正确类型的定时器(如RS-74型)。

4. 测试系统环境因素:
在不同环境条件下测试系统性能,确保系统在高温、低电压或变化电源频率下仍能正常工作。

结论:
通过重新配置计时和停止功能,优化内部32K晶振设置,并验证系统环境因素的影响,可以有效避免系统卡死的问题。确保系统处于稳定状态,避免因外部因素导致的异常行为。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:208
  • 最近打卡:2025-06-16 08:41:37
已绑定手机

67

主题

1910

回帖

4291

积分

荣誉版主

无情的代码机器

积分
4291
发表于 5 天前 | 显示全部楼层
参考此贴可以重复配置RTC的:
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=18421
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:93
  • 最近打卡:2025-06-14 13:12:15

74

主题

6088

回帖

1万

积分

超级版主

积分
12717
发表于 5 天前 | 显示全部楼层
RTC只是一个外设,MCU时钟并不从RTC取,关闭RTC不会影响程序运行的,除非你的程序等待RTC相关的时间信息,因为RTC已经关闭,你的程序永远等不来了,所以出现貌似卡死的情况。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-06-11 11:48:30

3

主题

6

回帖

37

积分

新手上路

积分
37
发表于 5 天前 | 显示全部楼层
梁*** 发表于 2025-6-11 13:16
RTC只是一个外设,MCU时钟并不从RTC取,关闭RTC不会影响程序运行的,除非你的程序等待RTC相关的时间信息, ...

不知道RTC中断是否跑飞?比如设置的秒中断,但是会不会存在其他中断导致跳转到没有写中断函数的中断向量里回不来了?

点评

你不用担心这些问题,一个MCU的中断是不会跑飞的,基本肯定是你的程序的问题,你肯定是关闭RTC后依旧查询RTC相关的信息,导致一直查询卡死。 专门改个例子给你测试,直接下载HEX文件测试,主频11.0592MHz。 主程序  详情 回复 发表于 5 天前
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:93
  • 最近打卡:2025-06-14 13:12:15

74

主题

6088

回帖

1万

积分

超级版主

积分
12717
发表于 5 天前 | 显示全部楼层
ks*** 发表于 2025-6-11 14:08
不知道RTC中断是否跑飞?比如设置的秒中断,但是会不会存在其他中断导致跳转到没有写中断函数的中断向量 ...

你不用担心这些问题,一个MCU的中断是不会跑飞的,基本肯定是你的程序的问题,你肯定是关闭RTC后依旧查询RTC相关的信息,导致一直查询卡死。

专门改个例子给你测试,直接下载HEX文件测试,主频11.0592MHz。
主程序开启RTC 5秒,RTC秒中断返回日期、时间。
然后关闭RTC 3秒,暂停返回3秒钟。
之后又开启RTC,继续返回时间5秒。
重复上述操作,并未出现你说的卡死情况,程序运行正常,我的程序还不是一个很简单的程序。
==========================================

请先别修改程序, 直接下载"02A-RTC(内部32K)基本操作-串口1设置返回"里的"rtc.hex"测试, 主频选择11.0592MHZ. 测试正常后再修改移植.

MCU通过串口1返回: 年 月 日 时 分 秒:  21-6-19 12:34:56
通过串口发送设置值: 21-6-19 12:34:56
通过串口发送闹钟值: A12:34:56

默认参数:
串口1设置均为 1位起始位, 8位数据位, 1位停止位, 无校验.
串口1(P3.0 P3.1): 115200bps.


==========================================
测试结果截图:
测试结果截图.PNG

工程源码压缩包:
02A-RTC(内部32K)基本操作-串口1设置返回.rar (136.9 KB, 下载次数: 0)


为了表明我的程序不是简单程序。源码拷贝如下:

/*********************************************************/
#define FOSC                11059200L        //定义主时钟

#include        "..\STC8Hxxx.h"


/*************        功能说明        **************

请先别修改程序, 直接下载"02A-RTC(内部32K)基本操作-串口1设置返回"里的"rtc.hex"测试, 主频选择11.0592MHZ. 测试正常后再修改移植.

MCU通过串口1返回: 年 月 日 时 分 秒:  21-6-19 12:34:56
通过串口发送设置值: 21-6-19 12:34:56
通过串口发送闹钟值: A12:34:56

默认参数:
串口1设置均为 1位起始位, 8位数据位, 1位停止位, 无校验.
串口1(P3.0 P3.1): 115200bps.

串口要发送数据2次(间隔4秒内), 第一次唤醒(唤醒需要时间, 第一次接收数据将会错误), 第二次数据才会正确接收.

******************************************/

/*************        本地常量声明        **************/
#define        RX1_Length        32                /* 接收缓冲长度 */


/*************        本地变量声明        **************/
u8        xdata        RX1_Buffer[RX1_Length];        //接收缓冲

u8        RX1_Cnt;                //串口接收计数.
u8        RX1_TimeOut;        //串口接收超时

bit        B_TX1_Busy;        // 发送忙标志

u8        year, month, day, hour, minute, second;        //RTC实时时间
bit        B_1S;        //秒中断, 秒有变化
bit        B_10ms;
u8        OpTime;                // 此变量非0时, 不睡眠, 连续运行程序(本例串口唤醒后连续运行5秒, 以便正确接收串口数据)

u8        GetDataIndex;        //获取数据索引仅仅用于读取计数
u8        GetDataState;        //获取数据状态, 非0则错误

u8                ALARM_hour;                 // RTC闹钟的小时值
u8                ALARM_minute;                // RTC闹钟的分钟值
u8                ALARM_second;                // RTC闹钟的秒值
bit                B_ALARM;

u16                Nx10ms;

/*************        本地函数声明        **************/
void        UART1_config(u32 brt, u8 timer, u8 io);        // brt: 通信波特率,  timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1,  =1: 切换到P3.6 P3.7,  =2: 切换到P1.6 P1.7.
void         UART1_TxByte(u8 dat);
void         UART1_PrintString(u8 *puts);
u8                SetRTC(void);                //设置RTC时间函数
void        RTC_config(void);        //RTC初始化函数
void        RTC_read(void);                //读RTC时间函数
void        ReturnRTC(void);        //返回时间信息
u8                GetData(void);                //获取数据, 设置时间命令: 21-6-19 12:34:56
void          delay_ms(u8 ms);
u8                Timer0_Config(u8 t, u32 reload);        //t=0: reload值是主时钟周期数,  t=1: reload值是时间(单位us), 返回0正确, 返回1装载值过大错误.




//========================================================================
// 函数: void main(void)
// 描述: 主函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void main(void)
{
        P_SW2 |= 0x80;                //SFR enable
        P0M1 = 0;        P0M0 = 0;
        P1M1 = 0;        P1M0 = 0;
        P2M1 = 0;        P2M0 = 0;
        P3M1 = 0;        P3M0 = 0;
        P4M1 = 0;        P4M0 = 0;
        P5M1 = 0;        P5M0 = 0;
        P1n_pure_input(Pin7+Pin6);

        EA = 1;

        OpTime = 0;
        RTC_config();

        UART1_config(115200UL, 1, 0);        // brt: 通信波特率,  timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1,  =1: 切换到P3.6 P3.7,  =2: 切换到P1.6 P1.7.
        UART1_PrintString("STC8H RTC Test Prgramme!\r\n");
        Timer0_Config(0, FOSC / 100);        //t=0: reload值是主时钟周期数,  (中断频率, 100次/秒)

        Nx10ms = 0;

        while (1)
        {
                if(B_10ms)
                {
                        B_10ms = 0;

                        if(++Nx10ms >= 800)                //8秒一个周期,RTC开启5秒,关闭3秒
                        {
                                Nx10ms = 0;
                                RTCCR  = 0x01;        //使能RTC, 并开始RTC计数
                                UART1_PrintString("允许RTC\r\n");
                        }
                        else if(Nx10ms == 500)        //关闭
                        {
                                RTCCR  = 0x00;        //关闭RTC, 并开始RTC计数
                                UART1_PrintString("关闭RTC\r\n");
                        }

                        if(RX1_TimeOut != 0)
                        {
                                if(--RX1_TimeOut == 0)        //设置时间命令: 21-6-19 12:34:56
                                {
                                        if(RX1_Buffer[0] == 'A')        //设置闹铃
                                        {
                                                GetDataIndex = 1;        //获取数据索引仅仅用于读取计数
                                                GetDataState = 0;        //获取数据状态, 非0则错误
                                                ALARM_hour   = GetData();                //获取数据 时
                                                ALARM_minute = GetData();                //获取数据 分
                                                ALARM_second = GetData();                //获取数据 秒
                                                if(GetDataState == 0)        //获取数据状态, 为0则正确, 非0则错误
                                                {
                                                        ALAHOUR = ALARM_hour;                 // RTC闹钟的小时值
                                                        ALAMIN  = ALARM_minute;                // RTC闹钟的分钟值
                                                        ALASEC  = ALARM_second;                // RTC闹钟的秒值
                                                        ALASSEC = 0;                                // RTC闹钟的1/128秒值
                                                        RTCIEN  |= 0x80;        //中断使能, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
                                                        UART1_PrintString("已设置闹铃!\r\n");
                                                }
                                                else
                                                {
                                                        UART1_PrintString("设置闹铃数据错误!\r\n");
                                                        UART1_PrintString("错误代码: ");
                                                        UART1_TxByte(GetDataState+'0');
                                                        UART1_PrintString("\r\n");
                                                }
                                        }
                                        else        //设置时间
                                        {
                                                GetDataIndex = 0;        //获取数据索引仅仅用于读取计数
                                                GetDataState = 0;        //获取数据状态, 非0则错误
                                                year   = GetData();                //获取数据 年
                                                month  = GetData();                //获取数据 月
                                                day    = GetData();                //获取数据 日
                                                hour   = GetData();                //获取数据 时
                                                minute = GetData();                //获取数据 分
                                                second = GetData();                //获取数据 秒
                                                if(GetDataState == 0)        //获取数据状态, 为0则正确, 非0则错误
                                                {
                                                        UART1_PrintString("获取设置时间: ");
                                                        ReturnRTC();
                                                        if(SetRTC() == 0)        UART1_PrintString("已设置时间!\r\n");
                                                        else                                UART1_PrintString("设置时间数据错误!\r\n");
                                                }
                                                else
                                                {
                                                        UART1_PrintString("设置时间数据错误!\r\n");
                                                        UART1_PrintString("错误代码: ");
                                                        UART1_TxByte(GetDataState+'0');
                                                        UART1_PrintString("\r\n");
                                                }
                                        }
                                        RX1_Cnt = 0;
                                }
                        }
                }

                if(B_ALARM)
                {
                        B_ALARM = 0;
                        UART1_PrintString("滴滴滴! 闹铃! \r\n");
                }

                if(B_1S)        //秒有变化
                {
                        B_1S = 0;
                        RTC_read();
                        if(OpTime != 0)        OpTime--;        //连续操作时间
                        ReturnRTC();        //从串口返回时间信息
                }

        /*        if(OpTime == 0)                // OpTime==0才进入掉电模式
                {
                        PCON |= 0x02;
                        NOP(5);
                } */

                        PCON |= 0x01;        //空闲模式
                        NOP(5);
        }
}

/********************** 获取串口数据 *****************************/
u8        GetData(void)
{
        u8 i,j,k;

        if(GetDataIndex >= RX1_Cnt)        //
        {
                GetDataState = 1;
                return 0;
        }
        if(RX1_Cnt < 6)                //数据长度错误 设置时间 设置闹铃
        {
                GetDataState = 2;
                return 0;
        }

        i = 0;
        k = 0;
        while(GetDataIndex <= RX1_Cnt)                //设置时间命令: 21-6-19 12:34:56, 设置闹钟命令: A12:34:56
        {
                j = RX1_Buffer[GetDataIndex];
                if((j == '-') || (j == ' ') || (j == ':') || (GetDataIndex == RX1_Cnt))        //数据段结束
                {
                        GetDataIndex++;
                        if(i == 0)        //数据错误
                        {
                                GetDataState = 3;
                                return 0;
                        }
                        else        return k;        //数据正确
                }
                if((j < '0') || (j > '9'))        //数据合法性检测
                {
                        GetDataIndex++;
                        GetDataState = 4;
                        return 0;
                }
                k = k * 10 + j - '0';
                i++;
                GetDataIndex++;
        }

        GetDataState = 9;
        return 10;        //数据错误
}

/********************** 串口返回时间信息 *****************************/
void        ReturnRTC(void)
{
        UART1_TxByte(year/10+'0');        //年
        UART1_TxByte(year%10+'0');
        UART1_TxByte('-');
        UART1_TxByte(month/10+'0');        //月
        UART1_TxByte(month%10+'0');
        UART1_TxByte('-');
        UART1_TxByte(day/10+'0');        //日
        UART1_TxByte(day%10+'0');
        UART1_TxByte(' ');
        UART1_TxByte(hour/10+'0');        //时
        UART1_TxByte(hour%10+'0');
        UART1_TxByte(':');
        UART1_TxByte(minute/10+'0');        //分
        UART1_TxByte(minute%10+'0');
        UART1_TxByte(':');
        UART1_TxByte(second/10+'0');        //秒
        UART1_TxByte(second%10+'0');
        UART1_TxByte(0x0d);
        UART1_TxByte(0x0a);
}

//========================================================================
// 函数: void  delay_N_10us(unsigned int j),  STC8xxx、AI8xxx系列
// 描述: 延时函数。
// 参数: j: 要延时的10us数, 1~65535*10us. 自动适应主时钟.
// 返回: none.
//========================================================================
void  delay_N_10us(unsigned int j)
{
        unsigned char i;
        do
        {
                i = (FOSC + 150000UL) / 300000UL -4;
                _nop_();
                _nop_();
                while(--i)        ;
        }while(--j);
}

/********************** 设置RTC时间 *****************************/
u8        SetRTC(void)
{
        P_SW2 |= 0x80;                //SFR enable
        if(year > 99)                                                return 1;
        if((month == 0) || (month > 12))        return 2;
        if((day == 0) || (day > 31))                return 3;
        if(hour > 23)                                        return 4;
        if(minute > 59)                                        return 5;
        if(second > 59)                                        return 6;
        INIYEAR  = year;
        INIMONTH = month;
        INIDAY   = day;
        INIHOUR  = hour;
        INIMIN   = minute;
        INISEC   = second;
        INISSEC  = 0;
        RTCCFG   = 0x01 | 0x02;        //设置RTC时间, |0x00:选择外部32K时钟, |0x02:选择内部32K时钟.
        delay_N_10us(50);        //等待初始化完成. 设置RTC时间需要32768Hz的1个周期时间,大约30.5us. 由于同步, 所以实际等待时间是0~30.5us.
                                                        //如果不等待设置完成就睡眠, 则RTC会由于设置没完成, 停止计数, 唤醒后才继续完成设置并继续计数.

        return 0;
}

/********************** RTC配置函数 *****************************/
void        RTC_config(void)        //RTC初始化函数
{
        P_SW2  |= 0x80;                //SFR enable
        P1n_pure_input(0xc0);                //P1.6 P1.7设置为高阻输入
        P1IE = ~0xc0;                                //P1.6 P1.7关闭数字输入功能
        IRC32KCR = 0x80;                        //启动内部32K IRC
        while (!(IRC32KCR & 1))        ;        //等待时钟稳定

        year    = 25;
        month   = 6;
        day     = 11;
        hour    = 12;
        minute  = 0;
        second  = 0;

        RTCCR   = 0x01;        //使能RTC, 并开始RTC计数
        SetRTC();                //设置RTC时间
        RTCIEN  = 0x08;        //中断使能, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
        RTCIF   = 0;        //中断标志, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
        ALAHOUR = 8;        //闹钟小时
        ALAMIN  = 30;        //闹钟分钟
        ALASEC  = 0;        //闹钟秒
        ALASSEC = 0;        //闹钟1/128秒
}

/********************** 读取RTC时间信息 *****************************/
void        RTC_read(void)
{
        P_SW2  |= 0x80;                //SFR enable
        year    = RTC_YEAR;                // RTC的年计数值
        month   = RTC_MONTH;        // RTC的月计数值
        day     = RTC_DAY;                // RTC的日计数值
        hour    = RTC_HOUR;                // RTC的时计数值
        minute  = RTC_MIN;                // RTC的分计数值
        second  = RTC_SEC;                // RTC的秒计数值
//        ssecond = RTC_SSEC;                // RTC的1/128秒计数值
}



//========================================================================
// 函数: SetTimer2Baudraye(u16 dat)
// 描述: 设置Timer2做波特率发生器。
// 参数: dat: Timer2的重装值.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void        SetTimer2Baudraye(u16 dat)        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
{
        AUXR &= ~(1<<4);        //Timer stop
        AUXR &= ~(1<<3);        //Timer2 set As Timer
        AUXR |=  (1<<2);        //Timer2 set as 1T mode
        TH2 = (u8)(dat >> 8);
        TL2 = (u8)dat;
        IE2  &= ~(1<<2);        //禁止中断
        AUXR |=  (1<<4);        //Timer run enable
}


//========================================================================
// 函数: void        UART1_config(u32 brt, u8 timer, u8 io)
// 描述: UART1初始化函数。
// 参数:   brt: 通信波特率.
//       timer: 波特率使用的定时器, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率.
//          io: 串口1切换到的IO,  io=1: 串口1切换到P3.0 P3.1,  =1: 切换到P3.6 P3.7,  =2: 切换到P1.6 P1.7.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void        UART1_config(u32 brt, u8 timer, u8 io)        // brt: 通信波特率,  timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1,  =1: 切换到P3.6 P3.7.
{
        brt = 65536UL - (FOSC / 4) / brt;
        if(timer == 2)        //波特率使用定时器2
        {
                AUXR |= 0x01;                //S1 BRT Use Timer2;
                SetTimer2Baudraye((u16)brt);
        }

        else                //波特率使用定时器1
        {
                TR1 = 0;
                AUXR &= ~0x01;                //S1 BRT Use Timer1;
                AUXR |=  (1<<6);        //Timer1 set as 1T mode
                TMOD &= ~(1<<6);        //Timer1 set As Timer
                TMOD &= ~0x30;                //Timer1_16bitAutoReload;
                TH1 = (u8)(brt >> 8);
                TL1 = (u8)brt;
                ET1 = 0;                        // 禁止Timer1中断
                INT_CLKO &= ~0x02;        // Timer1不输出高速时钟
                TR1  = 1;                        // 运行Timer1
        }

                 if(io == 1)        {S1_USE_P36P37();        P3n_standard(0xc0);}        //切换到 P3.6 P3.7
        else if(io == 2)        {S1_USE_P16P17();        P1n_standard(0xc0);}        //切换到 P1.6 P1.7
        else                                {S1_USE_P30P31();        P3n_standard(0x03);}        //切换到 P3.0 P3.1

        SCON = (SCON & 0x3f) | (1<<6);        // 8位数据, 1位起始位, 1位停止位, 无校验
//        PS  = 1;        //高优先级中断
        ES  = 1;        //允许中断
        REN = 1;        //允许接收
}


//========================================================================
// 函数: void UART1_TxByte(u8 dat)
// 描述: 串口1发送一个字节数据函数
// 参数: dat: 要发送的一个字节数据.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_TxByte(u8 dat)
{
        B_TX1_Busy = 1;                //标志发送忙
        SBUF = dat;                        //发一个字节
        while(B_TX1_Busy);        //等待发送完成
}

//========================================================================
// 函数: void UART1_PrintString(u8 *puts)
// 描述: 串口1字符串打印函数
// 参数: puts: 字符串指针.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_PrintString(u8 *puts)
{
    for (; *puts != 0;        puts++)        UART1_TxByte(*puts);
}


//========================================================================
// 函数: void UART1_int (void) interrupt UART1_VECTOR
// 描述: 串口1中断函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void UART1_ISR (void) interrupt UART1_VECTOR
{
        if(RI)
        {
                RI = 0;
                if(RX1_Cnt >= RX1_Length)        RX1_Cnt = 0;
                RX1_Buffer[RX1_Cnt++] = SBUF;
                RX1_TimeOut = 5;
                OpTime = 5;        //串口一旦唤醒, 接着5秒不睡眠, 以便正确接收数据. 唤醒帧将不能正确接收(因为唤醒需要计时us时间), 除非用很慢的速度(比如2400).

        }

        if(TI)
        {
                TI = 0;
                B_TX1_Busy = 0;
        }
}


//========================================================================
// 函数:u8        Timer0_Config(u8 t, u32 reload)
// 描述: timer0初始化函数.
// 参数:      t: 重装值类型, 0表示重装的是系统时钟数, 其余值表示重装的是时间(us).
//       reload: 重装值.
// 返回: 0: 初始化正确, 1: 重装值过大, 初始化错误.
// 版本: V1.0, 2018-3-5
//========================================================================
u8        Timer0_Config(u8 t, u32 reload)        //t=0: reload值是主时钟周期数,  t=1: reload值是时间(单位us)
{
        TR0 = 0;        //停止计数

        if(t != 0)        reload = (u32)(((float)FOSC * (float)reload)/1000000UL);        //重装的是时间(us), 计算所需要的系统时钟数.
        if(reload >= (65536UL * 12))        return 1;        //值过大, 返回错误
        if(reload < 65536UL)        AUXR |= 0x80;                //1T mode
        else
        {
                AUXR &= ~0x80;        //12T mode
                reload = reload / 12;
        }
        reload = 65536UL - reload;
        TH0 = (u8)(reload >> 8);
        TL0 = (u8)(reload);

        ET0 = 1;        //允许中断
//        PT0 = 1;        //高优先级中断
        TMOD = (TMOD & ~0x03) | 0;        //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
//        TMOD |=  0x04;                //对外计数或分频
        INT_CLKO |=  0x01;        //输出时钟
        P3n_standard(Pin5);        //P3.5设置为准双向口
        TR0 = 1;                        //开始运行
        return 0;
}

//========================================================================
// 函数: void timer0_int (void) interrupt TIMER0_VECTOR
// 描述:  timer0中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2016-5-12
//========================================================================
void timer0_ISR (void) interrupt TIMER0_VECTOR
{
   B_10ms = 1;
}


//========================================================================
// 函数: void        RTC_ISR(void) interrupt RTC_VECTOR
// 描述: 扩展中断函数(中断号>=32的中断)
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2018-4-2
// 备注:
//========================================================================
void        RTC_ISR(void) interrupt RTC_VECTOR
{
        u8        i;
        i = RTCIF;
        RTCIF = 0;                //中断标志, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
        if(i & 0x08)        //秒中断
        {
                B_1S = 1;        //秒标志
                P33 = ~P33;        //输出2秒周期方波, 方便测试精度
        }
        if(i & 0x80)        //闹铃中断
        {
                B_ALARM = 1;        //闹铃标志
        }
}





回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-16 11:14 , Processed in 0.313916 second(s), 88 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表