STC32G-实验指导书:实验内容与源代码
STC32G 实验指导书
《STC32-实验指导书》目前收录了22个大类目的实验:每项实验都经过全流程的验证,实验文档包含但不限于实验介绍、原理图、源代码、实验过程、实验现象。
3 实验3.1实验一:printf_usb("Hello World !\r\n"),第一个完整的C语言程序3.2实验二:查询方式,查询到电脑命令后,printfusb(Hello World!\rn")或其他3.3实验三:中断方式,单片机USB中断接收服务函数收到命令后,printf usb("HelloWorld!\rn")或其他3.4点灯实验一:点亮LED灯,继续完成前面的工程项目3.5点灯实验二:让LED灯闪烁起来3.6点灯实验三:通过USB-CDC方式控制STC32G12K128进行LED点灯3.7点灯实验四:使用STC32G12K128内置USB直接仿真流水灯3.8I/O口实验 -- I/O口读取按键状态并点灯 3.8.5 实验1 -- 位操作,用USB直接仿真来调试 3.8.6 实验2 -- 整组8位端口操作,用USB直接仿真来调试 3.8.7 实验3 -- 用USB-CDC读取按键状态在串口助手显示并点亮LED灯 3.8.8 实验4 -- 用USB-CDC读取按键状态,在ISP软件的【开天斧/居龙刀-LED-DIP64(6)】 虚拟显示 3.8.9 实验5 -- I/O口行列按键扫描,蜂鸣器发声实战3.9传统外部中断实验 -- INT0,INT1,INT2,INT3 3.9.1中断实验1(外部中断INT0/P3.2,INT1/P3.3控制点灯并USB仿真) 3.9.2 中断实验2(单片机主动触发外部中断INT2/P3.6,INT3/P3.7控制点灯并USB仿真)3.10定时器实验 -- 定时器0/1,16位定时器 3.10.1 定时器0/1,16位定时器实验(定时器中断点灯并通过USB-CDC端口输出信息) 3.10.2 定时器0/1,INT0/INT1,中断组合应用实验,演示程序3.11RTC实验(拓展学习之使用RTC功能设定闹钟)3.12大型综合实战 -- 课程设计:时钟+数码管+矩阵按键+蜂鸣器发声3.13串口实验 -- 串口通讯(硬件UART1与电脑收发通讯)3.14串口实验 -- 串口通讯(硬件UART2与UART3收发通讯)3.15串口实验 -- 串口通讯(硬件UART2与UART3数据透传)3.16串口实验 -- 串口1_2_3_4(中断设置标志位,主循环查询),演示实验3.17串口实验 -- 串口1_2_3_4+定时器0_1_3_4+外部中断INT0_1_2_3(中断设置标志位,主循环查询),演示实验3.18串口实验 -- 串口通讯(ADC检测按键,ADC热敏电阻测温,串口绘图)3.19大型综合实战 -- 模拟RTC时钟+数码管+ADC检测按键(查询)3.20ADC实验 -- 数码管+ NTC热敏电阻+ADC测温(中断方式)3.21大型综合实战 -- 课程设计:硬件SPI读写串行Flash3.22SPI实验 -- 硬件SPI驱动OLED显示图片、图形、字符
现将目录中实验的源代码按《STC32G-实验指导书》目录顺序,分楼陆续上传至本贴,以供大家参考和交流。
3.1 实验一:printf_usb("Hello World !\r\n"),第一个完整的C语言程序 看下面的程序,其实还是那个熟悉的标准C语言的printf(),只是到了单片机C语言中,变成了printf_usb()
3.1.1 printf( ),printf_usb( )实验程序代码
#include"stc32g.h" //头文件不分大小写,但关键字分大小写#include"ai_usb.h" //USB库和USB虚拟设备的头文件,需要在项目文件中添加对应的USB库 //由于在USB库函数的代码中已经定义了,不停电ISP下载命令字”@STCISP#”, //只需要在下载软件的“收到用户命令后复位到ISP监控程序区”选项卡中进行相应的设置, //即可实现USB不停电ISP下载功能,或串口不停电ISP下载功能。
voidmain(void){ EAXFR = 1; //允许访问扩展的特殊寄存器,XFR WTST = 0; //设置取程序代码等待时间,赋值为 0 表示不等待,程序以最快速度运行 CKCON = 0; //设置访问片内的 xdata 速度,赋值为 0 表示用最快速度访问,不增加额外的等待时间
usb_init(); //初始化USB模块,并且会将【P3.0, P3.1】初始化为高阻输入,不影响USB【D-, D+】通讯 EA = 1; //使能总中断
while (1) { printf_usb("Hello World !\r\n"); //直接打印输出 “Hello World !” 到主机相应软件的USB【CDC/HID-串口助手】 //\r是回车,跳到行首,\n是换行,就是换到下一行;\r\n不要交换次序 }}以上是完整的第一个程序代码 3.2 实验二:查询方式,查询到电脑命令后,printf_usb("Hello World !\r\n")或其他 看下面的程序,其实还是那个熟悉的标准C语言的printf(),只是到了单片机C语言中,变成了printf_usb()
3.2.1 printf( ),printf_usb( )实验程序代码
#include"stc32g.h " //头文件不分大小写,但关键字分大小写#include"ai_usb.h" //USB库和USB虚拟设备的头文件,需要在项目文件中添加对应的USB库 //由于在USB库函数的代码中已经定义了,不停电ISP下载命令字”@STCISP#”, //只需要在下载软件的“收到用户命令后复位到ISP监控程序区”选项卡中进行相应的设置, //即可实现USB不停电ISP下载功能,或串口不停电ISP下载功能。void main(void){ EAXFR = 1; //允许访问扩展的特殊寄存器,XFR WTST = 0; //设置取程序代码等待时间,赋值为 0 表示不等待,程序以最快速度运行 CKCON = 0; //设置访问片内的 xdata 速度,赋值为 0 表示用最快速度访问,不增加额外的等待时间
usb_init(); //初始化USB模块,并且会将【P3.0, P3.1】初始化为高阻输入,不影响USB【D-, D+】通讯
EA = 1; //使能全局中断
while(1) { if(bUsbOutReady) { //查询方式:USB-Device单片机查询是否有接收完成的USB主机送来的数据包 //“bUsbOutReady”:主机发送给HID/CDC设备的数据状态标志。 //USB库中有定义bUsbOutReady位变量,查询方式必须调用一次“usb_OUT_done();” //状态位为1表示,主机发送给HID/CDC设备数据已完成, //设备已成功接收一包数据,等待对数据继续处理。
if(UsbOutBuffer==6) printf_usb("HelloWorld!\r\n"); //接收到的数据包的第0个字节是6,打印“HelloWorld!” else if(UsbOutBuffer==7) printf_usb("China!\r\n"); //接收到的数据包的第0个字节是7后,打印“China!”
usb_OUT_done();//USB查询方式,Device单片机通知【主机可以发下一个数据包】 //当使用査询方式if(bUsbOutReady),查询调用USB库函数时,在数据处理完成后, //必须调用一次“usb_OUT_done();”,这样才能接收下一包数据。 //如果是使用中断方式调用USB库函数,用户程序不需要调用“usb_OUT_done();” //中断方式,USB库函数内部会自动处理。 } }}以上是完整的第一个程序代码 3.3 实验三:中断方式,单片机USB中断接收服务函数收到命令后,
printf_usb("Hello World !\r\n")或其他 看下面的程序,其实还是那个熟悉的标准C语言的printf(),只是到了单片机C语言中,变成了printf_usb()
3.3.1 printf( ),printf_usb( )实验程序代码
#include" stc32g.h " //头文件不分大小写,但关键字分大小写#include"ai_usb.h" //USB库和USB虚拟设备的头文件,需要在项目文件中添加对应的USB库 //由于在USB库函数的代码中已经定义了,不停电ISP下载命令字”@STCISP#”, //只需要在下载软件的“收到用户命令后复位到ISP监控程序区”选项卡中进行相应的设置, //即可实现USB不停电ISP下载功能,或串口不停电ISP下载功能。
// USB接收中断服务程序中,调用用户实际需要执行的服务程序,// 简称回调函数,用户根据实际应用场景需求编写void USBLIB_OUT_Callback(void){ //用户希望USB库函数,中断方式回调执行的用户自己编写的任务函数,简称回调函数 if (UsbOutBuffer == 6) printf_usb("Hello World !\r\n"); //接收到数据6后,直接打印输出“Hello World !”到主机相应软件的USB【CDC/HID-串口助手】 //\r是回车,跳到行首,\n是换行,就是换到下一行;\r\n不要交换次序 else if (UsbOutBuffer == 7) printf_usb("China !\r\n"); //接收到数据7后,直接打印输出 “China !” 到主机相应软件的USB【CDC/HID-串口助手】”}
void main(void){ EAXFR = 1; //允许访问扩展的特殊寄存器,XFR WTST = 0; //设置取程序代码等待时间,赋值为 0 表示不等待,程序以最快速度运行 CKCON = 0;//设置访问片内的 xdata 速度,赋值为 0 表示用最快速度访问,不增加额外的等待时间
usb_init(); //初始化USB模块 //初始化USB模块,并且会将【P3.0, P3.1】初始化为高阻输入,不影响USB【D-, D+】通讯
set_usb_OUT_callback(USBLIB_OUT_Callback);//设置USB中断服务程序可以调用的回调函数 //此处 USBLIB_OUT_Callback是前面用户自己编写的任务函数的函数名/地址,供USB库函数回调
EA = 1; //使能全局中断
while (1);}以上是完整的第一个程序代码
3.4 点灯实验一:点亮LED灯,继续完成前面的工程项目
3.4.1 原理介绍 STC32G12K128实验箱原理图
I/O口P4.0控制PNP三极管的通断,控制这8个灯的整体供电。 如果P4.0输出1,则PNP三极管不导通,这8个灯都不会获得电源,都不会有电流流过,都不会被点亮。 如果P4.0输出0,则PNP三极管导通,这8个灯才有可能会流过电流,才有可能会被点亮。 如果P4.0输出0,PNP三极管导通,特定LED灯的控制I/O口如输出0,则该LED灯会有电流流过,会被点亮。
如P6.0输出0,LED60灯就会被点亮;如P6.0输出1,LED60灯就会熄灭; 如P6.1输出0,LED61灯就会被点亮;如P6.1输出1,LED61灯就会熄灭; 如P6.2输出0,LED62灯就会被点亮;如P6.2输出1,LED62灯就会熄灭; 如P6.3输出0,LED63灯就会被点亮;如P6.3输出1,LED63灯就会熄灭; 如P6.4输出0,LED64灯就会被点亮;如P6.4输出1,LED64灯就会熄灭; 如P6.5输出0,LED65灯就会被点亮;如P6.5输出1,LED65灯就会熄灭; 如P6.6输出0,LED66灯就会被点亮;如P6.6输出1,LED66灯就会熄灭; 如P6.7输出0,LED67灯就会被点亮;如P6.7输出1,LED67灯就会熄灭
如P6口对外全部送0,则这8个灯全亮; 如P6口对外全部送1,则这8个灯全灭
如果P4.0输出1,则PNP三极管不导通,不管P6口对外全部送0或送1,这8个灯都不会有电流流过,都不会亮。 P4.0控制PNP三极管,作为这8个LED指示灯的总电源开关。
3.5 点灯实验二:让LED灯闪烁起来
3.5.1 原理介绍 STC32G12K128实验箱原理图 https://www.stcaimcu.com/data/attachment/forum/202509/29/180738sfqu6k7blkad5kk0.jpg
I/O口P4.0控制PNP三极管的通断,控制这8个灯的整体供电。 如果P4.0输出1,则PNP三极管不导通,这8个灯都不会获得电源,都不会有电流流过,都不会被点亮。 如果P4.0输出0,则PNP三极管导通,这8个灯才有可能会流过电流,才有可能会被点亮。 如果P4.0输出0,PNP三极管导通,特定LED灯的控制I/O口如输出0,则该LED灯会有电流流过,会被点亮。
如P6.0输出0,LED60灯就会被点亮;如P6.0输出1,LED60灯就会熄灭; 如P6.1输出0,LED61灯就会被点亮;如P6.1输出1,LED61灯就会熄灭; 如P6.2输出0,LED62灯就会被点亮;如P6.2输出1,LED62灯就会熄灭; 如P6.3输出0,LED63灯就会被点亮;如P6.3输出1,LED63灯就会熄灭; 如P6.4输出0,LED64灯就会被点亮;如P6.4输出1,LED64灯就会熄灭; 如P6.5输出0,LED65灯就会被点亮;如P6.5输出1,LED65灯就会熄灭; 如P6.6输出0,LED66灯就会被点亮;如P6.6输出1,LED66灯就会熄灭; 如P6.7输出0,LED67灯就会被点亮;如P6.7输出1,LED67灯就会熄灭
如P6口对外全部送0,则这8个灯全亮; 如P6口对外全部送1,则这8个灯全灭
如果P4.0输出1,则PNP三极管不导通,不管P6口对外全部送0或送1,这8个灯都不会有电流流过,都不会亮。 P4.0控制PNP三极管,作为这8个LED指示灯的总电源开关。
3.6 点灯实验三:通过USB-CDC方式控制STC32G12K128进行LED点灯
3.6.1 原理介绍 STC32G12K128实验箱原理图 https://www.stcaimcu.com/data/attachment/forum/202509/29/180738sfqu6k7blkad5kk0.jpg
I/O口P4.0控制PNP三极管的通断,控制这8个灯的整体供电。 如果P4.0输出1,则PNP三极管不导通,这8个灯都不会获得电源,都不会有电流流过,都不会被点亮。 如果P4.0输出0,则PNP三极管导通,这8个灯才有可能会流过电流,才有可能会被点亮。 如果P4.0输出0,PNP三极管导通,特定LED灯的控制I/O口如输出0,则该LED灯会有电流流过,会被点亮。
如P6.0输出0,LED60灯就会被点亮;如P6.0输出1,LED60灯就会熄灭; 如P6.1输出0,LED61灯就会被点亮;如P6.1输出1,LED61灯就会熄灭; 如P6.2输出0,LED62灯就会被点亮;如P6.2输出1,LED62灯就会熄灭; 如P6.3输出0,LED63灯就会被点亮;如P6.3输出1,LED63灯就会熄灭; 如P6.4输出0,LED64灯就会被点亮;如P6.4输出1,LED64灯就会熄灭; 如P6.5输出0,LED65灯就会被点亮;如P6.5输出1,LED65灯就会熄灭; 如P6.6输出0,LED66灯就会被点亮;如P6.6输出1,LED66灯就会熄灭; 如P6.7输出0,LED67灯就会被点亮;如P6.7输出1,LED67灯就会熄灭
如P6口对外全部送0,则这8个灯全亮; 如P6口对外全部送1,则这8个灯全灭
如果P4.0输出1,则PNP三极管不导通,不管P6口对外全部送0或送1,这8个灯都不会有电流流过,都不会亮。 P4.0控制PNP三极管,作为这8个LED指示灯的总电源开关。
3.7 点灯实验四:使用STC32G12K128内置USB直接仿真流水灯
3.7.1 原理介绍 STC32G12K128实验箱原理图 https://www.stcaimcu.com/data/attachment/forum/202509/29/180738sfqu6k7blkad5kk0.jpg
I/O口P4.0控制PNP三极管的通断,控制这8个灯的整体供电。 如果P4.0输出1,则PNP三极管不导通,这8个灯都不会获得电源,都不会有电流流过,都不会被点亮。 如果P4.0输出0,则PNP三极管导通,这8个灯才有可能会流过电流,才有可能会被点亮。 如果P4.0输出0,PNP三极管导通,特定LED灯的控制I/O口如输出0,则该LED灯会有电流流过,会被点亮。
如P6.0输出0,LED60灯就会被点亮;如P6.0输出1,LED60灯就会熄灭; 如P6.1输出0,LED61灯就会被点亮;如P6.1输出1,LED61灯就会熄灭; 如P6.2输出0,LED62灯就会被点亮;如P6.2输出1,LED62灯就会熄灭; 如P6.3输出0,LED63灯就会被点亮;如P6.3输出1,LED63灯就会熄灭; 如P6.4输出0,LED64灯就会被点亮;如P6.4输出1,LED64灯就会熄灭; 如P6.5输出0,LED65灯就会被点亮;如P6.5输出1,LED65灯就会熄灭; 如P6.6输出0,LED66灯就会被点亮;如P6.6输出1,LED66灯就会熄灭; 如P6.7输出0,LED67灯就会被点亮;如P6.7输出1,LED67灯就会熄灭
如P6口对外全部送0,则这8个灯全亮; 如P6口对外全部送1,则这8个灯全灭
如果P4.0输出1,则PNP三极管不导通,不管P6口对外全部送0或送1,这8个灯都不会有电流流过,都不会亮。 P4.0控制PNP三极管,作为这8个LED指示灯的总电源开关。
【实验现象】
3.8 I/O口实验 -- I/O口读取按键状态并点灯
3.8.1 实验要求 可以通过正确设置I/O口模式来读取实验箱上按键的电平,然后根据对应按键的电平来设置LED灯的点亮/熄灭状态。
3.8.2 实验建议
STC32G12K128系列单片机所有的I/O口均有4种工作模式: ü准双向口/弱上拉(标准8051输出口模式) ü强推挽输出/强上拉 ü高阻输入(电流既不能流入也不能流出) ü开漏模式(如果打开内部上拉电阻,就相当于准双向口;如果不加上拉并对外置1,就相当于高阻输入)
1)高阻输入模式,内部配有6K上拉电阻; 为了读取外部状态,需要打开内部的6K上拉电阻。
2)开漏模式,内部同样配有6K上拉电阻; 打开内部6K上拉电阻后,其功能与准双向口/弱上拉模式相似。
3)读取I/O口的外部状态时,可以采用以下三种模式: 准双向口/弱上拉模式: ===要确保对外输出锁存为1,关闭对内部对外强输出低的MOS管, 才能准确读到外部状态 ===如对外输出锁存为0,则外部被内部对外强输出低的MOS管拉低, 读到的是低电平,不能准确读到外部来的高输入/被内部拉低了
高阻输入模式,每个 I/O 口都有独立的 6K 上拉电阻: ===为了准确读取外部状态,需要打开内部的 6K 上拉电阻,或外部有上拉能力 ===内部的对外输出锁存器对此模式无效,对外无输出高/低的能力 ===电流流不进来,也留不出去, 高阻输入,无输出能力,不影响外部来的的输入状态
开漏模式,每个 I/O 口都有独立的 6K 上拉电阻: 启用内部 6K 上拉电阻后,其功能与准双向口/弱上拉模式相似 ===要确保对外输出锁存为1,关闭对内部对外强输出低的MOS管,才能准确读到外部状态 ===如对外输出锁存为0,则外部被内部对外强输出低的MOS管拉低, 读到的是低电平,不能准确读到外部来的高输入/被内部拉低了
4)I/O口对外输出高或低电平时,可以采用以下三种模式: Ø准双向口/弱上拉模式; 对外输出低时,相当于强推挽输出低 Ø强推挽输出模式; Ø开漏模式; 在对外输出低电平时,表现为强推挽输出的低电平状态。 在对外输出高电平时,表现为高阻输入状态,此时电流流不进来也流不出去。 如果用来控制LED灯,因为无电流流动,所以LED灯不亮。
5)P3.2/P3.3/P3.4/P3.5端口均有按键,按下按键可接地,建议: 读取这些I/O口的状态,并将结果输出到P6.2/P6.3/P6.4/P6.5对应的指示灯上。
3.8.3 原理图
3.8.3.1 STC32G12K128实验箱原理图
3.8.3.2 认识实验箱
STC32G12K128实验箱正面图:
3.8.4 I/O口工作模式和内部上拉/下拉电阻介绍
3.8.4.1 内部上拉电阻和外部上拉/下拉电阻的部分区别
外部上拉电阻随系统电源从0V上升到MCU-VCC,到3.3V或5V,这个时间是足够的长, 系统上电复位后到初始化运行用户程序时,外部上拉电阻已将外部拉高到高电平。 内部上拉电阻是运行用户程序时才使能打开的,由于外部电路的分布电容效应, 要等待0.7RC时间(R:电阻,C:电容)才能将外部拉高到0.7MCU-VCC高电平。 建议将需要打开的内部上拉电阻使能后,直接多等待一会,如等待1ms后,就可认为外部已被拉高。
3.8.4.2 准双向口介绍
准双向口(弱上拉)输出类型可用作输出和输入功能而不需重新配置端口输出状态。 这是因为当端口输出为1时驱动能力很弱,允许外部装置将其拉低。 当引脚输出为低时,它的驱动能力很强,可吸收相当大的电流。 准双向口输出低电平的驱动能力和强推挽的驱动能力是一样的。 此处的上拉电阻和下拉电阻是独立的,和I/O口4种功能模式无关。
3.8.4.3 强推挽输出
强推挽输出配置的下拉结构与开漏模式以及准双向口的下拉结构相同。 当对外输出锁存器设置为0时,强推挽的输出配置为强下拉结构,与开漏模式及准双向口的下拉是同一个MOS管,驱动能力是一样的。 当对外输出锁存器设置为1时,对外输出强上拉。强推挽模式一般用于需要大驱动电流的情况。
3.8.4.4 高阻输入
电流既不能流入也不能流出 输入口带有一个施密特触发输入以及一个抗干扰抑制电路
3.8.4.5 开漏模式
开漏工作模式,对外设置输出为1,等同于高阻输入 开漏工作模式,打开内部上拉电阻 | 或外部加上拉电阻,简单等同于 准双向口
开漏模式如果打开内部上拉电阻或外接上拉电阻,可准确的读到外部状态。 开漏模式对外可直接输出0,但如果要输出1,需打开内部上拉电阻或外接上拉电阻。
3.8.5 实验1:位操作,用USB直接仿真来调试
单独读【P3.2/ P3.3 / P3.4 / P3.5】4个独立I/O的状态,输出到【P6.2 / P6.3 / P6.4 / P6.5】对应的指示灯
3.8.5.1 I/O口设置
将不同的I/O口设置为不同的模式,尝试不同情况下依然可以正常输入/输出。打开AiCube-ISP软件: Ü配置输出端口的P63、P64为推挽输出,P65为开漏输出(可以输出0点亮LED)
Ü输入配置 ØP30、P31为高阻输入(因为跟USB复用,设置为高阻输入,不干扰USB的通讯控制) Ø设置P32为准双向口、P33为高阻输入、P34和P35为开漏模式(设置为1等效高阻输入) Ø开启P33、P34、P35的内部上拉电阻以稳定电平状态(不开启内部上拉电阻读外部状态,高阻输入/开漏模式,外部都需要有上拉电阻配合)
3.8 I/O口实验 -- I/O口读取按键状态并点灯
3.8.1 实验要求 可以通过正确设置I/O口模式来读取实验箱上按键的电平,然后根据对应按键的电平来设置LED灯的点亮/熄灭状态。
3.8.6 实验2:整组8位端口操作,用USB直接仿真来调试 整组 读【P3.2/P3.3/P3.4/P3.5】这4个I/O的状态,一次性读全部P3口 整体 输出到【P6.2/P6.3/P6.4/P6.5】在的P6口对应的指示灯