一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

利用C程序指针及函数参数实现单片机任意IO口线操作的方法与流程

2022-11-23 13:27:50 来源:中国专利 TAG:

利用c程序指针及函数参数实现单片机任意io口线操作的方法
技术领域
1.本发明涉及c语言程序对单片机编程技术领域,具体地说,涉及利用c程序指针及函数参数实现单片机任意io口线操作的方法。


背景技术:

2.由于c语言程序是一种编译执行程序语言,区别与解释执行语言,不能在运行过程中使用宏代换指令来更换关键字。对mcu的口线操作需在编程阶段就定义明确。现有技术中对mcu不同io(输入输出)口线进行同类操作控制时不方便用函数参数指向不同的io口,造成代码重复,进而造成程序占用存储空间大、执行效率低、调试代码工作量增大,即若一段程序参数调整,极其类似的另一段或几段程序也要调整。
3.常用方法中,一般采用直接操作io的方式,或者创新性地利用c程序switch case分支选择语句实现用函数操作io的方法。然而,这两种方法仍然存在较多问题,如:直接操作io的方式中,根据需操作的io口数量增加,会增加大量重复代码,占用大量存储空间,且非常不利于同类程序的调试和维护;直接操作io的方式中,如果在io口线通信中由于线缆材料或型式的不当选取、通信距离的延长等因素,造成串行数据波形发生畸变,导至通信数据错误,此时如果需调整通信时序(如延时参数等),则需要分别对不同io口的多个子程序(或函数)进行调整,调试工作量大大增加;利用c程序switch case语句实现用函数操作io的方法中,虽然实现了使用函数形参方式操作不同io口线,不需要重复同类型代码,但因为函数调用及分支选择次数增多,程序执行代码量增加,系统运行速度减慢,执行时间增长,导致整个系统的反应不及时等。
4.鉴于此,我们提出了利用c程序指针及函数参数实现单片机任意io口线操作的方法。


技术实现要素:

5.本发明的目的在于提供利用c程序指针及函数参数实现单片机任意io口线操作的方法,用以解决上述背景技术中提出的问题。
6.为实现上述技术问题的解决,本发明的目的之一在于,提供了利用c程序指针及函数参数实现单片机任意io口线操作的方法,基于c程序语言指针的指针和带参数函数访问、控制、选通所需的io口线,按io口所需操作功能数量增加相应数量的指向io端口功能寄存器地址指针的指针变量数组,对于只有p1到px口的单片机,指针数组的0元素值为0,1号元素值对应p1口的功能地址,且元素值需做地址的强制指针类型转换,x号元素对应x端口功能地址的强制指针类型转换值;在使用io口线操作前,先设定端口号、口线位,在后续的io口操作中,io口线操作语句转换为对选定的功能选择指针变量数组中端口号对应的指针变量元素赋值或取值;
7.具体包括如下步骤:
8.步骤1、创建指向io端口功能寄存器地址指针的指针变量数组;
9.步骤2、设置端口号及口线位对应排列的二维常量数组;
10.步骤3、在对单片机io口线操作前使用一个带参数的io口设置函数,取出将要操作的端口号值及口线位值分别写入两个8位的全局变量保存;
11.步骤4、io口线操作语句写成对步骤1指针变量数组中对应的指针变量元素赋值或取值。
12.作为本技术方案的进一步改进,所述步骤1中,创建指向io口地址指针的指针变量数组的具体方法为:
13.使用所选单片机c程序头文件中定义的io口功能地址定义字强制类型转化为指针后,创建一维指针变量数组,指针数组中保存io口功能指针元素的顺序分别对应端口号,即数组元素下标等于单片机端口号,以实现对不同端口的操作转换为对指针变量数组元素的赋值。
14.作为本技术方案的进一步改进,所述步骤2中,设置端口号及口线位对应排列的二维常量数组的方法为:
15.使用一个0到m的无符号字符型变量,分别代表0到m号口线;常量数组下标[0][0]、[0][1]元素分别存储0号口线的端口号、口线位,[m][0]、[m][1]元素分别存储m号口线的端口号、口线位;
[0016]
其中,p0到p7等端口号分别用0到7表示,口线位n写成口线所处位为“1”其它为“0”的单字节数,或写成“1左移n位”;
[0017]
作为本技术方案的进一步改进,所述步骤2中,设置端口号及口线位对应排列的二维常量数组,此步骤并非必须,如果省略此步骤及常量数组,将不方便对io口线设置和程序移置、不可遍历io口线;并且需在步骤3中通过选择或判断语句逐一指定需操作的端口号及口线位。
[0018]
作为本技术方案的进一步改进,所述步骤3中,在对单片机io口线操作前使用一个带参数的io口设置函数,函数从步骤2中设置的二维常量数组,取出端口号值及口线位值分别写入两个8位的全局变量保存,从而指定后续的口线操作均对应某一口线;io口线设置函数参数选取步骤2中的0到m。
[0019]
作为本技术方案的进一步改进,所述步骤4中,io口线操作语句写成对功能选择指针变量数组中对应的指针变量元素赋值或取值,具体方法为:
[0020]
对端口对应的指针元素赋值时,赋1值仅对口线位“或1”、赋0值仅对口线位“与0”;
[0021]
读取口线值时,端口对应的指针元素做口线位“与1”变换并增加“()”。
[0022]
作为本技术方案的进一步改进,所述步骤1中,创建指向io口地址指针的指针变量数组的具体方法还包括:
[0023]
如果此单片机mcu没有p6口,则删除p6的定义;
[0024]
如果有p7口则可增加p7的定义;
[0025]
如果mcu有p0口,可将数组中第0个元素的0值改为“(char*)p0”等类似语句;
[0026]
不同类型的mcu,可查询mcu的头文件来获得对io口功能寄存器地址(指针)定义的名称;
[0027]
如果还有pxsel等需要,相应增加指针变量数组“*pxsel”的定义即可。
[0028]
作为本技术方案的进一步改进,所述步骤3中,取出将要操作的端口号值及口线位值分别写入两个8位的全局变量保存,这两个8位的全局变量可省略,但所述步骤3中对单片机io口线操作前使用的带参数的io口设置函数,需变成对步骤2中常量数组指针的跳转。
[0029]
本发明的目的之二在于,提供了一种方法运行平台装置,包括处理器、存储器以及存储在存储器中并在处理器上运行的计算机程序,处理器用于执行计算机程序时实现上述的利用c程序指针及函数参数实现单片机任意io口线操作的方法的步骤。
[0030]
本发明的目的之三在于,提供了一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,所述计算机程序被处理器执行时实现上述的利用c程序指针及函数参数实现单片机任意io口线操作的方法的步骤。
[0031]
与现有技术相比,本发明的有益效果:
[0032]
1.该利用c程序指针及函数参数实现单片机任意io口线操作的方法,可以解决直接操作io的方式中,根据需操作的io口数量增加,会增加大量重复代码,占用大量存储空间的问题;同类型外围设备的操作(含控制、访问、选通等)程序不再需要重新写子程序或函数,在上层程序调用时使用函数参数即可分别完成分布在不同io口上的外围设备操作,程序简洁,易维护、易修改和移植;
[0033]
2.该利用c程序指针及函数参数实现单片机任意io口线操作的方法,对比直接操作io的方式中,如果在io口线通信中,由于线缆材料或型式的不当选取、通信距离的延长等因素,造成串行数据波形发生畸变,导致通信数据错误,此时如果需调整通信时序(如延时参数等),则需要分别对不同io口的多个子程序(或函数)进行调整,调试工作量大大增加;
[0034]
3.该利用c程序指针及函数参数实现单片机任意io口线操作的方法,对比利用c程序switch case语句实现用函数操作io的方法,解决了函数调用及分支选择次数增多问题,用io口地址指针的指针直接对io口操作,执行速度快、效率高;虽然增加了地址指针数组的再次定义(实施例中仅增加了3
×
7=21个字节),但大大减少分支选择函数程序执行代码量,系统运行速度进一步提高,对于要求时序较严格运用中,可以保证程序可靠行运行;此外,速度较快的串行通信中,效果更为显著;
[0035]
4.该利用c程序指针及函数参数实现单片机任意io口线操作的方法,对于现今大量运用arm(进阶精简指令集机器)架构的32位单片机,因此类单片机大部分io口线多、口线功能选择和操作指令多,面对需要一个单片机控制类似的多个或大量外围设备时,在去除重复代码、方便编程、提高运行效率、提高可靠性、降低功耗等方面,效果更为显著;
[0036]
5.该利用c程序指针及函数参数实现单片机任意io口线操作的方法,可以在pcb(印刷电路板)设计时不必局限于必须使用同一组io口(如不必是p21、p22、p23、p24等按顺序连续排列),方便pcb设计;对于成品pcb也可根据布局或方便性随意选择不同io口线来实现外围设备的通信或控制;程序对于mcu所有io口的操作,只需重新设置步骤2中io口线常量数组,即可实现任意io口采用函数单个参数的方式进行操作或访问,程序修改、配置简单且通用,运行高效;
[0037]
6.该利用c程序指针及函数参数实现单片机任意io口线操作的方法,对于一些排序无规则、io口较多的同类操作,方便用循环语句快速遍历所有io口。
附图说明
[0038]
图1为本发明中示例性的整体方法流程示意图;
[0039]
图2为本发明中示例性的c程序代码片断调用关系示意图;
[0040]
图3为本发明中示例性的整体方法细化后的流程示意图;
[0041]
图4为本发明中示例性的电子计算机平台装置结构图。
具体实施方式
[0042]
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
[0043]
实施例1
[0044]
如图1-图4所示,本实施例提供了利用c程序指针及函数参数实现单片机任意io口线操作的方法。
[0045]
如图1-图2所示,基于c程序语言指针的指针和带参数函数访问、控制、选通所需的io口线,按io口所需操作功能数量增加相应数量的指向io端口功能寄存器地址指针的指针变量数组,对于只有p1到px口的单片机,指针数组的0元素值为0,1号元素值对应p1口的功能地址,且元素值需做地址的强制指针类型转换,x号元素对应x端口功能地址的强制指针类型转换值;在使用io口线操作前,先设定端口号、口线位,在后续的io口操作中,io口线操作语句转换为对功能选择指针变量数组中端口号对应的指针变量元素赋值或取值;
[0046]
具体包括如下步骤:
[0047]
步骤1、创建指向io端口功能寄存器地址指针的指针变量数组;
[0048]
步骤2、设置端口号及口线位对应排列的二维常量数组;
[0049]
步骤3、在对单片机io口线操作前使用一个带参数的io口设置函数,取出将要操作的端口号值及口线位值分别写入两个8位的全局变量保存;
[0050]
步骤4、io口线操作语句写成对步骤1指针变量数组中对应的指针变量元素赋值或取值。
[0051]
本实施例中,步骤1中,创建指向io口地址指针的指针变量数组的具体方法为:
[0052]
使用所选单片机c程序头文件中定义的io口功能地址定义字强制类型转化为指针后,创建一维指针变量数组,指针数组中保存io功能指针元素的顺序分别对应端口号,即数组元素下标等于单片机端口号,以实现对不同端口的操作转换为对指针变量数组的赋值。
[0053]
进一步地,步骤1中,创建指向io口地址指针的指针变量数组的具体方法还包括:
[0054]
如果此单片机mcu没有p6口,则删除p6的定义;
[0055]
如果有p7口则可增加p7的定义;
[0056]
如果mcu有p0口,可将数组中第0个元素的0值改为“(char*)p0”等类似语句;
[0057]
不同类型的mcu,可查询mcu的头文件来获得对io口功能地址(指针)的定义名称;
[0058]
如果还有pxsel等需要,相应增加指针变量数组“*pxsel”的定义即可。
[0059]
本实施例中,步骤2中,设置端口号及口线位对应排列的二维常量数组的方法为:
[0060]
使用一个0到m的无符号字符型变量,分别代表0到m号口线;常量数组下标[0][0]、
[0][1]元素分别存储0号口线的端口号、口线位,[m][0]、[m][1]元素分别存储m号口线的端口号、口线位;
[0061]
其中,p0到p7等端口号分别用0到7表示,口线位n写成口线所处位为“1”其它为“0”的单字节数,或写成“1左移n位”;如p15口线的端口为1,口线位5写成“0x20”或“1《《5”;
[0062]
此步骤并非必须,如果省略此步骤及常量数组,将不方便对io口线设置和程序移置、不可遍历io口线;并且需在步骤3中通过选择或判断语句逐一指定需操作的端口号及口线位。
[0063]
本实施例中,步骤3中,在对单片机io口线操作前使用一个带参数的io口设置函数,函数从步骤2中设置的二维常量数组,取出端口号值及口线位值分别写入两个8位的全局变量保存,从而指定后续的口线操作均对应某一口线;io口线设置函数参数选取步骤2中的0到m。
[0064]
其中,io口线设置函数定义后,运行此设置函数后,从常量数组中分别取端口号及口线位,暂存到口线的全局变量,从而指定后续的口线操作均对应某一口线。
[0065]
进一步地,步骤3中,取出将要操作的端口号值及口线位值分别写入两个8位的全局变量保存,这两个8位的全局变量可省略,但所述步骤3中对单片机io口线操作前使用的带参数的io口设置函数,需变成对步骤2中常量数组指针的跳转。
[0066]
本实施例中,步骤4中,在io口线操作语句写成对功能选择指针变量数组中对应的指针变量元素赋值或取值,具体方法为:
[0067]
对端口对应的指针元素赋值时,赋1值仅对口线位“或1”、赋0值仅对口线位“与0”;
[0068]
读取口线值时,端口对应的指针元素做口线位“与1”变换并增加“()”。
[0069]
实施例2
[0070]
如图3所示,上述方法流程可以进一步细化为如下步骤:
[0071]
s1、c程序初始配置:
[0072]
s1.1、定义io口操作的指令字:使用预编译代换命令define建立类似函数的io口定义,需说明的是,此步骤不是必须,但对简洁化、移植程序有帮助,建议保留;
[0073]
s1.2、定义两个8位的端口及口线位的全局变量(如不定义,可在s1.4后定义一个指向二维数组的指针,用于定位所需操作的口线);
[0074]
s1.3、创建指向io口地址指针的指针变量数组;
[0075]
s1.4、定义需使用的多个io口线二维数组表;
[0076]
s1.5、定义io口线设置函数;
[0077]
s1.6、定义操作外围设备所需的子函数(此步骤中的具体指令字是步骤s1.1的真实形式呈现);
[0078]
s1.7、定义操作外围设备所需的带参数函数;
[0079]
s2、多io口操作函数调用关系(此步骤仅为逻辑关系的反应,并非程序执行流程):
[0080]
s2.1、按io口线号指定参数调用步骤s1.7;
[0081]
s2.2、执行步骤s1.5,此步内使用步骤s1.4定义的端口表将指定的io号线号转换为口线地址和口线位值;
[0082]
s2.3、调用步骤s1.6中定义的子函数任意个、任意次;
[0083]
s2.4、编程时选择是否需要执行下一个io操作;如需操作下一下io或遍历s1.4数
组中所有io口线,返回步骤s2.1,并依次执行步骤s2.1~步骤s2.3;否则,省略此步骤;
[0084]
s2.5、调用io口操作函数结束或返回值。
[0085]
进一步地,步骤s1.3中,创建指向io口地址指针的指针变量数组的具体方法为:使用mcu头文件定义的io口地址指针,创建一维数组指针变量数组。
[0086]
进一步地,步骤s1.5中,定义io口线设置函数的具体方法为:使用函数参数tn的方法来改变并保存对应口线的全局变量,从而指定后续的io口线操作均对应某一口线;其中,全局变量为步骤s1.2中已定义的两个8位的端口及口线位的全局变量。
[0087]
其中,预先定义两个8位的全局变量端口为port_x、口线位为bit_n。
[0088]
进一步地,步骤s1.6中定义操作外围设备所需的子函数主要为但不限于每个外围设备都会使用到的若干基本的子函数。
[0089]
具体地,步骤s1.6中,定义各子函数的过程中,预编译时将各子函数中的指令字代换为步骤s1.1中定义的io口操作的指令字。
[0090]
进而,在步骤s1.7定义操作外围设备所需带参数函数之后,还可以再次定义其他操作外围设备带参数函数,此步骤中定义的函数可以与步骤s1.7中的函数相同。
[0091]
本实施例中,针对本方案的方法,值得说明的是:
[0092]
1、步骤s1.1中定义io口操作的指令字,此段程序不是必需程序;如果省略此段程序,后边程序中的dq1、dq0操作io口输出高电平、低电平,则需要换成直接用指针的操作语句分别如:*pxout_addr[port_x]|=bit_n、*pxout_addr[port_x]&=~bit_n;其它的操作类同。但是这种方法,会导致程序的可读性、灵活性变差,程序变得不简洁,所以不建议省略此段定义语句。
[0093]
2、步骤s1.1中对io口将要进行的操作包含了读取io口值、设置io口状态为输入和输出、io口输出为电平、输出低电平等;如果使用的mcu并无设置状态操作(如mcs-51单片机等)、或者后续的程序功能仅需使用输出高低电平等,可以删除不需要的操作定义。相应地,可以删除步骤s1.3中io口功能定义的指针变量,可进一步节约ram(随机存储器)空间。如果使用的mcu其存储空间足够,建议保留io口功能定义的指针变量,以方便应对同类的不同型号单片机编程。
[0094]
3、步骤s1.3中提供了一种较为通用的程序,把所选mcu的所有io口段(如p1至p6)全部写入程序,可方便大部分mcu的编程。如果mcu的代码存储空间较小、为节约代码空间等,而所用的io端口集中在p1至p3,未使用p5、p6,则可以删除p5、p6的定义,并不影响程序的运行。
[0095]
为了验证上述方案的可行性及有效性,本实施例还提供了采用常用直接操作io方式、利用c程序switch case语句实现用函数操作io的方法及本方案的利用c程序指针及函数参数实现单片机任意io口线操作方法的实验比对,具体实验如下:
[0096]
首先,值得说明的是,三种方法均以msp430f413单片机控制某数字温度传感器测温的c语言程序为例,对不同io口操作时,首先定义各个io口操作的函数或者子程序,每个子程序中直接调用不同的io;具体为以3个温度传感器分别使用p12、p31、p50等3个io口操作为例。
[0097]
方法a、常用的直接操作io方式
[0098]
a1.1、第1个传感器接p12口,定义io口指向及功能:
[0099]
定义dq1_h为拉高p12口线;
[0100]
定义dq1_l为拉低p12口线;
[0101]
定义dq1_out为改p12口线为输出;
[0102]
定义dq1_in为改p12口线为输入;
[0103]
定义dq1_vl为取p12口线电平值;
[0104]
a1.2、第2个传感器接p31,定义io口指向及功能:
[0105]
定义dq2_h为拉高p31口线;
[0106]
定义dq2_l为拉低p31口线;
[0107]
定义dq2_out为改p31口线为输出;
[0108]
定义dq2_in为改p31口线为输入;
[0109]
定义dq2_vl为取p31口线电平值;
[0110]
a1.3、第3个传感器接p50口,定义io口指向及功能:
[0111]
定义dq3_h为拉高p50口线;
[0112]
定义dq3_l为拉低p50口线;
[0113]
定义dq3_out为改p50口线为输出;
[0114]
定义dq3_in为改p50口线为输入;
[0115]
定义dq3_vl为取p50口线电平值;
[0116]
a1.4、第1个传感器的部分程序流程:
[0117]
a1.4.1、复位1#口线传感器子程序:开始——dq1_out——dq1_l——延时600μs——dq1_h——延时30μs——dq1_in——空指令——dq1_out——dq1—_h——延时400μs——返回;
[0118]
a1.4.2、写入1#口线传感器一个字节操作函数流程:开始——循环8次【dq0——延时6μs——如果写入数末位是1,dq1_h/否则,dq1_l——写入数右移1位——延时30μs——dq1_h——延时10μs】——返回;
[0119]
a1.4.3、读取1#口线传感器一个字节函数流程:开始——循环8次【值右移1位——dq1_l——dq1_h——dq1_in——如果dq1_val为1,值高位写1——dq1_out——dq1_h——延时2μs】——返回值;
[0120]
a1.4.4、读取1#口线传感器值(两个字节)的函数流程如下:开始——定义温度值变量——调用read_1byte()读低8位——调用read_1byte()读高8位——合并值——换算值等等——返回值;
[0121]
a1.4.5、启动1#口线传感器温度转换函数流程如下:开始——调用a1.4.1复位io口——调用a1.4.2写入1字节——a1.4.2写入1字节——返回;
[0122]
a1.4.6、读取1#口线传感器温度值的函数流程如下:开始——a1.4.1复位io口——a1.4.2写入1字节——a1.4.2写入1字节——a1.4.4读取值(两个字节)——返回值;
[0123]
a1.4.7、其它1#口线子程序:其它代码——dq1等语句——其它代码;
[0124]
a1.5、第2个传感器的部分程序流程:
[0125]
a1.5.1、复位2#口线传感器子程序:a1.4.1中dq1换成dq2,其它类同;
[0126]
a1.5.2、写入2#口线传感器一个字节操作函数流程:a1.4.2中dq1换成dq2,其它类同;
[0127]
a1.5.3、读取2#口线传感器一个字节函数流程:a1.4.3中dq1换成dq2,其它类同;
[0128]
a1.5.4、读取2#口线传感器值(两个字节)的函数流程如下:a1.4.4中dq1换成dq2,其它类同;
[0129]
a1.5.5、启动2#口线传感器温度转换函数流程如下:开始——调用a1.5.1复位io口——调用a1.5.2写入1字节——a1.5.2写入1字节——返回;
[0130]
a1.5.6、读取2#口线传感器温度值的函数流程如下:开始——a1.5.1复位io口——a1.5.2写入1字节——a1.5.2写入1字节——a1.5.4读取值(两个字节)——返回值;
[0131]
a1.5.7、其它2#口线传感器子程序:其它代码——dq2等语句——其它代码;
[0132]
a1.6、第3个传感器的部分程序流程:
[0133]
a1.6.1、复位3#口线传感器子程序:a1.4.1中dq1换成dq3,其它类同;
[0134]
a1.6.2、写入3#口线传感器一个字节操作函数流程:a1.4.2中dq1换成dq3,其它类同;
[0135]
a1.5.3、读取3#口线传感器一个字节函数流程:a1.4.3中dq1换成dq3,其它类同;
[0136]
a1.6.4、读取3#口线传感器值(两个字节)的函数流程如下:a1.4.4中dq1换成dq3,其它类同;
[0137]
a1.6.5、启动3#口线传感器温度转换函数流程如下:开始——调用a1.6.1复位io口——调用a1.6.2写入1字节——a1.6.2写入1字节——返回;
[0138]
a1.6.6、读取3#口线传感器温度值的函数流程如下:开始——a1.6.1复位io口——a1.6.2写入1字节——a1.6.2写入1字节——a1.6.4读取值(两个字节)——返回值;
[0139]
a1.6.7、其它3#口线传感器子程序:其它代码——dq3等语句——其它代码。
[0140]
上述方法是一种常用方法,从a1.2到a1.3与a1.1的代码重复,从a1.5到a1.6的代码与a1.4是除了io口线不同外,操作流程和功能完全类似,代码重复。
[0141]
由于a方法会造成大量代码重复,并进一步带来很多缺点,我们最先测试并使用c程序switch case分支选择语句来分别调用不同的io口,即下述方法b。
[0142]
b、利用c程序switch case实现用函数操作io的方法
[0143]
b2.1、使用预编译代换命令define建立类似函数的io口定义:
[0144]
#define p1(dioii)p1##dioii
[0145]
……
(类同上)
[0146]
#define p6(dioii)p6##dioii
[0147]
b2.2、定义两个8位的端口及口线位的全局变量:
[0148]
此变量用于暂存将要对温度传器操作的io口线号,端口为port_x,口线位为bit_n;如p32对应port_x值为3,bit_n值为0x04;程序如下:
[0149]
unsigned char port_x,bit_n;
[0150]
b2.3、定义5个口线操作的无参数函数,分别是:a.设置口线为输出函数dq_out();b.设置口线为输入的函数dq_in();c.输出为高电平(拉高)函数dq1();d.输出为低电平(拉低)的函数dq0();e.读取口线值的函数dq_val();“()”代表是c程序无参数函数,下同;
[0151]
其中设置口线为输出的函数如下:
[0152][0153]
其它4个函数,因为io口线操作需要使用到,则必须要定义;其中,dq_in()、dq1()、dq0()、dq_val()等4个函数分别用px(dir)&=~bit_n、px(out)|=bit_n、px(out)&=~bit_n、return(px(in)&bit_n)代替,函数中px的x为1~6,其它类同;如果还有功能选择px(sel)等操作,需一并定义;
[0154]
b2.4、定义3个传感器的不同口线常量二维数组表,如下:
[0155][0156][0157]
b2.5、定义口线配置函数,使用函数参数tn的方法来改变并保存对应口线的全局变量(见b2.2),从而指定后续的口线操作对应某一口线,程序如下:
[0158][0159]
b2.6、定义3个传感器操作函数,分别是:(1)复位操作函数reset();(2)写入一个字节函数write_1byte(unsigned char wdata);(3)读取传感器一个字节函数read_1byte
();
[0160]
其中复位函数流程:
[0161]
开始——dq_out()——dq0()——延时600μs——dq1()——延时30μs——dq_in()——空指令——dq_out()——dq1()——延时400μs——返回;
[0162]
其中传感器口线写入1字节操作函数流程:
[0163]
开始——循环8次【dq0()——延时6μs——如果写入数末位是1,dq1()/否则,dq0()——写入数右移1位——延时30μs——dq1()——延时10μs】——返回;
[0164]
其中读取传感器一个字节函数流程:
[0165]
开始——循环8次【值右移1位——dq0()——dq1()——dq_in()——如果dq_val()为1,值高位写1——dq_out()——dq1()——延时2μs】——返回值;
[0166]
上述3个函数流程中“()”代表是一个函数,即在流程中再次调用了一个函数;可看出调用函数很多,调用层级增加;
[0167]
b2.7、定义读取传感器温度值函数signed int readtempe(),函数流程如下:
[0168]
开始——定义温度值变量——调用read_1byte()读低8位——调用read_1byte()读高8位——合并值——换算为摄氏度——返回;
[0169]
b2.8、定义启动其中一个传感器温度转换的函数,参数tn为传感器的不同口线表中0、1、2等各个传感,程序如下:
[0170][0171]
b2.9、定义读取其中一个传感器温度值的函数,参数tn为传感器的不同口线表中0、1、2等各个传感,程序如下:
[0172][0173]
方法c、利用c程序指针及函数参数实现单片机任意io口线操作
[0174]
c3.1、定义io口操作的指令字,程序如下:
[0175][0176][0177]
需要注意的是,上述程序假设对任意一个io口将要进行的操作为dq_val取io口值、dq_out设置为输出、dq_in设置为输入、dq1输出为高电平(拉高)、dq0输出低电平(拉低)等共5种,已涵盖大部分io口操作;如果还有功能选择(选通)pxsel等需要,相应增加定义即可;另外,第一行语句中无“=”号,且“()”必须要;
[0178]
c3.2、定义两个8位的端口及口线位的全局变量:
[0179]
此变量用于暂存将要操作的io口线号,端口为port_x,口线位为bit_n;如p31对应port_x值为3,bit_n值为0x02;程序如下:
[0180]
unsigned char port_x,bit_n;
[0181]
c3.3、使用mcu头文件定义的io口地址指针,创建一维数组指针变量数组,假设mcu的所有io口是p1~p6,程序如下:
[0182]
[0183][0184]
需要注意的是,上述程序,如果此mcu没有p6口,则删除p6的定义;如果有p7口则可增加p7的定义;不同类型的mcu,可查询mcu的头文件来获得对io口功能寄存器地址(指针)的定义名称;如果还有pxsel等需要,相应增加指针变量数组定义即可;如果mcu有p0口,可将数组中第0个元素的0值改为(char*)p0等类似语句;
[0185]
c3.4、定义需使用的多个io口线二维数组表,如需使用p12、p31、p50共3个io口,则程序如下:
[0186]
[0187][0188]
c3.5、定义io口线设置函数,使用函数参数tn的方式来改变并保存对应口线的全局变量(c3.2已定义),从而指定后续的口线操作均对应某一口线,程序如下:
[0189][0190]
c3.6、定义操作外围设备所需的子函数:
[0191]
以某单总线传感器为例,假设有3个传感器分别接在c3.4中定义的io口上;现每个传感器都会使用到3个基本的子个函数,分别是:(1)复位操作函数reset();(2)写入一个字节函数write_1byte(unsigned char wdata);(3)读取传感器一个字节函数read_1byte();
[0192]
c3.6.1、其中复位函数流程:
[0193]
开始——dq_out——dq0——延时600μs——dq1——延时30μs——dq_in——空指令——dq_out——dq1——延时400μs——返回;
[0194]
需要注意的是,io口的操作对比b方式已不是无参数函数的调用,再进行分支选择后操作;而是直接用了io口地址指针的方式操作,程序运行速度极快;下同;
[0195]
c3.6.2、其中传感器口线写入1字节操作函数流程:
[0196]
开始——循环8次【dq0——延时6μs——如果写入数末位是1,dq1/否则,dq0——写入数右移1位——延时30μs——dq1——延时10μs】——返回;
[0197]
c3.6.3、其中读取传感器一个字节函数流程:
[0198]
开始——循环8次【值右移1位——dq0——dq1——dq_in——如果dq_val为1,值高位写1——dq_out——dq1——延时2μs】——返回值;
[0199]
c3.7、定义读取外围设备值(两个字节)的函数signed int readtempe(),函数流程如下:
[0200]
开始——定义温度值变量——调用read_1byte()读低8位——调用read_1byte()读高8位——合并值——换算值等等——返回;
[0201]
c3.8、定义启动其中一个传感器温度转换的带参数函数,参数tn为传感器的不同口线表中0、1、2等各个传感,程序如下:
[0202][0203]
c3.9、定义读取某一个传感器温度值的带参数函数,参数tn为传感器的不同口线表中0、1、2等各个传感,程序如下:
[0204][0205]
至此,对3个io口各种操作的程序已实现。
[0206]
通过实验对比可以得出,方法a及方法b中存在的缺点和不足包括:
[0207]
1、常用方法a中,根据需操作的io口数量增加,会增加大量重复代码,占用大量存储空间,且非常不利于同类程序的调试和维护;
[0208]
2、常用方法a中,如果在io口线通信中由于线缆材料或型式的不当选取、通信距离的延长等因素,造成串行数据波形发生畸变,导至通信数据错误,此时如果需调整通信时序(如延时参数等),则需要分别对不同io口的多个子程序(或函数)进行调整,调试工作量大大增加;
[0209]
3、创新方法b中,使用switch case分支语句对不同io口操作,虽然实现了使用函数形参方式操作不同io口线,不需要重复同类型代码,但因为函数调用及分支选择次数增多,程序执行代码量增加,系统运行速度减慢,执行时间增长,导致整个系统的反应不及时;在一些要求时序较严格的运用中,此方法常常会导致外围设备时序逻辑错误,或者串行通讯数据错误;在利用某数字温度传感器测温的实际运用中,发现这种方法会错过15μs的读时间隙,即通信时序错误,并最终导致数据错误。
[0210]
此外,根据本方案的方法及上述对比实验,值得说明的是:
[0211]
1、本方案的核心内容为利用c程序指针定义表和带参数函数方式操作(含访问、控制、选通等)io口线的方法;
[0212]
2、操作一个或多个io口,当选用同一总线io口时,如果使用总线值(0x00到0xff)操作整条总线,则说明没有使用本方案的方法;如果还是使用了指针定义表和带参数函数两者结合的方式,则说明使用了本方案的方法;
[0213]
3、利用指针的指针,具体地,是利用指向io口地址指针的单个指针或指针表重新定义io口操作功能的方法;
[0214]
4、本方法中的示例程序、流程图等均为了说明程序逻辑思路及论证本方法的创新,本领域的专业技术人员应当知道,程序的变量名、函数名、子程序名等定义可根据个人习惯和偏好来随意命名,这些名称的改变并不说明未使用案方法。
[0215]
如图4所示,本实施例还提供了一种方法运行平台装置,该装置包括处理器、存储器以及存储在存储器中并在处理器上运行的计算机程序。
[0216]
处理器包括一个或一个以上处理核心,处理器通过总线与存储器相连,存储器用于存储程序指令,处理器执行存储器中的程序指令时实现上述的利用c程序指针及函数参数实现单片机任意io口线操作的方法的步骤。
[0217]
可选的,存储器可以由任何类型的易失性或非易失性存储设备或者它们的组合实现,如静态随机存取存储器(sram),电可擦除可编程只读存储器(eeprom),可擦除可编程只读存储器(eprom),可编程只读存储器(prom),只读存储器(rom),磁存储器,快闪存储器(flash rom),铁电存储器(fram)等。
[0218]
此外,本发明还提供一种计算机可读存储介质,计算机可读存储介质存储有计算机程序,计算机程序被处理器执行时实现上述的利用c程序指针及函数参数实现单片机任意io口线操作的方法的步骤。
[0219]
可选的,发明还提供了一种包含指令的计算机程序产品,当其在计算机上运行时,使得计算机执行上述各方面利用本c程序指针及函数参数实现单片机任意io口线操作的方法的步骤。
[0220]
本领域普通技术人员可以理解,实现上述实施例的全部或部分步骤的过程可以通过硬件来完成,也可以通过程序来指令相关的硬件完成,程序可以存储于计算机可读存储介质中,上述提到的存储介质可以是上述提到的存储介质可以是只读存储器、可擦写存储器等。
[0221]
以上显示和描述了本发明的基本原理、主要特征和本发明的优点。本行业的技术人员应该了解,本发明不受上述实施例的限制,上述实施例和说明书中描述的仅为本发明的优选例,并不用来限制本发明,在不脱离本发明精神和范围的前提下,本发明还会有各种变化和改进,这些变化和改进都落入要求保护的本发明范围内。本发明要求保护范围由所附的权利要求书及其等效物界定。
再多了解一些

本文用于创业者技术爱好者查询,仅供学习研究,如用于商业用途,请联系技术所有人。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献