跟冲哥学习32G12K128打卡
2024.9.2 第一集:认识单片机1、什么是单片机?
单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器R@M、多种/0口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、AD转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。
2、单片机能做什么?
单片机基本就是一个小的功能减少的计算机,能写入用户程序;能读取在输入引脚上的电压信号,能在引脚上输出特定的电平信号,能在特定引脚上输出电压信号,能计算时间,能计数,能做数学运算,能做逻辑运算,能顺序动作,能通信等功能,最概括的来说就是他能做有规律可循的控制应用。
用途:单片机广泛应用于仪器仪表、家用电器、医用设备、航空航天、专用设备的智能化管理及过程控制等领域,大致可分如下几个范畴:
●智能仪器:电压、电流、功率、频率、湿度、温度、流量等的仪器仪表工业控制:工厂流水线的智能化,电梯智能化控制、各种报警系统等家用电器:电饭煲、洗衣机、电冰箱、空调机、彩电等
●网络和通信:手机,电话机、楼宇自动通信呼叫系统、列车无线通信等医用设备领域:医用呼吸机,!监护仪,超声诊断设备及病床呼叫系统等
●模块化系统:电子音乐贺卡,PLC工控板等。汽车电子:发动机控制器,基于CAN总线的汽车发动机智能电子控制器GRS导航系统、abs防抱死系统、制动系统、胎压检测等
3、介绍常见的单片机封装
单片机有很多封装形式
4、介绍32G12K128实验箱,使用实验箱或者使用stc的开发板都可正常完成学习
5、新手常见问题
(1)推荐使用51单片机入门
(2)51单片机肯定不会淘汰的,51单片机应用非常广泛,有独特的优势,长盛不衰,稳定运行,51单片机也越做越好,性能越来越强大
(3)个人入门单片机,耐心学习完一套视频,可以做做竞赛的项目,检验自己是否入门
(4)STC单片机资料做的非常好,技术支持到位;广泛赠送单片机给爱好者,非常良心
(5)做产品,选择单片机并不是越贵越好,满足需求,合适的就是最好的
(6)没学过单片机的人,已经上班了,也可以学习单片机开发
6、官网功能介绍
我一定要坚持跟着学习,静下心沉住气!
第二集:了解硬件
介绍32G12K128实验箱具备的功能:红外发射与接收、电压比较、8位数码管、LED灯、NTC测温、18B20测温、ADC按键、PWM模拟DAC、24C02存储、独立按键、LCD接口、USB接口、232接口、FLASH扩展、RS232电路、蜂鸣器电路、测试接口、模拟示波器接口等。
实验箱的功能基本涵盖了单片机常见的功能,非常强大! 第三集:开发环境搭建和程序下载
主要包含以下内容:
1.STC-ISP软件的下载
STC-ISP软件是开发STC家的单片机的必备神器,他不仅能下载STC全系列单片机的程序,甚至集成了虚拟显示功能,范例程序程序,在线生成工具,驱动安装等等功能。
2.STC32手册下载
可以下载阅读,也可以在线阅读,推荐下载阅读。
两种下载方式
3.PDF阅读器下载
本人已有,不需要重新下载。
4.学会PDF阅读器查阅手册
手册制作的时候已经做了详细的目录索引,可以点击目录,快速进入自己需要的内容;
可以通过书签快速定位内容;
可以通过搜索快速找到需要的内容;
5.跟着手册搭建C251开发环境
手册第五章有C251开发环境下载安装方法,跟着做就可以了。
6.程序包的下载
网站上有实验箱的代码下载,可以直接下下来参考学习
7.第一个工程的编译和下载
下载描述
本帖最后由 webfly 于 2024-9-3 23:25 编辑
硬件USB直接下载功能很强大
申请的开发板到了,第一时间测试了一下硬件USB,确实很好用
本帖最后由 webfly 于 2024-9-13 23:02 编辑
第四集:建立工程点亮第一颗LED
1、LED点亮的原理
LED就是发光二极管,单片机操作指定IO口,输出高电平或者低电平,可以点亮LED;电路中,要给LED加限流电阻,防止烧坏LED
2、什么是GPIO
GPlO(general purpose intput output)是通用输入输出端口的简称,可以通过软件来读取其输入电平,或者控制他输出高低电平,点亮LED就需要用到IO口
GPIO可以按组批量操作,也可以单个操作;通过控制IO口输出高低电平,就能控制LED的亮和灭
3、建立工程,点亮led
根据官方文档,建立开发环境
环境建立好以后,新建一个工程led,然后添加一个main.c,在这个文件里编写代码
sfr P2=0xA0;
sfr P2M1=0x95;
sfr P2M0=0x96;
void main()
{
P2M1=0x00;
P2M0=0x00;
while(1)
{
P2++;
}
}
成功点亮P2组对应的LED
GPIO的寄存器地址从手册里找
4、思考问题
(1)思考LED为什么不会亮?注意检查程序中设置的引脚是否正确。
(2)怎么控制单独的一个引脚?sbit P00 = P0^0;//选择P0.0引脚
(3)怎么控制这个引脚输出电平?P00 = 1;//输出低电平
(4)书写规范一行一句,大括号缩进(需要设置),缩进4格,注释完整
(5)注释符号// 单行注释 /**/ 多行注释
(6)学会搜索CTRL+F
5、举一反三
使用学到的寄存器点灯方法,点亮自己做的开发板的P53端口的LED灯
sfr P5= 0xC8;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
void main()
{
P5M1=0x00;
P5M0=0x00;
while(1)
{
P5++;
}
}
6、重要知识点:实现不断电自动下载+USB CDC串口调试
本例程基于STC32G核心转接板(屠龙刀)进行编写测试。
使用USB线连接核心板USB接口与电脑;
MCU通过USB CDC(Communication Device Class)协议识别为串口设备;
使用串口助手打开CDC虚拟串口,然后向MCU发送数据,MCU返回接收到的数据到串口助手;
数据长度限制在63字节以内。
此外程序演示两种复位进入USB下载模式的方法:
1. 通过每1毫秒执行一次“KeyResetScan”函数,实现长按P3.2口按键触发MCU复位,进入USB下载模式。
(如果不希望复位进入USB下载模式的话,可在复位代码里将 IAP_CONTR 的bit6清0,选择复位进用户程序区)
2. 通过加载“stc_usb_cdc_32g.lib”库函数,实现使用STC-ISP软件发送指令触发MCU复位,进入USB下载模式并自动下载。
(注意:使用CDC接口触发MCU复位并自动下载功能,需要勾选端口设置:下次强制使用”STC USB Writer (HID)”进行ISP下载)
下载时, 选择时钟 24MHZ (用户可自行修改频率)。
******************************************/
#include "stc.h"
#include "usb.h"
#define MAIN_Fosc 24000000L //定义主时钟
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#"; //设置自动复位到ISP区的用户接口命令
//P3.2口按键复位所需变量
bit Key_Flag;
u16 Key_cnt;
void sys_init();
void delay_ms(u8 ms);
void KeyResetScan(void);
void main()
{
sys_init();//系统初始化
usb_init();//USB CDC 接口配置
EA = 1;
while (1)
{
delay_ms(1);
KeyResetScan(); //长按P3.2口按键触发软件复位,进入USB下载模式,不需要此功能可删除本行代码
if(DeviceState != DEVSTATE_CONFIGURED)//等待USB完成配置
continue;
if (bUsbOutReady)
{
usb_OUT_done(); //接收应答(固定格式)
printf("OutNumber=0x%X\r\n",OutNumber);//使用 printf 函数打印接收数据长度
memcpy(UsbInBuffer, UsbOutBuffer, OutNumber);//将接收数据(UsbOutBuffer),复制到发送缓冲区(UsbInBuffer)
usb_IN(OutNumber); //原路返回, 用于测试
}
}
}
void sys_init()
{
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; //设置为准双向口
//====== USB 初始化 ======
P3M0 &= ~0x03;
P3M1 |= 0x03;
IRC48MCR = 0x80;
while (!(IRC48MCR & 0x01));
USBCLK = 0x00;
USBCON = 0x90;
//========================
}
//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2021-3-9
// 备注:
//========================================================================
void delay_ms(u8 ms)
{
u16 i;
do{
i = MAIN_Fosc / 6000;
while(--i); //6T per loop
}while(--ms);
}
//========================================================================
// 函数: void KeyResetScan(void)
// 描述: P3.2口按键长按1秒触发软件复位,进入USB下载模式。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2022-6-11
// 备注:
//========================================================================
void KeyResetScan(void)
{
if(!P32)
{
if(!Key_Flag)
{
Key_cnt++;
if(Key_cnt >= 1000) //连续1000ms有效按键检测
{
Key_Flag = 1; //设置按键状态,防止重复触发
USBCON = 0x00; //清除USB设置
USBCLK = 0x00;
IRC48MCR = 0x00;
delay_ms(10);
IAP_CONTR = 0x60; //触发软件复位,从ISP开始执行
while (1);
}
}
}
else
{
Key_cnt = 0;
Key_Flag = 0;
}
}
本帖最后由 webfly 于 2024-9-8 14:14 编辑
第五集:C语言运算符和进制数入门
1.C语言 printf函数的实现
printf是C语言的标准输入输出库stdio提供的库函数,所以在使用它时,需要使用#include <stdio.h>指令包含stdio.h头文件。
printf的功能用以显示格式化字符串的内容,其输入参数必须包括格式化字符串,可能需要提供插入在字符串指定位置的值。格式化字符串由普通字符和转换说明组成,普通字符完全如在格式化字符串中显示的那样打印出来,而转换说明以字符%开头,表示为插入值提供的占位符。插入的值可以由常量、变量、表达式或带有返回值的函数提供,并且个数没有限制。
printf(格式化字符串, 表达式1, 表达式2, ...)
常规用法:
打印字符串 :printf(“Hello World!”)
打印格式化数据:printf(“室内温度:%.2frn”,11.2);
2.数的进制:2进制、10进制、16进制
2进制是只有两个选项的计数系统,表示为1和0。
10进制计算的唯一目的是使数值为人类可方便阅读。
(1)二进制转换十进制每个二进制位都有一个位置值。很像一系列的灯开关,位置值有0或1与它们相关联。我们所需要做的就是把“开”的位置值加起来。8位二进制,从低位到高位,第一位为2的0次方,即对应10进制的1,一次往上,最高位为2的7次方,即对应10进制的128.
(2)十六进制转换十进制十六进制数通常以0x 开头,:A=10、B=11、C=12、D=13、E=14和F=15。就像二进制系统一样。我们将只使用4位十六进制数字。从低位到高位,第一位为16的0次方,第二位为16的1次方,第三位为16的2次方,第四位为16的3次方,然后分别乘以所在位的值
3.C语言常用运算符
① 、算术运算符:加(+)、减(-)、乘(*)、除(/);
模(余)运算符(%):不允许出现浮点型,余数正负取决于被除数正负;
自增自减(++i、-i;i++、i-)
②、位运算符:
右移(>>) 左移(<<)
按位与(&)
按位或(|)
按位异或(^)
取反(~)
4.数据的基本类型
其中,以下四个类型是C51扩展数据类型:
数据类型 数据长度 数值范围 注释
bit 1位 0或1 位型
sbit 1位 0或1 可位寻址的位型
sfr 单字节 0~255 特殊功能寄存器
sfr16 双字节 0~65535 16位特殊功能寄存器
本帖最后由 webfly 于 2024-9-10 22:44 编辑
第六集:LED闪烁第六集:LED闪烁和花式点灯上和花式点灯
1、基于Delay实现的LED闪烁
1秒= 1000毫秒=1000000微秒
自定义一个延时函数
void delay_ms(unsigned int ms)
{
unsigned int i;
do
{
i = MAIN_Fosc / 6000;
while(--i);
}while(--ms);
}
完整测试代码:
#include <STC32G.H>
#define MAIN_Fosc 24000000UL //定义一个IRC系统时钟
void delay_ms(unsigned int ms);
sfr P2=0xA0;
sfr P2M1=0x95;
sfr P2M0=0x96;
//自定义延时函数
void delay_ms(unsigned int ms)
{
unsigned int i;
do
{
i = MAIN_Fosc / 6000;
while(--i);
}while(--ms);
}
void main()
{
//寄存器点灯
P2M1=0x00;
P2M0=0x00;
// while(1)
// {
// P2++;
// }
//自定义函数闪烁
while(1)
{
P20 = 0; //点亮
delay_ms(200);
P20 = 1; //熄灭
delay_ms(200);
P20 = 0; //点亮
delay_ms(200);
P20 = 1; //熄灭
delay_ms(200);
P20 = 0; //点亮
delay_ms(200);
P20 = 1; //熄灭
delay_ms(1000);
}
}
关于while的用法
2、函数的用法
int Add(int a,int b)
{
return a+b;
}
3、新建文件,使用模块化编程
模块化编程是一种有效的编程方法,它通过将程序的不同部分(模块)分离成独立的文件,以提高代码的可读性、可维护性和可重用性。
在不同的编程语言中,模块化编程的实现方式略有不同,但基本原理相似。以下是在不同编程语言中实现模块化编程的步骤:
将相关的函数和变量定义在不同的.c文件中,每个文件实现特定的功能,
为每个模块创建一个对应的头文件,后缀为.h,用于声明模块中的函数和变量,以便其他文件可以使用。
在主文件(如main.c)中,通过#include指令包含所需的头文件,并调用相应模块中的函数。
新建xxx.c和xxx.h文件,代表一个功能块。
xxx.h格式:
#ifndef __XXX_H
#define __XXX_H
调用头文件
函数声明...
#endif
xxx.c格式
#include “xxx.h”
函数定义
本帖最后由 webfly 于 2024-9-13 23:53 编辑
第七集:按键点灯
1、按键
按键有常开的,有常闭的,常开的摁下以后导通,常闭的按下以后断开
按键摁下以后,需要一定的时间以后才能稳定,所以会有抖动,需要做消抖处理
if( KEY == 0 )
{
Delay_ms(10);
if( KEY == 0 )
{
while(KEY == 0);
执行具体的功能
}
}
2、按键的应用:
按键按下LED灯亮,松开熄灭;
if(P32==0)
{
delay_ms(10);
if( P32==0 ){
printf("按键P32已经按下");
P60 = 0;
}
else
{
printf("按键P32已经放开");
P60=1;
}
}
按键按下KED灯熄灭,松开点亮;
if( P33== 0) //判断按键有没有按下{ delay_ms(10); if( P33== 0 ) { printf("按键P33已经按下\r\n"); P67 = 1; //LED熄灭 }}else { P67 = 0; //LED熄灭 }
按键按下一次,LED状态改变一次;
if( P33== 0) //判断按键有没有按下{ delay_ms(10); if( P33== 0 ) { while(KEY2 == 0) {
} printf("按键P33已经按下,led取反一次\r\n"); P67 = !P67; //LED熄灭 }}
数组的使用
本帖最后由 webfly 于 2024-9-19 09:45 编辑
第八集:蜂鸣器的应用
1、蜂鸣器分为有源蜂鸣器和无源蜂鸣器,有源是指内部有震荡源,能够驱动蜂鸣器发声,振荡源有芯片、二极管、三极管等,所以,只要一通电就会发声。声音种类有连续声、间断声、报警声等。
无源的蜂鸣器是指内部是没有震荡源,所以,通电是不会发声的,必须有信号来驱动它,才可以使其发声,声音频率可控。
如何区分是有源蜂鸣器还是无源蜂鸣器?
(1)通过外观:可以把蜂鸣器焊脚朝天,如果电路板是黑色的表明是有源的,如果电路板是绿色的表示无源的 ;
(2)测试:把万用表调到欧姆档位,如果电阻数值有显示则是无源蜂鸣器,如果发出持续的声音,则是有源蜂鸣器。
2、STC32G开发板控制有源蜂鸣器:P54引脚低电平,蜂鸣器打开;P54引脚高电平,蜂鸣器关闭。
3、STC32G开发板控制有源蜂鸣器代码
#include "COMM/stc.h" //调用头文件
#include "COMM/usb.h"
#include "test.h"
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
void sys_init(); //函数声明
void delay_ms(u16 ms); //unsigned int
void main() //程序开始运行的入口
{
u8 LED_Data = 0XFE;
u8 num=0;
u8 LED_DataTab = { 0XFE,0XFD, 0XFB,0XF7,0XEF,0XDF,0XBF,0X7F};
sys_init(); //USB功能+IO口初始化
usb_init(); //usb库初始化
EA = 1; //CPU开放中断,打开总中断。
P6 = LED_Data;
while(1) //死循环
{
if( DeviceState != DEVSTATE_CONFIGURED )
continue;
if( bUsbOutReady )
{
usb_OUT_done();
}
if( KEY1 == 0)
{
delay_ms(10);
if(KEY1 == 0 )
{
while(KEY1 == 0 );
BEEP = !BEEP;
}
}
}
}
4、蜂鸣器实战应用