四汐 发表于 2023-12-3 21:38:08

STC32G跟着冲哥学习打卡篇:(8)蜂鸣器

原来制作一个“电磁炉”如此简单!

四汐 发表于 2023-12-4 00:58:36

本帖最后由 四汐 于 2023-12-4 01:02 编辑


STC32G跟着冲哥学习打卡篇:(9)数码管
单位数码管:



四位数码管:

开发板上的原理图:

一位数码管显示0~9:
P6端口
0:0xc0
1:0xf9
2:0xa4
3:0xb0
4:0x99
5:0x92
6:0x82
7:0xf8
8:0x80
9:0x90
带小数点:
0:0x40
1:0x79
2:0x24
3:0x30
4:0x19
5:0x12
6:0x02
7:0x78
8:0x00
9:0x10


实现按键控制一位数码管的加减。
动态刷新显示4位数码管:
利用高刷新率,使人眼看起来是4个数码管同时亮起

数码管位码1~7位:

P7端口
1:0x7f
2:0xbf
3:0xdf
4:0xef
5:0xf7
6:0xfb
7:0xfd
8:0xfe



倒计时挑战程序:
123456789/100 000 000%10 = 1 //取亿位
123456789/010 000 000%10 = 2 //取千万位
123456789/001 000 000%10 = 3 //取百万位
123456789/000 100 000%10 = 4 //取十万位
123456789/000 010 000%10 = 5 //取万位
123456789/000 001 000%10 = 6 //取千位
123456789/000 000 100%10 = 7 //取百位
123456789/000 000 010%10 = 8 //取十位
123456789/000 000 001%10 = 9 //取个位




四汐 发表于 2023-12-4 21:21:29


STC32G跟着冲哥学习打卡篇:(11)定时器
STC32G的定时器计数器有5个,



有12T\1T模式选择:

1T:不分频,时间短但精度高。

定时器的工作模式选择:

定时器的设置介绍:





定时器频率的计算方法:


中断号介绍:



中断的频率越低越好!!!






四汐 发表于 2023-12-5 23:28:06

STC32G跟着冲哥学习打卡篇:(12)计数器

计数器的配置介绍:

直流电机测速的应用。

四汐 发表于 2023-12-6 00:57:11


STC32G跟着冲哥学习打卡篇:(13)多任务处理【视频干货特别多!】
模块化编程:
添加.c和.h文件。


添加函数头:

keil软件内找到Templates,右键添加configuration。


创建程序文件:
新建文件并保存;添加文件到工程;添加引用路径。
引脚定义都放在.h文件;
函数定义、声明、调用。
修饰符 extern(动态变量,不可赋初值)

修饰符 static(静态变量,可以赋初值):仅在第一次进入程序时赋值,后续再次进入该程序时,不重新赋值,沿用上次执行时变化的值。

位寻址变量 bdata



可以使用尖括号(^)对一个8位数据的单独各个位进行定义!
学到一个特别实用的东西:使用一个中断程序,同时控制多种外设,而不冲突的方法
可以在一个中断程序内设置分段刷新,如下图的例子,10毫秒为一个循环,0~7毫秒刷新数码管显示,8毫秒刷新LED显示,其他时间重置数码管和LED显示。
由于10毫秒非常短,肉眼几乎无法分辨,所以就算是数码管和LED都公用一个P6端口,他们在显示的时候也可以互不冲突!

按键功能自定义:


强烈建立看视频学习!!!{:4_175:}










四汐 发表于 2023-12-18 00:07:47

STC32G跟着冲哥学习打卡篇:(14)矩阵式按键

时隔多天,我又回来啦!


(刚写完,目前没有发现什么太大的BUG,就是数码管熄灭之后重新点亮不能立马显示“-”,不过我觉得问题不大{:4_164:}。如果大家发现其他什么BUG,欢迎回帖!互相学习!)
今天是来交作业的!话不多说,密码锁的课后练习主函数奉上:
#include <intrins.h>
#include <stdio.h>
#include <string.h>

#include "stc32g.h"
#include "stc32_stc8_usb.h"

#include "Led_Seg.h"
#include "Key.h"
#include "Beep.h"
#include "Timer.h"

#defineMAIN_FOSC      24000000UL//ISP下载时需将工作频率设置为24MHz


char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";       //不停电自动ISP下载命令

bit TIME_10ms_flag;   //10ms的标志位

void sys_init();           // 函数声明

void delay_ms(u16 ms)
{
    u16 i;
    do
    {
      i = MAIN_FOSC / 6000;
      while(--i);
    } while (--ms);
}

void Counter1_Init(void)    //
{
        TMOD = 0x50;                        //设置计数器模式
        TL1 = 0x00;                                //设置计数器始值
        TH1 = 0x00;                                //设置计数器始值
        TF1 = 0;                                //清除TF1标志
        TR1 = 1;                                //定时器1开始计时
        ET1 = 1;                                //使能定时器1中断
    P3PU = 0x20;            //打开P35内部上拉4.1K
}

void main()
{
//—————————————————主程序参数定义———————————————————————————//

u8 KEY_NUM = 0;         //保存矩阵按键的键码
u8 KEY_Str = 0;         //表示当前输入了几个密码位
u16 LED_TIME = 0;       //门锁开启了多久
u16 SEG_TIME = 0;       //数码管亮了多久
bit DOOR_OPEN_Flag = 0; //0:关门 1:开门
bit SEG_OPEN_Flag = 1;//0:熄灭 1:显示

u8 Password = {1, 2, 3, 4, 5, 6, 7, 8};      //正确密码
u8 i;   //密码判断for函数所使用的变量
u8 Ture_flag = 0;   //正确的密码数量

//—————————————————主程序参数初始化—————————————————————————//

Timer0_Init();

// SEG0 = 0;
// SEG1 = 1;
// SEG2 = 2;
// SEG3 = 3;
// SEG4 = 4;
// SEG5 = 5;
// SEG6 = 6;
// SEG7 = 7;

LED = 0xff;


    //—————————————————以下为USB_CDC串口代码———————————————————//
       
    sys_init();      //使能USB功能
    usb_init();      //USB初始化   //调用USB CDC初始化库函数
    EUSB= 1;         //使能USB中断
    EA= 1;             //总中断开
    while(DeviceState != DEVSTATE_CONFIGURED);//等待USB完成配置
    while(1)
    {
                //当硬件接收完成上位机通过串口助手发送数据后,会自动将bUsbOutReady置1
                //接收的数据字节数保存在OutNumber变量中,接收的数据保存在UsbOutBuffer缓冲区
                if(bUsbOutReady)   
                {
                        //使用USB_SendData库函数可向上位机发送数据,这里的测试代码为将接收数据原样返回
                        //USB_SendData(UsbOutBuffer,OutNumber);
                        //处理完成接收的数据后,调用usb_OUT_done准备接收下一笔数据
                        usb_OUT_done();   
            //——————在这里写代码,单片机接受到数据后才会执行———————//
            

      }

      //—————————————————此处开始写代码———————————————————//

      if(TIME_10ms_flag == 1)             //如果10ms到了
      {
            TIME_10ms_flag = 0;             //清空标志位
            KEY_Deal();   //按键处理
            BEEP_RUN();   //蜂鸣器运行

            // if( KEY_ReadState(KEY1) == KEY_PRESS)               //判断KEY1是否单击
            // {
            //   BEEP_ON(2);   //蜂鸣50ms
            //   LED0 = 0;       //点亮LED0
            // }
            // else if( KEY_ReadState(KEY1) == KEY_LONGPRESS)      //判断KEY1是否长按
            // {
            //   BEEP_ON(5);
            //   LED1 = 0;   //点亮LED1
            // }
            // else if(KEY_ReadState(KEY1) == KEY_RELAX)         //判断KEY1是否松开
            // {
            //   BEEP_ON(2);   //蜂鸣50ms
            //   LED = 0xff;   //LED全部熄灭
            // }

            KEY_NUM = MateixKEY_Read();   //当前矩阵按键的键值
            if (KEY_NUM > 0)                          //如果有按键拿下
                        {
                                BEEP_ON(2);                                       //蜂鸣20ms
                                SEG_Show_Tab = KEY_NUM; //将当前的按键的键值保存到数码管显示变量里
                                KEY_Str++;                                       //输入的密码位数+1
                SEG_OPEN_Flag = 1;
                SEG_TIME = 0;
               

                if (KEY_Str == 8) //如果密码已经输到了8位
                                {
                                        KEY_Str = 0; //清空当前密码的位数
                                        // 用for循环的方式实现密码判断
                  for ( i = 0; i < 8; i++)
                  {
                        if (SEG_Show_Tab == Password)
                        {
                            Ture_flag++;
                        }
                  }
                                        if (Ture_flag == 8) //如果密码正确
                                        {
                                                LED0 = 0;       //点亮LED0
                        DOOR_OPEN_Flag = 1;
                        LED_TIME = 0;   //门开了之后重新计时
                  }
                                        else
                                        {
                                                BEEP_ON(200); // 密码错误,蜂鸣2秒
                                        }
                                        SEG0 = SEG1 = SEG2 = SEG3 = SEG4 = SEG5 = SEG6 = SEG7 = 46; // 将所有的数码管显示位 -
                  Ture_flag = 0;      //重置正确的密码数量
                }
                                KEY_NUM = 0; // 清空按键键值
            }

            //LED0(门锁)打开后,5S后自动关闭
            if(DOOR_OPEN_Flag == 1)
            {
                LED_TIME++;
                if (LED_TIME == 500)
                {
                  LED_TIME = 0;
                  DOOR_OPEN_Flag = 0;
                  LED0 = 1;
                }
            }
            
            //增加门内的手动开门按钮,按下按钮门锁打开
            if( KEY_ReadState(KEY1) == KEY_PRESS)               //判断KEY1是否单击
            {
                BEEP_ON(2);         //蜂鸣50ms
                LED0 = 0;       //点亮LED0
                DOOR_OPEN_Flag = 1;
                LED_TIME = 0;   //门开了之后重新计时
            }

            //10秒内没有输入密码,自动熄灭数码管,更加省电;按下时再显示
            if (SEG_OPEN_Flag == 1)
            {
                SEG_TIME++;
                if (SEG_TIME == 1000)
                {
                  SEG0 = SEG1 = SEG2 = SEG3 = SEG4 = SEG5 = SEG6 = SEG7 = 74; //熄灭所有数码管
                  KEY_Str = 0; //清空当前密码的位数
                  SEG_OPEN_Flag = 0;
                }
               
            }
            
            
      }
      

    }
}

void Timer0_Isr(void) interrupt 1   //1ms@24MHZ
{
    static timercount = 0;

    SEG_LED_Show();             //数码管刷新的

    timercount++;               //1ms +1
    if( timercount >= 10)       //如果>=10,10ms计数到达
    {
      timercount = 0;
      TIME_10ms_flag = 1;   //说明10ms时间到
    }
}

// void Timer1_Isr(void) interrupt 3
// {
//   P60 = !P60;   //LED0取反
// }

void sys_init()
{
    WTST = 0;// 设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; // 扩展寄存器(XFR)访问使能
    CKCON = 0; // 提高访问XRAM速度

    P0M1 = 0x30;        P0M0 = 0x30; // 设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
    P1M1 = 0x32;        P1M0 = 0x32; // 设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
    P2M1 = 0x3c;        P2M0 = 0x3c; // 设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
    P3M1 = 0x50;        P3M0 = 0x50; // 设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
    P4M1 = 0x3c;        P4M0 = 0x3c; // 设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
    P5M1 = 0x0c;        P5M0 = 0x0c; // 设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
    P6M1 = 0xff;        P6M0 = 0xff; // 设置为漏极开路(实验箱加了上拉电阻到3.3V)
    P7M1 = 0x00;        P7M0 = 0x00; // 设置为准双向口
       
        P3M0&= ~0x03;                //P3.0/P3.1和USB的D-/D+共用PIN脚,
    P3M1|= 0x03;

    // 设置USB使用的时钟源
    IRC48MCR = 0x80; // 使能内部48M高速IRC
    while (!(IRC48MCR & 0x01)); // 等待时钟稳定

    USBCLK = 0x00; // 使用CDC功能需要使用这两行,HID功能禁用这两行。
    USBCON = 0x90;
}
页: 1 [2]
查看完整版本: STC32G跟着冲哥学习打卡篇:(1~14)矩阵按键和密码锁