webfly
发表于 2024-9-3 10:30:22
本帖最后由 webfly 于 2024-9-20 11:14 编辑
第九集:数码管的静态使用
1、认识数码管
日常生活中有各式各样的数码管应用,他们外观不同,作用不同,但是本质来说他们都是通过点亮内部的LED来显示信息,控制方法基本一样。
按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管,尾缀A表示共阳,K表示共阴。数码管内部,一般把各笔划段的发光二极管阴极或阳极连在一起,叫做数码管的公共端,阴极作为公共端的数码管叫做共阴极数码管,阳极作为公共端的数码管叫做共阳极数码管。 共阳极数码管与共阴的控制方式相反,公共端接高电平,需要点亮的发光二极管阴极送低电平,所以它的显示代码与共阴的相反。
数码管内部连线
2、控制原理
数码管实际上是由七个发光二极管组成一个8字形,还有另外一个发光二极管做成圆点形,主要作为显示数据的小数点使用,这样一共使用了八个发光二极管,所以叫八段LED数码管。这些段分别由字母a、b、c、d、e、f、g和dp来表示。当给这些数码管特定的段加上电压后,这些特定的段就会发亮,以显示出各种数字和图形。
3、数码管实现0-9显示(静态显示)
#include "COMM/stc.h" //调用头文件
#include "COMM/usb.h"
#define KEY1 P32 //定义一个按键 引脚选择P32
#define KEY2 P33 //定义一个按键 引脚选择P33
#define BEEP P54 //定义一个按键 引脚选择P54
#define MAIN_Fosc 24000000UL //定义主时钟
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
u8 SEG_Tab = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90 }; //0-9
void sys_init(); //函数声明
void delay_ms(u16 ms); //unsigned int
void main() //程序开始运行的入口
{
u8 num = 0;
sys_init(); //USB功能+IO口初始化
usb_init(); //usb库初始化
EA = 1; //CPU开放中断,打开总中断。
while(1) //死循环
{
if( DeviceState != DEVSTATE_CONFIGURED ) //
continue;
if( bUsbOutReady )
{
usb_OUT_done();
}
P70 = 0; //开启一个数码管
//------------------------------------------------P32按下一次,灯往右边边移动一个单位 -----------------------------------------------
// P6 = SEG_Tab; //这个数码管输出段码
// num ++;
// if( num>9 )
// num = 0;
//
// delay_ms(1000);
P6 = SEG_Tab; //这个数码管输出段码
if( KEY1 ==0 )
{
delay_ms(10);
if( KEY1 ==0 )
{
BEEP = 0;
delay_ms(10);
BEEP = 1;
while( KEY1 ==0 );
if( num<9 )
{
num++;
}
}
}
if( KEY2 ==0 )
{
delay_ms(10);
if( KEY2 ==0 )
{
BEEP = 0;
delay_ms(10);
BEEP = 1;
while( KEY2 ==0 );
if( num>0 )
num--;
}
}
}
}
/*
11111110 0XFE
11111101 0XFD
11111011 0XFB
11110111 0XF7
11101111 0XEF
11011111 0XDF
10111111 0XBF
01111111 0X7F
*/
void sys_init() //函数定义
{
WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
P3M0 = 0x00;
P3M1 = 0x00;
P3M0 &= ~0x03;
P3M1 |= 0x03;
//设置USB使用的时钟源
IRC48MCR = 0x80; //使能内部48M高速IRC
while (!(IRC48MCR & 0x01));//等待时钟稳定
USBCLK = 0x00; //使用CDC功能需要使用这两行,HID功能禁用这两行。
USBCON = 0x90;
}
void delay_ms(u16 ms) //unsigned int
{
u16 i;
do
{
i = MAIN_Fosc/6000;
while(--i);
}while(--ms);
}
webfly
发表于 2024-9-3 10:30:43
本帖最后由 webfly 于 2024-9-20 11:38 编辑
第十集:数码管的动态显示
1、数码管动态刷新的原理
静态显示方式接口编程容易,但是占用口线较多。若用I/O口线接口,要占用四个八位I/O口。如果显示器的数目增多,则需要增加I/O口的数目。因此在显示位数较多的情况下,一般都采用动态显示方式。若要各个数码管能够同时显示出与本位相应的显示字符,就必须采用动态扫描显示方式。即在某一时刻,只让某一位的位选线处于选通状态,而其他位的位选线处于关闭状态,同时,段码线上输出相应位要有显示的字符的段码。这样,在同一时刻,四位LED中只有被选通的那一位显示出字符,而其他三位则是熄灭的。同样,在下一时刻,只让其下一位的位选线处于选通状态,而其他各位的位选线处于关闭状态,在段码线上输出将要显示字符的段码,此时,只有在选通位显示出相应的字符,其他各位则是熄灭的。如此循环下去,就可使各位显示出将要显示的字符。虽然这些字符是在不同时刻出现的,而在同一时刻,只有一位显示,其他各位熄灭,但由于LED数码管的余辉和人眼的“视觉暂留”作用,只要每位显示间隔足够短,则可以造成“多位同时亮”的假象,达到同时显示的效果。
2、控制原理
3、8位数码管同时点亮
#include "COMM/stc.h" //调用头文件
#include "COMM/usb.h"
#define KEY1 P32 //定义一个按键 引脚选择P32
#define KEY2 P33 //定义一个按键 引脚选择P33
#define BEEP P54 //定义一个按键 引脚选择P54
#define SEG_Delay1 //延时多少ms
#define MAIN_Fosc 24000000UL //定义主时钟
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
u8 SEG_Tab = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //0-9段码,0-9带小数点
u8 COM_Tab = { 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe }; //0-7的位码数组
u8 Show_Tab = {3,0,0,0,0,10,0,0};
u32 TimCount = 0; //计数单位1ms
bit RUN_State = 0; //开始运行/结束运行
u8 num = 0;
void sys_init(); //函数声明
void delay_ms(u16 ms); //unsigned int
void SEG_Fre( void )
{
//位码选择第一位,段码选择0
P7 = COM_Tab; //位码的选择
P6 = SEG_Tab];//需要显示的数字的内码 赋给 P6 NUM =0 -> Show_Tab] = 1 -> p6 = oxF9
delay_ms(SEG_Delay);
num++;
if( num >7 )
num = 0;
}
void main() //程序开始运行的入口
{
sys_init(); //USB功能+IO口初始化
usb_init(); //usb库初始化
EA = 1; //CPU开放中断,打开总中断。
while(1) //死循环
{
if( DeviceState != DEVSTATE_CONFIGURED ) //
continue;
if( bUsbOutReady )
{
usb_OUT_done();
}
//------------------------------------------------P32按下一次,灯往右边边移动一个单位 -----------------------------------------------
Show_Tab= 1; //选择 1
Show_Tab= 10; //选择 0.
Show_Tab= 0; //选择 0
Show_Tab= 0; //选择 0
if( RUN_State==1 )
{
TimCount++;
Show_Tab = TimCount/10000%10;
Show_Tab = TimCount/1000%10+10;
Show_Tab = TimCount/100%10;
Show_Tab = TimCount/10%10; //取10位
}
SEG_Fre();
if( KEY1 ==0 )
{
delay_ms(10);
if( KEY1 ==0 )
{
BEEP = 0;
delay_ms(10);
BEEP = 1;
while( KEY1 ==0 )
{
SEG_Fre();
}
if( RUN_State==0 )
TimCount = 0;
RUN_State = !RUN_State;
}
}
}
}
/*
11111110 0XFE
11111101 0XFD
11111011 0XFB
11110111 0XF7
11101111 0XEF
11011111 0XDF
10111111 0XBF
01111111 0X7F
*/
void sys_init() //函数定义
{
WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
P3M0 = 0x00;
P3M1 = 0x00;
P3M0 &= ~0x03;
P3M1 |= 0x03;
//设置USB使用的时钟源
IRC48MCR = 0x80; //使能内部48M高速IRC
while (!(IRC48MCR & 0x01));//等待时钟稳定
USBCLK = 0x00; //使用CDC功能需要使用这两行,HID功能禁用这两行。
USBCON = 0x90;
}
void delay_ms(u16 ms) //unsigned int
{
u16 i;
do
{
i = MAIN_Fosc/6000;
while(--i);
}while(--ms);
}
webfly
发表于 2024-9-3 10:30:52
本帖最后由 webfly 于 2024-9-20 13:33 编辑
第十一集:定时器的使用
1.定时器的作用和意义
定时器是定时器和计数器的统称。设置为定时器时,可实现硬件计时,或者使程序每隔一固定时间完成一项操作;设置为计数器时候能够对脉冲进行计数;替代长时间的delay,提高CPU的运行效率和处理速度,能及时的响应某个事件。
2.STC32G单片机定时器使用原理
3.定时器的简单应用
4.定时器的快速使用方法
webfly
发表于 2024-9-3 10:31:32
第十二集:计数器的使用
webfly
发表于 2024-9-3 10:31:45
第十三集:简易多任务处理上
webfly
发表于 2024-9-3 10:32:12
第十四集:矩阵按键
webfly
发表于 2024-9-3 10:32:24
第十五集:外部中断
webfly
发表于 2024-9-3 10:32:33
第十六集:IO中断
webfly
发表于 2024-9-5 08:37:05
签到
wgh2024
发表于 2024-9-5 09:25:44
学习中,简单易懂!