找回密码
 立即注册
楼主: admin

视频教学:《32位8051单片机原理及应用》,一等奖2万, 送实验箱; 冲哥版

   火... [复制链接]

0

主题

15

回帖

46

积分

新手上路

积分
46
发表于 2023-7-5 10:53:18 | 显示全部楼层
xbl2473*** 发表于 2023-7-5 10:20
第二集的学习日记:了解了STC32G开发板的硬件,明白了大部分的硬件组成以及硬件模块的功能用途。 ...

第三集的学习日记:关于STC-ISP的下载,STC-ISP用于软体下载入芯片内。手册记录了芯片的所有寄存器,IO接口的使用说明。STC32G编译器使用的是C251,除了C251以外还需要额外下载一个程序包。可以从ISP内直接下载,也可以官网下载。然后需要使用ISP往C251中添加型号,WIN10需要额外安装驱动。STC32G实验板可以使用USB-USB来进行下载。首次下载程序,需要在代码中查看时钟频率,从而在ISP中选择对应的时钟频率。
回复 支持 反对

使用道具 举报 送花

0

主题

15

回帖

46

积分

新手上路

积分
46
发表于 2023-7-5 15:16:03 | 显示全部楼层
本帖最后由 xbl2473*** 于 2023-7-5 15:39 编辑
xbl2473740563 发表于 2023-7-5 10:53
第三集的学习日记:关于STC-ISP的下载,STC-ISP用于软体下载入芯片内。手册记录了芯片的所有寄存器,IO接 ...

第四集的学习日记:
点亮LED的需要LED的一端接地一端接电源(还需要电阻),也就是一端高电平(1),一端低电平(0)。要通过单片机来实现的话需要通过IO口来输入输出,IO的电平可通过类似P0的IO口组,也可以通过类似P0.0的单独IO口来操作。
视频中的P4.0连接PNP三极管,输入低电平时可以使电源正极的电流正常通过,从而给P6的LED供电,目前P6已有一侧为高电平,所以主要给另外一侧低电平就可以点亮LED灯。
在代码中的实现,需要使用特殊功能寄存器(sfr)操作IO口组(sfr P0 = 0x80;)以及特殊功能寄存器位变量(sbit)操作单独的IO口(sbit P00 = P0^0;),PnM1与PnM0是用于配置Pn口的模式,00准双向,01推挽输出,10高阻输入,11开漏输出。
在代码中,main函数上方声明函数,可以让编译器知道代码中还有这个函数的存在,避免写了函数但是不生效或者报错,添加头文件需要在目录内添加.h头文件, 使用方法为 #include "名称.h"。
个人认为第四集主要要掌握手册的查询、sfr、sbit的使用方法以及Pn口的模式以及使用方法。在USB_CDC、USB_HID不停电下载部分涉及到了定时器,中断,但目前还不用操作。在添加头文件之后,可以不用手动操作sfr以及sbit,但还是需要掌握这两个功能的操作方法。
课后练习—点亮所有LED灯:
使用位操作的方法为 在死循环中新增P62 = 0;P63 = 0;... P67 =0,或者使用IO口组的操作方法 P6= 0x00;操作原理都是使得P6的IO口都为低电平,从而点亮LED灯。

回复 支持 反对

使用道具 举报 送花

0

主题

15

回帖

46

积分

新手上路

积分
46
发表于 2023-7-5 16:55:11 | 显示全部楼层
xbl2473*** 发表于 2023-7-5 15:16
第四集的学习日记:
点亮LED的需要LED的一端接地一端接电源(还需要电阻),也就是一端高电平(1),一端 ...

第五集的学习日记:
printf 需要增加三行代码
if( DeviceState != DEVSTATE_CONFIGURED) continue;
if(bUsbOutReady){
usb_OUT_done();
printf();
}
二进制 遇2向前进一位 八进制 遇8向前进一位 十六进制 0-9对应十进制的0-9 10以后 对应ABCDEF
常用输出格式
%d 十进制 %f 单精度浮点型 %lf 双精度浮点型 %o 八进制 %x 十六进制 %c 输出单个字符 %s 输出字符串 %p 输出指针地址
\r 回车 \n 换行

<<左移  1<<1 :0001 左移1位为0010  >>右移 1>>1:1000 右移1位为0100
&与运算 全1为1
|或运算  有1为1

bit 0/1
有符号 signed 无符号 unsigned
默认有符号 char -128~127对应 2^8  但第一位是符号 所以最大只能2^7
int -32768~32767 对应2^16 long int 对应2^32
回复 支持 反对

使用道具 举报 送花

0

主题

15

回帖

46

积分

新手上路

积分
46
发表于 2023-7-5 17:39:09 | 显示全部楼层
xbl2473*** 发表于 2023-7-5 16:55
第五集的学习日记:
printf 需要增加三行代码
if( DeviceState != DEVSTATE_CONFIGURED) continue;

第六集的学习日记:
首先在代码顶部定义MAIN_fosc(ISR时钟频率)为24MHz #define MAIN_fosc 24000000UL
u16 =#define unsigned int 无符号int 0~65535
闪烁的原理是 延时后取反IO接口的值 P60 != P60
do while先执行后判断 while先判断后执行
printf(a++)先输出a目前的值 再执行a+1 printf(++a)先执行a+1 在输出a的值
返回类型 函数名称() 如int add() 在add()函数内return的值为int类型

模块化需要.h和.c文件
.h文件中
#ifndef __XXX_h 避免多次包含同一个源文件
#define __XXX_h
#include "xxx.h" 调用头文件
void add() 函数声明
#endif 结尾

.c文件中
#include "xxx.h" 调用头文件
撰写代码
int add(){代码功能实现};

需要在设置中的setting-c251中添加引用路径

课后练习:SOS灯光编写(三短三长三短)
P60 = 0;
delay(500);
P60 != P60;
delay(1000);
P60 != P60;
delay(500);
P60 != P60;
回复 支持 反对

使用道具 举报 送花

0

主题

15

回帖

46

积分

新手上路

积分
46
发表于 2023-7-6 08:46:02 | 显示全部楼层
xbl2473*** 发表于 2023-7-5 17:39
第六集的学习日记:
首先在代码顶部定义MAIN_fosc(ISR时钟频率)为24MHz #define MAIN_fosc 24000000UL
u ...

第七集的学习日记:
按钮的原理本质是控制两个引脚的通断(常开开关 常闭开关)
按键按下时有10ms的抖动,所以需要添加去抖动代码
<<左移或者右移都是补0
数组的定义 类型 名称[容量]
数组的赋值 名称[索引] = 值
课后练习:按下按键 切换不同LED的效果

unsigned int LED_Type[] = {0XFE,0XFD,0XFB,0XF7,0XEF,0XDF,0XBF,0X7F};
sbit KEY0 = P0^0;

void main(){
int num = 0;
if(KEY0 == 0){
  delay(10);
  if(KEY0 == 0){
   P6 = LED_Type[num];
   delay(500);
   while(KEY == 0){};
   num++;
   if(num == 7)
    num = 0;
  }
}
}
回复 支持 反对

使用道具 举报 送花

0

主题

15

回帖

46

积分

新手上路

积分
46
发表于 2023-7-6 09:06:55 | 显示全部楼层
本帖最后由 xbl2473*** 于 2023-7-6 09:10 编辑
xbl2473740563 发表于 2023-7-6 08:46
第七集的学习日记:
按钮的原理本质是控制两个引脚的通断(常开开关 常闭开关)
按键按下时有10ms的抖动 ...

第八集的学习日记:
有源蜂鸣器只要一通电就会叫,无源需要不断切换高低电平。有源比无源多出了震荡源。

课后作业:增加按钮3,按下后表示启动,选择的对应的功能的LED持续闪烁,表示正在工作,且在工作的时候无法切换功能。

我的思路大概是新增一个bit START 来判断是否按下按钮3,另外在模式切换中增加一个判断条件if(START == 0)就执行模式切换,如果if(START == 1)就进行闪烁。
回复 支持 反对

使用道具 举报 送花

0

主题

15

回帖

46

积分

新手上路

积分
46
发表于 2023-7-6 10:04:38 | 显示全部楼层
xbl2473*** 发表于 2023-7-6 09:06
第八集的学习日记:
有源蜂鸣器只要一通电就会叫,无源需要不断切换高低电平。有源比无源多出了震荡源。

第九集的学习日记:
数码管是由多个发光二极管组成的。数码管分为共阳极(尾缀A)和共阴极(尾缀K)数

码管。共阳极低电平点亮,共阴极高电平点亮。
单位数码管的控制是由8个发光二极管组成的,可以通过十六进制来控制每个发光二极管的亮灭,从而显示不同的数字或者图形。
课后作业:
1.尝试使用数码管显示- H J L 等字母或符号。
-:点亮数码管中的g
共阴极 二进制0000 0001 十六进制0x01 共阳极 二进制 1111 1110 十六进制0xfe
H:点亮bcefg
共阴极 二进制 0110 1110 十六进制0xce 共阳极 二进制 1001 0001 十六进制0x91
J:点亮bcde
共阴极 二进制 0111 1000 十六进制0x78 共阳极 二进制 1000 0111 十六进制0x87
回复 支持 反对

使用道具 举报 送花

0

主题

15

回帖

46

积分

新手上路

积分
46
发表于 2023-7-6 10:49:45 | 显示全部楼层
本帖最后由 xbl2473*** 于 2023-7-6 10:51 编辑
xbl2473740563 发表于 2023-7-6 10:04
第九集的学习日记:
数码管是由多个发光二极管组成的。数码管分为共阳极(尾缀A)和共阴极(尾缀K)数

第十集的学习日记:
数码管的动态刷新原理就是选择需要打开的数码管,给该数码管的8位发光二极管赋值,

控制不同的发光二极管的亮灭,从而显示不同的数字图案。
控制原理:在选择完数码管后输出对应的位码,再输出该位码的段码,以此类推,直到

所有数码管都显示完毕。
位码和段码可以写成两个数组。需要使用时直接调用 位码[索引]=段码[索引] 即可方便

显示内容。
多个数码管的循环时间不能大于20ms,一旦超过20ms,将会出现断断续续的现象。
课后练习:
一、做一个简易时钟,功能如下
1.初始状态显示00-00-00
int wei[] = {0(第一位地址),1(第二位地址)...7(第八位地址)};
int duan[] = {0,1,2,3,4,5,6,7,8,9,-};
void CLOCK_init(){
        wei[0] = duan[0];  //数字0
        wei[1] = duan[0];
        wei[2] = duan[10]; //图形-
        wei[3] = duan[0];  //分针
        wei[4] = duan[0];
        wei[5] = duan[10]; //图形-
        wei[6] = duan[0];  //秒针
        wei[7] = duan[0];
}
void main(){
        CLOCK_init();
}

2.每隔一秒钟,秒+1,一分钟,分+1
全局变量
int FIRST_second = 0;
int SECOND_second = 0;
int FIRST_minute = 0;
int SECOND_minute = 0;

void time_add(){
        while(1){
                wei[3] = duan[SECOND_minute];  //分针
                wei[4] = duan[FIRST_minute];
                wei[6] = duan[SECOND_second];  //秒针
                wei[7] = duan[FIRST_second];
                delay(1000);
                FIRST_second++;
                //秒针
                if(FIRST_second == 10){
                        SECOND_second++;
                        FIRST_second =0;
                }
                if(SECOND_second == 6){
                        FIRST_minute++;
                        SECOND_second =0;
                }
                //分针
                if(FIRST_minute == 10){
                        SECOND_minute++;
                        FIRST_minute =0;
                }
                if(SECOND_minute == 6){
                        SECOND_minute =0;
                }
        }
}
void main(){
        CLOCK_init();
        time_add();
}

3.时间到达00 - 00 - 30,蜂鸣 3秒表示闹钟
sbit beep = P5^3;
void BEEP_3sec(){
        if(SECOND_minute == 3){
                beep = 1;
                delay(3000);
                beep = 0;
        }
}
回复 支持 反对

使用道具 举报 送花

0

主题

15

回帖

46

积分

新手上路

积分
46
发表于 2023-7-6 11:02:45 | 显示全部楼层
本帖最后由 xbl2473*** 于 2023-7-6 11:20 编辑
xbl2473740563 发表于 2023-7-6 10:49
第十集的学习日记:
数码管的动态刷新原理就是选择需要打开的数码管,给该数码管的8位发光二极管赋值,

第十一集的学习日记:
定时器会打断主程序的运行,中断后进行响应,执行中断处理程序,结束中断处理程序后,返回主程序继续执行主程序。
定时器是定时器和计数器的统称,可以通过TMOD设置为定时器,每隔一段时间就执行一箱操作。也可以设置为计数器,对脉冲进行计数。
定时器模式下可以设置分频(系统时钟/分频),不分频每12个时钟得到一个计数脉冲,12分频每1个时钟得到一个计数脉冲。
TCON中的TR是用来启动对应的定时器的,需要手动清0。
IE中的EA是中断总开关,ET0为定时器0的中断允许位。
定时器比delay函数更加精准的控制时间。
课后作业:
一、将第十课的简易时钟改成定时器驱动。
默认为不分频,TMOD设置为模式0。
EA=1,ET0=1;TR0=0;打开总开关,打开定时器0的中断允许位

时钟频率24Mhz,首先计算1ms需要的TH0以及TL0 65536-24000=41536 十六进制为A240 所以TH0=0xa2,TL0=0x40

int times = 0; //计数
void main(){
TMOD = 0X00;
TH0=0XA2;
TL0=0X40;
EA=1;
TR0=1;
ET0=1;
}

void TM0_Isr() interrupt 1{
times ++;
if(times == 1000){
First_second ++;
}
}

二、在上述基础上增加一个按钮用于暂停时间,再按一下恢复,再按一下暂停。
sbit KEY_Pause = p5^4;
void main(){
if(KEY_Pause == 1){//按下按钮
EA !=EA; //关闭中断
}
}
回复 支持 反对

使用道具 举报 送花

0

主题

15

回帖

46

积分

新手上路

积分
46
发表于 2023-7-6 11:47:13 | 显示全部楼层
xbl2473*** 发表于 2023-7-6 11:02
第十一集的学习日记:
定时器会打断主程序的运行,中断后进行响应,执行中断处理程序,结束中断处理程序后 ...

第十二集的学习日记:
设置计数器需要配置TMOD中的C/T 当C/T为1时则为计数器,为0时则为定时器。
计数器的用途:
可以用来计算编码器的脉冲,有高低电平变化的,都可以使用计数器的功能。
工作在方式1,可以从0到65536,超过65535就产生中断,如果想要10000个数,可以设置

TH0和TL0的初值为55536。
晶振频率12Mhz,1秒可以产生12000000个脉冲,计算12个数用时12/12000000秒,如果要

定时1ms,可以让计数器数12000个数,设置计数器的初值(TH0,TL0)为53535。
回复 支持 反对

使用道具 举报 送花

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

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

GMT+8, 2025-5-9 00:58 , Processed in 0.124149 second(s), 108 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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