[STC屠龙刀]学习打卡日历/学习感悟 - 跟着冲哥学习 STC32G12K128
本帖最后由 nano 于 2024-5-31 23:07 编辑单片机(Microcontroller)是一种集成电路芯片,它集成了处理器、存储器、输入/输出接口以及各种功能模块于一身。
能写入用户程序;能读取在输入引脚上的电压信号,能在引脚上输出特定的电平信号,能在特定引脚上输出电压信号,能计算时间,能计数,能做数学运算,能做逻辑运算,能顺序动作,能通信等功能,最概括的来说就是他能做有规律可循的控制应用。
1. 总线:总线是一组导线,连接了单片机中的各个部分,如处理器、存储器和输入/输出接口。它负责在各个部件之间传递信息和数据。常见的总线有地址总线、数据总线和控制总线。
[*]地址总线:用于传递存储器和外设的地址信息。
[*]数据总线:用于传输实际的数据。
[*]控制总线:用于传递控制信号,如读写操作。
2. 总线与外设通信:单片机通过总线与外设进行通信。当处理器需要与外设通信时,它会将外设的地址放在地址总线上,将要传输的数据放在数据总线上,并通过控制总线发送控制信号,以实现对外设的读写操作。3. GPIO(General Purpose Input/Output,通用输入输出):GPIO是单片机上的一种通用接口,可用于连接各种外设。GPIO接口可以配置为输入或输出模式,实现单片机与外设之间的数据传输。
4. 通信协议:单片机与外设之间通信的方式有很多,通常需要遵循一定的协议。以下是一些常见的通信协议:
[*]UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器):这是一种异步串行通信协议,用于在单片机与外设之间传输数据。UART通信需要两根线:一根用于发送数据(TX),另一根用于接收数据(RX)。
[*]SPI(Serial Peripheral Interface,串行外设接口):SPI是一种同步串行通信协议,使用主从模式进行通信。它需要四根线:时钟线(SCLK)、主设备数据输出线(MOSI)、主设备数据输入线(MISO)和片选线(SS)。
[*] I2C(Inter-Integrated Circuit,内部集成电路总线):I2C是一种同步串行通信协议,使用主从模式进行通信。它只需要两根线:串行数据线(SDA)和串行
[STC屠龙刀]学习打卡日历/学习感悟 - 第02集
本帖最后由 nano 于 2024-5-31 17:40 编辑思考:做什么产品
想通过学习单片机做一个 MP5 播放器或者,这需要学习很多的电子元器件的知识,以及嵌入式开发的知识。
[STC屠龙刀]学习打卡日历/学习感悟 - 第03集
本帖最后由 nano 于 2024-5-31 17:40 编辑1. 成功完成开发环境的搭建
2. 使用 stcai-isp 通过 HID 下载程序,屠龙刀板子完成跑马灯固件烧录,并实现跑马灯效果。
[STC屠龙刀]学习打卡日历/学习感悟 - 第04集
本帖最后由 nano 于 2024-5-31 22:50 编辑[*]成功完成点灯的工程
[*]了解 LED 点亮原理,并学会了使用寄存器来点灯。源码如下
// ================================================================
// 寄存器点灯学习
// ================================================================
// 在开发板的左上方有八个共阳 LED 灯。对应的引脚是 P20...7
//
// 在数据手册 《11.1 I/O 口相关寄存器》章节有说明相关的寄存器地址
//
// | 符号 | 描述 | 地址 |
// | ---- | ----------------- | ---- |
// | P2 | P2 端口 | A0H|
// | P2M0 | P2 口配置寄存器 0 | 96H|
// | P2M1 | P2 口配置寄存器 1 | 95H|
//
// ================================================================
sfr P2 = 0xA0;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sbit P20 = P2^0;
sbit P21 = P2^1;
sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;
int main() {
P2M1 = 0x00, P2M0 = 0x00; //设置为准双向口
// 共阳 LED 灯 : 高电平灭, 低电平亮
P20 = 0; P21 = 0; P22 = 0; P23 = 0;
P24 = 0; P25 = 0; P26 = 0; P27 = 0;
while(1) {}
}
3. 使用 USB-HID 方式实现不断电自动下载
这是我最喜欢的下载方式,USB-CDC 下载方式还需要生成一个串口,STC-USB Link1 还需要外拖一个设备,这种方式只需要一个 USB 数据即可。
4. 使用 USB-CDC 方式实现不断电自动下载
5. 使用 STC-USB Link1 方式实现不断电自动下载
[STC屠龙刀]学习打卡日历/学习感悟 - 第05集
1. C语言表示进制中,二进制以0B 或0b 开头,八进制以0 开头,十六进制以 0x 或 0X 开头2. 标识符只能由 字母、数字 和 下划线 组成,不能以 数字 开头
3. 二进制和八进制相互转换
111 010 101 011 转换为八进制后结果为
步骤:
∵ 二进制每三位都可以转为一个八进制位的值
111 010 101 011
7 2 5 3
∴ 转换结果为:0753
76321 转换为二进制结果为
步骤:
∵ 八进制的每位都可以转换为三位的二进制
7 --> 111
6 --> 110
3 --> 011
2 --> 010
1 --> 001
∴ 结果为:111 110 011 010 001
4. 二进制和十六进制相互转换
1111 1010 1101 1011 转换为十六进制后结果为
步骤:
∵ 二进制每四位都可以转为一个十六进制位的值
1111 1010 1101 1011
15 10 13 11
又∵ 在十六进制中,大于九的数值都有其字母对应,即
10 -> A 11 -> B 12 -> C 13 -> D 14 -> E 15 -> F
∴ 结果为:0XFADB
a6b2f1 转换为二进制结果为
步骤:
∵ 十六进制的每位都可以转换为四位的二进制
a --> 10 --> 1010
6 -->6 --> 0110
b --> 11 --> 1011
2 -->2 --> 0010
f --> 15 --> 1111
1 -->1 --> 0001
∴ 结果为:1010 0110 1011 0010 1111 0001
[STC屠龙刀]学习打卡日历/学习感悟 - 第06集
本帖最后由 nano 于 2024-6-1 22:28 编辑今天学习的是 LED 闪烁和花式点灯,我声明了一个函数,可以实现跑马灯和流水灯两个效果。源码如下:
#include "stc_usb_auto_download.h"
// ==============================================================================================
// 流水灯&跑马灯
// 在开发板的右上方有八个共阳 LED 灯。对应的引脚是 P20...7
// ==============================================================================================
/*!
\brief 延迟函数
\paramms: 延迟时间(单位:毫秒)
\param none
\retval none
*/
void delay_ms(u16 ms) {
u16 i;
do {
i = MAIN_Fosc / 6030;
while(--i);
}while(--ms);
}
/*!
\brief 延迟函数
\paramstatus : 灯的状态, 0 或 1
\paramstart : 起始索引, 取值范围
\paramstep : 移动步长
\paramflowing : 是否是流水灯, 1: 流水不灭, 0: 走马单亮
\param none
\retval none
*/
#define TURN_OFF_ALL_LED() {P27 = P26 = P25 = P24 = P23 = P22 = P21 = P20 = 1;}
void marquee(u8 status, u16 start, int step, u16 flowing) {
u16 i = 0;
status = status ? 1 : 0;
for(i = start; i < 8 && i >= 0; i+= step) {
switch(i) {
case 0: P20 = status; break; case 1: P21 = status; break;
case 2: P22 = status; break; case 3: P23 = status; break;
case 4: P24 = status; break; case 5: P25 = status; break;
case 6: P26 = status; break; case 7: P27 = status; break;
}
delay_ms(10);
if(!flowing) {
TURN_OFF_ALL_LED();
}
}
}
int main() {
auto_usb_hid_download(); // 开启自动下载
P2M1 = 0x00, P2M0 = 0x00; //设置为准双向口
while (1) {
marquee(0, 0, 1, 1); // 依次亮灯[流水灯]
delay_ms(200);
marquee(1, 7, -1, 1);// 依次灭灯[流水灯]
delay_ms(200);
marquee(0, 0, 1, 0); // 依次亮灯[跑马灯]
delay_ms(200);
marquee(0, 7, -1, 0);// 依次亮灯[跑马灯]
delay_ms(200);
}
}
[STC屠龙刀]学习打卡日历/学习感悟 - 第07集
今天学习的是按键按下的时候点灯,我将上节课的代码封装起来,方便这节课使用,封装代码如下:
LED.h
#ifndef __LED_H__
#define __LED_H__
#include "STC32G_Delay.h"
/*!
\brief 初始化 LED
\paramnone
\param none
\retval none
*/
void led_init();
/*!
\brief 打开所有灯
\paramnone
\param none
\retval none
*/
void turn_on_all_led();
/*!
\brief 关闭所有灯
\paramnone
\param none
\retval none
*/
void turn_off_all_led();
/*!
\brief 延迟函数
\paramstatus : 灯的状态, 0 或 1
\paramstart : 起始索引, 取值范围
\paramstep : 移动步长
\paramflowing : 是否是流水灯, 1: 流水不灭, 0: 走马单亮
\param none
\retval none
*/
void marquee(u8 status, u16 start, int step, u16 flowing);
/*!
\brief SOS 灯
\paramnone
\param none
\retval none
*/
void led_sos();
#endif
LED.c
#include "LED.h"
/*!
\brief 初始化 LED
\paramnone
\param none
\retval none
*/
void led_init() { P2M1 = 0x00, P2M0 = 0x00; }
/*!
\brief 打开所有灯
\paramnone
\param none
\retval none
*/
void turn_on_all_led() {
P27 = P26 = P25 = P24 = P23 = P22 = P21 = P20 = 0;
}
/*!
\brief 关闭所有灯
\paramnone
\param none
\retval none
*/
void turn_off_all_led() {
P27 = P26 = P25 = P24 = P23 = P22 = P21 = P20 = 1;
}
/*!
\brief 延迟函数
\paramstatus : 灯的状态, 0 或 1
\paramstart : 起始索引, 取值范围
\paramstep : 移动步长
\paramflowing : 是否是流水灯, 1: 流水不灭, 0: 走马单亮
\param none
\retval none
*/
void marquee(u8 status, u16 start, int step, u16 flowing) {
u16 i = 0;
status = status ? 1 : 0;
for(i = start; i < 8 && i >= 0; i+= step) {
switch(i) {
case 0: P20 = status; break; case 1: P21 = status; break;
case 2: P22 = status; break; case 3: P23 = status; break;
case 4: P24 = status; break; case 5: P25 = status; break;
case 6: P26 = status; break; case 7: P27 = status; break;
}
delay_ms(10);
if(!flowing) {
turn_off_all_led();
}
}
}
/*!
\brief SOS 灯
\paramnone
\param none
\retval none
*/
void led_sos() {
int i = 0;
unsigned int times = 0;
for(i = 0; i < 9; i++) {
times = i < 3 || i > 5 ? 100 : 300;
turn_on_all_led();
delay_ms(times);
turn_off_all_led();
delay_ms(times);
}
}
main.c
#include "stc_usb_auto_download.h"
// ==============================================================================================
// 按键点灯
// 在开发板的右上方有八个共阳 LED 灯。对应的引脚是 P20...7
// 在开发板的左下方有四个按键。对应的引脚是 P32...5
// ==============================================================================================
#include "LED.h"
int main() {
int key_released = 1; // 标识位: 记录按键上一次按下的状态
auto_usb_hid_download(); // 开启自动下载
led_init(); // 设置为准双向口
P3M0 &= ~0x08; P3M1 &= ~0x08; // 将按键 P33 设置为准双向
led_sos(); // SOS 闪灯效果
while (1) {
if(P33 == 0 && key_released == 1) {
// 按下
key_released = 0;
turn_on_all_led();
} else if(P33 == 1 && key_released == 0) {
// 弹起
key_released = 1;
turn_off_all_led();
}
delay_ms(10);
}
}
{:4_250:} autodown直接定义成函数这方法不错
[STC屠龙刀]学习打卡日历/学习感悟 - 第08集
本帖最后由 nano 于 2024-6-4 13:48 编辑今天学习的是按键按下的时候蜂鸣器会响起,我结合上节课的 LED 灯的操作。完成了如下代码:
#include "stc_usb_auto_download.h"
// ==============================================================================================
// 蜂鸣器
// 在开发板的右上方有八个共阳 LED 灯。对应的引脚是 P20...7
// 在开发板的左下方有四个按键。对应的引脚是 P32...5
// 在开发板左下方的 P54 引脚外接有源蜂鸣器, 引脚输出低电平能让蜂鸣器响起
//
// 课后练习:按下后表示启动,选择的对应的功能的LED持续闪烁,表示正在工作,
// 且在工作的时候无法切换功能。
// ==============================================================================================
// 工作倒计时宏定义, 因为每 10ms 记一次数, 则 1000 表示工作十秒
#define MAX_TIMES 1000
void delay_ms(unsigned int ms) {
unsigned int i;
do{
i = MAIN_Fosc / 13060;
while(--i);
}while(--ms);
}
// 打开所有灯
void set_all_led(uint16 v){ P27 = P26 = P25 = P24 = P23 = P22 = P21 = P20 = v; };
// 打开所有灯
void turn_on_all_led(){ set_all_led(0); };
// 关闭所有灯
void turn_off_all_led() { set_all_led(1); };
int main() {
uint16 i = 0, s = 0;
uint16 work_times = MAX_TIMES; // 工作倒计时 10s, 每 10ms 减一, 到零说明工作完成
uint16 working = 0; // 标识位: 表示此时是否正在工作
uint16 key_released = 1; // 标识位: 记录按键上一次按下的状态
auto_usb_hid_download(); // 开启自动下载
P2M0=0x00, P2M1=0x00; // 将共阳灯P20...7 引脚设置为双向
P5M0 |=0x10, P5M1 &=0x10; // 将蜂鸣器P54 引脚设置为推挽
P3M0 &= ~0x08, P3M1 &= ~0x08; // 将按键的P33 引脚设置为准双向
P54 = 0; // 测试启动蜂鸣器
turn_on_all_led(); // 测试开灯
delay_ms(5000); // 测试延迟 1s
turn_off_all_led(); // 测试关灯
P54 = 1; // 测试关闭蜂鸣器
while (1) {
if(working == 1) {
// LED持续闪烁,表示正在工作,
set_all_led(work_times % 10 == 0 ? 0 : 1);
work_times--;
if(work_times < 1) {
// 倒计时结束, 工作完成, 蜂鸣器响起 1s, LED 灯闪烁 三次
working = 0;
work_times = MAX_TIMES;
P54 = 0;
turn_on_all_led();
delay_ms(500);
for(i = 0; i < 7; i++) {
s = i % 2 == 0 ? 1 : 0;
P54 = s;
set_all_led(s);
delay_ms(100);
}
turn_off_all_led();
P54 = 1;
}
} else {
// 未工作的时候按钮可允许按键按下
if(P33 == 0 && key_released == 1) { // 按下
key_released = 0;
P54 = 0;
} else if(P33 == 1 && key_released == 0) { // 弹起
key_released = 1;
P54 = 1;
working = 1; // 开始工作
}
}
delay_ms(10);
}
}
页:
[1]
2