8H8K64U开天斧开发板学习笔记
之前自学过89C52,没有留下任何记录,代码都删完了。这次创个帖子记录下自己学习8H8K64U的过程,本人会把每次的收获分享到这里,欢迎同道中人交流借鉴,欢迎大佬指点。
以下是我目前计划学习单片机的途径:
1.8H8K64U 官方芯片手册
2.STCAI官方论坛
3.郭天祥相关课程
4.b站搜索教程
5.单片机交流学习群
学习重点:
1.单片机寄存器的使用
2.库函数的使用
使用硬件:
1.开天斧三.2
2.后期可能会使用Link 1d下载器
本帖最后由 未元星系 于 2024-5-24 12:18 编辑
自学开天斧第①课:
学习内容:1、IO口点灯;2、IO口模式;
学习简介:点亮LED一般是学习一款单片机的第一课,不过8h单片机与stc89c52略有不同,它的每个引脚都有四种模式可供我们选择:准双向口、高阻输入、推挽输出、开漏输出。在未定义引脚情况下,8H单片机引脚默认为高阻输入模式,此时电流既不流入也不流出,故点灯前需要配置IO口模式。
配置IO口方法:芯片手册有关于选择IO口模式的表格,我们也可以从STC-ISP的I/O口配置工具进行配置,这样方便很多。开天斧板载LED是都是共阳极,所以上电后IO口为低电平时LED点亮,我们可以把IO口配置成准双向口模式。
代码下载方式:USB下载:按住P3.2按键再按电源按键,STC-ISP识别到串口即可下载。
程序代码:
#include <STC8H.H>
void main()
{
P2M0 = 0x00; P2M1 = 0x00; //将P2口全配置为准双向口模式
while(1) //死循环
{
P2 = 0x00; //P2口全部输出低电平,即“00000000”,点亮板载共阳极LED
}
}
开发板现象:P2口8个LED灯同时点亮
本帖最后由 未元星系 于 2024-5-25 14:21 编辑
自学开天斧第②课:
学习内容:1、Delay 延时函数
学习简介:点亮LED后需要观察更多信号,我们可以利用延时函数让LED亮一段时间再灭一段时间,如此循环,就能看到闪烁的LED,也能够根据自己的需要配置过更多花样的闪烁。Delay延时函数原理上是就是占用单片机运行程序的时间,实际上这会降低单片机运行效率,后期学到定时器时会有效率更高的延时代码。
Delay 延时函数配置方法(两种选一即可):
1.STC-ISP 软件延时计算器(本人有改动:unsigned char 换成了unsigned int / 加了do while()循环和形参,方便灵活设置具体延时时长):
void Delay_ms(unsigned int ms) //@24.000MHz
{
do{
unsigned char data i, j;
i = 29;
j = 183;
do
{
while (--j);
} while (--i);
}while(--ms);
}
// 自己配置需要的频率
2.STC8H8K64U开天斧库函数(本人有改动:unsigned char 换成了unsigned int):
#define MAIN_Fosc 24000000L //定义单片机主频24MHZ,这里可根据需要修改
void Delay_ms(unsigned int ms)
{
unsigned int i;
do{
i = MAIN_Fosc / 8920;//理论1.000ms,debug实测约1.00022291s (这里库函数原本除的是10000,
//但我这里延时略慢于设定时间,自行调整了参数,大家根据自己实际情况选择是否直接用库函数的参数即可)
while(--i);
}while(--ms);
}
主函数:
void main()
{
P2M0 = 0x00; P2M1 = 0x00; //将P2口全配置为准双向口模式
while(1) //死循环
{
P2 = 0x00; //点亮8颗LED
Delay_ms(500); //延时500毫秒
P2 = 0xff; //熄灭8颗LED
Delay_ms(500); //延时500毫秒
}
}
程序现象:LED以1000毫秒为频率闪烁
8920怎么来的,官方给的是10000 本帖最后由 未元星系 于 2024-5-25 14:16 编辑
soma 发表于 2024-5-25 11:27
8920怎么来的,官方给的是10000
自己debug测的,但我这边用官方的10000和Debug的都不太准,官方的10000我实际延时时间略慢了 本帖最后由 未元星系 于 2024-5-25 23:56 编辑
自学开天斧第③课:
学习内容:1、独立按键
学习简介:
开天斧板载四个用户自定义独立按键,一头分别接P3.5、P3.4、P3.3、P3.2,另一头接地,所以当按键引脚输出高电平时,按键按下,引脚接地,释放电流,IO口检测为低电平。
本次学习内容为用四个按键控制LED灯以四种方式亮灭。
所用延时函数:
void Delay_ms(unsigned int ms) //@24.000MHz
{
do{
unsigned char data i, j;
i = 29;
j = 183;
do
{
while (--j);
} while (--i);
}while(--ms);
}
按键函数:
unsigned char key(void)
{
unsigned char KeyNumber=0;
if(P35==0){Delay_ms(10);while(P35==0);Delay_ms(10);KeyNumber=1;} //Delay_ms(10) 是因为按下按键时会产生抖动,在抖动期间引脚会在高低电平间来回跳跃,
if(P34==0){Delay_ms(10);while(P34==0);Delay_ms(10);KeyNumber=2;} //需要延时一段时间去除干扰
if(P33==0){Delay_ms(10);while(P33==0);Delay_ms(10);KeyNumber=3;}
if(P32==0){Delay_ms(10);while(P32==0);Delay_ms(10);KeyNumber=4;}
return KeyNumber;
}
主函数:
void main()
{
int i;
unsigned char num = 0x01;
P2M0 = 0x00; P2M1 = 0x00; //将P2口全配置为准双向口模式
P3M0 = 0x00; P3M1 = 0x00; //将P3口全配置为准双向口模式
P3 |= 0x3C; //初始化需要的P3,将P3.5、P3.4、P3.3、P3.2置1
while(1) //死循环
{
char keynumber = key();
if(keynumber == 1) //P3.5按键按下松开,LED一边流水灯
{
for(i = 0;i <= 8;i++)
{
P2 = ~(num << i);
Delay_ms(100);
}
}
if(keynumber == 2) //P3.4按键按下松开,LED长亮400ms后熄灭
{
P2 = 0x00;Delay_ms(400);
P2 = 0xff;
}
if(keynumber == 3) //P3.3按键按下松开,LED亮灭亮灭,每100ms切换
{
P2 = 0x00;Delay_ms(100);
P2 = 0xff;Delay_ms(100);
P2 = 0x00;Delay_ms(100);
P2 = 0xff;Delay_ms(100);
}
if(keynumber == 4) //P3.2按键按下松开,8个LED每4位交替闪烁2个循环
{
P2 = 0x55;Delay_ms(150);
P2 = 0xAA;Delay_ms(150);
P2 = 0x55;Delay_ms(150);
P2 = 0xAA;Delay_ms(150);
P2 = 0xff;
}
}
}
代码现象:P3.5按键按下松开,LED一边流水灯;P3.4按键按下松开,LED长亮400ms后熄灭;P3.3按键按下松开,LED亮灭亮灭,每100ms切换;P3.2按键按下松开,8个LED每4位交替闪烁2个循环
##第一集
##第二集
##第三集
{:4_174:}{:4_174:}{:4_174:}跟着论坛学就可以了 qike009 发表于 2024-5-26 05:31
跟着论坛学就可以了
现在这个时代学技术的方式很多,只要真正想学或多或少都会有收获{:4_168:} zhaoye818 发表于 2024-5-26 13:59
加油!
嗯嗯{:4_197:} 本帖最后由 未元星系 于 2024-5-26 23:59 编辑
自学开天斧第④课:
学习内容:1、定时器(以定时器T0为例)
学习简介:STC8H8K64U单片机内置5个定时器,T0,T1支持传统8051单片机16位模式,T2,T3,T4支持24位模式(即8位预分频+16位定时器),本次学习定时器0做定时使用,延时控制LED灯闪烁。
程序代码:
void Timer0_Init(void)//定时1ms
{
AUXR |= 0x80;//设置定时器为1T模式,即不分频
TMOD &= 0xF0;//保留高四位(定时器1),低四位全为0:设置定时器/计数器0为定时器、GATE置0、16位自动重装模式
TL0 = 0x3F; //初始值65535 - 24000 = 41535 = 1010 0010 0011 1111,即高8位为0xA2,低8位为0x3F
TH0 = 0xA2; //
TF0 = 0; //清零TF0中断标志位
TR0 = 1; //定时器开始计时
ET0 = 1; //开启定时器0中断
}
void main()
{
P2M0 = 0x00; P2M1 = 0x00; //P2口设为准双向口模式
Timer0_Init(); //初始化定时器0
EA = 1; //打开总中断
P2 = 0x00; //P2口8个LED灯全亮
while(1){} //死循环
}
static unsigned int Timer1_num = 0; //初始化定时变量
void Timer0_interrupt(void) interrupt 1 //定时器0中断
{
Timer1_num ++; //当定时器完成一次定时,即1ms,Timer1_num加一
if(Timer1_num == 500) //延时500ms
{
Timer1_num = 0; //清零定时变量
P2 = ~(P2); //反转P2口
}
}
代码现象:8个LED每500ms翻转一次