当前位置:首页 > 单片机 > 单片机
[导读]上下移动我们会了,那我们还想左右移动该如何操作呢?方法一、最简单,就是把板子侧过来放,纵向取模就可以完成。这里大家是不是有种头顶冒汗的感觉?我们要做好技术,但是不能沉溺于技术。技术是我们的工具,我们在

 

上下移动我们会了,那我们还想左右移动该如何操作呢?

方法一、最简单,就是把板子侧过来放,纵向取模就可以完成。

这里大家是不是有种头顶冒汗的感觉?我们要做好技术,但是不能沉溺于技术。技术是我们的工具,我们在做开发的时候除了用好这个工具外,也得多拓展自己解决问题的思路,要慢慢培养自己的多角度思维方式。

那把板子正过来,左右移动就完不成了吗?当然不是。大家慢慢的学多了就会培养了一种感觉,就是一旦硬件设计好了,我们要完成一种功能,大脑就可以直接思考出来能否完成这个功能,这个在我们进行电路设计的时候最为重要。我们在开发产品的时候,首先是设计电路,设计电路的时候,工程师就要在大脑中通过思维来验证板子硬件和程序能否完成我们想要的功能,一旦硬件做好了,做好板子回来剩下的就是靠编程来完成了。只要是硬件逻辑上没问题,功能上软件肯定可以实现。

当然了,我们在进行硬件电路设计的时候,也得充分考虑软件编程的方便性。因为我们的程序是用 P0 来控制点阵的整行,所以对于我们这样的电路设计,上下移动程序是比较好编写的。那如果我们设计电路的时候知道我们的图形要左右移动,那我们设计电路画板子的时候就要尽可能的把点阵横过来放,有利于我们编程方便,减少软件工作量。

方法二、利用二维数组来实现,算法基本上和上下移动相似。

二维数组,前边提过一次,他的使用其实也没什么复杂的。它的声明方式是:

数据类型数组名[数组长度1][数组长度2];

与一位数组类似,数据类型是全体元素的数据类型,数组名是标识符,数组长度1和数组长度2分别代表数组具有的行数和列数。数组元素的下标一律从0开始。

例如:unsigned char a[2][3];声明了一个具有2行3列的无符号字符型的二维数组 a。

二维数组的数组元素总个数是两个长度的乘积。二维数组在内存中存储的时候,采用行优先的方式来存储,即在内存中先存放第0行的元素,再存放第一行的元素......,同一行中再按照列顺序存放,刚才定义的那个 a[2][3]的存放形式就如表7-1所示。

表7-1 二维数组的物理存储结构







a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]

二维数组的初始化方法分两种情况,我们前边学一维数组的时候学过,数组元素的数量可以小于数组元素个数,没有赋值的会自动给0。当数组元素的数量等于数组个数的时候,如下所示:

unsignedchara[2][3]={{1,2,3},{4,5,6}};

或者是

unsignedchara[2][3]={1,2,3,4,5,6};

当数组元素的数量小于数组个数的时候,如下所示:

unsignedchara[2][3]={{1,2},{3,4}};

等价于

unsignedchara[2][3]={1,2,0,3,4,0};

而反过来的写法

unsignedchara[2][3]={1,2,3,4};

等价于

unsignedchara[2][3]={{1,2,3},{4,0,0}};

此外,二维数组初始化的时候,行数可以省略,编译系统会自动根据列数计算出行数,但是列数不能省略。

讲这些,只是为了让大家了解一下,看别人写的代码的时候别发懵就行了,但是我们今后写程序的时候,按照规范,行数列数都不要省略,全部写齐,初始化的时候,全部写成unsigned char a[2][3] = {{1,2,3}, {4,5,6}};的形式,而不允许写成一维数组的格式,防止大家出错,同时也是提高程序的可读性。

那么下面我们要进行横向做 I ? U 的动画了,先把我们需要的图片画出来,再逐一取模,和上一张图片类似的是,我们这个图形共有30张图片,通过程序每 250 ms 改变一张图片,就可以做出来动画效果了。但是不同的是,我们这个是要横向移动,横向移动的图片切换时的字模数据不是连续的,所以这次我们要对30张图片分别取模,如图7-11所示。

图7-11 横向动画取模图片

图7-11中最上面的图形是横向连在一起的效果,而实际上我们要把它分解为30个帧,每帧图片单独取模,取出来都是8个字节的数据,一共就是30*8个数据,我们用一个二维数组来存储它们。

#includesbitADDR0=P1^0;sbitADDR1=P1^1;sbitADDR2=P1^2;sbitADDR3=P1^3;sbitENLED=P1^4;unsignedcharcodeimage[30][8]={{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//动画帧1{0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F},//动画帧2{0xFF,0x3F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F},//动画帧3{0xFF,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F},//动画帧4{0xFF,0x0F,0x9F,0x9F,0x9F,0x9F,0x9F,0x0F},//动画帧5{0xFF,0x87,0xCF,0xCF,0xCF,0xCF,0xCF,0x87},//动画帧6{0xFF,0xC3,0xE7,0xE7,0xE7,0xE7,0xE7,0xC3},//动画帧7{0xFF,0xE1,0x73,0x73,0x73,0xF3,0xF3,0xE1},//动画帧8{0xFF,0x70,0x39,0x39,0x39,0x79,0xF9,0xF0},//动画帧9{0xFF,0x38,0x1C,0x1C,0x1C,0x3C,0x7C,0xF8},//动画帧10{0xFF,0x9C,0x0E,0x0E,0x0E,0x1E,0x3E,0x7C},//动画帧11{0xFF,0xCE,0x07,0x07,0x07,0x0F,0x1F,0x3E},//动画帧12{0xFF,0x67,0x03,0x03,0x03,0x07,0x0F,0x9F},//动画帧13{0xFF,0x33,0x01,0x01,0x01,0x03,0x87,0xCF},//动画帧14{0xFF,0x99,0x00,0x00,0x00,0x81,0xC3,0xE7},//动画帧15{0xFF,0xCC,0x80,0x80,0x80,0xC0,0xE1,0xF3},//动画帧16{0xFF,0xE6,0xC0,0xC0,0xC0,0xE0,0xF0,0xF9},//动画帧17{0xFF,0x73,0x60,0x60,0x60,0x70,0x78,0xFC},//动画帧18{0xFF,0x39,0x30,0x30,0x30,0x38,0x3C,0x7E},//动画帧19{0xFF,0x9C,0x98,0x98,0x98,0x9C,0x1E,0x3F},//动画帧20{0xFF,0xCE,0xCC,0xCC,0xCC,0xCE,0x0F,0x1F},//动画帧21{0xFF,0x67,0x66,0x66,0x66,0x67,0x07,0x0F},//动画帧22{0xFF,0x33,0x33,0x33,0x33,0x33,0x03,0x87},//动画帧23{0xFF,0x99,0x99,0x99,0x99,0x99,0x81,0xC3},//动画帧24{0xFF,0xCC,0xCC,0xCC,0xCC,0xCC,0xC0,0xE1},//动画帧25{0xFF,0xE6,0xE6,0xE6,0xE6,0xE6,0xE0,0xF0},//动画帧26{0xFF,0xF3,0xF3,0xF3,0xF3,0xF3,0xF0,0xF8},//动画帧27{0xFF,0xF9,0xF9,0xF9,0xF9,0xF9,0xF8,0xFC},//动画帧28{0xFF,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFE},//动画帧29{0xFF,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF}//动画帧30};voidmain(){EA=1;//使能总中断ENLED=0;//使能U4,选择LED点阵ADDR3=0;TMOD=0x01;//设置T0为模式1TH0=0xFC;//为T0赋初值0xFC67,定时1msTL0=0x67;ET0=1;//使能T0中断TR0=1;//启动T0while(1);}/*定时器0中断服务函数*/voidInterruptTimer0()interrupt1{staticunsignedchari=0;//动态扫描的索引staticunsignedchartmr=0;//250ms软件定时器staticunsignedcharindex=0;//图片刷新索引TH0=0xFC;//重新加载初值TL0=0x67;//以下代码完成LED点阵动态扫描刷新P0=0xFF;//显示消隐switch(i){case0:ADDR2=0;ADDR1=0;ADDR0=0;i++;P0=image[index][0];break;case1:ADDR2=0;ADDR1=0;ADDR0=1;i++;P0=image[index][1];break;case2:ADDR2=0;ADDR1=1;ADDR0=0;i++;P0=image[index][2];break;case3:ADDR2=0;ADDR1=1;ADDR0=1;i++;P0=image[index][3];break;case4:ADDR2=1;ADDR1=0;ADDR0=0;i++;P0=image[index][4];break;case5:ADDR2=1;ADDR1=0;ADDR0=1;i++;P0=image[index][5];break;case6:ADDR2=1;ADDR1=1;ADDR0=0;i++;P0=image[index][6];break;case7:ADDR2=1;ADDR1=1;ADDR0=1;i=0;P0=image[index][7];break;default:break;}//以下代码完成每250ms改变一帧图像tmr++;if(tmr>=250){//达到250ms时改变一次图片索引tmr=0;index++;if(index>=30){//图片索引达到30后归零index=0;}}}

 

 

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

单片机是一种嵌入式系统,它是一块集成电路芯片,内部包含了处理器、存储器和输入输出接口等功能。

关键字: 单片机 编写程序 嵌入式

在现代电子技术的快速发展中,单片机以其高度的集成性、稳定性和可靠性,在工业自动化、智能家居、医疗设备、航空航天等诸多领域得到了广泛应用。S32单片机,作为其中的佼佼者,其引脚功能丰富多样,是实现与外部设备通信、控制、数据...

关键字: s32单片机引脚 单片机

在微控制器领域,MSP430与STM32无疑是两颗璀璨的明星。它们各自凭借其独特的技术特点和广泛的应用领域,在市场上占据了重要的位置。本文将深入解析MSP430与STM32之间的区别,探讨它们在不同应用场景下的优势和局限...

关键字: MSP430 STM32 单片机

该系列产品有助于嵌入式设计人员在更广泛的系统中轻松实现USB功能

关键字: 单片机 嵌入式设计 USB

单片机编程语言是程序员与微控制器进行交流的桥梁,它们构成了单片机系统的软件开发基石,决定着如何有效、高效地控制和管理单片机的各项资源。随着微控制器技术的不断发展,针对不同应用场景的需求,形成了丰富多样的编程语言体系。本文...

关键字: 单片机 微控制器

单片机,全称为“单片微型计算机”或“微控制器”(Microcontroller Unit,简称MCU),是一种高度集成化的电子器件,它是现代科技领域的关键组件,尤其在自动化控制、物联网、消费电子、汽车电子、工业控制等领域...

关键字: 单片机 MCU

STM32是由意法半导体公司(STMicroelectronics)推出的基于ARM Cortex-M内核的32位微控制器系列,以其高性能、低功耗、丰富的外设接口和强大的生态系统深受广大嵌入式开发者喜爱。本文将详细介绍S...

关键字: STM32 单片机

在当前的科技浪潮中,单片机作为嵌入式系统的重要组成部分,正以其强大的功能和广泛的应用领域受到越来越多行业的青睐。在众多单片机中,W79E2051以其卓越的性能和稳定的工作特性,成为市场上的明星产品。本文将深入探讨W79E...

关键字: 单片机 w79e2051单片机

单片机,又称为微控制器或微处理器,是现代电子设备中的核心部件之一。它集成了中央处理器、存储器、输入输出接口等电路,通过外部信号引脚与外部设备进行通信,实现对设备的控制和管理。本文将详细介绍单片机的外部信号引脚名称及其功能...

关键字: 单片机 微控制器 中央处理器

随着科技的飞速发展,单片机和嵌入式系统在现代电子设备中的应用越来越广泛。它们不仅提高了设备的智能化水平,还推动了各行各业的创新与发展。在单片机和嵌入式系统的开发中,编程语言的选择至关重要。本文将深入探讨单片机和嵌入式系统...

关键字: 单片机 嵌入式系统 电子设备
关闭
关闭