求助8H8K64U版本识别及问题
最近使用8H8K64U 做了一个温湿度计,想使用硬件RTC功能。当时芯片是积分兑换的,没有注意版本,仔细看芯片最后一行最小的字母,最后两个是HD, 不是到是不是D版本的。
软件是使用keil。
RTOS使用的是CosyOs。
现象:
在初始化钩子中未添加RTC相关初始化代码时能正常工作,任务管理器也工作正常;
在初始化钩子中缇娜家了RTC相关初始化代码后就不能正常工作了,具体时停留在一个欢迎界面,任务管理器也不能正常工作;
在欢迎界面的退出部分添加了点亮一个指示灯。指示灯也能点亮。就是页面不切换, 任务管理器也不能正常工作。
您好,正看芯片丝印最下面一行最后一个字母为芯片版本号
是D版 DebugLab 发表于 2025-2-5 12:58
是D版
那就是可以使用硬件RTC了。
我初始化设置使用内部32K,
按照试验箱的例程初始化,导致RTOS不工作了。 麻烦哪位大佬帮忙看下这个程序有什么问题吗?
现象是,按一下复位键,串口打印信息:
接收←.
接收←Second=0
接收←
彊0欭聶"..稿.$.鮽?
然后就一直不打印任何信息了。
#include "STC8H.H"
#include "stdio.h"
#define MAIN_Fosc 24000000L //定义主时钟
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
#define Baudrate 115200L
#define TM (65536 -(MAIN_Fosc/Baudrate/4))
#define Timer0_Reload (65536UL -(MAIN_Fosc / 1000)) //Timer 0 中断频率, 1000次/秒
u8 B_1s;
void RTC_config(void);
/******************** 串口打印函数 ********************/
void UartInit(void)
{
SCON = (SCON & 0x3f) | 0x40;// 00xx xxxx | 0100 0000 = 01xx xxxx
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TL1= TM;
TH1= TM>>8;
TR1 = 1; //定时器1开始计时
// REN = 1; //允许接收
// SCON = (SCON & 0x3f) | 0x40;
// T2L= TM;
// T2H= TM>>8;
// AUXR |= 0x15; //串口1选择定时器2为波特率发生器
// REN = 1; //允许接收
}
void UartPutc(unsigned char dat)
{
SBUF = dat;
while(TI==0);
TI = 0;
}
char putchar(char c)
{
UartPutc(c);
return c;
}
void main(void)
{
P_SW2 |= 0x80;//扩展寄存器(XFR)访问使能
P0M1 = 0x00; P0M0 = 0x00; //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
P1M1 = 0x00; P1M0 = 0x00; //设置P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V)
P2M1 = 0x00; P2M0 = 0x00; //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V)
P3M1 = 0x00; P3M0 = 0x00; //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
P4M1 = 0x00; P4M0 = 0x00; //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
P5M1 = 0x00; P5M0 = 0x00; //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
P6M1 = 0x00; P6M0 = 0x00; //设置为漏极开路(实验箱加了上拉电阻到3.3V)
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
// AUXR = 0x80; //Timer0 set as 1T, 16 bits timer auto-reload,
// TH0 = (u8)(Timer0_Reload / 256);
// TL0 = (u8)(Timer0_Reload % 256);
// ET0 = 1; //Timer0 interrupt enable
// TR0 = 1; //Tiner0 run
UartInit();
RTC_config();
EA = 1; //打开总中断
while(1)
{
if(B_1s)
{
B_1s = 0;
printf("Second=%bd\r\n",SEC);
}
}
}
/******************** RTC中断函数 *********************/
void RTC_Isr() interrupt 13
{
if(RTCIF & 0x80) //闹钟中断
{
RTCIF &= ~0x80;
}
if(RTCIF & 0x08) //秒中断
{
RTCIF &= ~0x08;
B_1s = 1;
}
}
//========================================================================
// 函数: void RTC_config(void)
// 描述: RTC初始化函数。
// 参数: 无.
// 返回: 无.
// 版本: V1.0, 2020-6-10
//========================================================================
void RTC_config(void)
{
INIYEAR = 21; //Y:2021
INIMONTH = 12; //M:12
INIDAY = 31; //D:31
INIHOUR = 23; //H:23
INIMIN = 59; //M:59
INISEC = 50; //S:50
INISSEC = 0; //S/128:0
ALAHOUR = 0; //闹钟小时
ALAMIN= 0; //闹钟分钟
ALASEC= 0; //闹钟秒
ALASSEC = 0; //闹钟1/128秒
//STC8H8K64U B版本芯片使用内部32K时钟,休眠无法唤醒
IRC32KCR = 0x80; //启动内部32K晶振.
while (!(IRC32KCR & 1));//等待时钟稳定
RTCCFG = 0x03; //选择内部32K时钟源,触发RTC寄存器初始化
// X32KCR = 0x80 + 0x40; //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
// while (!(X32KCR & 1));//等待时钟稳定
// RTCCFG = 0x01; //选择外部32K时钟源,触发RTC寄存器初始化
RTCIF = 0x00; //清中断标志
RTCIEN = 0x88; //中断使能, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
RTCCR = 0x01; //RTC使能
while(RTCCFG & 0x01); //等待初始化完成,需要在 "RTC使能" 之后判断.
//设置RTC时间需要32768Hz的1个周期时间,大约30.5us. 由于同步, 所以实际等待时间是0~30.5us.
//如果不等待设置完成就睡眠, 则RTC会由于设置没完成, 停止计数, 唤醒后才继续完成设置并继续计数.
} DebugLab 发表于 2025-2-5 12:58
是D版
我看试验箱上的最后两个字符是 0D 也是D版本吧?
我把5楼贴出来的程序烧录到试验箱和我的温湿度计后,都不能正常工作。
然后在试验箱的示例程序中有一段汇编代码,加上后试验箱就工作了。
有关于汇编中那段代码的解释吗?
RTC的中断编号是13, 按照 13 *8 + 3 计算就是 6bH。 也就是如果RTC中断发生应该会跳到 6BH去执行代码把, 为啥还需要跳转。 大锤子 发表于 2025-2-6 11:39
我看试验箱上的最后两个字符是 0D 也是D版本吧?
我把5楼贴出来的程序烧录到试验箱和我的温湿度计后,都 ...
中断13是保留中断
RTC中断是中断36
汇编是借用中断13重映射中断
也可以使用中断号扩展插件
大锤子 发表于 2025-2-6 11:39
我看试验箱上的最后两个字符是 0D 也是D版本吧?
我把5楼贴出来的程序烧录到试验箱和我的温湿度计后,都 ...
又是一个不读手册的大神。
RTC的中断编号是36
目前 Keil 各个版本的 C51 和 C251 编译器均只支持 32 个中断号(0~31)
中断编号13是使用保留中断号进行中转
angmall 发表于 2025-2-6 11:57
又是一个不读手册的大神。
RTC的中断编号是36
目前 Keil 各个版本的 C51 和 C251 编译器均只支持 32 个中 ...
在没有遇到问题之前确实没有看关于中断序号部分的手册,直接使用了示例程序。
就单纯以为中断序号就是13。
那中专了了是不是可以在示例程序中说明一下呢
页:
[1]