STM32F1开发标准教程 课件 ch17实验16-ADC_第1页
STM32F1开发标准教程 课件 ch17实验16-ADC_第2页
STM32F1开发标准教程 课件 ch17实验16-ADC_第3页
STM32F1开发标准教程 课件 ch17实验16-ADC_第4页
STM32F1开发标准教程 课件 ch17实验16-ADC_第5页
已阅读5页,还剩68页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验16——ADC卓越工程师培养系列本书获深圳大学教材出版资助STM32F1开发标准教程第十七章01实验内容实验内容编写程序实现以下功能:①将PA4引脚通过杜邦线连接到PA1引脚;②通过ADC1对PA1引脚的模拟信号量进行采样和模数转换;③将转换后的数字量按照PCT通信协议进行打包;④通过STM32核心板的UART1实时将打包后的数据发送至计算机;⑤通过计算机上的信号采集工具(位于本书配套资料包的“08.软件资料信号采集工具.V1.0”文件夹中)动态显示接收到的波形。将STM32F103RCT6芯片的PA1引脚配置为ADC1输入端口02实验原理1.ADC功能框图ADC的输入范围在VREF-和VREF+之间,VDDA和VSSA分别是ADC的电源和地。ADC的参考电压也称为基准电压,如果没有基准电压,就无法确定被测信号的准确幅值例如,基准电压为5V,分辨率为8位的ADC,则当被测信号电压达到5V时,ADC输出满量程读数,即255,就代表被测信号电压等于5V,如果ADC输出127,就代表被测信号电压等于2.5V。不同的ADC,有的是外接基准,有的是内置基准无须外接,还有的ADC外接基准和内置基准都可以用,但外接基准优先于内置基准。1.ADC的电源与参考电压1.ADC功能框图表17-1是STM32的ADC参考电压,VDDA和VSSA建议分别连接到VDD和VSS。STM32的参考电压负极是需要接地的,即VREF=0V,而参考电压正极的范围为2.4V≤VREF+≤3.6V,所以STM32的ADC是不能直接测量负电压的,而且其输入的电压信号的范围为VRSF≤VIN≤VRSF+。当需要测量负电压或被测电压信号超出范围时,要先经过运算电路进行抬高或利用申阻进行分压。需要注意的是,STM32核心板上的STM32F103RCT6芯片的V通过内部连接在VoDA,VEF-通过内部连接在VssA。由于STM32核心板上的VDDA电压为3.3V,VssA电压为0V,因此,VREF+电压为3.3V,VREF-电压为0V。1.ADC的电源与参考电压1.ADC功能框图1)ADC时钟STM32的ADC输入时钟ADC_CLK由PCLK2经过分频产生,最大为14MHZ,本实验中,PCLK2为72MHz,ADC_CLK为PCLK2的6分频,因此,ADC输入时钟为12MHz。ADCCLK的时钟分频系数可以通过RCCCFGR进行更改也可以通过RCCADCCLKConfi函数进行更改。2.ADC时钟及其转换时间1.ADC功能框图2)ADC转换时间ADC使用若ADC_CLK周期对输入电压采样采样周期数目可以通过ADC_SMPR1和ADC_SMPR2中的SMPx[2:0]位进行配置,当然,也可以通过ADC_RegularChannelConfig函数进行更改。每个通道可以分别用不同的时间采样。ADC的总转换时间可以根据如下公式计算:2.ADC时钟及其转换时间1.ADC功能框图2)ADC转换时间其中,采样时间可以配置为1.5、7.5、13.5、28.5、41.5、55.5、71.5、239.5个ADC时钟周期。本实验的ADC时钟是12MHz,即ADC_CLK-12MHz,采样时间为239.5个ADC时钟周期,则计算ADC的总转换时间TCONV如下:2.ADC时钟及其转换时间1.ADC功能框图STM32的ADC有多达18个通道,可以测量16个外部通道(ADCx_INO~ADCx_IN15)和2个内部通道(温度传感器和VREFINT)。本实验中,用到的ADC通道是ADC1IN1,该通道与PA1引脚相连接。3.ADC输入通道1.ADC功能框图STM32的ADC支持外部事件触发转换,包括内部定时器触发和外部IO发。本实验中,使用TIM3进行触发,该触发源通过ADC控制寄存器2,即ADC_CR2的EXTSELI[2:0]进行选择,选择好该触发源后,还需要通过ADC_CR2的EXTTRIG对触发源进行使能。4.ADC触发源1.ADC功能框图模拟至数字转换器是ADC的核心单元,模拟量在该单元被转换为数字量。模拟至数字转换器有2个通道组,分别是规则通道组和注入通道组。规则通道相当于正常运行的程序,而注入通道就相当于中断。本实验中,仅用到了规则通道组,未用到注入通道组。5.模拟至数字转换器1.ADC功能框图模拟量在模拟至数字转换器中转换成数字量之后,规则通道组的数据存放在ADC_DR中注入组的数据存放在ADCJDRX中。由于本实验仅用到了规则通道组,因此,数字量存放在ADC_DR中,该寄存器是一个32位的寄存器,只有低16位有效。然而,ADC的分辨率是12位,因此,转换后的数字量可以按照左对齐进行存储,也可以按照右对齐进行存储,具体按照哪种方式进行存储,还需要通过ADC_CR2的ALIGN进行设置。6.数据寄存器1.ADC功能框图前文讲过,规则通道最多可以对16个信号源进行转换,然而用于存放规则通道组的ADC_DR只有1个,如果对多个通道进行转换,旧的数据就会被新的数据覆盖,因此,每完成一次转换都需要立刻将数据取走,或开启DMA模式,把数据转存至SRAM。本实验中,只对外部通道ADC_1IN1(与引脚PA1相连)进行采和转换,每次转换完之后,都会通过DMA1的通道1转存到SRAM,即s_arrADC1Data变量进一步在TIM3的中断服务函数又会将s_arrADC1Data变量写入ADC缓冲区,即s_structADCCirQue循环队列,应用层根据需要再从ADC缓冲区读取转换后的数字量。6.数据寄存器2.ADC实验逻辑框图分析图17-2是ADC实验逻辑框图,在该实验中,TIM3设置为ADC1的发源,每8ms触发一次,用于对ADC1_CH1即PA1的模拟信号量进行模数转换。每次转换结束后,DMA控制器会把ADC_DR中的数据通过DMA1传送到SRAM,即s_arTADC1Data变量。TIM3每8ms在中断服务函数,通过WriteADCBuf函数将sarTADC1Data变量值存放至s_structADCCirQue缓冲区,该缓冲区是一个循环队列,应用层可以通过ReadADC_Buf函数读取s_structADCCirQue缓冲区中的数据由于图17-2中灰色部分的代码由本书配套的资料包提供,因此,在开展本实验时,只需要完成ADC采样和处理部分即可。3.ADC实验中的ADC缓冲区如图17-3所示,本实验中,ADC将模拟信号量转换为数字信号量,转换结束后,产生个DMA请求再由DMA1将ADCDR中的数据传送到SRAM,即变量saADC1Data。TIM3除了用于触发ADC1,同时,每8ms还产生一次中断在TIM3IRQHandler中断服务函数中,通过WriteADCBuf函数将变量s_arrADC1Data写入ADC缓冲区,即结构体变量s_structADCCirOue。在微控制器应用层,用户可以通过ReadADCBuf函数读取ADC缓区。写ADC缓冲区实际上是间接调用EnU160ueue函数实现的,读ADC缓冲区实际上是间接调用DeU16Queue函数实现的。ADC缓冲区的大小由ADC1_BUF_SIZE决定,本实验中,ADC1_BUFSIZE取100,即ADC缓冲区大小为100,该缓冲区的变量类型为unsignedshort型。4.ADC部分寄存器ADC_CR1的结构偏移地址和复位值如图17-4所示对部分位的解释说明如表17-2所示。1.控制寄存器1(ADC_CR1)4.ADC部分寄存器ADC_CR2的结构、偏移地址和复位值如图17-5所对部分位的解说明如表17-3所示。2.控制寄存器2(ADC_CR2)4.ADC部分寄存器ADC_SMPR1的结构偏移地址和复位值如图17-6所示,对部分位的解释说明如表17-4所示。3.采样时间寄存器1(ADC_SMPR1)4.ADC部分寄存器ADC_SMPR2的结构偏移地址和复位值如图17-7所对部分位的解释说明如表17-5所示。4.采样时间寄存器2(ADC_SMPR2)4.ADC部分寄存器ADC_SQR1的结构、偏移地址和复位值如图17-8所示,对部分位的解说明如表17-6所示。5.规则序列寄存1(ADC_SQR1)4.ADC部分寄存器ADC_SQR2的结构偏移地址和复位值如图17-9所示对部分位的解释说明如表17-7所示。6.规则序列寄存器2(ADC_SQR2)4.ADC部分寄存器ADC_SQR3的结构偏移地址和复位值如图17-10所对部位的解释说明如表17-8所示。7.规则序列寄存器3(ADC_SQR3)5.ADC部分固件库函数ADC_Init函数的功能是根据ADC_IitStruct中指定的参数初始外设ADCx的存器,通过向ADCx→CR1、ADCx→CR2、ADCx→SOR1写入参数来实现。具体描述如表17-9所示。1.ADC_Init5.ADC部分固件库函数ADC_InitTypeDef结构体定义在stm32f10x_adch文件中,内容如下:1.ADC_Init5.ADC部分固件库函数参数ADC_Mode用于设置ADC工作在独立或双ADC模式,可取值如表17-10所示。1.ADC_Init5.ADC部分固件库函数参数ADC_ScanConvMode规定了模数转换工作在扫描模式(多通道)或单次(单通道模式,可取值为ENABLE或DISABLE。参数ADC_ContinuousConvMode规定了模数转换工作在连续或单次模式,可取值头ENABLE或DISABLE。参数ADC_ExteralTrigConv用于选择某一外部触发来启动规则通道的模数转换可取值如表17-11所示。1.ADC_Init5.ADC部分固件库函数参数ADC_DataAlign规定了ADC数据向左边对齐或向右边对齐可取值如表17-12所示。参数ADC_NbrOfChannel规定了顺序进行规则转换的ADC通道数目可取值范围为1~16。1.ADC_Init5.ADC部分固件库函数ADC_RegularChannelConfig函数的功能是设置指定ADC的规则组通道,设置它们的转换顺序和采样时间通过向ADCx→SMPR1或ADCx→SMPR2以及ADCx→SOR1或ADCx→SOR2或ADCx→SOR3写入参数来实现。具体描述如表17-13所示。2.ADC_ReqularChannelConfig5.ADC部分固件库函数参数ADC_Channel用于指定调用函数ADC_RegularChannelConfig来设置的ADC通道可取值如表17-14所示。2.ADC_ReqularChannelConfig5.ADC部分固件库函数参数ADC_SampleTime用于设定选中通道的ADC采样时间,可取值如表17-15所示。。2.ADC_ReqularChannelConfig5.ADC部分固件库函数ADC_DMACmd函数的功能是使能或除能指定的ADC的DMA请求,通过向ADCx→CR2写入参数来实现。具体描述如表17-16所示。3.ADC_DMACmd5.ADC部分固件库函数ADC_ExternalTrigConvCmd函数的功能是能或除能ADCx的外部触发启动转换功能,通过向ADCx→CR2写入参数来实现。具体描述如表17-17所示。4.ADC_ExternalTrigConvCmd5.ADC部分固件库函数ADC_Cmd函数的功能是使能或除能指定的ADC,通过向ADCx→CR2写入参数来实现具体描述如表17-18所示。注意,ADC_Cmd只能在其他ADC设置函数之后被调用。5.ADC_Cmd5.ADC部分固件库函数ADC_ResetCalibration函数的功能是重置指定的ADC的校准寄存器,通过向ADCx→CR2写入参来实现。具体描述如表17-19所示。6.ADC_ResetCalibration5.ADC部分固件库函数ADC_GetResetCalibrationStatus函数的功能是获取ADC重置校准寄存器的状态,通过读取并判新ADCx→CR2来实现。具体描述如表17-20所示。7.ADC_GetResetCalibrationStatus5.ADC部分固件库函数ADC_StartCalibration函数的功能是开始指定ADC的校准通过向ADCx→CR2写入参数来实现。具体描述如表17-21所示。8.ADC_StartCalibration5.ADC部分固件库函数ADC_GetCalibrationStatus函数的功能是获取指定ADC的校准状态通过向ADCx→CR2写入参数来实现。具体描述如表17-22所示。9.ADC_GetCalibrationStatus03实验步骤步骤1:首先,将“D:STM32KeilTestlMaterial16ADC实验”文件夹复制到“D:STM32KeilTesProduct”文件夹中。然后,双击运行“D:STM32KeilTestProduct\16ADC实验Project”文夹中的STM32KeilPriuvproix,单击工具栏中的西按钮。当BwidOutut栏出现FromELF:creatinghexfile..时表示已经成功生成hex文件出现0Error(s)0Waing(s)麦示编译成功最后,将axf文件下载到STM32的内部Flash,观察STM32核心板上的两个LED是否交闪烁。如果两个LED交替闪烁,就可以进入下一步操作。复制并编译原始工程步骤2:首先,将“D:STM32KeilTest\Product\16ADC实验HWADC”文件夹中的ADCc和U16Queuec添加到HW分组,具体操作可参见2.3节步8。然后,将“D:STM32KeilTestProduct\16ADC实验HWADC”路径添加到IncludePaths栏具体操作可参见2.3节步11。添加ADC和U16Queue文件对步骤3:单击

按钮进行编译,编译结束后在Project面板中,双击ADCc下的ADCh。在ADC.文件的“包含头文件”区,添加代码#include"DataType.h"。在ADCh文件的“宏定义”区,添加如程序清单17-1所示的宏定义代码。该宏定义是ADC缓冲区大小的定义。完善ADC.h文件步骤3:在ADC.h文件的“API函数声明”区,添加如程序清单17-2所的API函数声明代码InitADC函数用于初始化ADC模块,WriteADCBuf函数用于写ADC缓冲区,ReadADCBuf函数用于读ADC缓冲区。完善ADC.h文件步骤4:在ADCc文件的“包含头文件”区的最后添加代码#include"stm32f10x_conth"和#includ"U16Queue.h”。在ADC.c文件的“内部变量”区,添加如程序清单17-3所示的内部变量定义代码。其中,数组s_arrADC1Data为图17-3中的SRAM,结构体变量s_structADCCirQue为ADC循环队列;数组s_arrADCBuf为ADC循环队列的缓冲区,该数组的大小ADC1_BUF_SIZE为缓冲区的大小。完善ADC.c文件步骤4:在ADCc文件的“内部函数声明”区,添加内部函数的声明代码,如程序清单17-4所示。ConfigADC1函数用于配置ADC1,ConfigDMA1Ch1函数用于配置DMA1的通道1ConfigTimer3函数用于配置TIM3。完善ADC.c文件步骤4:在ADCc文件的“内部函数实现”区,添加ConfigADC1函数的实现代码,如程序清单17-5所示。下面按照顺序对ConfgADC1函数中的语句进行解释说明。(1)RCCADCCLKConfig函数对PCLK2进行6分频由于本实验的PCLK2是72MHz因此,经过6分频之后,ADC输入时钟为12MHz。(2)本实验是通过ADC1对PA1引脚的信号量进行模数转换的,因此,还需要通过RCC_APB2PeriphClockCmd函数使能ADC1时钟和GPIOA时钟。(3)通过GPIO_Imit函数将PA1配置为模拟输入模式。完善ADC.c文件步骤4:(4)通过ADCInit函数对ADC1进行配置该函数涉及ADCCR1的DUALMOD3:01SCAN,以及ADCCR2的ALIGN、EXTSEL[2:01CONT,ADCSQR1的L3:0]DUALMOD3:0用于设置ADC的操作模式,SCAN用于设置扫描模式,可参见图17-4和表17-2,本实验中,ADC1配置为独立模式,且使用扫描模式。ALIGN用于设置数据对齐方式,EXTSELI2:0用于选择启动规则转换组转换的外部事件,CONT用于设置是否进行连续转换,可参见图17-5和表17-3,本实验中,ADC1采用右对齐方式,通过TIM3触发,且转换模式为单转换。L[3:01用于存储规则序列的长度,可参见图17-8和表17-6,本实验中ADC1只对PA1引脚的模拟信号量进行模数转换,因此,这里取1。完善ADC.c文件步骤4:(5)通过ADC_RegularChannelConfig函数设置规则序列1中的通道采样顺序和采样周期,该函数涉及ADC_SMPR2的SMP12:0和ADC_SOR3的SQ1T4:01SMP12:01用于选择通道1的采样时间,可参见图17-7和表17-5,本实验中,ADC1通道1的采样时间设置为239.5周期SO14:01用于设置规则序列中的第一个转换,可参见图17-10和表17-8,由于本实验只有1个采样通道,且为通道1,因此,第一个转换即为通道1。(6)通过ADC_DMACmd函数启用DMA传输,该函数涉及ADC_CR2的DMA,可参见图17-5和表17-3。完善ADC.c文件步骤4:(7)通过ADC_ExteralTrigConvCmd函数开启或禁止规则通道组转换的外部触发事件该函数涉及ADC_CR2的EXTTRIG,可参见图17-5和表17-3。本实验中ADC1使用TIM3作为触发源,因此,ADC1需要开启规则通道组转换的外部触发事件。(8)通过ADC_Cmd函数使能ADC1,该函数涉及ADC_CR2的ADON,可参见图17-5和表17-3。(9)ADC_ResetCalibration函数用于启动ADC复位校准,ADC_GetResetCalibrationStatus函数用于获取ADC复位校准状态,两个函数均涉及ADC_CR2的RSTCAL,可参见图17-5和表17-3,第一个函数用于写RSTCAL,第二个函数用于读RSTCAL。在本实验中,通过ADC_ResetCalibration函数启动ADC1复位校准之后还需要通过while语等待复位校准结束。完善ADC.c文件步骤4:(10)ADC_StartCalibration函数用于启动ADC校准,ADC_GetCalibrationStatus函数用于获取ADC校准状态,两个函数均涉及ADC_CR2的CAL,可参见图17-5和表17-3第一个函数用于写CAL,第二个函数用于读CAL。在本实验中,通过ADC_StartCalibration函数启动ADC1校准之后,还需要通过while语句等待校准结束。完善ADC.c文件步骤4:在ADCc文件的“内部函数实现”区,在ConfigADC1函数实现区的后面添加ConfigDMA1Ch1函数的实现代码,如程序清单17-6所示。下面按照顺序对ConfgDMA1Ch1函数中的语句进行解释说明。(1)本实验是通过DMA1通道1将ADC_DR中的数据传送到SRAM的因此还需要通过RCC_AHBPeriphClockCmd函数使能DMA1通道1的时钟。(2)通过DMA_DeImit函数将DMA1通道1寄存器重设为默认值。完善ADC.c文件步骤4:(3)通过DMA_Init函数对DMA1的通道1进行配置该函数涉及DMA_CCR1的DIRCIRC、PINC、MINC、PSIZE[1:0]、MSIZE[1:0]、PL1:0]、MEM2MEM,以及DMACNDTR1,还涉及DMA_CPAR1和DMA_CMAR1。DIR用于设置数据传输方向,CIRC用于设置循环方式,PINC用于设置外设地址增量模式,MINC用于设置存储器地址增量模式,PSIZET1:01用于设置外设数据宽度,MSIZE[1:01用于设置存储器数据宽度,PL[1:]用于设置通道优先级,MEM2MEM用于设置存储器模式,可参见图16-33和表16-26。本实验中,DMA1的通道将外设ADC1的数据传输到存储器SRAM,因此,传输方向是从外设读,外设不执行地址增量操作,存储器执行地址增量操作,存储器和外设数据宽度均为半字,数据传输采用循环模式,即数据传输的数目变为0时,会自动地被恢复成配置通道时设置的初值,DMA操作将会继续进行,通道优先级设置为中等,MEM2MEM设置为0,表示工作在非存储器到存储器模式。完善ADC.c文件步骤4:DMA_CPAR1是DMA1通道1外设地址寄存器DM_ACMAR1是DMA1通道1存储器地址寄存器DMA_CNDTR1是DMA1通道1传输数量寄存器可参见图16-34~图16-36表16-27~表16-29。本实验中,DMA_CPAR1写入ADC1-DR的地址DMACMAR1写入s_arrADC1Data的地址;DMA_CNDTR1写入1。(4)通过DMA_Cmd函数使能DMA1通道1,该函数涉及DMA_CCR1的EN,可参见图16-33和表16-26。完善ADC.c文件步骤4:在ADCc文件的“内部函数实现”区在ConfigDMA1Ch1函数实现区的后面添加ConfigTimer3函数的实现代码,如程序清单17-7所示。下面按照顺序对ConfgTimer3函数中的语句进行解释说明。(1)本实验中的TIM3设置为ADC1的发源,且每隔8s产生一次中断触发,因此需要通过RCC_APB1PeriphClockCmd函数使能TIM3的时钟。(2)通过TIM_TimeBaseInit函数对TIM3进行配置,该函数涉及TIM_3CR1的DIRCMS[1:0]、CKD[1:0],TIM3ARR,TIM3PSC,以及TIM3_EGR的UG。DIR用于设置计数器计数方向,CMS[1:0]用于选择中央对齐模式,CKD[1:0]用于设置时钟分频系数,可参见图7-2和表7-1。本实验中,TIM3设置为边沿对齐模式,计数器递增计数。TIM3ARR和TIM3PSC用于设置计数器的自动重装载值和预分频器的值,可参见图7-8、图7-9,以及表7-7和表7-8本实验中的这两个值通过CnfgTimer3函数的参数ar和ps来决定。UG用于产生更新事件,可参见图7-6和表7-5,本实验中将该值设置为1,用于重新初始化计数器,并产生一个更新事件。完善ADC.c文件步骤4:(3)通过TIM_SelectOutputTrigger函数将TM3的更新事件选为ADC1的触发输入,该函数涉及TIM3_CR2的MMS[2:0]。MMS[2:0]用于选择在主模式下送到从定时器的同步信息(TRGO),可参见图7-3和表7-2。(4)通过TIM_ITConfig函数使能TIM3的更新中断,该函数涉及TIM_3DIER的UIE。UIE用于禁止和允许更新中断,可参见图7-4和表7-3。本实验中,将该值设置为1,用于每8ms产生一次中断,在中断服务函数中,通过WriteADCBuf函数将s_rrADC1Data变量值存放至s_structADCCirQue缓冲区。完善ADC.c文件步骤4:(5)通过NVIC_Init函数使能TIM3的中断,同时设置抢占优先级为1,子优先级为1。(6)通过TIM_Cmd函数使能TIM3,该函数涉及TIM_3CR1的CEN,可参图7-2和表7-1。在本实验中,TIM3的参数配置完之后,就需要通过该函数使能TIM3。完善ADC.c文件步骤4:在ADCc文件的“内部函数实现”区,在ConfigTimer3函数实现区的后面添加TIM3IROHandler中断服务函数的实现代码,如程序清单17-8所示。下面按照顺序对TIM3IRQHandler函数中的语句进行解释说明。(1)通过TIM_GetITStatus函数获取TIM3更新中断标志,该函数涉及TIM3_DIER的UIE和TIM3_SR的UIF,可参见图7-4图7-5表7-3和表7-4。本实验中,UIE为1,表示使能更新中断,当TIM3递增计数产生溢出时,UIF由硬件置为1,并产生更新中断,执行TIM3_IROHandler函数,因此,在TIM3_IRQHandler函数中还需要通过TIM_ClearITPendingBit函数将UIF清零。完善ADC.c文件步骤4:(2)本实验中,TIM3_IROHandler函数是每8ms进入一次,即每8ms产生一次中断在中断服务函数中,通过WriteADCBuf函数将s_arADC1Data变量值存放至ADC的缓冲区。完善ADC.c文件步骤4:在ADCc文件的“API函数实现”区,添加API函数的实现代码如序清单17-9所示。ADC.c文件的API函数有3个,下面按照顺序对这3个函数中的语进行解释说明。(1)在InitADC函数中,通过ConfigTimer3函数配置TIM3,通过ConfigADC1函数配置ADC1,通过ConfigDMA1Ch1函数配置DMA1的通道1,最后,通过IitU16Queue函数对ADC的缓冲区进行初始化。(2)WriteADCBu函数调用入队函数EnU16Queue,将数据写入ADC缓冲区。完善ADC.c文件步骤4:(3)ReadADCBuf函数调用出队函数DeU16Queue,从ADC缓冲区读出数据。完善ADC.c文件步骤5:首先,将“D:STM32KeilTestProduct\16ADC实验ApSendDataToHost”文件夹中的SendDataToHostc添加到App分组,具体操作可参见2.3节步8。然后将“D:STM32KeilTestProduct\16ADC实验AppSendDataToHost”路径添加到IncludePaths栏,具体操作可参见2.3节步骤11。添加SendDataToHost文件对步骤6:单击

按钮进行编译,编译结束后,在Project面板中,双击SendDataToHost.c下的SendDataToHosth。在SendDataToHosth文件的“包含头文件”区,添加代码#include"DataType.h"。在SendDataToHosth文件的“API函数声明”区,添加如程序清单17-10所示的API函数声明代码。InitSendDataToHost函数用于初始化SendDataToHost模块,SendAckPack函数用于发送命令应答数据包,SendWaveToHost函数用于发送波形数据包到主机。完善SendDataToHost.h文件步骤7:在SendDataToHostc文件的“包含头文件”区的最后添加代码#include"PackUnpack.h"、#include"UART1h"。在SendDataToHostc文件的“内部函数声明”区,添加内部函数的声明代码,如程序清单17-11所示。SendPackToHost函数用于发送打包之后的数据包到主机。完善SendDataToHost.c文件步骤7:在SendDataToHost.c文件的“内部函数实现”区,添加SendPackToHost函数的实现代码如程序清单17-12所示。下面按照顺序对SendPackToHost函数中的语句进行解释说明。(1)PackData函数用于将参数pPackSent指向的打包前数据包(包含模块ID二级ID和数据)进行打包,打包之后的结果依然保存于pPackSent指向的结构体变量。(2)如果PackData函数的返回值大于0表示打包成功,则调用WriteUART1函数将打包之后的数据包通过UART1发送出去。注意pPackSent是结构体指针变量,而WriteUARTI函数的第一个参数是指向u8类型变量的指针变量,因此需要通过“(u8*)”将pPackSent强制转换为指向u8类型变量的指针变量。完善SendDataToHost.c文件步骤7:在SendDataToHostc文件的“API函数实现”区添加InitSendDataToHost、SendAckPack、SendWaveToHost函数的实现代码,如程序清单17-13所示。IitSendDataToHost函数用于初始化SendDataToHost模块,因为没有需要初始化的内容,函数体留空即可,如果后续升级版有需要初始化的代码,直接填入即可。下面按照顺序对SendAckPack和SendWaveToHost数中的语句进行解释说明。(1)定义一个StructPackType类型的结构体变量pt,用于存放打包前的数据包。(2)SendAckPack函数将MODULESYS和DATCMDACK分别赋给ptpackModuleId和ptpackSecondId,将参数moduleld、secondId和ackMsg分别赋给ptarrData[0]、pt.arrData[1]和pt.arrData[2],再将ptarrData[3]~ptarrData5]赋值为0最后调用SendPackToHost函数对结构体变量pt进行打包,并将打包之后的结果发送到主机。完善SendDataToHost.c文件步骤7:(3)SendWaveToHost函数将MODULE_WAVE和DATWA

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论