AI8051学习历程 |已送实验箱
https://www.stcaimcu.com/data/attachment/forum/202412/09/103446c0mcpt8vpmys6q8p.png第一集,了解到这颗单片机不仅功能强大,还能兼容早期的89C52等等单片机,自带USB,无需额外硬件就能烧录调试,这个太方便开发者了
第二季,硬件和软件,视频中的是试验箱,由于我到时候的是及核心板,就重点了解一下软件,按照教程步骤安装好了开发软件,尝试刷入默认的流水灯固件,中间下错成工具箱的资料了还纳闷怎么不亮灯,仔细一看工具箱用的P0,核心板是P2,重新下载正确的固件就亮灯了 第三集,跟着教程步骤,
1. 新建工程,选择保存位置,选择单片机型号为 AO8051U-32BIT,新建main.c文件,保存后双击添加到Source Group 1工程目录下
然后点击设置 CPU mode选择C251,勾上后面的4 Byte, Memory Model选择XS开头这个, Rom 大小选择 Large 64K的 ,切换到输出选项卡,勾上 生成HEX文件
2. 使用ISP,保存AI8051的头文件到当前工程目录,然后编写main 和 while(1)框架, 点击编译,0错误0警告,OK
3. 开始点灯 教程中 P0M0 P0M1 P4M0 P4M1 都设置为0x00 P40 = 0;然后 P00 = 0; 点亮LED
通过查阅手册442页得知,每个 I/O 的配置都需要使用两个寄存器进行设置
即 P0M0 的第 0 位和 P0M1 的第 0 位组合起来配置 P0.0 口的模式
准双向口为 0 0 , 秦天柱版本对应的是P2,所以把P2M0P2M1 都设置为0
void main(void)
{
P2M0 = 0X00;
P2M1 = 0X00;
while(1)
{
P20 = 0;
P21 = 0;
P22 = 0;
}
}
尝试烧录进板子,成功点亮三颗灯 第四课,USB自动烧录
复制上一课的代码,添加 stc32_stc8_usb 头文件,主要用到usb_init();
创建3个指针变量
char *USER_DEVICEDESC = NULL; // 产品系列?
char *USER_PRODUCTDESC = NULL; // 产品型号?
char *USER_STCISPCMD = "@STCISP#"; // 必须和ISP软件内设置的的相同
// 由于USB用到的一些寄存器在 EAXFR里面,所以 P_SW2 的B7位要打开
P_SW2 |= 0x80; // B7位写1,使能访问XFR
usb_init(); // USB CDC 接口配置
IE2 |= 0x80; // 使能USB中断
EA = 1; // IE |= 0X80; // 只要用到了中断, 中断IE总开关也要打开
while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
if (bUsbOutReady)
{
//USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
usb_OUT_done();
}
编译出现42个警告 代码57 , 这个是提示有函数没有使用到 ,打开设置将警告一栏填入57,忽略掉这个提示
再次编译,0错误0警告
手动烧录一次,灯没亮,仔细查看了ISP的设置,√都勾上了啊,难道是程序没烧录进去?
仔细检查代码 怀疑是 while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置这里的问题
尝试修改成 ==重新烧录,灯亮了,说明程序已经烧录进去了,但是自动烧录还是不行,难不成硬件有问题?
打开下载的代码,一字不改烧录进去,一样不亮灯,说明程序卡在初始化那里了? 第五课,printf
复制上一课的代码,添加 tc32_stc8_usb 头文件,主要用到usb_init();
打开usb头文件,取消第二行的注释
#define printf prontf_hid // 参数原型
int printf_hid(const char *fmt, ...);
参数fmt--格式控制字符串,包含普通字符和转换说明
普通字符在输出时原样输出
常用的
/*格式字符
%c-单个字符形式 %s-字符串形式
%d-十进制整数形式 %x-十六进制整数形式
%f-单精度浮点数形式 %lf -双精度浮点数形式
%e-指针形式 %p-地址
转义字符
\?-多个?时使用,防止被解析成3字字词 \\-表示1个反斜杠,防止被解释称转义字符
\r-回车符 \n-换行符
\t-水平制表符 \v-垂直制表符
*/
C语言基础和逻辑运算符 第6课GPIO
#include "AI8051.h" // 调用头文件
#include "stc32_stc8_usb.h" // 调用头文件
#include "intrins.h" // 调用头文件
u8 i = 0;
void Delay20ms(void) //@24.000MHz
{
unsigned long edata i;
_nop_();
_nop_();
i = 119998UL;
while (i) i--;
}
void main(void)
{
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00;
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
while(1)
{
// 1,按下点亮,松开熄灭
if (P32 == 0)
{
P20 = 0;
}else{
P20 = 1;
}
// 按下熄灭,松开点亮
if (P33 == 0)
{
P21 = 1;
}else{
P21 = 0;
}
// 按一下切换亮灭,while等待
if (P32 == 0)
{
i = !i;
P22 = i;
while(P32 == 0){}
}
if (P33 == 0)
{
Delay20ms();
if (P33 == 0)
{
i = !i;
P23 = i;
while(P33 == 0){}
}
}
}
}
课后作业按一下P32灯亮按一下P33灯灭
if (P32 == 0)
{
Delay20ms();
if (P32 == 0)
{
P25 = 0;
while(P32 == 0){}
}
}
if (P33 == 0)
{
Delay20ms();
if (P33 == 0)
{
P25 = 1;
while(P33 == 0){}
}
}
课后作业按一下亮一颗灯,再按一下亮两颗灯,依次全部亮起
u8 x = 0;
if (P33 == 0)
{
Delay20ms();
if (P33 == 0)
{
x++;
if ( x > 8) {x = 0;}
while(P33 == 0){}
}
}
if (x == 1)
{
P20 = 0;
}else if (x == 2)
{
P20 = 0;P21 = 0;
}else if (x == 3)
{
P20 = 0;P21 = 0;P22 = 0;
}else if (x == 4)
{
P20 = 0;P21 = 0;P22 = 0;P23 = 0;
}else if (x == 5)
{
P20 = 0;P21 = 0;P22 = 0;P23 = 0;P24 = 0;
}else if (x == 6)
{
P20 = 0;P21 = 0;P22 = 0;P23 = 0;P24 = 0;P25 = 0;
}else if (x == 7)
{
P20 = 0;P21 = 0;P22 = 0;P23 = 0;P24 = 0;P25 = 0;P26 = 0;
}else if (x == 8)
{
P20 = 0;P21 = 0;P22 = 0;P23 = 0;P24 = 0;P25 = 0;P26 = 0;P27 = 0;
}else
{
P20 = 1;P21 = 1;P22 = 1;P23 = 1;P24 = 1;P25 = 1;P26 = 1;P27 = 1;
}
目前只想到用if判断,继续学习看看还有什么更便捷的方法 第7课,定时器中断
#include "AI8051.h" // 调用头文件
#include "intrins.h" // 调用头文件
#define u8unsigned char //8位无符号变量(0-255)
#define u16 unsigned int //16位无符号变量(0-65535)
u8 state = 0; //初始状态
u8 Run_State = 0; //运行状态
void Delay20ms(void) //@24.000MHzDelay20ms();
{
unsigned long edata i;
_nop_();
_nop_();
i = 119998UL;
while (i) i--;
}
void Timer0_Init(void) //500毫秒@24.000MHz
{
TM0PS = 0x0F; //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xDC; //设置定时初始值
TH0 = 0x0B; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断 设置为0可以关闭定时器
}
void main(void)
{
int count=1; //按键计数变量
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00;
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
IE2 |= 0x80; //使能USB中断
// Timer0_Init(); //定时器初始化
EA = 1; //IE |= 0X80;
while(1)
{
//任务1:
// if( P32 == 0 ) //判断P32按钮是否按下
// {
// Delay20ms(); //延时20ms消抖
// if( P32 == 0 )
// {
// printf("按键按下次数\xfd:%d 次\r\n",(int)count);
// count++;
//
// while( P32 == 0 ); //等待P32松开
//
// }
// }
// //任务2:灯按一下点亮三秒后熄灭。
if( P32 == 0 ) //判断P32按钮是否按下
{
Delay20ms(); //延时20ms消抖
if( P32 == 0 )
{
// printf("按键按下次数\xfd:%d 次\r\n",(int)count);
// count++;
P20 = 0;
Timer0_Init();
while( P32 == 0 ); //等待P32松开
}
}
//
//任务3:救护车灯控制器,按下报警按钮,红蓝交替闪烁(LED1和LED2 表示红和蓝灯),再按一下报警按钮,红蓝灯停止。
if( P33 == 0 ) //判断P32按钮是否按下
{
Delay20ms(); //延时20ms消抖
if( P33 == 0 )
{
Run_State = !Run_State; //运行状态取反
if( Run_State==1 ) //运行
{
Timer0_Init();
}
else
{
TR0 = 0; //关闭定时器
P21 = 1;
P22 = 1;
}
while( P33 == 0 ); //等待P32松开
}
}
}
}
void Timer0_Isr(void) interrupt 1 //Timer0的中断运行函数
{
state = !state;
P20 = state;
P21 = !state;
}
课后练习,多个定时器可以用多个变量来解决,比如我有2个任务需要每隔10ms50ms执行一次,代码如下
void Timer0_Init(void) //1毫秒@24.000MHz
{
TM0PS = 0x00; //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x30; //设置定时初始值
TH0 = 0xF8; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void Timer0_Isr(void) interrupt 1 //Timer0的中断运行函数
{
A++;
b++;
}
然后在住循环里面执行下面的函数
Task10ms()
{
if( A > 9 )
{
A = 0;
//code...
}
}
Task10ms()
{
if( B > 49 )
{
B = 0;
//code...
}
}
第八课,可以创建结构体体来对应多个任务
这个特别好用,让上一课的定时器能够创建多个任务
创建多个C和H文件用来区分同一类的函数是个好思路,要习惯
typedef struct //任务控制结构体,用于创建任务
{
u8 Run; //任务状态:Run/Stop
u16 TIMCount; //定时计数器
u16 TRITime; //重载计数器
void (*TaskHook) (void); //任务函数
} TASK_COMPONENTS;
void Task_Marks_Handler_Callback(void)
{
u8 i; // 定义一个8位无符号整数变量 i 作为循环计数器
for (i = 0; i < Tasks_Max; i++)// 遍历所有任务,Tasks_Max 是任务的最大数量
{
if (Task_Comps.TIMCount)// 检查当前任务的时间计数器是否不为0
{
Task_Comps.TIMCount--;// 时间计数器减1
if (Task_Comps.TIMCount == 0)// 如果时间计数器减到0
{
// 重置时间计数器为任务的初始时间
Task_Comps.TIMCount = Task_Comps.TRITime;
// 标记任务为可运行状态
Task_Comps.Run = 1;
}
}
}
}
void Task_Pro_Handler_Callback(void)
{
u8 i; // 定义一个8位无符号整数变量 i 作为循环计数器
for (i = 0; i < Tasks_Max; i++) // 遍历所有任务,Tasks_Max 是任务的最大数量
{
if (Task_Comps.Run) // 检查当前任务的 Run 标志是否为1(可运行)
{
Task_Comps.Run = 0; // 清零 Run 标志
Task_Comps.TaskHook(); // 执行任务
}
}
}
第9课,数码管
学习了74HC595移位寄存器的工作原理 , 可以用3个引脚传输数据控制更多的LED
// 发送1个字节给595
void send595byts (u8 data)
{
u8 i;
for (i = 0; i < 8; i++)
{
dat <<= 1; // 左移1位到了CY
HC_595_SER = CY;
HC_595_SCK = 1;
HC_595_SCK = 0;
}
}
// 发送多个字节给多个595
void send595(const u8 *data, u8 length)
{
u8 i;
for (i = 0; i < length; i++) {
send595byts(data);
}
HC_595_RCK = 1;
HC_595_RCK = 0;
}
学习了ISP软甲的虚拟LED和虚拟数码管,在没有硬件的情况下也可以调试
用到了stc32_stc8_usb中的SEG7_ShowCode函数
先建立码表,然后显示对应的数组成员号,简单高效
认真打卡的小伙伴免费包邮 送AI8051U实验箱~~也期待拿到实验箱后 更多测试分享!
【免费 + 包邮 送】 送/申样/采购 可上班时间加 如下您对应地区的客服 QQ或微信联系
加STC华南区客服司经理QQ: 2234917869 ;微信:18012226298要求 【免费+包邮】 送, 还免费教仿真
加STC华南区客服刘经理QQ: 3398500488 ;微信:18106296592要求 【免费+包邮】 送, 还免费教仿真
加STC华南区客服佘经理QQ: 614777595; 微信:18106296591 要求 【免费+包邮】 送, 还免费教仿真
加STC华南区客服曹经理QQ: 1933892258 ;微信:18106296595 要求 【免费+包邮】 送, 还免费教仿真
加STC华东区客服聂经理QQ: 2593903262; 微信:18106296598要求 【免费+包邮】 送, 还免费教仿真
加STC华东区客服吴经理QQ: 1463035472; 微信:19952583954要求 【免费+包邮】 送, 还免费教仿真
加STC西北区客服孙经理QQ: 1347154513 ;微信:18106296593要求 【免费+包邮】 送, 还免费教仿真
加STC华北区客服石经理QQ: 1638975601 ;微信:19952583876要求 【免费+包邮】 送, 还免费教仿真
加STC华中区客服唐经理QQ:2571301708 ; 微信:18106296589 要求 【免费+包邮】 送, 还免费教仿真
加STC东北区客服庄经理QQ: 1017142298 ;微信:19952583534要求 【免费+包邮】 送, 还免费教仿真
加STC西南区客服曹经理QQ: 3897745450 ;微信:18012226281 要求 【免费+包邮】 送, 还免费教仿真
加STC西南区客服吴经理QQ: 1463035472 ;微信:19952583954 要求 【免费+包邮】 送, 还免费教仿真
工作时间:8:30-12:00,13:00-17:30(周一 到 周五, 法定节假日除外)
【免费 + 包邮 送】 送/申样/采购传统电话热线:0513-55012928,0513-89896509,0513-55012929
页:
[1]
2