第二周学习笔记

第二周

零基础入门(一)

1. 新建工程

  • 养成良好的编程习惯:每一个不同的工程项目对应一个不同的文件夹。
  • 芯片选择 AT89C52
  • 点开“品”字工具栏,修改相关信息。

  • 点开魔术棒,勾选生成 HEX 文件。

2. 认识 LED 原理图

  • 根据 VCC 连接位置可知,DB 引脚输出低电平 0 时 LED 点亮。

  • 根据引脚图可知,DB 由 P1 引脚控制。

3. 编写程序

  1. 右键点击 User 栏,添加主程序 main.c
  2. 编写主体框架:
 /*头文件区域*/
 #include <REGX52.H>
 
 /*Main*/
 void main()
 {
     while(1)
     {
     
     }
  }

实现 LED 交替亮:

//方法一:对P1整体进行赋值,控制所有的LED灯
P1 = 0xAA//1010 1010 切记0是亮
    
//方法二:对P1中八个IO口单独赋值,控制单个LED灯
P1_0 = 0;
P1_7 = 0;

4. LED 闪烁

  • 使用 STC-ISP 软件生成 1 毫秒延时程序。

  • 改写延时函数:
void Delay(unsigned char xms)   //@12.000MHz
 {
     unsigned char data i, j;
     while(xms--)
     {
         i = 2;
         j = 239;
         do
         {
             while (--j);
         } while (--i);
 
     }
 }
  • 如果程序中包含 _nop_() 函数导致报错,可先删除;正常使用时需要包含 intrins.h 头文件。

5. 流水灯

  • _crol_:循环左移。
  • _cror_:循环右移。
  • 所属库:intrins.h
ucLed = _crol_(ucLed,1);
P1 = ucLed;
Delay(100);

零基础入门(二)

1. 独立按键原理图

  • 根据接地情况可知,按键按下时引脚读到低电平 0

  • 根据原理图可知,按键连接引脚 P3_4~P3_7

2. 独立按键程序

unsigned char Key_Down,Key_Up,Key_Val,Key_OLd;//按键扫描专用变量

unsigned char Key_Read()
{
	unsigned char temp = 0;
	if(P3_4 == 0) temp = 1;
    if(P3_5 == 0) temp = 2;
    if(P3_6 == 0) temp = 3;
    if(P3_7 == 0) temp = 4;
    
    return temp;
}

Key_Val = Key_Read();//读取键码值
Key_Down = Key_Val & (Key_Val ^ Key_OLd);//检测下降沿
Key_Up = ~Key_Val & (Key_Val ^ Key_OLd);//检测上升沿
Key_OLd = Key_Val;//按键扫描辅助函数

控制 LED:

if(Key_Down == 1)	P1_0 = 0;

控制流水灯:

bit System_Flag;//系统标志位

if(System_Flag == 1)
{
    ucLed = _cror_(ucLed,1);
    P1 = ucLed;
    Delay(100);
}

switch(Key_Down)
{
    case 1:
        System_Flag = 1;
    break;
    case 2:
        System_Flag = 0;
    break;
}

3. 矩阵按键原理图

  • 矩阵按键扫描顺序:先扫描行,再扫描列。

4. 矩阵按键程序编写

unsigned char Key_Read()
{
	unsigned char temp = 0;
    P3_0 = 0;P3_1 = 1;P3_2 = 1;P3_3 = 1;
	if(P3_4 == 0) temp = 1;
    if(P3_5 == 0) temp = 2;
    if(P3_6 == 0) temp = 3;
    if(P3_7 == 0) temp = 4;
    P3_0 = 1;P3_1 = 0;P3_2 = 1;P3_3 = 1;
	if(P3_4 == 0) temp = 5;
    if(P3_5 == 0) temp = 6;
    if(P3_6 == 0) temp = 7;
    if(P3_7 == 0) temp = 8;
    P3_0 = 1;P3_1 = 1;P3_2 = 0;P3_3 = 1;
	if(P3_4 == 0) temp = 9;
    if(P3_5 == 0) temp = 10;
    if(P3_6 == 0) temp = 11;
    if(P3_7 == 0) temp = 12;
    P3_0 = 1;P3_1 = 1;P3_2 = 1;P3_3 = 0;
	if(P3_4 == 0) temp = 13;
    if(P3_5 == 0) temp = 14;
    if(P3_6 == 0) temp = 15;
    if(P3_7 == 0) temp = 16;
    
    return temp;
}

零基础入门(三)

1. SEG 原理图

  • 段选:控制单个数码管中 LED 段的亮灭,对应引脚 P2.6
  • 位选:控制多个数码管中哪些位点亮,对应引脚 P2.7

2. 数码管程序

unsigned char Seg_Dula[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
unsigned char Seg_Wela[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf};

/*数码管显示函数*/
void Seg_Disp(unsigned char wela, dula)
{
	//先消影
	P0 = 0x00;
	P2_6 = 1;
	P2_6 = 0;
	
	//再位选
	P0 = Seg_Wela[wela];
	P2_7 = 1;
	P2_7 = 0;
	
	//再断选
	P0 = Seg_Dula[dula];
	P2_6 = 1;
	P2_6 = 0;
}

3. 定时器程序

  • 在 STC-ISP 软件中生成定时器程序。

image-20260906021919909

  • 在初始化函数中增加 ET0 = 1;EA = 1;,分别用于使能定时器 0 中断和总中断。
/*定时器0初始化函数*/
void Timer0_Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;
	EA = 1;
}
  • 编写中断服务函数、数码管扫描并显示程序:
unsigned char Seg_Pos;//数码管扫描变量
unsigned char Seg_Buf[6] = {10,10,10,10,10,10};//数码管显示数据存放数组

/*定时器0中断服务函数*/
void Timer0Server() interrupt 1
{
    TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
    if(++Seg_Pos == 6)	Seg_Pos = 0;
    Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);
}

提示:使用定时器中断刷新数码管,可以让显示更稳定。

我用cloudflare配置图床但部分图片仍然不能显示,目前未找到解决办法