STM32串口读写迪文屏8位、16位、32位数据(应用层实现)
独立操作STM32F103的GPIO组半字节(8位)方法
怎么对高八位或低八位写值而不影响其它位,还有怎样单独读取高八位或低八位的值((u8*)(&GPIOB->ODR))[0] = 0xaa;写低八位g_io_tempvalue =((u8*)(&GPIOB->ODR))[1];读高八位写高八位GPIOB->CRH &= 0X00000000;GPIOB->CRH |= 0X33333333;GPIOB->ODR |= 0XFF00;低八位也一样,做与或者或运算的时候就可以避免影响不想改变的位。
读高八位:u8 temp;temp = ((GPIOB->IDR>>8)&0xff)读低八位:temp = ((GPIOB->IDR&0xff)使用BSRR和BRR寄存器直接操作STM32的I/O端STM32的每个GPIO端口都有两个特别的寄存器,GPIOx_BSRR和GPIOx_BRR寄存器,通过这两个寄存器可以直接对对应的GPIOx端口置'1'或置'0'。
GPIOx_BSRR的高16位中每一位对应端口x的每个位,对高16位中的某位置'1'则端口x的对应位被清'0';寄存器中的位置'0',则对它对应的位不起作用。
GPIOx_BSRR的低16位中每一位也对应端口x的每个位,对低16位中的某位置'1'则它对应的端口位被置'1';寄存器中的位置'0',则对它对应的端口不起作用。
简单地说GPIOx_BSRR的高16位称作清除寄存器,而GPIOx_BSRR的低16位称作设置寄存器。
另一个寄存器GPIOx_BRR只有低16位有效,与GPIOx_BSRR的高16位具有相同功能。
举个例子说明如何使用这两个寄存器和所体现的优势。
例如GPIOE的16个IO都被设置成输出,而每次操作仅需要改变低8位的数据而保持高8位不变,假设新的8位数据在变量Newdata中,这个要求可以通过操作这两个寄存器实现,STM32的固件库中有两个函数GPIO_SetBits()和GPIO_ResetBits()使用了这两个寄存器操作端口。
STM32串口教程
STM32串口教程STM32是一种基于ARM Cortex-M内核的32位微控制器系列。
它具有强大的处理能力和丰富的外设接口,适用于各种嵌入式应用。
其中,串口通信是STM32常用的外设之一,可以用于和其他设备进行数据的收发。
本文将介绍STM32串口的配置和使用方法。
一、串口的基本原理串口是一种以串行方式传输数据的通信方式。
在串口通信中,数据按照比特位的顺序传输,一次传输一个位。
数据的传输包括一个或多个字节,每个字节由8位组成,其中包括1位起始位、1位停止位和可选的奇偶校验位。
串口通信需要两根信号线,一根用于发送数据(TX),一根用于接收数据(RX)。
二、STM32串口的配置配置串口的步骤如下:1.设置GPIO引脚功能和模式:将串口的引脚配置为复用功能,并设置引脚的模式为推挽输出。
2.使能串口时钟:根据串口的编号,使能对应串口的时钟。
3.配置串口参数:设置串口的波特率、数据位、停止位、奇偶校验位等参数。
4.使能串口:使能串口的发送和接收功能。
三、STM32串口的使用方法配置完成后,即可使用STM32的串口进行数据的收发。
下面是使用STM32串口的一般流程:1.发送数据:将要发送的数据写入到串口的发送缓冲区,等待数据发送完成。
2.接收数据:检测是否有数据接收到,如果有则读取数据。
在发送数据时,可以使用printf函数实现方便的格式化输出。
为了使用printf函数,需要先配置printf函数的底层接口。
可以使用标准库提供的函数重定向方法,将输出重定向到串口。
在接收数据时,可以使用中断方式或轮询方式。
中断方式需要配置串口的中断,并在中断服务函数中处理接收到的数据。
轮询方式是在主循环中不断检测数据是否接收到,并进行读取。
四、常见问题及解决方法1.串口通信乱码问题:可能是波特率设置不正确导致的,可以检查波特率设置是否和目标设备匹配。
2.串口接收数据丢失问题:可能是接收缓冲区溢出导致的,可以增加接收缓冲区的大小或者使用中断方式处理接收数据。
STM32HAL库UART串口读写功能笔记
STM32HAL库UART串⼝读写功能笔记串⼝发送功能:uint8_t TxData[10]= "01234abcde";HAL_UART_Transmit(&huart2,TxData,10,0xffff);//把TxData的内容通过uart2发送出去,长度是10,timeout的时间是最⼤值0xffff串⼝接收功能1:uint8_t value='F';HAL_UART_Receive(&huart2,(uint8_t *)&value,1,1000);//在这个语句停留1000ms内等待接收1个字节数据,把数据存放在value中串⼝接收功能2:HAL_UART_Receive_IT(&huart2,(uint8_t *)&value,1);//程序不会在这个语句停留,直接会按照中断⽅式把接收数据存放在value中,但是这个语句只能使能⼀次串⼝中断。
所以要在中断服务函数或者回调函数中重新使能串⼝接收功能3:if(HAL_UART_Receive_IT(&huart2,(uint8_t *)&value,1) != HAL_OK){ //这⼀句写在main函数的while(1)上⾯。
⽤于启动程序启动⼀次中断接收HAL_UART_Transmit(&huart2, (uint8_t *)&"ERROR\r\n",7,10);while(1);}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle){HAL_UART_Transmit(&huart2, (uint8_t *)&"\r\ninto HAL_UART_RxCpltCallback\r\n",32,0xffff); //验证进⼊这个函数了HAL_UART_Transmit(&huart2,(uint8_t *)&value,1,0xffff); //把接收到的数据通过串⼝发送出去HAL_UART_Receive_IT(&huart2,(uint8_t *)&value,1); //重新打开串⼝中断}串⼝DMA发送DMA的TX要这样设置uint8_t txData[] = {"HelloWorld\r\n"};HAL_UART_Transmit_DMA(&huart2,txData,sizeof(txData));//可以通过DMA把数据发出去DMA接收if(HAL_UART_Receive_DMA(&huart2, (uint8_t *)rxData, sizeof(rxData)-1) != HAL_OK)//main函数while(1)前,启动⼀次DMA接收{Error_Handler();}串⼝回调函数:void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle){uint8_t temp[] = {"\r\nin Callback\r\n"};HAL_UART_Transmit_DMA(&huart2,temp,sizeof(temp)-1);//可以通过DMA把数据发出去HAL_UART_Receive_DMA(&huart2, (uint8_t *)rxData, sizeof(rxData)-1); //重新使能接收}main函数while(1)中不断输出rxData值HAL_UART_Transmit_DMA(&huart2,rxData,sizeof(rxData)-1);//可以通过DMA把数据发出去写在前⾯ 最近需要使⽤⼀款STM32L4系列的芯⽚进⾏开发,需要学习使⽤HAL库。
迪文串口屏开发例程
迪文串口屏开发例程
迪文串口屏开发例程是一种用于编写串口操作程序的工具。
串口
屏开发例程的核心功能是实现与串口屏之间的数据通信。
它通过定义
若干指令和函数来辅助开发者实现与各种类型的串口屏的通信,大大
减少了程序代码的编写量。
迪文串口屏开发例程是基于STM32F10xC8系列单片机的,支持中
文汉字显示,可显示32×16行,能够实现定时器、计步数等功能。
此外,这款串口屏还支持光电传感器,可以实现与外部设备的手势识别,以及实现图形、文字、图像等的显示和控制。
迪文串口屏开发例程使用时可以方便设置系统参数,实现与串口
屏的通信设备的高效交互。
另外,它还提供了完整的串口屏编程环境,可以根据需要将用户自定义的程序烧录到开发板上,以便进行测试和
使用。
总之,迪文串口屏开发例程是一款功能强大、实用性高的开发工具,可以有效地帮助用户实现与串口屏之间的数据通信,并实现特定
功能。
EFM32系列32位MCU的GPIO配置,读取-写入,外设功能
EFM32 系列32 位MCU 的GPIO 配置,读取/写入,
外设功能
本文主要针对Silicon Labs(亦称芯科科技)EFM32 系列32 位MCU 的GPIO 配置,读取/写入,外设功能,外部中断功能以及GPIO 引脚作为外设
反射系统(PRS)等功能进行概要描述。
与此相关的功能演示可以在Silicon Labs 推出的EFM32 入门套件主板上实现。
与通用型MCU 应用类似,EFM32 系列每个端口最多容纳16 个引脚,命名规则为Pxn,其中x 表示端口(A,B,C ...),n 表示引脚编号(0,1,...,15),其中每个端口都有独立的寄存器控制单元,用于功能的配置和数据读写等。
GPIO 配置输出端,通过写入DOUT 寄存器中的相应位来驱动引脚,其输出可以配置为线或,开漏或者具有特定驱动属性的推挽式输出。
输入配置,
其输入的引脚状态反映在其对应的DIN 寄存器中,可为每个输入引脚启用可
编程的上拉或下拉功能,另外还有滤波器功能可选,可以抑制长达50 ns 的毛刺。
在实际的应用设计中,为避免意外影响GPIO 的配置,可以按引脚锁
定其GPIO 配置。
另外,针对部分外设线路有上、下拉电阻的配置需求,这
就需要与MCU GPIO 上、下拉功能的协调使用。
EFM32 系列的三个典型寄存器配置:GPIO_Px_MODEL(端口引脚0-7)或GPIO_Px_MODEH(端口引脚8-15),GPIO_Px_DOUT 和。
牛人的STM32学习笔记(寄存器版本)..
一、GPIO口的配置STM32的DGPIO口最多可以有7组(GPIOa~GPIOg),而每一组GPIO口均有16个双向IO组成。
并且没个IO口均可配置成8种模式(4种输入模式,4种输出模式)。
不管配置哪个IO口也不论将其配置成哪种模式(但是配置成哪种模式要看具体应用,参考《中文参考手册》第105页)都可以按以下步骤来进行配置:(1)使能PORTx(x=A~G)时钟这里就得操作寄存器RCC_APB2ENR(32为寄存器)了15 14 13 12 11 10 9 8 ADC3EN USART1EN TIM8EN SPI1EN TIM1EN ADC2EN ADC1EN IOPGEN7 6 5 4 3 2 1 0 IOPFEN IOPEEN IOPDEN IOPCEN IOPBEN IOPAEN 保留AFIOENRCC_APB2ENR的0~15位(06~32位保留)第2~8分别是使能GPIOA~GPIOG时钟的,只要将其置“1”即可,如RCC_APB2ENR|=1<<2;就是使能GPIOA的时钟;其余IO口的始终使能一次类推。
(2)对相应的IO模式进行配置,低8位配置GPIOx_CRL;高8位配置GPIOx_CRH31 30 29 28 27 26 25 24CNF7[1:0] MODE7[1:0] CNF6[1:0] MODE6[1:0]23 22 21 20 19 18 17 16CNF5[1:0] MODE5[1:0] CNF4[1:0] MODE4[1:0]15 14 13 12 11 10 9 8CNF3[1:0] MODE3[1:0] CNF2[1:0] MODE2[1:0]7 6 5 4 3 2 1 0CNF1[1:0] MODE1[1:0] CNF0[1:0] MODE0[1:0]GPIOx_CRL(x=A~G(端口配置低寄存器x=A…E)该寄存器用于配置GPIOx的低8位,具体8种模式的配置见《中文参考手册》例如:GPIOD->CRL&=0XFFFFF0FF;GPIOD->CRL|=0X00000300;/PD.2推挽输出;其余IO口的低8位以此类推。
STM32的IO端口高8位或低8位单独操作方法
举例说下怎幺对IO端口赋值:
1.对高8位/低8位/全部清零
很明显,这个只需要操作BRR寄存器即可:
对高8位清零:GPIOA->BRR=0xFF00
对低8位清零:GPIOA->BRR=0x00FF
全部清零:GPIOA->BRR=0xFFFF或GPIOA->ODR=0x0000
1,置0的位不影响原来的值
高16位应该置为0000000010101010,这个就等于~0x55(即取反)的结
果,置1使某位为ห้องสมุดไป่ตู้,置0不影响原来的值
这样,BSRR寄存器的值就是00000000101010100000000001010101,
两部分的高8位均为0,所以不会影响到IO口的高8位
总结,以下的宏实现对某端口的低8位置数,不影响高8位:
STM32的IO端口高8位或低8位单独操作方法
几天前刚接触stm32的时候,被单独操作IO口给弄糊涂了,现记录下,现
在发现其实蛮简单的,只是刚开始的时候~~~
stm32的IO端口都是16位的,如果要单独操作某高8位或低8位,则不
是那幺简单,先看两张BSRR/BRR寄存器的图:
据官方数据手册上面说,这两个寄存器用于专门对ODR进行原子操作的
#defineGPIO_WriteLow(GPIOx,a)GPIOx-
>BSRR=(((uint32_t)(uint8_t)~(a))BSRR=(((uint8_t)(uint8_t)~(a))BSRR=value的
形式,所以担心是多余的
当然了,使用下面2,3的两个宏也可以完全该清零操作~stm32固件库是不
是应该加上这两个宏/函数?
stm32位操作详解
stm32位操作详解stm32位操作详解STM32位操作原理思想:把⼀个⽐特分成32位,每位都分配⼀个地址,这样就有32个地址,通过地址直接访问。
位操作基础位运算位运算的运算分量只能是整型或字符型数据,位运算把运算对象看作是由⼆进位组成的位串信息,按位完成指定的运算,得到位串信息的结果。
位运算&(按位与)、|(按位或)、^(按位异或)、~ (按位取反)。
其中,按位取反运算符是单⽬运算符,其余均为双⽬运算符。
位运算符的优先级从⾼到低,依次为~、&、^、|,其中~的结合⽅向⾃右⾄左,且优先级⾼于算术运算符,其余运算符的结合⽅向都是⾃左⾄右,且优先级低于关系运算符。
(1)按位与运算符(&)按位与运算将两个运算分量的对应位按位遵照以下规则进⾏计算:0 & 0 = 0, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1。
即同为1的位,结果为1,否则结果为0。
例如,设3的内部表⽰为000000115的内部表⽰为00000101则3&5的结果为00000001按位与运算有两种典型⽤法,⼀是取⼀个位串信息的某⼏位,如以下代码截取x的最低7位:x & 0177。
⼆是让某变量保留某⼏位,其余位置0,如以下代码让x只保留最低6位:x = x & 077。
以上⽤法都先要设计好⼀个常数,该常数只有需要的位是 (2)按位或运算符(|)按位或运算将两个运算分量的对应位按位遵照以下规则进⾏计算:0 | 0 = 0, 0 | 1 = 1, 1 | 0 = 1, 1 | 1 = 1即只要有1个是1的位,结果为1,否则为0。
例如,023 | 035结果为037。
按位或运算的典型⽤法是将⼀个位串信息的某⼏位置成1。
如将要获得最右4为1,其他位与变量j的其他位相同,可⽤逻辑或运算017|j。
若要把这结果赋给变量j,可写成:j = 017|j(3)按位异或运算符(^)按位异或运算将两个运算分量的对应位按位遵照以下规则进⾏计算:0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0即相应位的值相同的,结果为0,不相同的结果为1。
关于单片机位数的思考(8位、16位、32位)
关于单⽚机位数的思考(8位、16位、32位)8位、16位、32位是指单⽚机的“字长”,也就是⼀次运算中参与运算的数据长度,这个位是指⼆进制位。
以8位为例,8位⼆进制的表达范围是0000,0000~1111,1111即⼗进制的0~255,即每次参与运算的数据最⼤不能超过255。
⽽16位机的字长是16位,其数据表达范围是0~65535,即每次参与运算的数据最⼤不能超过65535;32位单⽚机的字长是32位,其数据表达范围是0~4294967295,即每次参与运算的数据最⼤不能超过4294967295。
8位、16位、32位与单⽚机的性能密切相关,通常32位机的性能要⾼于16位机,⽽16位机的性能⼜要⾼于8位机。
为什么会这样呢?这要从2个⽅⾯来分析。
第⼀,位数不同,运算效率不同。
对于8位机⽽⾔,由于在⼀次运算中的每⼀个数都不能超过8位,因此即便如100+200=300这样的运算,它也不能⼀次完成,因为300已超过了8位所能表达的最⼤范围(255),因此,要对这样的⼀个式⼦进⾏运算,就要编写⼀段程序,将运算分步完成,最后合成起来得到⼀个正确的结果。
⽽如果采⽤16位单⽚机来运算的话,那么⼀次运算就够了,显然分步完成所需要的时间要远远⼤于单步完成所需要的时间。
同样道理,当某个运算的结果或者中间值⼤于65535时,16位机也不能⼀次运算,要分步实现它,⽽32位机则可以⼀次运算完成。
第⼆,商业因素。
通常运算能⼒越⾼,表⽰这个单⽚机性能越强,当然,价格⾼⼀些⼈们也可以接受,有了价格空间,⽣产商通常都会在这些芯⽚中提供更多的其他的功能,使得芯⽚的整体性能得到更⼤的提升。
典型的单⽚机中,80C51系列,PIC系列,AVR系列都是8位单⽚机;80C196、MSP430系列是16位机;⽽⽬前⾮常热门的ARM系列则是32位机。
另外在CSDN的讨论中的⼀些⽐较好的回答:=================================8位单⽚机,典型的是51系列的,再⾼级点⽤AVR、pic的,功能⽅⾯,似乎都不会很复杂,⼀般可能是控制类的多⼀下。
STM32内部FLASH读写操作详解
STM32芯片内部的FLASH存储器,主要用于存储我们代码。
如果内部FLASH存储完我们的代码还有剩余的空间,那么这些剩余的空间我们就可以利用起来,存储一些需要掉电保存的数据。
本文以STM32103ZET6为例。
STM32103ZET6属于大容量产品,其闪存模块组织如下:其主存储器大小为512KB,分为256页,每页大小都为2KB。
我们的程序- 般默认烧写到第0页的起始地址(0x08000000)处。
当BOOT0引脚和BOOT1引脚都接GND时,就是从这个地址开始运行代码的。
这个地址在keil中可以看到:回I Options for Target'FLASH'D evic e Target ' Output | Li sting User C/C++ Asm Linkei Debug Utilities ' 假如我们要下载的程序大小为4.05KB,则第0、1、2页用于保存我们的程 序,我们需要掉电保存的数据只能保存在第3〜第255页这一部分空间内。
我们最终要下载的程序大小可在工程对应的.map 文件中看到。
.map 文件可以双 击工程的Target 的名字快速打开,如:下面对STM32内部FLASH 进行简单的读写测试: 内部FLASH 读写测试 流程图如下:本流程图省略异常情况,只考虑成功的情况:由反£419S ( 4P eike :iSTMicroelectnnics STM32F13GZE1rm乂 ।F -J y.dPtripl\Cn\ifeij sEN32H[h :_na5hh二| 立府211以一Lr a nd " c^tu J ■EL户 inagt latalsROM Totals耳 QR Ct它 PcOirn.!:T u Tt57HJx_hkp.c wn n Fil K _< a n,= tTn32Fllx cezce 口system.1示例代码:本例的关键代码如下(以读写第255页为例):/、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、上、上Ki> /力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、Ki^、上、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、上、上Ki> 个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个小* ------------------------------------------- STM32 Demo ------------------------------------------- 工程说明:STM32内部FLASH 实验 作 者:ZhengNian博 客:zhengnianli.github.io 公众号:嵌入式大杂烩Ki^、上、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、上、上Ki> 个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个小Ki^、上、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、上、卜 / 力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、/#define MAIN_CONFIG #include "config.h/* STM32F103ZET6有256页,每一页的大小都为2KB */#define ADDR_FLASH_PAGE_255 ((uint32_t)0x0807F800) /* Page255 2KB */* * * * */* FLASH读写测试结果*/#define TEST_ERROR -1 /* 错误(擦除、写入错误)*/#define TEST_SUCCESS 0 /* 成功*/#define TEST_FAILED 1 /* 失败*/ /* Flash读写测试buf */#define BufferSize 6uint16_t usFlashWriteBuf[BufferSize]={0x0101,0x0202,0x0303,0x0404,0x0505,0x0606};uint16_t usFlashReadBuf[BufferSize] = {0};/*供本文件调用的函数声明*/ static int FlashReadWriteTest(void);小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小** 函数:main** --------------------------------------------------------------------------------------------------------- ** 参数:void**返回:无**说明:主函数小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小int main(void){/*上电初始化*/SysInit();/*内部Flash读写测试*/if (TEST_SUCCESS == FlashReadWriteTest()){printf("Flash test success!\n");}else{printf("Flash test failed!\n");}while (1) {}}小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小**函数:FlashReadWriteTest,内部Flash读写测试函数** ---------------------------------------------------------------------------------------------------------** 参数:void**返回:TEST_ERROR:错误(擦除、写入错误)TEST_SUCCESS:成功TEST_FAILED:失败**说明:无小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小小/*J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* /static int FlashReadWriteTest(void) (uint32_t ucStartAddr;/*解锁*/FLASH_Unlock();/*擦除操作*/ucStartAddr = ADDR_FLASH_PAGE_255;if (FLASH_COMPLETE != FLASH_ErasePage(ucStartAddr)) (printf("Erase Error!\n");return TEST_ERROR;)else(ucStartAddr = ADDR_FLASH_PAGE_255;printf("擦除成功,此时FLASH中值为:\n");for (int i = 0; i < BufferSize; i++) (usFlashReadBuf[i] = *(uint32_t*)ucStartAddr;printf("ucFlashReadBuf[%d] = 0x%.4x\n”, i, usFlashReadBuf[i]);ucStartAddr += 2;))/*写入操作*/ucStartAddr = ADDR_FLASH_PAGE_255;printf("\n往FLASH中写入的数据为:\n");for (int i = 0; i < BufferSize; i++)(if (FLASH_COMPLETE != FLASH_ProgramHalfWord(ucStartAddr, usFlashWriteBuf[i]))(printf("Write Error!\n");return TEST_ERROR;)printf("ucFlashWriteBuf[%d] = 0x%.4x\n", i, usFlashWriteBuf[i]);ucStartAddr += 2;)/*上锁*/FLASH_Lock();/*读取操作*/ucStartAddr = ADDR_FLASH_PAGE_255;printf("\n从FLASH中读出的数据为:\n");for (int i = 0; i < BufferSize; i++)(usFlashReadBuf[i] = *(_IO uint16_t*)ucStartAddr;printf("ucFlashReadBuf[%d] = 0x%.4x\n”, i, usFlashReadBuf[i]); ucStartAddr += 2;)/*读出的数据与写入的数据做比较*/for (int i = 0; i < BufferSize; i++)(if (usFlashReadBuf[i] != usFlashWriteBuf[i])(return TEST_FAILED;))return TEST_SUCCESS;)/、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、上、上/力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、、上、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、上、上个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个小** End Of File、上、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、上、上个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个个小、上、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、卜、上、卜 / 力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、力、/ (1)进行解锁操作STM32的闪存编程是由内嵌的闪存编程/擦除控制器(FPEC)管理,这个模块包含的寄存器如下:STM32复位后,FPEC模块是被保护的,不能写入FLASH_CR寄存器;通过写入特定的序列到FLASH_KEYR寄存器可以打开FPEC模块(即写入KEY1和KEY2),只有在写保护被解除后,我们才能操作相关寄存器。
stm32串口调参数
stm32串口调参数串口调参数是指在使用STM32单片机进行串口通信时,需要通过设置一系列参数来控制串口的工作方式。
下面将详细介绍调整这些参数的方法:1. 总线速率(Baud Rate):通过修改USART_CR1寄存器的USART_CR1_BR位来设置串口的波特率。
BR通常是一个由APB1总线频率和所需波特率计算得出的值。
例如,如果APB1总线频率为72MHz,希望设置波特率为9600,那么BR的计算公式为:BR=APB1总线频率/所需波特率BR=72MHz/9600=7500通过设置USART_BRR寄存器的USART_BRR_DIV位为BR来实现调整。
2. 数据位长度(Data Bits):STM32单片机的USART_CR1寄存器的USART_CR1_M位用于设置数据位长度。
有两个选项可供选择:8位和9位。
3. 校验位(Parity Bits):STM32单片机的USART_CR1寄存器的USART_CR1_PCE位用于启用或禁用校验位。
如果启用校验位,还需要根据实际情况选择奇校验还是偶校验。
4. 停止位长度(Stop Bits):STM32单片机的USART_CR2寄存器的USART_CR2_STOP位用于设置停止位长度。
有两个选项可供选择:1位和2位。
5. 硬件流控制(Hardware Flow Control):如果需要使用硬件流控制,可以设置STM32单片机的USART_CR3寄存器的USART_CR3_RTSE、USART_CR3_CTSE和USART_CR3_CTSIE位。
6.中断控制:STM32单片机的USART_CR1寄存器的USART_CR1_TXEIE和USART_CR1_RXNEIE位可用于使能或禁用发送和接收中断。
7.DMA控制:STM32单片机的USART_CR3寄存器的USART_CR3_DMAT和USART_CR3_DMAR位可用于使能或禁用DMA传输。
调整这些参数的步骤如下:1.初始化串口:配置引脚,设置GPIO模式为复用模式,选择对应的复用功能映射,然后初始化USART控制器。
STM32UART详细使用说明整理
STM32 UART整理说明该接口通过3个引脚连接到另外的外部设备上。
任何USART双向通信都至少需要两个引脚:接收数据输入RX和发送数据输出TX当发送器禁能时输出引脚恢复到I/O端口配置。
当发送器使能时且无数据发送,TX引脚为高电平。
字长可以通过设置USART_CR1寄存器中的M位来选择是8位还是9位TX引脚在起始位期间为低,停止位期间为高空闲符被认为是一个全“1”的帧,其后紧跟着包含数据的下一个帧的起始位(“1”的数目包含了停止位的数目)间隙符被认为是一个帧周期都接收到“0”。
在间隙帧之后,发送器插入1个或者2个的停止位(逻辑“1”)来应答起始位发送器发送器可以发送8或者9位的数据字,这取决于M位的状态。
相关时钟脉冲在SCLK引脚输出1、字符发送USART发送期间,TX引脚先出现最低有效位。
这种模式下,USART_DR寄存器包含了一个内部总线和发送移位寄存器之间的缓冲区TDR。
每个字符之前都有一位逻辑低电平的起始位,以可设置数目的停止位结束。
TE位使能之后将发送一个空闲帧2、可配置的停止位1个停止位:这是陌生人的停止位数目2个停止位:常规USART,单线和调制解调器模式下支持0.5个停止位:当处于智能卡模式下接收数据时使用1.5个停止位:当处于智能卡模式下发送数据时使用空闲帧的发送包含了停止位。
间隙帧是10(11)个低位之后跟着配置的停止位配置流程:通过把USART_CR1寄存器中的UE位写1来使能USART->配置USART_CR1寄存器中的M位来定义字长->配置USART_CR2寄存器中的停止位数目->若采用多缓冲通信选择USART_CR3寄存器中的DMA使能位(DMA T),按照多缓冲通信中解释的配置DMA 寄存器->设置USART_CR1寄存器中的TE位来发送一个空闲帧来作为第一次发送->通过USART_BRR寄存器选择期望的波特率->往USART_DR寄存器中写入要发送的数据,这也将清除TXE位。
STM32单片机串口的定义及应用方法
STM32单片机串口的定义及应用方法STM32配置串口需要配置的寄存器包括:1、时钟配置,开启相应IO端口的时钟,以及串口模块的时钟。
串口1模块时钟寄存器:RCC_APB2Periph_USART1;串口1的端口是PA9,PA10,对应的时钟寄存器:RCC_APB2Periph_GPIOA;开启的函数是:RCC_APB2PeriphClockCmd (RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);串口2的模块时钟寄存器:RCC_APB1Periph_USART2;串口2的端口是PA2,PA3;对应的时钟寄存器是:RCC_APB2Periph_GPIOA;开启的函数是:RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART2| RCC_APB2Periph_GPIOA,ENABLE);此处的意义在于开启了我们要使用的模块:串口模块1/串口模块2,以及对应的IO时钟项。
如果要使用STM32中的硬件首先就是要配置和开启相应模块的时钟。
2、IO重映射的问题:STM32的管脚功能可以重映射,可以将串口2的TX和RX端口从原来默认的PA2PA3,重新定义到PD5,PD6上,定义完成后,串口2的TX和RX端口就不再是原来的管脚,而是PD5,PD6了。
要进行IO的重映射,首先要开启IO重映射的时钟:此项时钟寄存器的名称是:RCC_APB2Periph_AFIO;开启此时钟的代码:RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);开启了时钟后,还要写入控制IO重定义功能的寄存器:GPIO_PinRemapConfig函数是用来写入此寄存器的,写入对应的位,就可以实现IO的重定义功能。
GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);。
STM32的液晶与触摸屏显示
STM32的液晶与触摸屏显示TFT-LCD 英文全称为:Thim Film Transistor Liquid Crystal Display。
TFT即薄膜场效应管。
所谓薄膜晶体管,是指液晶显示器上的每一液晶像素点都是由集成在其后的薄膜晶体管来驱动。
从而可以做到高速度、高亮度、高对比度显示屏幕信息。
TFT-LCD 液晶显示屏是薄膜晶体管型液晶显示屏。
我们采用的3.5 寸液晶屏,它的控制芯片是ILI9488,触摸驱动芯片为TSC2046。
最大支持解析度为:HVGA,分辨率为480×320,接口可以为8位或者16位并口,我们这里是使用16 位并口,以发挥STM32的优势。
而背光则使用一个三极管驱动。
引脚电路图如下图:引脚介绍LCD_CS是TFTLCD的片选信号LCD_RS是命令和数据的标志(0,读写命令。
1是写命令)LCD_WR是向TFTLCD写入数据LCD_RD是从TFTLCD读取数据D[17-1]是数据16位双向数据线RST是硬复位的标志BL_CTR背光处理信号lT_MISO/T_MOSI/T_PEN/T_CS/T_CLK,触摸屏接口信号驱动时序图:驱动流程:RGB565格式说明(16色):指令集:0XD3指令:用于读取LCD控制器的ID0X36指令:用于控制读写方向0X2A指令:用于设置横坐标起始位置和终止位置(x坐标)0X2B指令:用于设置纵坐标起始位置和终止位置(y坐标)0X2C指令:用于写颜色数据0X2E指令:用于读颜色指令接线图:程序:#include "led.h"#include "delay.h"#include "sys.h"#include "usart.h"#include "lcd.h"int main(void){u8 x=0;u8 lcd_id[12]; //存放LCD ID字符串delay_init(); //延时函数初始化uart_init(9600); //串口初始化为9600LED_Init(); //初始化与LED连接的硬件接口LCD_Init();POINT_COLOR=RED;sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。
stm32中u8,u16,u32的理解
stm32中u8,u16,u32的理解在STM32中,u8、u16、u32是用于表示无符号整数的数据类型。
它们分别代表8位、16位和32位的无符号整数。
下面将对每个数据类型进行详细的解释:1. u8(无符号8位整数):u8是一个无符号整数类型,它占用8个比特位(即1个字节)的存储空间。
因此,它的取值范围是0到255。
u8类型可以用来表示各种需要小范围整数的情况,比如表示像素的亮度、按钮的状态等。
2. u16(无符号16位整数):u16是一个无符号整数类型,它占用16个比特位(即2个字节)的存储空间。
因此,它的取值范围是0到65535。
u16类型通常用于需要中等范围整数的场景,比如表示计数值、数据传输等。
3. u32(无符号32位整数):u32是一个无符号整数类型,它占用32个比特位(即4个字节)的存储空间。
因此,它的取值范围是0到4294967295。
u32类型通常用于需要大范围整数的场景,比如表示内存地址、存储器大小等。
在STM32的编程中,这些无符号整数类型经常用于与外设进行数据交互、处理计时和延时等。
此外,它们也可以用于定义变量、函数参数和返回值等。
使用这些无符号整数类型时,需要注意以下几点:1. 数据表示范围:根据数据类型的比特位数,了解其取值范围。
确保所选数据类型能够满足所需的数值范围,避免数据溢出或表示范围不足的情况。
2. 运算问题:由于这些数据类型属于无符号整数类型,因此它们不能表示负数。
在进行运算时,需要注意在使用减法或递减操作时的边界条件,以避免出现预期外的结果。
3. 数据类型选择:根据具体需求选择最适合的数据类型。
如果需要存储或处理小范围整数数据,则选择u8类型;如果需要处理中等范围整数数据,则选择u16类型;如果需要处理大范围整数数据,则选择u32类型。
需要提醒的是,在STM32中,还有其他数据类型,如s8、s16、s32等有符号整数类型,它们与无符号整数类型的不同之处在于能够表示正负数,但数据表示的范围有所不同。
STM32串口详解
STM32串⼝详解01、USART的特点USART是通⽤异步收发传输器(UniversalAsynchronousReceiver/Transmitter),通常称作UART,是⼀种异步收发传输器,是设备间进⾏异步通信的关键模块。
UART负责处理数据总线和串⾏⼝之间的串/并、并/串转换,并规定了帧格式;通信双⽅只要采⽤相同的帧格式和波特率,就能在未共享时钟信号的情况下,仅⽤两根信号线(Rx和Tx)就可以完成通信过程,因此也称为异步串⾏通信。
全双⼯异步通信。
⼩数波特率发⽣器系统,提供精确的波特率。
可配置的16倍过采样或8倍过采样,因⽽为速度容差与时钟容差的灵活配置提供了可能。
可编程的数据字长度(8位或者9位);可配置的停⽌位(⽀持1或者2位停⽌位);可配置的使⽤DMA多缓冲器通信。
单独的发送器和接收器使能位。
检测标志:①接受缓冲器②发送缓冲器空③传输结束标志多个带标志的中断源。
触发中断。
其他:校验控制,四个错误检测标志。
通信结构02、USART简介2.1、数据传输模型2.2、帧结构串⼝异步通信需要定义的参数①起始位②数据位(8位或者9位)③奇偶校验位(第9位)④停⽌位(1,15,2位)⑤波特率设置带奇偶校验的数据为就是9位1.数据包串⼝通讯的数据包由发送设备通过⾃⾝的TXD接⼝传输到接收设备得RXD接⼝,在协议层中规定了数据包的内容,具体包括起始位、主体数据(8位或9位)、校验位以及停⽌位,通讯的双⽅必须将数据包的格式约定⼀致才能正常收发数据。
2.波特率由于异步通信中没有时钟信号,所以接收双⽅要约定好波特率,即每秒传输的码元个数,以便对信号进⾏解码,常见的波特率有4800、9600、115200等。
STM32中波特率的设置通过串⼝初始化结构体来实现。
3.起始和停⽌信号数据包的⾸尾分别是起始位和停⽌位,数据包的起始信号由⼀个逻辑0的数据位表⽰,停⽌位信号可由0.5、1、1.5、2个逻辑1的数据位表⽰,双⽅需约定⼀致。
STM32串口读写迪文屏8位、16位、32位数据(应用层实现)
STM32串口读写迪文屏8位、16位、32位数据(应用层实现)文章目录•前言•一、串口需要的相关实现•o▪数据类型▪需要自定义实现的变量和函数•二、迪文屏读写•o 2.1 向迪文屏写数据o 2.2 从迪文屏读取数据前言基于STM32F407实现与迪文串口屏T5L系列的串口通信,实现8位,16位,32位的数据读写。
PS:不包含完整程序,这里只说一下核心的代码。
一、串口需要的相关实现数据类型#define u8 unsigned char#define u16 unsigned short#define u32 unsigned int//32位int与8位char互转typedef union{u32 intdata;u8 chardata[4];}int_char_unioin;//16位short与8位char互转typedef union{u16 shortdata;u8 chardata[2];}short_char_unioin;需要自定义实现的变量和函数1.buffer——串口收发缓冲区数组。
2.send_buffer()——向串口发送buffer数组。
3.delay_time——等待迪文屏返回数据的时间,例:5ms,迪文屏上OS的周期是20ms,读写过快可能出问题。
(可能有更好的方法,一般情况下几ms还是可以容忍的。
)4.clear_usart()——清空串口缓冲区数组buffer,如用memset()将数组置零即可。
二、迪文屏读写STM32与迪文屏的通信核心在于向迪文屏中定义的变量进行读写,迪文屏中的变量用一个16位数据表示其地址。
迪文屏的用户可操作地址空间为0x1000-0xFFFF,我们要做的就是在这个区间内的一个地址上读写数据,这个地址指向的数据类型由DGUS II(迪文屏开发上位机软件)设置,详细内容可以查看迪文公司的应用开发指南。
2.1 向迪文屏写数据向迪文屏上的16位地址写8位,16位,32位数据。
stm32的串口接收字符串以十六进制数
stm32的串口接收字符串以十六进制数#include 'pbdata.h'uint8_t TxBuffer1[] = 'USART Interrupt Example: This isUSART1 DEMO';uint8_t RxBuffer1[],rec_f,tx_flag;vola tile uint8_t TxCounter1 = 0x00;volatile uint8_t RxCounter1 = 0x00;uint32_t Rec_Len;int main(void){u8 a=0;RCC_Configuration();NVIC_Configuration();GPIO_Configuration();USART_Config(USART1);while(1){if(rec_f==1){rec_f=0;USART_OUT(USART1,&TxBuffer1[0]);if(a==0){GPIO_SetBits(GPIOA, GPIO_Pin_2); a=1;} else{GPIO_ResetBits(GPIOA, GPIO_Pin_2);a=0; }}}}这是主函数部分,在主函数中只有几个函数的初始化,还有就是定义的数组和标志位。
在一般的串口历程中大家会看到的就是定义一个缓冲区,将接收到的串口数据通过串口中断存放到缓冲区中然后在发送到串口中,但是在接收字符串的时候就要用到逐位发送,新手自己有些不了程序,所以只能一直处于蒙着的状态。
其实个人感觉整点原子的程序写的真的挺好的,建议新手开始学习的时候看他的程序,有的人就是不喜欢他写程序的风格,这个因人而异,在这里只是建议一下。
原子的串口就给出了字符串就收的历程,但是用这个历程的时候结尾必须要是0d 0a结尾的也就是空格和回车。
在这了给出一个自己定义的头和尾的串口程序。
串口接收字符串的原理和接收单字符的差不多,只是在接收的时候定义的缓冲区是一个数组,将接受到的数据存放到数组中,在从数组中读出想要的十六进制数在主程序中调用。
手把手教你写STM32的bootloader(SDIO读取TF更新Bootloader)
手把手教你写STM32的bootloader(SDIO读取TF卡更新固件)作者:谭建裕1、bootloader的简介及作用什么是bootloader?本人不知道该怎么说,反正会来看这篇都是知道自己要干嘛的。
不过bootloader的作用还是要提提的,bootloader最直观的作用就方便,比如你用单片机给人家做了一款产品,后期你的产品固件需要更新的时候,你总不能带着电脑直接去客户那里拆开产品给单片机下程序吧?也不能教客户怎么给单片机下程序吧?用户体验感太差。
其实本质上bootloader的也是一个完整的程序,也有main函数,有自己的中断向量表,栈顶指针,它可以检查有没有新的固件,如果有,则将新的固件的数据写入到我们指定的flash地址中,之后跳到新的程序中去就OK了。
此时bootloader的优势就来了,bootloade 更新固件有很多种方式,本人在这里只详细讲解一种,搞懂一种之后,其它的都好办,因为它们的思路都是一样的。
Bootloader的主体原理是:首先将bin文件的数据复制到特定的地址。
然后设置中断向量表,设置MSP主堆栈指针(具体请看CM3权威指南),设置复位向量。
然后就没有然后了。
2、bootloader涉及的知识本人在此讲解的是STM32通过读取TF内的bin文件数据来更新固件。
这里牵扯到STM32的SDIO外设,FATFS文件系统,STM32的flash读写操作。
2.1 SDIOSDIO是STM32的外设,需要注意的是只有100引脚及以上的才有。
电路原理图如图2-1-1所示。
图2-1-1注意:在使用TF之前必须保证TF卡格式为FAT32,单元大小为2048。
如图2-1-2所示。
图2-1-2记得在stm32f10x_it.c文件中添加中断函数。
如图2-1-3所示。
图2-1-32.2 FATFS文件系统移植和使用文件系统使用的是FATFS9,源码在压缩包的ff9文件夹,如图2-2-1所示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
STM32串口读写迪文屏8位、16位、32位数据(应用层实
现)
文章目录
•前言
•一、串口需要的相关实现
•
o
▪数据类型
▪需要自定义实现的变量和函数
•二、迪文屏读写
•
o 2.1 向迪文屏写数据
o 2.2 从迪文屏读取数据
前言
基于STM32F407实现与迪文串口屏T5L系列的串口通信,实现8位,16位,32位的数据读写。
PS:不包含完整程序,这里只说一下核心的代码。
一、串口需要的相关实现
数据类型
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int
//32位int与8位char互转
typedef union
{
u32 intdata;
u8 chardata[4];
}int_char_unioin;
//16位short与8位char互转
typedef union
{
u16 shortdata;
u8 chardata[2];
}short_char_unioin;
需要自定义实现的变量和函数
1.buffer——串口收发缓冲区数组。
2.send_buffer()——向串口发送buffer数组。
3.delay_time——等待迪文屏返回数据的时间,例:5ms,迪文屏上OS的周期是20ms,读写过快可能出问题。
(可能有更好的方法,一般情况下几ms还是可以容忍的。
)
4.clear_usart()——清空串口缓冲区数组buffer,如用memset()将数组置零即可。
二、迪文屏读写
STM32与迪文屏的通信核心在于向迪文屏中定义的变量进行读写,迪文屏中的变量用一个16位数据表示其地址。
迪文屏的用户可操作地址空间为0x1000-0xFFFF,我们要做的就是在这个区间内的一个地址上读写数据,这个地址指向的数据类型由DGUS II(迪文屏开发上位机软件)设置,详细内容可以查看迪文公司的应用开发指南。
2.1 向迪文屏写数据
向迪文屏上的16位地址写8位,16位,32位数据。
/************************************************************** **********************
* @name:write_to_dwin
* @brief:串口4向迪文屏写数据
* @param: addr_h 变量地址高字节
addr_l 变量地址低字节
value_h 变量值高字节
value_l 变量值低字节
* @retval:
*************************************************************** *********************/
void write_to_dwin(u8 addr_h, u8 addr_l, u8 value_h, u8 value_l)
{
u8 write_cmd[8] = {0x5A, 0xA5, 0x05, 0x82, addr_h, addr_l, value_h, value_l};
send_buffer(write_cmd, sizeof(write_cmd));
}
void writeu8_to_dwin(u16 addr, u8 data)
{
short_char_unioin m;
m.shortdata = addr;
write_to_dwin(m.chardata[1], m.chardata[0], 0x00, data);
}
void writeu16_to_dwin(u16 addr, u16 data)
{
short_char_unioin m;
m.shortdata = addr;
short_char_unioin n;
n.shortdata = data;
write_to_dwin(m.chardata[1], m.chardata[0], n.chardata[1], n.chardata[0]);
}
void writeu32_to_dwin(u16 addr, u32 data)
{
short_char_unioin m;
m.shortdata = addr;
int_char_unioin n;
n.intdata = data;
u8 write_cmd[10] = {0x5A, 0xA5, 0x07, 0x82, m.chardata[1], m.chardata[0], n.chardata[3], n.chardata[2], n.chardata[1], n.chardata[0]};
send_buffer(write_cmd, sizeof(write_cmd));
}
2.2 从迪文屏读取数据
从迪文屏上的16位地址上读取8位,16位,32位数据。
/************************************************************** **********************
* @name:read_from_dwin
* @brief:串口4从迪文屏读数据
* @param: addr_h 变量地址高字节
addr_l 变量地址低字节
size 数据大小(单位:字/两字节/16位)
* @retval:
***************************************************************
*********************/
void read_from_dwin(u8 addr_h, u8 addr_l, u8 size)
{
clear_usart();
u8 read_cmd[7] = {0x5A, 0xA5, 0x04, 0x83, addr_h, addr_l, size};
send_buffer(read_cmd, sizeof(read_cmd));
}
u8 readu8_from_dwin(u16 addr)
{
u8 data = 0;
short_char_unioin m;
m.shortdata = addr;
read_from_dwin(m.chardata[1], m.chardata[0], 0x01);
delay_xms(delay_time);
if (buffer[0] == 0x5A && buffer[1] == 0xA5 && buffer[3] == 0x83) //返回数据检查
{
if(buffer[4] == m.chardata[1] && buffer[5] == m.chardata[0]) //地址检查
{
data = buffer[8];
}
}
clear_usart();
return data;
}
u16 readu16_from_dwin(u16 addr)
{
u16 data = 0;
short_char_unioin m;
short_char_unioin n;
m.shortdata = addr;
read_from_dwin(m.chardata[1], m.chardata[0], 0x01);
delay_xms(delay_time);
if (buffer[0] == 0x5A && buffer[1] == 0xA5 && buffer[3] == 0x83) //返回数据检查
{
if(buffer[4] == m.chardata[1] && buffer[5] == m.chardata[0]) //地址检查
{
n.chardata[1] = buffer[7];
n.chardata[0] = buffer[8];
data = n.shortdata;
}
}
clear_usart();
return data;
}
u32 readu32_from_dwin(u16 addr)
{
u32 data = 0;
short_char_unioin m;
m.shortdata = addr;
int_char_unioin n;
read_from_dwin(m.chardata[1], m.chardata[0], 0x02);
delay_xms(delay_time);
if (buffer[0] == 0x5A && buffer[1] == 0xA5 && buffer[3] == 0x83) //返回数据检查
{
if(buffer[4] == [1] && buffer[5] == m.chardata[0]) //地址检查{
n.chardata[3] = buffer[7];
n.chardata[2] = buffer[8];
n.chardata[1] = buffer[9];
n.chardata[0] = buffer[10];
data = n.intdata;
}
}
clear_usart();
return data;
}。