原来制作一个“电磁炉”如此简单!
本帖最后由 四汐 于 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 //取个位
STC32G跟着冲哥学习打卡篇:(11)定时器
STC32G的定时器计数器有5个,
有12T\1T模式选择:
1T:不分频,时间短但精度高。
定时器的工作模式选择:
定时器的设置介绍:
定时器频率的计算方法:
中断号介绍:
中断的频率越低越好!!!
STC32G跟着冲哥学习打卡篇:(12)计数器
计数器的配置介绍:
直流电机测速的应用。
STC32G跟着冲哥学习打卡篇:(13)多任务处理【视频干货特别多!】
模块化编程:
添加.c和.h文件。
添加函数头:
keil软件内找到Templates,右键添加configuration。
创建程序文件:
新建文件并保存;添加文件到工程;添加引用路径。
引脚定义都放在.h文件;
函数定义、声明、调用。
修饰符 extern(动态变量,不可赋初值)
修饰符 static(静态变量,可以赋初值):仅在第一次进入程序时赋值,后续再次进入该程序时,不重新赋值,沿用上次执行时变化的值。
位寻址变量 bdata
可以使用尖括号(^)对一个8位数据的单独各个位进行定义!
学到一个特别实用的东西:使用一个中断程序,同时控制多种外设,而不冲突的方法
可以在一个中断程序内设置分段刷新,如下图的例子,10毫秒为一个循环,0~7毫秒刷新数码管显示,8毫秒刷新LED显示,其他时间重置数码管和LED显示。
由于10毫秒非常短,肉眼几乎无法分辨,所以就算是数码管和LED都公用一个P6端口,他们在显示的时候也可以互不冲突!
按键功能自定义:
强烈建立看视频学习!!!{:4_175:}
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]