本帖最后由 272761180 于 2024-11-27 10:25 编辑
【第三课】 《点亮第一颗LED》
实战小白化身点灯大师上线!(不是,其实基础功能已经学完一遍了)本节课主要讲了两部分重点内容,其一是工程的搭建,其二是IO点灯。
一、环境搭建
这里不再赘述,相比于使用vscode部署esp idf开发环境那个“难”以置信的方法,AI8051U环境搭建很为方便,技术手册里面也是手把手地教导。下面讲几个注意点:
1. AI8051U支持32位和8位两种方式,由不同编译器支持,注意区分,烧录时ISP也要注意选择;
2. 安装好编译环境后注意看一下软件的激活情况,没有激活时当项目工程体量较大会无法编译。这里官方没有讲到,因为要涉及到魔法激活的事情。激活后会有激活号。
未激活时报错如下:*** ERROR L250: CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED
LIMIT: 0800H BYTES
二、IO点灯
很简单粗暴的一行代码实现: PXX=0(下拉)、PXX=1(上拉)。
因为我有强迫症,为了增加代码可读性,进行了封装:(这一部分代码是错误的,8051的运行逻辑不能照搬STM32,不用封装为宜,已有大佬指出)
// 为P5端口封装设置引脚状态的函数
void set_P5(unsigned char pin, unsigned char level) {
if(pin>=0 && pin <=7){
if (level == HIGH) { P5 |= (1 << pin); }
else { P5 &= ~(1 << pin); }
}
}
void BoardLED_ON(void) // 开发板板载绿色LED P50
{
set_P5(0,LOW); //P50写入低电平开启LED
}
void BoardLED_OFF(void)
{
set_P5(0,HIGH);
}
复制代码
下面给出一些拓展:
1. IO口模式
不同IO口有不同功能,技术手册也都解释说明了。这里板子启动时默认将所有IO口都设置为了准双向口。
准双向口的拉电流能力是270-150uA,因此也可以驱动高亮0603LED而不需要限流电阻。
但是,推挽输出的拉电流能力能够到20mA,会达到某些0603LED的Imax,因此需要电路串联限流电阻。当然,推挽输出模式下LED发光会更亮。
P5M0 = 0x01; //推挽输出模式开灯
P5M1 = 0x00; //注释掉这两行为准双向口模式开灯 复制代码
图左为准双向口,图右为推挽输出模式。那么为什么两个图的灯亮度一致呢?(这一部分是需要IO口拉高点灯时,准双向口和推挽才会有明显的差异,我这里因为使用限流电阻所以看不出来,已有大佬指出)
因为虽然推挽模式下约为uA级别电流,而当使用推完输出模式在3.3V供电模式下,由于电路串联了1K的限流电阻,电流 I=(3.3-Vf)/1000。翠绿色LED的Vf在3V左右,因此电路电流约为3mA(这一部分实际是0.3mA,已有大佬指出) 。开发板使用的是高亮LED,因此流明差别肉眼辨认不出。因为现在是在外实验的,没有使用我的大开发板;大板上面可以使用三色灯进行进一步测试。
2. 关于Borad_Init()
另外,刚开始写代码看到案例的时候会有读者质疑下面这一串是什么东西了吧,这里做个解释:
P_SW2 = 0X80; //使能访问XFR,没有冲突不用关闭
CKCON = 0x00, //设置外部数据总线速度为最快
WTST = 0x00; //设置程序代码等待参数
//赋值为0可将CPU执行程序的速度设置为最快
P0M0 = 0x00; P0M1 = 0x00;
P1M0 = 0x00; P1M1 = 0x00;
P2M0 = 0x00; P2M1 = 0x00;
P3M0 = 0x00; P3M1 = 0x00;
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x00; 复制代码
那么这就完了吗?并不是的。
每款MCU工作时都要进行时钟配置,那么为什么没有看到AI8051U像STM一样进行SYSCLK配置呢?其实,当你打开ISP进行烧录的那一刻,你已经配置完了。(WOWOOOOOOOOOOOO!)
也就是说,AI8051U的时钟配置更为灵活,无需进行代码配置,只要在使用时钟进行相应计算时做个宏定义#FOSC 即可。这里可以阅读我的其他帖子,有大佬解释的很到位:
新手请教关于AI8051U的时钟问题 https://www.stcaimcu.com/forum.php?mod=viewthread&tid=12083 (出处: 国芯技术交流网站)
另外,代码里也并不是不用配置时钟,毕竟时钟源也是需要MCU选择的,只是系统默认使用高速内部IRC,帮你省掉了下面的代码:
//注:芯片上电后系统会默启动内部高速HRC,并选择为系统时钟,
//所以一般情况下不需要作这一部分设置
// HIRCCR = 0X80; //启动内部高速IRC
// while (!(HIRCCR & 1)); //等待时钟稳定,检查最低位ST状态,为1时震荡频率稳定
// CLKSEL = 0x00; 复制代码
这里再提到一句,ISP可设置的IRC频率范围应该是通过高速内部IRC计算的,即
为什么±27%?是时钟误差大吗?当然不是的,是可调的IRC范围,也就是类似11.0592等数据的来源。因此在自己设置时钟时,注意不要设置到盲区了
(大佬指导一下是这个意思吗)
最后,如果是使用片外晶振,配置代码如下(手册也已给出)
//选择时钟来源为内部低速IRC
// IRC32KCR = 0X80; //启动内部低速IRC
// while (!(IRC32KCR & 1));
// CLKDIV = 0X00;
// CLKSEL = 0x03;
//选择时钟来源为内部48M IRC
// IRC48MCR = 0X80; //启动内部48M IRC
// while (!(IRC48MCR & 1));
// CLKDIV = 0X02;
// CLKSEL = 0x0C;
//选择时钟来源为外部32K晶振 【板载这个】
// X32KCR = 0xC0; //启动外部晶振
// while (!(X32KCR & 1)); //等待时钟稳定
// CLKDIV = 0X00;
// CLKSEL = 0x02; //选择外部32K晶振
//选择时钟来源为外部晶振
// XOSCCR = 0xC0; //启动外部晶振
// while (!(XOSCCR & 1));
// CLKDIV = 0X00;
// CLKSEL = 0X01; //选择外部晶振 复制代码
同样,如果使用外部晶振,要研究一下芯片的上电过程了:
配置后,按照时钟树配置相应变量分频、倍频就行了。(还没试验验证操作性)
这堂课涉及内容很少吗?其实不是的。
点灯大师很低级吗?其实不是的。