(学习日记)2023.4.12
写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。
点击此处进入学习日记的总目录
2023.4.12
- 一、51:LED点阵屏图形
- 二、 Keil:`ERROR L107: ADDRESS SPACE OVERFLOW`
- 三、51:LED点阵屏显示汉字动画
一、51:LED点阵屏图形
74HC595
- 设置
引脚变量
sbit RCK=P3^5; //RCLK
sbit SCK=P3^6; //SRCLK
sbit SER=P3^4; //SER#define MATRIX_LED_PORT P0 // 点阵屏数据口连接到P0
- 编写
字节写入函数
这个函数用来向74HC595
芯片中写入一个字节的数据.
具体来说,是将8
位二进制数依次通过SER
引脚输入到74HC595
芯片中,然后通过SCK
和RCK
控制信号输出到点阵屏中。
这个函数在程序中被调用来实现点阵屏的数据显示
。
/* @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管脚为低电平
}
- 编写
初始化函数
这个函数用来初始化点阵屏的控制引脚,即将RCK
、SCK
和SER
信号全部初始化为0
。
/* @brief 点阵屏初始化* @param 无* @retval 无*/
void MatrixLED_Init()
{SCK=0; // 置SCK管脚为低电平RCK=0; // 置RCK管脚为低电平
}
- 编写
数据显示函数
这个函数用来显示一个指定列的数据
。
其中,参数Column
是要显示的列的序号,范围为0~7
,0
表示最左边的列,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
-
原因:
这个错误是由于芯片的数据段(DATA)
空间不足而导致的。
在代码中,有一些变量或数组被存储在数据段中,但是这个芯片的数据段大小是有限制的,超过限制就会导致这个错误。 -
解决办法1:
删变量
单片机的RAM
不够,但变量太多,所以删掉一些不重要的变量就ok
。 -
解决办法2:
修改保存位置
把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点阵屏显示汉字动画
- 上述使用的
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};
运行发现,这是个横着的 西
- 中文点阵生成软件
可以使用这个网站获得汉字的Data[]
值。
目前是网上能搜到的最好用的一个
- 将文字显示横过来
若觉得文字横着不好看,可以用下面的函数把文字显示横过来。
/* @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)));}
}
- 快速显示文字动画
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
,即可快速显示一段文字动画。