nano 发表于 2024-5-31 14:00:55

[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)和串行

nano 发表于 2024-5-31 17:10:03

[STC屠龙刀]学习打卡日历/学习感悟 - 第02集

本帖最后由 nano 于 2024-5-31 17:40 编辑


思考:做什么产品


想通过学习单片机做一个 MP5 播放器或者,这需要学习很多的电子元器件的知识,以及嵌入式开发的知识。



nano 发表于 2024-5-31 17:34:00

[STC屠龙刀]学习打卡日历/学习感悟 - 第03集

本帖最后由 nano 于 2024-5-31 17:40 编辑

1. 成功完成开发环境的搭建
2. 使用 stcai-isp 通过 HID 下载程序,屠龙刀板子完成跑马灯固件烧录,并实现跑马灯效果。






nano 发表于 2024-5-31 22:44:50

[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 方式实现不断电自动下载












nano 发表于 2024-5-31 23:02:26

[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

nano 发表于 2024-6-1 22:25:11

[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);
      }
}



nano 发表于 2024-6-1 23:08:58

[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);
      }
}


小涵子爸爸 发表于 2024-6-2 00:36:52

{:4_250:}

soma 发表于 2024-6-2 10:07:46

autodown直接定义成函数这方法不错

nano 发表于 2024-6-2 23:45:06

[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
查看完整版本: [STC屠龙刀]学习打卡日历/学习感悟 - 跟着冲哥学习 STC32G12K128