版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
系统硬件设计3.1电源硬件电路本设计中USB供电电源电路整体功能,是为整个基于ARM的智能桌面终端稳定供电。需通过电路中的电容等元件对输入电压进行稳定和滤波处理,使输出电压满足各硬件部分的工作需求,从而保障整个系统稳定运行。供电电路如图3.1所示。图3.1电源电路USB供电电源电路选用USB接口SW1引入5V电源输入。此5V电压会经过C1(220uF)和C2(0.1uF)电容的滤波处理,C1滤除低频纹波,C2滤除高频杂波,让电压更为纯净稳定REF_Ref8075\r\h[13]。DC-005-A200直流电源插座可提供备用电源输出接口。磁珠U5能抑制高频噪声,避免其干扰其他电路。处理后的电源为各硬件模块供电。PCB设计如图3.2所示。图3.2PCB设计3.2光敏电阻监测硬件电路在该基于ARM的智能桌面终端设计中,STM32F103C8T6核心板通过其内置的ADC(模数转换器)来读取光敏电阻的模拟信号。光敏电阻GL5528与电阻R2组成分压电路,随着环境光变化,光敏电阻阻值改变,分压值也随之变化,此变化的电压信号作为模拟信号接入核心板对应的模拟IO口。核心板将处理过的信号用于智能台灯模块的亮度调节控制。当环境光较暗时,光敏电阻阻值增大,分压值改变,核心板据此控制智能台灯自动提高亮度;环境光较亮时,阻值减小,台灯自动降低亮度,实现自动调节终端亮度的功能。光敏电阻监测硬件电路设计原理图如图3.3所示,光敏电阻监测硬件电路设计PCB图如图3.4所示。图3.3光敏电阻监测硬件电路原理图图3.4光敏电阻监测硬件电路PCB图3.3按键硬件电路按键:图中按键电路包含多个独立按键(S1-S4),这些按键是用户输入的接口,通过按下或释放操作产生电信号变化。排阻RN1(10KΩ):排阻在这里起到上拉电阻的作用。每个按键的一端连接到3V3电源,经过排阻后,在按键未按下时,与按键相连的STM32F103C8T6核心板引脚被拉高到3V3,处于高电平状态。按键硬件电路设计原理图如图3.5所示,按键硬件电路PCB图如图3.6所示。图3.5按键硬件电路原理图图3.6按键硬件电路PCB图3.4超声波传感器硬件电路超声波传感器(U4)是核心元件,它有多个引脚,包括VCC(电源正,接+5V)、GND(电源地)、Trig(触发引脚)、Echo(接收引脚)等。其功能是发射和接收超声波信号,以此来检测物体的距离、位置等信息。超声波传感器硬件电路设计原理图如图3.7所示,超声波传感器硬件电路设计PCB图如图3.8所示。图3.7超声波传感器硬件电路原理图图3.8超声波传感器硬件电路PCB图3.5存储模块硬件电路STM32F103C8T6核心板与AT24C02芯片通过I2C总线进行通信。I2C总线是一种双线制的同步串行通信总线,由SCL时钟线和SDA数据线组成REF_Ref6614\r\h[14]。在通信过程中,核心板作为主设备,发起通信并控制时钟信号;AT24C02芯片作为从设备,响应主设备的指令。数据读写操作是关于当核心板需要读取存储在AT24C02芯片中的数据时,会先发送起始信号,然后通过SDA线发送芯片地址和读操作命令,等待芯片响应。芯片确认地址匹配后,会将存储的数据通过SDA线逐位返回给核心板。当核心板需要向芯片写入数据时,同样先发送起始信号,接着发送芯片地址和写操作命令,随后通过SDA线将需要写入的数据逐位发送给芯片。芯片接收到数据后,会将其存储在内部的存储单元中。超声波传感器硬件电路设计原理图如图3.9所示,超声波传感器硬件电路设计PCB图如图3.10所示。图3.9存储模块硬件电路原理图图3.10存储模块硬件电路PCB图3.6MOS管驱动硬件电路STM32F103C8T6核心板通过PB6引脚输出PWM(脉冲宽度调制)信号。PWM信号是一种周期性的方波信号,通过改变方波的高电平持续时间(即占空比)来实现对输出信号的控制。MOS管的导通与截止
是当核心板输出的PWM信号为高电平时,电流通过电阻R4流入MOS管的栅极,使栅极电压升高。对于N沟道增强型MOS管(如S2302-HXY),当栅极电压(Vgs)高于其阈值电压时,MOS管导通。此时,漏极和源极之间形成低电阻通路,+5V电源通过MOS管为灯板供电,灯板点亮。当PWM信号为低电平时,MOS管栅极电压降低,低于阈值电压后,MOS管截止,漏极和源极之间的通路断开,灯板熄灭。MOS管驱动硬件电路设计原理图如图3.11所示,MOS管驱动硬件电路设计PCB图如图3.12所示。图3.11MOS管驱动硬件电路原理图图3.12MOS管驱动硬件电路PCB图3.7语音模块硬件电路STM32F103C8T6核心板根据智能桌面终端的不同功能需求,如检测到人体姿态不正、距离过近或达到疲劳提醒时间等情况时,通过SPI接口向语音模块U3发送相应的语音播报指令和文本信息。例如,当超声波传感器检测到人体姿态不正,核心板会将“请调整坐姿”等文本信息及播报指令发送给语音模块。语音模块U3接收到核心板发送的指令和文本信息后,内部的语音合成芯片会根据预设的语音合成算法,将文本信息转换为对应的语音信号。这些语音信号经过模块内部的放大电路等处理后,驱动连接的喇叭(CN1)发出声音,实现语音提醒功能。比如将文字“工作学习时间过长请注意劳逸结合”转换为语音播放出来。语音模块硬件电路设计原题图如图3.13所示,语音模块硬件电路设计原题图如图3.14所示。图3.13语音模块硬件电路原理图图3.14语音模块硬件电路PCB图系统软件设计系统软件设计应用于基于ARM的智能桌面终端设计的流程图设计如下图4.1所示。系统整个流程包括系统初始化、进入主循环、读取按键、读取传感器和更新显示等环节,以实现智能桌面终端的应用。图4.1系统软件设计流程图搭建环境本设计采用KeiluVision5编程软件,Keil5是由德国KS公司开发的ARM编程环境,可以对8051和AR内核的芯片进行编程操作内部包含汇编语言、C++和C语言,极大地提高了开发效率。KeiluVision5的操作界面如下图4.2所示。图4.2KeiluVision5的操作界面程序下载选用ST-LINK/V2调试器,ST-LINK/V2可以在线对STM32进行调试,包括设置断点和全速运行,可以用于电路组件值的返回、I/O信号波形的提供、电流误差图表的提供以及高侧电流感应等功能。如图4.3ST-LINK/V2调试器所示。图4.3ST-LINK/V2调试器4.3程序设计4.3.1OLED12864显示屏的驱动代码实现了OLED12864显示屏的基本驱动功能,包括初始化、I2C通信、字符和汉字的显示。通过定义不同的字符点阵数据数组,代码能够灵活地显示各种字符和汉字。同时,代码中使用了一些宏定义和结构体来配置GPIO和I2C通信,提高了代码的可读性和可维护性REF_Ref11318\n\h[16]。部分代码如下:voidOLED_IIC_Start(void){OLED_SCL(1);OLED_SDA(1);OLED_SDA(0);OLED_SCL(0);}voidOLED_IIC_Stop(void){OLED_SCL(0);OLED_SDA(0); OLED_SCL(1);OLED_SDA(1);}voidWrite_IIC_Byte(unsignedcharIIC_Byte){ unsignedchari; for(i=0;i<8;i++) { if(IIC_Byte&0x80) OLED_SDA(1); else OLED_SDA(0); //delay_us(1); OLED_SCL(1); OLED_SCL(0); IIC_Byte<<=1; } OLED_SDA(1);__NOP();__NOP(); OLED_SCL(1);__NOP();__NOP(); OLED_SCL(0);__NOP();__NOP(); }4.3.2串口通信程序代码围绕STM32的串口通信功能展开,基于HAL库实现了对UART1、UART2和UART3的初始化、数据发送以及接收中断处理等操作,定义了与三个串口(UART1、UART2、UART3)相关的全局变量,用于存储接收的原始数据、处理后的数据以及接收状态标志,还定义了串口句柄结构体变量,用于配置和操作串口REF_Ref8794\r\h[15]。串口数据发送函数字节发送函数:voidUART1_SendStr(char*s){HAL_UART_Transmit(&UART1_Handle,(uint8_t*)s,strlen(s),1000);while(__HAL_UART_GET_FLAG(&UART1_Handle,UART_FLAG_TC)!=SET);}voidUART2_SendByte(uint8_tbyte){HAL_UART_Transmit(&UART2_Handle,&byte,1,1000);while(__HAL_UART_GET_FLAG(&UART2_Handle,UART_FLAG_TC)!=SET);}voidUART3_SendByte(uint8_tbyte){HAL_UART_Transmit(&UART3_Handle,&byte,1,1000);while(__HAL_UART_GET_FLAG(&UART3_Handle,UART_FLAG_TC)!=SET);}这三个函数功能相似,分别用于通过对应的串口(UART1、UART2、UART3)发送一个字节数据。借助HAL_UART_Transmit函数发送数据,并通过循环检测发送完成标志位(UART_FLAG_TC
),确保数据发送完成。字符串发送函数:voidUART1_SendStr(char*s){HAL_UART_Transmit(&UART1_Handle,(uint8_t*)s,strlen(s),1000);while(__HAL_UART_GET_FLAG(&UART1_Handle,UART_FLAG_TC)!=SET);}voidUART2_SendStr(char*s){HAL_UART_Transmit(&UART2_Handle,(uint8_t*)s,strlen(s),1000);while(__HAL_UART_GET_FLAG(&UART2_Handle,UART_FLAG_TC)!=SET);}voidUART3_SendByte(uint8_tbyte){HAL_UART_Transmit(&UART3_Handle,&byte,1,1000);while(__HAL_UART_GET_FLAG(&UART3_Handle,UART_FLAG_TC)!=SET);}分别实现了通过UART1、UART2、UART3发送字符串的功能。先使用HAL_UART_Transmit函数发送字符串数据,再等待发送完成标志位,保证字符串完整发送。串口初始化函数voidUART1_init(uint32_tbaudrate){UART1_Handle.Instance=USART1;UART1_Handle.Init.BaudRate=baudrate;UART1_Handle.Init.WordLength=UART_WORDLENGTH_8B;UART1_Handle.Init.StopBits=UART_STOPBITS_1;UART1_Handle.Init.Parity=UART_PARITY_NONE;UART1_Handle.Init.HwFlowCtl=UART_HWCONTROL_NONE;UART1_Handle.Init.Mode=UART_MODE_TX_RX;HAL_UART_Init(&UART1_Handle);HAL_UART_Receive_IT(&UART1_Handle,&UART1_Original_Data,1);}voidUART2_init(uint32_tbaudrate){UART2_Handle.Instance=USART2;UART2_Handle.Init.BaudRate=baudrate;UART2_Handle.Init.WordLength=UART_WORDLENGTH_8B;UART2_Handle.Init.StopBits=UART_STOPBITS_1;UART2_Handle.Init.Parity=UART_PARITY_NONE;UART2_Handle.Init.HwFlowCtl=UART_HWCONTROL_NONE;UART2_Handle.Init.Mode=UART_MODE_TX_RX;HAL_UART_Init(&UART2_Handle);HAL_UART_Receive_IT(&UART2_Handle,&UART2_Original_Data,1);}voidUART3_init(uint32_tbaudrate){UART3_Handle.Instance=USART3;UART3_Handle.Init.BaudRate=baudrate;UART3_Handle.Init.WordLength=UART_WORDLENGTH_8B;UART3_Handle.Init.StopBits=UART_STOPBITS_1;UART3_Handle.Init.Parity=UART_PARITY_NONE;UART3_Handle.Init.HwFlowCtl=UART_HWCONTROL_NONE;UART3_Handle.Init.Mode=UART_MODE_TX_RX;HAL_UART_Init(&UART3_Handle);HAL_UART_Receive_IT(&UART3_Handle,&UART3_Original_Data,1);}这三个函数分别对UART1、UART2、UART3进行初始化。设置串口的实例、波特率、数据位长度、停止位、校验位、硬件流控以及收发模式等参数,调用HAL_UART_Init函数完成初始化,并开启接收中断(HAL_UART_Receive_IT),准备接收数据。串口底层初始化函数(MSP初始化)voidHAL_UART_MspInit(UART_HandleTypeDef*huart){GPIO_InitTypeDefgpio_init_struct;if(huart->Instance==USART1){UART1_CLK_ENABLE();UART1_TX_GPIO_CLK_ENABLE();UART1_RX_GPIO_CLK_ENABLE();gpio_init_struct.Pin=UART1_TX_GPIO_PIN;gpio_init_struct.Mode=GPIO_MODE_AF_PP;gpio_init_struct.Pull=GPIO_PULLUP;gpio_init_struct.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(UART1_TX_GPIO_PORT,&gpio_init_struct);gpio_init_struct.Pin=UART1_RX_GPIO_PIN;gpio_init_struct.Mode=GPIO_MODE_AF_INPUT;HAL_GPIO_Init(UART1_RX_GPIO_PORT,&gpio_init_struct);HAL_NVIC_EnableIRQ(USART1_IRQn);HAL_NVIC_SetPriority(USART1_IRQn,3,3);}if(huart->Instance==USART2){UART2_CLK_ENABLE();UART2_TX_GPIO_CLK_ENABLE();UART2_RX_GPIO_CLK_ENABLE();gpio_init_struct.Pin=UART2_TX_GPIO_PIN;gpio_init_struct.Mode=GPIO_MODE_AF_PP;gpio_init_struct.Pull=GPIO_PULLUP;gpio_init_struct.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(UART2_TX_GPIO_PORT,&gpio_init_struct);gpio_init_struct.Pin=UART2_RX_GPIO_PIN;gpio_init_struct.Mode=GPIO_MODE_AF_INPUT;HAL_GPIO_Init(UART2_RX_GPIO_PORT,&gpio_init_struct);HAL_NVIC_EnableIRQ(USART2_IRQn);HAL_NVIC_SetPriority(USART2_IRQn,3,3);}if(huart->Instance==USART3){UART3_CLK_ENABLE();UART3_TX_GPIO_CLK_ENABLE();UART3_RX_GPIO_CLK_ENABLE();gpio_init_struct.Pin=UART3_TX_GPIO_PIN;gpio_init_struct.Mode=GPIO_MODE_AF_PP;gpio_init_struct.Pull=GPIO_PULLUP;gpio_init_struct.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(UART3_TX_GPIO_PORT,&gpio_init_struct);gpio_init_struct.Pin=UART3_RX_GPIO_PIN;gpio_init_struct.Mode=GPIO_MODE_AF_INPUT;HAL_GPIO_Init(UART3_RX_GPIO_PORT,&gpio_init_struct);HAL_NVIC_EnableIRQ(USART3_IRQn);HAL_NVIC_SetPriority(USART3_IRQn,3,3);}}externvoidUS100_Distance_Uart_Receive(unsignedcharReceive_Data);该函数是HAL库中串口MSP(硬件相关初始化)初始化函数。根据传入的串口句柄,分别对UART1、UART2、UART3进行硬件相关初始化,包括使能串口时钟、使能TX和RX引脚时钟,配置引脚模式(复用推挽输出或复用浮空输入)、上拉设置、速度等,以及使能对应的串口中断并设置中断优先级。串口接收中断回调函数与中断处理函数voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart){if(huart->Instance==USART1){UART1_Receive_Change=1;UART1_Receive_Data=UART1_Original_Data;HAL_UART_Receive_IT(&UART1_Handle,&UART1_Original_Data,1);}if(huart->Instance==USART2){UART2_Receive_Change=1;UART2_Receive_Data=UART2_Original_Data; US100_Distance_Uart_Receive(UART2_Receive_Data);HAL_UART_Receive_IT(&UART2_Handle,&UART2_Original_Data,1);}if(huart->Instance==USART3){UART3_Receive_Change=1;UART3_Receive_Data=UART3_Original_Data;HAL_UART_Receive_IT(&UART3_Handle,&UART3_Original_Data,1);}}当串口接收数据完成时,HAL库会调用此回调函数。根据不同的串口实例,更新接收状态标志,保存接收数据,并重新开启接收中断,准备下次接收。对于UART2,还额外调用了US100_Distance_Uart_Receive函数处理接收到的数据。voidUSART1_IRQHandler(void){HAL_UART_IRQHandler(&UART1_Handle);}voidUSART2_IRQHandler(void){HAL_UART_IRQHandler(&UART2_Handle);}voidUSART3_IRQHandler(void){HAL_UART_IRQHandler(&UART3_Handle);}这三个函数分别是UART1、UART2、UART3的中断处理函数,内部直接调用HAL库提供的HAL_UART_IRQHandler函数,由该函数处理串口中断的具体逻辑,如判断中断类型、清除中断标志等。4.3.3延时函数程序代码通过条件编译,既实现了基本的微秒和毫秒延时功能,又能在支持操作系统的情况下,合理利用操作系统的任务调度和延时机制,优化延时操作对CPU的占用。代码围绕系统滴答定时器展开,通过对定时器计数值的读取和计算,结合操作系统相关函数,实现了准确且灵活的延时功能。部分代码如下:voiddelay_us(uint32_tnus){uint32_tticks;uint32_ttold,tnow,tcnt=0;uint32_treload=SysTick->LOAD;ticks=nus*g_fac_us;#ifSYS_SUPPORT_OSdelay_osschedlock();#endiftold=SysTick->VAL;while(1){tnow=SysTick->VAL;if(tnow!=told){if(tnow<told){tcnt+=told-tnow;}else{tcnt+=reload-tnow+told;}told=tnow;if(tcnt>=ticks){break;}}}4.3.4GPIO引脚(连接LED0)的初始化配置程序代码这段代码实现了对STM32上特定GPIO引脚(连接LED0)的初始化配置,包括设置引脚的工作模式、上拉状态、输出速度,使能引脚时钟,并对引脚进行初始化。最后通过一个自定义宏控制LED0处于熄灭状态。代码结构清晰,遵循了STM32HAL库的使用规范,便于理解和维护。代码如下:voidGPIO_User_Init(void){ GPIO_InitTypeDefgpio_init_struct;gpio_init_struct.Mode=GPIO_MODE_OUTPUT_PP;gpio_init_struct.Pull=GPIO_PULLUP;gpio_init_struct.Speed=GPIO_SPEED_FREQ_HIGH;LED0_GPIO_CLK_ENABLE();gpio_init_struct.Pin=LED0_GPIO_PIN;HAL_GPIO_Init(LED0_GPIO_PORT,&gpio_init_struct); LED0(1);}4.3.5定时器程序代码这段代码实现了对STM32通用定时器的完整初始化过程,包括时钟使能、参数配置、中断优先级设置和中断使能等操作。通过这些配置,定时器可以按照设定的计数模式、预分频系数和自动重装载值进行计数,并在满足条件时触发中断,为后续基于定时器的应用(如定时任务、PWM输出等)提供了基础。部分代码如下:voidGtim_Timx_Init(uint16_tarr,uint16_tpsc){GTIM_TIMX_INT_CLK_ENABLE();g_timx_handle.Instance=GTIM_TIMX_INT;g_timx_handle.Init.Prescaler=psc;g_timx_handle.Init.CounterMode=TIM_COUNTERMODE_UP;g_timx_handle.Init.Period=arr;HAL_TIM_Base_Init(&g_timx_handle);HAL_NVIC_SetPriority(GTIM_TIMX_INT_IRQn,1,3);HAL_NVIC_EnableIRQ(GTIM_TIMX_INT_IRQn);HAL_TIM_Base_Start_IT(&g_timx_handle);}4.3.6按键程序代码这段代码实现了对STM32按键的完整处理逻辑,包括按键初始化、按键状态读取、按键长按和快速变化等第二功能的检测。代码使用状态机的方式,使按键处理逻辑清晰且易于维护。代码如下:voidKey_Acquisition(){staticunsignedcharKey_Con=0;staticunsignedcharKey_Keep;staticunsignedcharKey_Count;staticunsignedcharKey_Function_Con;switch(Key_Con){case0:{ if(Key_Pin_Read()!=0xff) { Key_Con=1; Key_Count=0; } break; }case1: { if(Key_Pin_Read()!=0xff) { switch(Key_Pin_Read()) { case0xFE:Key_Keep=1;Key_Function_Con=Key_Value_1;break; case0xFD:Key_Keep=2;Key_Function_Con=Key_Value_2;break; case0xFB:Key_Keep=3;Key_Function_Con=Key_Value_3;break; case0xF7:Key_Keep=4;Key_Function_Con=Key_Value_4;break; } Key_Con=2; } else Key_Con=0; break; }case2: { if(Key_Pin_Read()==0XFF) { Key_Con=0; Key_Count=0; Key_Change=1; Key_Value=Key_Keep; } else { if(Key_Second_Function(Key_Function_Con)!=0) { if(Key_Count<Key_Trigger_Time) Key_Count++; else { Key_Count=0; Key_Con=3; } } } break; }case3: { if(Key_Pin_Read()==0XFF) { Key_Con=0; Key_Count=0; } else { if(Key_Second_Function(Key_Function_Con)==1) { if(Key_Count<Key_Space_Time) Key_Count++; else { Key_Count=0; Key_Change=1; Key_Value=Key_Keep; } } else { if(Key_Count==0) { Key_Change=1; Key_Value=Key_Keep+0x10; Key_Count=1; } } } break; }}}4.3.7超声波模块程序代码这段代码实现了对US100超声波模块的距离和温度检测功能,通过串口与模块进行通信,接收并解析模块返回的数据。代码结构较为清晰,通过标志位和静态变量来管理数据的接收和处理过程。代码如下:voidUS100_Distance_Detect(){ UART2_SendByte(0x55); US100_Distance_EN=1;}voidUS100_Temp_Detect(){ UART2_SendByte(0x50); US100_Temp_EN=1;}voidUS100_Distance_Uart_Receive(unsignedcharReceive_Data){ staticunsignedcharReceive_Num=0; staticunsignedintDis_Num=0; if(US100_Temp_EN==1) { US100_Temp_EN=0; US100_Temp_Data=Receive_Data-45; US100_TempView[0]=US100_Temp_Data/10+0x30; US100_TempView[1]=US100_Temp_Data%10+0x30; US100_Temp_Complete=1; } else { if(US100_Distance_EN==1) { if(Receive_Num==0) { Receive_Num++; Dis_Num=Receive_Data; } else { Receive_Num=0; US100_Distance_EN=0; Dis_Num=Dis_Num<<8; Dis_Num=Dis_Num+Receive_Data; if(Dis_Num<4500) { US100_Distance_Data=Dis_Num; US100_DisView[0]=US100_Distance_Data/1000+0x30; US100_DisView[1]=US100_Distance_Data%1000/100+0x30; US100_DisView[2]=US100_Distance_Data%100/10+0x30; US100_DisView[4]=US100_Distance_Data%10+0x30; US100_Distance_Complete=1; } } } }}4.3.8模拟数字转换器程序代码这段代码实现了STM32ADC的完整操作流程,包括初始化、配置、数据读取以及获取平均值等功能。代码结构清晰,遵循了STM32HAL库的使用规范,便于理解和维护REF_Ref9058\n\h[17]。部分代码如下:voidSTM32_ADC_Init(void){g_adc_handle.Instance=ADC_ADCX;g_adc_handle.Init.DataAlign=ADC_DATAALIGN_RIGHT;g_adc_handle.Init.ScanConvMode=ADC_SCAN_DISABLE;g_adc_handle.Init.ContinuousConvMode=DISABLE;g_adc_handle.Init.NbrOfConversion=1;g_adc_handle.Init.DiscontinuousConvMode=DISABLE;g_adc_handle.Init.NbrOfDiscConversion=0;g_adc_handle.Init.ExternalTrigConv=ADC_SOFTWARE_START;HAL_ADC_Init(&g_adc_handle);HAL_ADCEx_Calibration_Start(&g_adc_handle);}4.3.9电可擦可编程只读存储器程序代码这段代码实现了对AT24CXX系列EEPROM的完整IIC通信和数据读写操作,包括IIC总线的初始化、各种信号的产生和处理、设备的初始化以及数据的单字节和多字节读写REF_Ref9130\n\h[18]REF_Ref9137\n\h[19]。代码结构清晰,逻辑严谨,遵循了IIC协议的规范。IIC初始化函数voidAT24CXX_IIC_Init(void){ GPIO_InitTypeDefgpio_init_struct; AT24CXX_IIC_SCL_GPIO_CLK_ENABLE(); AT24CXX_IIC_SDA_GPIO_CLK_ENABLE();gpio_init_struct.Pull=GPIO_PULLUP;gpio_init_struct.Speed=GPIO_SPEED_FREQ_HIGH; gpio_init_struct.Mode=GPIO_MODE_OUTPUT_PP; gpio_init_struct.Pin=AT24CXX_IIC_SCL_GPIO_PIN;HAL_GPIO_Init(AT24CXX_IIC_SCL_GPIO_PORT,&gpio_init_struct); gpio_init_struct.Mode=GPIO_MODE_OUTPUT_OD; gpio_init_struct.Pin=AT24CXX_IIC_SDA_GPIO_PIN;HAL_GPIO_Init(AT24CXX_IIC_SDA_GPIO_PORT,&gpio_init_struct); AT24CXX_IIC_SCL(1); AT24CXX_IIC_SDA(1);}该函数用于初始化IIC总线相关的GPIO引脚:使能SCL和SDA引脚对应的GPIO时钟。配置SCL引脚为推挽输出模式(GPIO_MODE_OUTPUT_PP),上拉模式(GPIO_PULLUP),高速(GPIO_SPEED_FREQ_HIGH)。配置SDA引脚为开漏输出模式(GPIO_MODE_OUTPUT_OD),上拉模式(GPIO_PULLUP),高速(GPIO_SPEED_FREQ_HIGH)。初始化完成后,将SCL和SDA引脚置为高电平。IIC总线操作函数起始信号函数代码如下:voidAT24CXX_IIC_Start(void){ AT24CXX_IIC_SDA(1); AT24CXX_IIC_SCL(1); delay_us(4); AT24CXX_IIC_SDA(0); delay_us(4); AT24CXX_IIC_SCL(0);}通过将SDA引脚从高电平变为低电平,同时保持SCL为高电平,产生IIC总线的起始信号,然后拉低SCL以准备传输数据。停止信号函数代码如下:voidAT24CXX_IIC_Stop(void){ AT24CXX_IIC_SCL(0); AT24CXX_IIC_SDA(0); delay_us(4); AT24CXX_IIC_SCL(1); AT24CXX_IIC_SDA(1); delay_us(4); } 通过将SDA引脚从低电平变为高电平,同时保持SCL为高电平,产生IIC总线的停止信号。等待应答信号函数代码如下:uint8_tAT24CXX_IIC_Wait_Ack(void){ uint8_tucErrTime=0; AT24CXX_IIC_SDA(1);delay_us(1); AT24CXX_IIC_SCL(1);delay_us(1); while(AT24CXX_READ_SDA) { ucErrTime++; if(ucErrTime>250) { AT24CXX_IIC_Stop(); return1; } } AT24CXX_IIC_SCL(0); return0;释放SDA引脚,拉高SCL引脚,等待从设备应答。如果在一定时间内(ucErrTime)没有收到应答信号,则产生停止信号并返回错误标志(1),否则返回成功标志(0)。产生应答信号函数代码如下:voidAT24CXX_IIC_Ack(void){ AT24CXX_IIC_SCL(0); AT24CXX_IIC_SDA(0); delay_us(2); AT24CXX_IIC_SCL(1); delay_us(2); AT24CXX_IIC_SCL(0);}不产生应答信号函数代码如下:voidAT24CXX_IIC_NAck(void){ AT24CXX_IIC_SCL(0); AT24CXX_IIC_SDA(1); delay_us(2); AT24CXX_IIC_SCL(1); delay_us(2); AT24CXX_IIC_SCL(0);} 发送字节函数程序代码如下:voidAT24CXX_IIC_Send_Byte(uint8_ttxd){uint8_tt; AT24CXX_IIC_SCL(0);for(t=0;t<8;t++){ if((txd&0x80)>>7) AT24CXX_IIC_SDA(1); else AT24CXX_IIC_SDA(0);txd<<=1; delay_us(2); AT24CXX_IIC_SCL(1); delay_us(2); AT24CXX_IIC_SCL(0); delay_us(2);} } 将一个字节的数据逐位发送到IIC总线上,通过设置SDA引脚的电平并配合SCL的高低电平变化来实现。 发送字节函数程序代码如下:uint8_tAT24CXX_IIC_Read_Byte(unsignedcharack){ unsignedchari,receive=0; AT24CXX_IIC_SDA(1);for(i=0;i<8;i++) {AT24CXX_IIC_SCL(0);delay_us(2); AT24CXX_IIC_SCL(1);receive<<=1;if(AT24CXX_READ_SDA)receive++; delay_us(1);} if(!ack)AT24CXX_IIC_NAck();elseAT24CXX_IIC_Ack();returnreceive;}从IIC总线上接收一个字节的数据,通过读取SDA引脚的电平并移位操作来获取数据。根据传入的参数ack决定是否发送应答信号。AT24CXX初始化函数初始化IIC总线,然后尝试从AT24CXX的地址255读取一个字节的数据。如果读取到的值为0X55,则表示初始化成功,返回0;否则,向地址255写入0X55,再次读取并判断是否为0X55,如果是则返回0,否则返回1表示初始化失败。代码如下:uint8_tAT24CXX_Init(void){ uint8_ttemp; AT24CXX_IIC_Init(); temp=AT24CXX_ReadOneByte(255); if(temp==0X55)return0; Else { AT24CXX_WriteOneByte(255,0X55); temp=AT24CXX_ReadOneByte(255); if(temp==0X55)return0; } return1; }AT24CXX数据读写函数这段代码实现了对AT24CXX系列EEPROM的完整IIC通信和数据读写操作,包括IIC总线的初始化、各种信号的产生和处理、设备的初始化以及数据的单字节和多字节读写。读一个字节函数:uint8_tAT24CXX_ReadOneByte(uint16_tReadAddr){ uint8_ttemp=0; AT24CXX_IIC_Start(); if(EE_TYPE>AT24C16) { AT24CXX_IIC_Send_Byte(0XA0); AT24CXX_IIC_Wait_Ack(); AT24CXX_IIC_Send_Byte(ReadAddr>>8); AT24CXX_IIC_Wait_Ack(); }elseAT24CXX_IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); AT24CXX_IIC_Wait_Ack();AT24CXX_IIC_Send_Byte(ReadAddr%256); AT24CXX_IIC_Wait_Ack(); AT24CXX_IIC_Start(); AT24CXX_IIC_Send_Byte(0XA1); AT24CXX_IIC_Wait_Ack(); temp=AT24CXX_IIC_Read_Byte(0); AT24CXX_IIC_Stop(); returntemp;}根据不同的AT24CXX型号(通过EE_TYPE判断),发送设备地址和要读取的地址,然后进入接收模式,从指定地址读取一个字节的数据,并返回读取到的值。写一个字节函数:voidAT24CXX_WriteOneByte(uint16_tWriteAddr,uint8_tDataToWrite){ AT24CXX_IIC_Start(); if(EE_TYPE>AT24C16) { AT24CXX_IIC_Send_Byte(0XA0); AT24CXX_IIC_Wait_Ack(); AT24CXX_IIC_Send_Byte(WriteAddr>>8); }else { AT24CXX_IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); } AT24CXX_IIC_Wait_Ack(); AT24CXX_IIC_Send_Byte(WriteAddr%256); AT24CXX_IIC_Wait_Ack(); AT24CXX_IIC_Send_Byte(DataToWrite); AT24CXX_IIC_Wait_Ack(); AT24CXX_IIC_Stop(); delay_ms(10); }根据不同的AT24CXX型号,发送设备地址和要写入的地址,然后发送要写入的数据,等待应答后产生停止信号,并延时一段时间(10ms)以确保数据写入成功。写长度字节函数:voidAT24CXX_WriteLenByte(uint16_tWriteAddr,uint32_tDataToWrite,uint8_tLen){ uint8_tt; for(t=0;t<Len;t++) { AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff); } }读长度字节函数:uint32_tAT24CXX_ReadLenByte(uint16_tReadAddr,uint8_tLen){ uint8_tt; uint32_ttemp=0; for(t=0;t<Len;t++) { temp<<=8; temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1); } returntemp; }读数据块函数:voidAT24CXX_Read(uint16_tReadAddr,uint8_t*pBuffer,uint16_tNumToRead){ while(NumToRead) { *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++); NumToRead--; }}从AT24CXX的指定地址开始,连续读取指定数量(NumToRead)的字节数据,并存储到指定的缓冲区(pBuffer)中。写数据块函数:voidAT24CXX_Write(uint16_tWriteAddr,uint8_t*pBuffer,uint16_tNumToWrite){ while(NumToWrite--) { AT24CXX_WriteOneByte(WriteAddr,*pBuffer); WriteAddr++; pBuffer++; }}将指定缓冲区(pBuffer)中的数据,按顺序写入到AT24CXX的指定地址开始的连续地址中,写入的字节数量为NumToWrite。系统调试硬件部分调试5.1.1硬件连接排插检查各模块与核心板的电源引脚连接是否牢固,有无短路、断路情况。调试结果如图5.1所示。图5.1引脚连接软件模块调试5.2.1程序调试硬件设备上电后,各模块功能正常显示,系统硬件初始化没有问题,随后进行调试,如图5.2所示为代码编译结果。图5.2编译结果5.2.2功能模块调试(1)智能桌面模块调试分别测试自动模式和手动模式下的台灯亮度调节功能。自动模式下,改变周围环境的亮度和人体位置,观察台灯亮度是否能够自动调节,当环境光亮度比较亮时(光强为3),终端实现(灯光为1)如图5.3左所示,当环境光亮度比较暗时(光强为2),终端实现(灯光为3)结果如图5.3右所示;在手动模式下,通过按键方式调节台灯亮度,检查亮度等级是否正确切换。如图5.4所示环境光亮度为3,图5.4左为灯光为4,图5.4右为灯光为3。图5.3自动模式调试图5.4手动模式调试(2)语音播报和人体姿态模块调试模拟人体的不同姿态和位置,检查超声波传感器是否能够准确检测人体信息姿态是否正确。当检测到姿态不正确时(距离小于10cm),如图5.5所示。当检测到姿态正确的时候(距离大于10cm),如图5.6所示。图
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 星云股份合同范本
- 果场买卖合同范本
- 土地使用权出让合同范本参考
- 大合同框架协议
- 易显示屏合同范本
- 果树销售合同范本
- 增补购买合同范本
- 教育代理合同范本
- 大合同签效的协议
- 教授顾问合同范本
- 2025青海省生态环保产业有限公司招聘11人笔试考试参考题库及答案解析
- 骨科VSD治疗患者的体位管理护理
- 茶楼餐厅转让协议书
- 中国正常分娩临床实践指南
- 2025中国工业互联网研究院校园招聘笔试历年参考题库附带答案详解
- 浙江省诸暨市2025年12月高三诊断性考试政治(含答案)
- 2026年高考时政热点学习167条
- 2025年《项目管理认证考试》知识考试题库及答案解析
- 偏头痛护理查房
- 安徽消防笔试题及答案
- 2025年档案工作的工作总结和计划(5篇)
评论
0/150
提交评论