> 文章列表 > (学习日记)2023.4.12

(学习日记)2023.4.12

(学习日记)2023.4.12

写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。

标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。

点击此处进入学习日记的总目录

2023.4.12

  • 一、51:LED点阵屏图形
  • 二、 Keil:`ERROR L107: ADDRESS SPACE OVERFLOW`
  • 三、51:LED点阵屏显示汉字动画

一、51:LED点阵屏图形

  1. 74HC595
    (学习日记)2023.4.12
  2. 设置引脚变量
sbit RCK=P3^5;		//RCLK
sbit SCK=P3^6;		//SRCLK
sbit SER=P3^4;		//SER#define MATRIX_LED_PORT		P0	// 点阵屏数据口连接到P0
  1. 编写 字节写入函数
    这个函数用来向74HC595芯片中写入一个字节的数据.
    具体来说,是将8位二进制数依次通过SER引脚输入到74HC595芯片中,然后通过SCKRCK控制信号输出到点阵屏中。
    这个函数在程序中被调用来实现点阵屏的数据显示
/* @brief  74HC595写入一个字节* @param  Byte 要写入的字节* @retval 无*/
void _74HC595_WriteByte(unsigned char Byte)
{unsigned char i;for(i=0;i<8;i++){SER=Byte&(0x80>>i);		// 逐位写入字节SCK=1;					// 时钟上升沿,数据被移位SCK=0;					// 时钟下降沿}RCK=1;						// 上升沿时,将数据存储到寄存器中RCK=0;						// 下降沿,保持RCK管脚为低电平
}
  1. 编写 初始化函数
    这个函数用来初始化点阵屏的控制引脚,即将RCKSCKSER信号全部初始化为0
/* @brief  点阵屏初始化* @param  无* @retval 无*/
void MatrixLED_Init()
{SCK=0;		// 置SCK管脚为低电平RCK=0;		// 置RCK管脚为低电平
}
  1. 编写 数据显示函数
    这个函数用来显示一个指定列的数据
    其中,参数Column是要显示的列的序号,范围为0~70表示最左边的列,7表示最右边的列;参数Data是该列的数据,是一个8位二进制数,高位在上,1表示点亮0表示熄灭
    这个函数在内部会调用_74HC595_WriteByte函数将Data写入到74HC595芯片中,并通过P0口来控制点阵屏的列选信号,从而实现在指定列显示指定的数据。
/* @brief  LED点阵屏显示一列数据* @param  Column 要选择的列,范围:0~7,0在最左边* @param  Data 选择列显示的数据,高位在上,1为亮,0为灭* @retval 无*/
void MatrixLED_ShowColumn(unsigned char Column,unsigned char Data)
{_74HC595_WriteByte(Data);			// 向74HC595写入要显示的数据MATRIX_LED_PORT=~(0x80>>Column);	// 设置要显示的列Delay_ms(1);						// 延时一段时间以显示出效果MATRIX_LED_PORT=0xFF;				// 清除要显示的列的数据
}

二、 Keil:ERROR L107: ADDRESS SPACE OVERFLOW

  1. 原因:
    这个错误是由于芯片的数据段(DATA)空间不足而导致的。
    在代码中,有一些变量或数组被存储在数据段中,但是这个芯片的数据段大小是有限制的,超过限制就会导致这个错误。

  2. 解决办法1:删变量
    单片机的RAM不够,但变量太多,所以删掉一些不重要的变量就ok

  3. 解决办法2:修改保存位置
    (学习日记)2023.4.12
    Small改成 Compact Large,其中:

  • DATA:指的是内部RAM的默认存储区域。在Keil中,该区域的变量被分配在数据段中,也就是由CPU直接寻址的RAM中。这意味着,这些变量的寻址速度比较快,但是存储容量较小,通常只有几百个字节
  • PDATA:指的是片内可编程RAM(Programmable Data Memory),也称为P-RAM或小数据RAM。这是一种在内部RAM之外的额外存储区域,可以用于存储在程序中定义的常量和变量。P-RAM 的优点是访问速度比外部存储器快,但是存储容量相对较小。在Keil中,变量分配在P-RAM中,可以通过编译器和链接器配置来控制。
  • XDATA:指的是片外扩展RAM的存储区域,可以扩展内部RAM的存储容量。X-RAM通常用于需要大量存储空间的应用程序。在Keil中,变量分配在X-RAM中,可以通过编译器和链接器配置来控制。

三、51:LED点阵屏显示汉字动画

  1. 上述使用的MatrixLED_ShowColumn只能每次输出一列,那样程序将无比的冗长
    我们需要用数组来实现一次输出8列(因为点阵是 8*8
/* @brief  LED点阵屏按列显示八列数据* @param  Data 选择列显示的数组,共八个数* @retval 无*/
void MatrixLED_ShowData(unsigned char *Data)
{unsigned char i = 0;while(i<8){MatrixLED_ShowColumn(i, Data[i]);i++;}
}

就可以通过如下来调用使用了:

unsigned char Data[]={0xff, 0x28, 0x7e, 0x6a, 0x6a, 0x66, 0x42, 0x7e};

运行发现,这是个横着的 西

  1. 中文点阵生成软件
    可以使用这个网站获得汉字的Data[]值。

目前是网上能搜到的最好用的一个

  1. 将文字显示横过来
    若觉得文字横着不好看,可以用下面的函数把文字显示横过来。
/* @brief  将LED阵列沿对角线翻转* @param  Data 选择列显示的数组,共八个数* @retval 无*/
void row2col(unsigned char *Data)
{unsigned char i = 0;unsigned char j = 0;unsigned char temp = 0;// 对于每列数据,遍历每个字节for (i = 0; i < 8; i++) for (j = 0; j < i; j++) {// 获取原始数据中当前列对应的位和行对应的位temp = (Data[j] >> (7 - i)) & 0x01;// 将原始数据中当前列对应的位和行对应的位交换// 如果原始数据中行对应的位为1,则将列对应的位也设为1// 否则,将列对应的位设为0((Data[i] >> (7 - j)) & 0x01) ? (Data[j] |= (1 << (7 - i))) : (Data[j] &= ~(1 << (7 - i)));// 如果原始数据中列对应的位为1,则将行对应的位也设为1// 否则,将行对应的位设为0(temp) ? (Data[i] |= (1 << (7 - j))) : (Data[i] &= ~(1 << (7 - j)));}
}
  1. 快速显示文字动画
    main.c 如下
#include <main.h>void main()
{// 修改区unsigned char num = 5;		//字的数量unsigned char Data[][8]={{0x3c, 0xea, 0xff, 0x2a, 0x3a, 0xe5, 0x2f, 0x73},{0x7c, 0x7c, 0x44, 0x7c, 0xff, 0x5e, 0x70, 0xbf},{0x28, 0x7f, 0x53, 0xe4, 0xd6, 0x57, 0x65, 0x4c},{0x2c, 0x6e, 0x38, 0xc7, 0x7c, 0x7c, 0x46, 0x7e},{0x2c, 0x6e, 0x38, 0xc7, 0x7c, 0x7c, 0x46, 0x7e}};//程序变量(无需修改)unsigned char i=0;unsigned char delay=0;unsigned char time=50;for(i=0; i<num; i++)row2col(Data[i]);while(1){for(i=0; i<num; i++){while(delay++ != time){MatrixLED_ShowData(Data[i]);Delay_ms(1);}delay=0;}}
}

将网站生成代码复制到 Data[][8]中,加上逗号,再更改num,即可快速显示一段文字动画。
(学习日记)2023.4.12