├── .DS_Store ├── Code ├── .DS_Store ├── README.md ├── USART Send Only │ ├── valuepack.c │ └── valuepack.h ├── USART+DMA │ ├── valuepack.c │ └── valuepack.h └── USART+Interruption │ ├── valuepack.c │ └── valuepack.h ├── Examples ├── .DS_Store ├── PWM控制彩灯 │ ├── main.c │ ├── valuepack.c │ └── valuepack.h ├── STM32F103收发示例 │ ├── STM32F103仅发送数据包 │ │ ├── main.c │ │ ├── valuepack.c │ │ └── valuepack.h │ ├── STM32F103基于DMA+USART收发数据 │ │ ├── main.c │ │ ├── valuepack.c │ │ └── valuepack.h │ └── STM32F103基于USART中断收发数据 │ │ ├── main.c │ │ ├── valuepack.c │ │ └── valuepack.h ├── 心率检测MAX30100 │ ├── fake_i2c.c │ ├── fake_i2c.h │ ├── main.c │ ├── valuepack.c │ └── valuepack.h ├── 心率检测MAX30102 │ ├── fake_i2c.c │ ├── fake_i2c.h │ ├── main.c │ ├── valuepack.c │ └── valuepack.h ├── 控制LED灯 │ ├── main.c │ ├── valuepack.c │ └── valuepack.h ├── 湿度回传 │ ├── 湿度回传-USART+DMA │ │ ├── main.c │ │ ├── valuepack.c │ │ └── valuepack.h │ ├── 湿度回传-USART+中断 │ │ ├── main.c │ │ ├── valuepack.c │ │ └── valuepack.h │ └── 湿度回传-USART简版 │ │ ├── main.c │ │ ├── valuepack.c │ │ └── valuepack.h └── 超声波测距 │ ├── main.c │ ├── valuepack.c │ └── valuepack.h └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XieLazyDog/ValuePack/19c998d7d8b9fa73f1f5d1a3106b1dd938c65c2e/.DS_Store -------------------------------------------------------------------------------- /Code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XieLazyDog/ValuePack/19c998d7d8b9fa73f1f5d1a3106b1dd938c65c2e/Code/.DS_Store -------------------------------------------------------------------------------- /Code/README.md: -------------------------------------------------------------------------------- 1 | 此目录下存放了实现与手机进行数据收发的基本库文件。其实现了针对应用“蓝牙调试器”的协议。 2 | 代码是基于STM32F103的,代码通过三种方式实现了数据包的收发。 3 | 4 | 1.USART+DMA 5 | 6 | 性能最高,需要DMA通道支持 7 | 8 | 2.USART+接收中断 9 | 10 | 需要频繁进入中断接收数据 11 | 12 | 3.USART 仅发送 13 | 14 | 仅支持将数据回传,采用start-put-end-send 流程,无需配置数据结构。 15 | -------------------------------------------------------------------------------- /Code/USART Send Only/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char *valuepack_tx_buffer; 4 | unsigned short valuepack_tx_index; 5 | unsigned char valuepack_tx_bit_index; 6 | unsigned char valuepack_stage; 7 | 8 | void initValuePack(int baudrate) 9 | { 10 | 11 | USART_InitTypeDef USART_InitStructure; 12 | GPIO_InitTypeDef GPIO_InitStructure; 13 | 14 | // 时钟初始化 15 | 16 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 17 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 18 | 19 | // 引脚初始化 20 | 21 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 22 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 23 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 24 | GPIO_Init(GPIOA, &GPIO_InitStructure); 25 | /* PA10 USART1_Rx */ 26 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 27 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 28 | GPIO_Init(GPIOA, &GPIO_InitStructure); 29 | 30 | // 串口初始化 31 | 32 | USART_InitStructure.USART_BaudRate = baudrate; 33 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 34 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 35 | USART_InitStructure.USART_Parity = USART_Parity_No; 36 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 37 | USART_InitStructure.USART_Mode = USART_Mode_Tx; 38 | USART_Init(USART1, &USART_InitStructure); 39 | USART_Cmd(USART1, ENABLE); 40 | } 41 | 42 | 43 | // 1. 开始将数据打包,需传入定义好的数组(需保证数组长度足以存放要发送的数据) 44 | 45 | void startValuePack(unsigned char *buffer) 46 | { 47 | valuepack_tx_buffer = buffer; 48 | valuepack_tx_index = 1; 49 | valuepack_tx_bit_index = 0; 50 | valuepack_tx_buffer[0] = PACK_HEAD; 51 | valuepack_stage = 0; 52 | } 53 | 54 | // 2. 向数据包中放入各类数据,由于数据包的顺序结构是固定的,因此注意严格以如下的顺序进行存放,否则会出现错误 55 | 56 | void putBool(unsigned char b) 57 | { 58 | if(valuepack_stage<=1) 59 | { 60 | if(b) 61 | valuepack_tx_buffer[valuepack_tx_index] |= 0x01<=8) 67 | { 68 | valuepack_tx_bit_index = 0; 69 | valuepack_tx_index++; 70 | } 71 | valuepack_stage = 1; 72 | } 73 | } 74 | 75 | 76 | void putByte(char b) 77 | { 78 | if(valuepack_stage<=2) 79 | { 80 | if(valuepack_tx_bit_index!=0) 81 | { 82 | valuepack_tx_index++; 83 | valuepack_tx_bit_index = 0; 84 | } 85 | valuepack_tx_buffer[valuepack_tx_index] = b; 86 | valuepack_tx_index++; 87 | 88 | valuepack_stage = 2; 89 | } 90 | } 91 | void putShort(short s) 92 | { 93 | if(valuepack_stage<=3) 94 | { 95 | if(valuepack_tx_bit_index!=0) 96 | { 97 | valuepack_tx_index++; 98 | valuepack_tx_bit_index = 0; 99 | } 100 | valuepack_tx_buffer[valuepack_tx_index] = s&0xff; 101 | valuepack_tx_buffer[valuepack_tx_index+1] = s>>8; 102 | 103 | valuepack_tx_index +=2; 104 | valuepack_stage = 3; 105 | } 106 | } 107 | void putInt(int i) 108 | { 109 | if(valuepack_stage<=4) 110 | { 111 | if(valuepack_tx_bit_index!=0) 112 | { 113 | valuepack_tx_index++; 114 | valuepack_tx_bit_index = 0; 115 | } 116 | 117 | valuepack_tx_buffer[valuepack_tx_index] = i&0xff; 118 | valuepack_tx_buffer[valuepack_tx_index+1] = (i>>8)&0xff; 119 | valuepack_tx_buffer[valuepack_tx_index+2] = (i>>16)&0xff; 120 | valuepack_tx_buffer[valuepack_tx_index+3] = (i>>24)&0xff; 121 | 122 | valuepack_tx_index +=4; 123 | 124 | valuepack_stage = 4; 125 | } 126 | } 127 | int fi; 128 | void putFloat(float f) 129 | { 130 | if(valuepack_stage<=5) 131 | { 132 | if(valuepack_tx_bit_index!=0) 133 | { 134 | valuepack_tx_index++; 135 | valuepack_tx_bit_index = 0; 136 | } 137 | 138 | fi = *(int*)(&f); 139 | valuepack_tx_buffer[valuepack_tx_index] = fi&0xff; 140 | valuepack_tx_buffer[valuepack_tx_index+1] = (fi>>8)&0xff; 141 | valuepack_tx_buffer[valuepack_tx_index+2] = (fi>>16)&0xff; 142 | valuepack_tx_buffer[valuepack_tx_index+3] = (fi>>24)&0xff; 143 | valuepack_tx_index +=4; 144 | valuepack_stage = 5; 145 | } 146 | } 147 | 148 | 149 | 150 | 151 | // 3. 结束打包,函数将返回 数据包的总长度 152 | unsigned short endValuePack() 153 | { 154 | unsigned char sum=0; 155 | for(int i=1;i>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 5 | 6 | // 接收数据包的字节长度 7 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 8 | 9 | // 接收数据包的原数据加上包头、校验和包尾 之后的字节长度 10 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 11 | 12 | // 接收计数-记录当前的数据接收进度 13 | // 接收计数每次随串口的接收中断后 +1 14 | long rxIndex=0; 15 | 16 | // 读取计数-记录当前的数据包读取进度,读取计数会一直落后于接收计数,当读取计数与接收计数之间距离超过一个接收数据包的长度时,会启动一次数据包的读取。 17 | // 读取计数每次在读取数据包后增加 +(数据包长度) 18 | long rdIndex=0; 19 | 20 | // 用于环形缓冲区的数组,环形缓冲区的大小可以在.h文件中定义VALUEPACK_BUFFER_SIZE 21 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 22 | 23 | // 用于暂存发送数据的数组 24 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 25 | 26 | 27 | DMA_InitTypeDef dma; 28 | 29 | //--------------------------------------------------------------------------------------------------------------------- 30 | // 初始化DMA和串口USART0 可设置串口波特率 31 | // DMA将串口接收寄存器和接收缓冲数组连接,将DMA设置为循环模式,实现环形缓冲区 32 | void initValuePack(int baudrate) 33 | { 34 | USART_InitTypeDef USART_InitStructure; 35 | GPIO_InitTypeDef GPIO_InitStructure; 36 | // 时钟初始化 37 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 38 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 39 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); 40 | 41 | // 引脚初始化 42 | 43 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 44 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 45 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 46 | GPIO_Init(GPIOA, &GPIO_InitStructure); 47 | /* PA10 USART1_Rx */ 48 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 49 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 50 | GPIO_Init(GPIOA, &GPIO_InitStructure); 51 | 52 | // 串口初始化 53 | 54 | USART_InitStructure.USART_BaudRate = baudrate; 55 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 56 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 57 | USART_InitStructure.USART_Parity = USART_Parity_No; 58 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 59 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 60 | USART_Init(USART1, &USART_InitStructure); 61 | 62 | // DMA初始化 63 | 64 | DMA_DeInit(DMA1_Channel4); 65 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 66 | dma.DMA_M2M = DMA_M2M_Disable; 67 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 68 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 69 | 70 | dma.DMA_Priority = DMA_Priority_High; 71 | dma.DMA_BufferSize = 4; 72 | dma.DMA_MemoryBaseAddr = (uint32_t)0; 73 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 74 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 75 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 76 | dma.DMA_Mode = DMA_Mode_Normal; 77 | DMA_Init(DMA1_Channel4,&dma); 78 | 79 | USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 80 | 81 | DMA_DeInit(DMA1_Channel5); 82 | dma.DMA_DIR = DMA_DIR_PeripheralSRC; 83 | dma.DMA_BufferSize = VALUEPACK_BUFFER_SIZE; 84 | dma.DMA_MemoryBaseAddr = (uint32_t)vp_rxbuff; 85 | dma.DMA_Mode = DMA_Mode_Circular; 86 | DMA_Init(DMA1_Channel5,&dma); 87 | 88 | USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); 89 | USART_Cmd(USART1, ENABLE); 90 | DMA_Cmd(DMA1_Channel5,ENABLE); 91 | } 92 | 93 | 94 | // 数据读取涉及到的变量 95 | unsigned short this_index=0; 96 | unsigned short last_index=0; 97 | unsigned short rdi,rdii,idl,idi,bool_index,bool_bit; 98 | uint32_t idc; 99 | // 记录读取的错误字节的次数 100 | unsigned int err=0; 101 | // 用于和校验 102 | unsigned char sum=0; 103 | // 存放数据包读取的结果 104 | unsigned char isok; 105 | 106 | //------------------------------------------------------------------------------------------------------------------------ 107 | // unsigned char readValuePack(RxPack *rx_pack_ptr) 108 | // 尝试从缓冲区中读取数据包 109 | // 参数 - RxPack *rx_pack_ptr: 传入接收数据结构体的指针,从环形缓冲区中读取出数据包,并将各类数据存储到rx_pack_ptr指向的结构体中 110 | // 返回值 - 如果成功读取到数据包,则返回1,否则返回0 111 | // 112 | 113 | unsigned char readValuePack(RxPack *rx_pack_ptr) 114 | { 115 | isok = 0; 116 | 117 | // 这次通过DMA接收的计数值 118 | this_index =VALUEPACK_BUFFER_SIZE-DMA1_Channel5->CNDTR; 119 | 120 | // 根据上次DMA计数值和本次DMA计数值的差值,确定两次函数执行中间接收的数据字节数,并使rxIndex增加 121 | if(this_index=VALUEPACK_BUFFER_SIZE) 147 | rdi -= VALUEPACK_BUFFER_SIZE; 148 | sum += vp_rxbuff[rdi]; 149 | } 150 | rdi++; 151 | if(rdi>=VALUEPACK_BUFFER_SIZE) 152 | rdi -= VALUEPACK_BUFFER_SIZE; 153 | 154 | if(sum==vp_rxbuff[rdi]) 155 | { 156 | // 提取数据包数据 一共有五步, bool byte short int float 157 | 158 | // 1. bool 159 | #if RX_BOOL_NUM>0 160 | 161 | idc = (uint32_t)rx_pack_ptr->bools; 162 | idl = (RX_BOOL_NUM+7)>>3; 163 | 164 | bool_bit = 0; 165 | for(bool_index=0;bool_index=8) 170 | { 171 | bool_bit = 0; 172 | rdii ++; 173 | } 174 | } 175 | if(bool_bit) 176 | rdii ++; 177 | #endif 178 | // 2.byte 179 | #if RX_BYTE_NUM>0 180 | idc = (uint32_t)(rx_pack_ptr->bytes); 181 | idl = RX_BYTE_NUM; 182 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 185 | rdii -= VALUEPACK_BUFFER_SIZE; 186 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 187 | rdii++; 188 | idc++; 189 | } 190 | #endif 191 | // 3.short 192 | #if RX_SHORT_NUM>0 193 | idc = (uint32_t)(rx_pack_ptr->shorts); 194 | idl = RX_SHORT_NUM<<1; 195 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 198 | rdii -= VALUEPACK_BUFFER_SIZE; 199 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 200 | rdii++; 201 | idc++; 202 | } 203 | #endif 204 | // 4.int 205 | #if RX_INT_NUM>0 206 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 207 | idl = RX_INT_NUM<<2; 208 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 211 | rdii -= VALUEPACK_BUFFER_SIZE; 212 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 213 | rdii++; 214 | idc++; 215 | } 216 | #endif 217 | // 5.float 218 | #if RX_FLOAT_NUM>0 219 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 220 | idl = RX_FLOAT_NUM<<2; 221 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 224 | rdii -= VALUEPACK_BUFFER_SIZE; 225 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 226 | rdii++; 227 | idc++; 228 | } 229 | #endif 230 | // 更新读取计数 231 | rdIndex+=rx_pack_length; 232 | isok = 1; 233 | }else 234 | { 235 | // 校验值错误 则 err+1 且 更新读取计数 236 | rdIndex++; 237 | err++; 238 | } 239 | }else 240 | { 241 | // 包尾错误 则 err+1 且 更新读取计数 242 | rdIndex++; 243 | err++; 244 | } 245 | }else 246 | { 247 | // 包头错误 则 err+1 且 更新读取计数 248 | rdIndex++; 249 | err++; 250 | } 251 | } 252 | last_index = this_index; 253 | return isok; 254 | } 255 | 256 | //-------------------------------------------------------------------------------------- 257 | // 配置 DMA 使用DMA通过串口 发送数据 258 | // 259 | 260 | void sendBuffer(unsigned char *p,unsigned short length) 261 | { 262 | DMA_DeInit(DMA1_Channel4); 263 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 264 | dma.DMA_M2M = DMA_M2M_Disable; 265 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 266 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 267 | dma.DMA_Priority = DMA_Priority_High; 268 | dma.DMA_BufferSize = length; 269 | dma.DMA_MemoryBaseAddr = (uint32_t)p; 270 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 271 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 272 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 273 | dma.DMA_Mode = DMA_Mode_Normal; 274 | DMA_Init(DMA1_Channel4,&dma); 275 | DMA_Cmd(DMA1_Channel4,ENABLE); 276 | } 277 | 278 | // 数据包发送涉及的变量 279 | unsigned short loop; 280 | unsigned char valuepack_tx_bit_index; 281 | unsigned char valuepack_tx_index; 282 | 283 | //--------------------------------------------------------------------------------------------------------- 284 | // void sendValuePack(TxPack *tx_pack_ptr) 285 | // 将发送数据结构体中的变量打包,并发送出去 286 | // 传入参数- TxPack *tx_pack_ptr 待发送数据包的指针 287 | // 288 | // 先将待发送数据包结构体的变量转移到“发送数据缓冲区”中,然后将发送数据缓冲区中的数据发送 289 | // 290 | void sendValuePack(TxPack *tx_pack_ptr) 291 | { 292 | int i; 293 | vp_txbuff[0]=0xa5; 294 | sum=0; 295 | // 由于结构体中不同类型的变量在内存空间的排布不是严格对齐的,中间嵌有无效字节,因此需要特殊处理 296 | 297 | valuepack_tx_bit_index = 0; 298 | valuepack_tx_index = 1; 299 | 300 | #if TX_BOOL_NUM>0 301 | 302 | for(loop=0;loopbools[loop]) 306 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 313 | { 314 | valuepack_tx_bit_index = 0; 315 | valuepack_tx_index++; 316 | } 317 | } 318 | if(valuepack_tx_bit_index!=0) 319 | valuepack_tx_index++; 320 | #endif 321 | 322 | #if TX_BYTE_NUM>0 323 | for(loop=0;loopbytes[loop]; 326 | valuepack_tx_index++; 327 | } 328 | #endif 329 | #if TX_SHORT_NUM>0 330 | for(loop=0;loopshorts[loop]&0xff; 333 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 334 | valuepack_tx_index+=2; 335 | } 336 | #endif 337 | 338 | #if TX_INT_NUM>0 339 | for(loop=0;loopintegers[loop]; 342 | vp_txbuff[valuepack_tx_index] = i&0xff; 343 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 344 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 345 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 346 | valuepack_tx_index+=4; 347 | } 348 | #endif 349 | 350 | #if TX_FLOAT_NUM>0 351 | for(loop=0;loopfloats[loop])); 354 | vp_txbuff[valuepack_tx_index] = i&0xff; 355 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 356 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 357 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 358 | valuepack_tx_index+=4; 359 | } 360 | #endif 361 | 362 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 363 | sum+=vp_txbuff[d]; 364 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 365 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 366 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 367 | } 368 | 369 | 370 | 371 | -------------------------------------------------------------------------------- /Code/USART+DMA/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过DMA和USART 进行数据包的接收和发送 4 | // 接收的数据自动写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | // 数据发送也采用DMA 6 | 7 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 8 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 9 | #define VALUEPACK_BUFFER_SIZE 1024 10 | 11 | 12 | /// 2.指定发送到手机的数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 13 | /// 14 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 15 | 16 | #define TX_BOOL_NUM 0 17 | #define TX_BYTE_NUM 0 18 | #define TX_SHORT_NUM 0 19 | #define TX_INT_NUM 0 20 | #define TX_FLOAT_NUM 0 21 | 22 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 23 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 24 | 25 | #define RX_BOOL_NUM 0 26 | #define RX_BYTE_NUM 0 27 | #define RX_SHORT_NUM 0 28 | #define RX_INT_NUM 0 29 | #define RX_FLOAT_NUM 0 30 | 31 | 32 | 33 | typedef struct 34 | { 35 | #if TX_BOOL_NUM > 0 36 | unsigned char bools[TX_BOOL_NUM]; 37 | #endif 38 | 39 | #if TX_BYTE_NUM > 0 40 | char bytes[TX_BYTE_NUM]; 41 | #endif 42 | 43 | #if TX_SHORT_NUM > 0 44 | short shorts[TX_SHORT_NUM]; 45 | #endif 46 | 47 | #if TX_INT_NUM > 0 48 | int integers[TX_INT_NUM]; 49 | #endif 50 | 51 | #if TX_FLOAT_NUM > 0 52 | float floats[TX_FLOAT_NUM]; 53 | #endif 54 | 55 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 56 | } 57 | TxPack; 58 | typedef struct 59 | { 60 | #if RX_BOOL_NUM > 0 61 | unsigned char bools[RX_BOOL_NUM]; 62 | #endif 63 | 64 | #if RX_BYTE_NUM > 0 65 | char bytes[RX_BYTE_NUM]; 66 | #endif 67 | 68 | #if RX_SHORT_NUM > 0 69 | short shorts[RX_SHORT_NUM]; 70 | #endif 71 | 72 | #if RX_INT_NUM > 0 73 | int integers[RX_INT_NUM]; 74 | #endif 75 | 76 | #if RX_FLOAT_NUM > 0 77 | float floats[RX_FLOAT_NUM]; 78 | #endif 79 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 80 | }RxPack; 81 | // 初始化 valuepack 包括一些必要的硬件外设配置 82 | 83 | void initValuePack(int baudrate); 84 | 85 | // 需要保证至少每秒执行10次该函数 86 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 87 | // 接收到数据包时 返回 1 ,否则返回 0 88 | unsigned char readValuePack(RxPack *rx_pack_ptr); 89 | 90 | 91 | // 发送数据包 92 | void sendValuePack(TxPack *tx_pack_ptr); 93 | 94 | 95 | #define PACK_HEAD 0xa5 96 | #define PACK_TAIL 0x5a 97 | -------------------------------------------------------------------------------- /Code/USART+Interruption/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | // 发送数据包的字节长度 4 | const unsigned short TXPACK_BYTE_SIZE = ((TX_BOOL_NUM+7)>>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 5 | 6 | // 接收数据包的字节长度 7 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 8 | 9 | // 接收数据包的原数据加上包头、校验和包尾 之后的字节长度 10 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 11 | 12 | // 接收计数-记录当前的数据接收进度 13 | // 接收计数每次随串口的接收中断后 +1 14 | long rxIndex=0; 15 | 16 | // 读取计数-记录当前的数据包读取进度,读取计数会一直落后于接收计数,当读取计数与接收计数之间距离超过一个接收数据包的长度时,会启动一次数据包的读取。 17 | // 读取计数每次在读取数据包后增加 +(数据包长度) 18 | long rdIndex=0; 19 | 20 | // 用于环形缓冲区的数组,环形缓冲区的大小可以在.h文件中定义VALUEPACK_BUFFER_SIZE 21 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 22 | 23 | // 用于暂存发送数据的数组 24 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 25 | 26 | // 初始化数据包 使用的是USART1 波特率可配置 27 | void initValuePack(int baudrate) 28 | { 29 | 30 | USART_InitTypeDef USART_InitStructure; 31 | GPIO_InitTypeDef GPIO_InitStructure; 32 | NVIC_InitTypeDef NVIC_InitStructure; 33 | 34 | // 时钟初始化 35 | 36 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 37 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 38 | 39 | // 引脚初始化 40 | 41 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 42 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 43 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 44 | GPIO_Init(GPIOA, &GPIO_InitStructure); 45 | /* PA10 USART1_Rx */ 46 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 47 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 48 | GPIO_Init(GPIOA, &GPIO_InitStructure); 49 | 50 | // 串口初始化 51 | 52 | USART_InitStructure.USART_BaudRate = baudrate; 53 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 54 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 55 | USART_InitStructure.USART_Parity = USART_Parity_No; 56 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 57 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 58 | USART_Init(USART1, &USART_InitStructure); 59 | USART_ClearITPendingBit(USART1,USART_IT_RXNE); 60 | USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); 61 | 62 | NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 63 | NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 64 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 65 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; 66 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 67 | NVIC_Init(&NVIC_InitStructure); 68 | 69 | USART_Cmd(USART1, ENABLE); 70 | } 71 | 72 | 73 | // 数据包环形缓冲区计数 74 | unsigned int vp_circle_rx_index; 75 | 76 | // 串口接收中断 服务函数, 每次接收到数据后将字节存入环形缓冲区中,从头存到尾。所谓的环形缓冲区就是当接收环形缓冲区计数大于等于缓冲区的大小时(即数据到达缓冲区的尾部时) 77 | // 数据会在缓冲区的头部继续存储,覆盖掉最早的数据。 78 | void USART1_IRQHandler(void) 79 | { 80 | // 判断是否是USART1接收了数据 81 | if(USART_GetITStatus(USART1, USART_IT_RXNE)) 82 | { 83 | // 读取数据到缓冲区中 84 | vp_rxbuff[vp_circle_rx_index] = USART1->DR; 85 | 86 | // 将环形缓冲接收计数加一 87 | vp_circle_rx_index++; 88 | // 数据到达缓冲区尾部后,转移到头部 89 | if(vp_circle_rx_index>=VALUEPACK_BUFFER_SIZE) 90 | vp_circle_rx_index=0; 91 | 92 | // 将全局接收计数加一 93 | rxIndex++; 94 | } 95 | USART_ClearITPendingBit(USART1,USART_IT_RXNE); 96 | } 97 | 98 | 99 | // 数据读取涉及到的变量 100 | unsigned short rdi,rdii,idl,idi,bool_index,bool_bit; 101 | // 变量地址 102 | uint32_t idc; 103 | // 记录读取的错误字节的次数 104 | unsigned int err=0; 105 | // 用于和校验 106 | unsigned char sum=0; 107 | 108 | // 存放数据包读取的结果 109 | unsigned char isok; 110 | 111 | 112 | //------------------------------------------------------------------------------------------------------------------------ 113 | // unsigned char readValuePack(RxPack *rx_pack_ptr) 114 | // 尝试从缓冲区中读取数据包 115 | // 参数 - RxPack *rx_pack_ptr: 传入接收数据结构体的指针,从环形缓冲区中读取出数据包,并将各类数据存储到rx_pack_ptr指向的结构体中 116 | // 返回值 - 如果成功读取到数据包,则返回1,否则返回0 117 | // 118 | 119 | unsigned char readValuePack(RxPack *rx_pack_ptr) 120 | { 121 | 122 | isok = 0; 123 | 124 | // 确保读取计数和接收计数之间的距离小于2个数据包的长度 125 | while(rdIndex<(rxIndex-((rx_pack_length)*2))) 126 | rdIndex+=rx_pack_length; 127 | 128 | // 如果读取计数落后于接收计数超过 1个 数据包的长度,则尝试读取 129 | while(rdIndex<=(rxIndex-rx_pack_length)) 130 | { 131 | rdi = rdIndex % VALUEPACK_BUFFER_SIZE; 132 | rdii=rdi+1; 133 | if( vp_rxbuff[rdi]==PACK_HEAD) // 比较包头 134 | { 135 | if(vp_rxbuff[(rdi+RXPACK_BYTE_SIZE+2)%VALUEPACK_BUFFER_SIZE]==PACK_TAIL) // 比较包尾 确定包尾后,再计算校验和 136 | { 137 | // 计算校验和 138 | sum=0; 139 | for(short s=0;s=VALUEPACK_BUFFER_SIZE) 143 | rdi -= VALUEPACK_BUFFER_SIZE; 144 | sum += vp_rxbuff[rdi]; 145 | } 146 | rdi++; 147 | if(rdi>=VALUEPACK_BUFFER_SIZE) 148 | rdi -= VALUEPACK_BUFFER_SIZE; 149 | 150 | if(sum==vp_rxbuff[rdi]) // 校验和正确,则开始将缓冲区中的数据读取出来 151 | { 152 | // 提取数据包数据 一共有五步, bool byte short int float 153 | // 1. bool 154 | #if RX_BOOL_NUM>0 155 | 156 | idc = (uint32_t)rx_pack_ptr->bools; 157 | idl = (RX_BOOL_NUM+7)>>3; 158 | 159 | bool_bit = 0; 160 | for(bool_index=0;bool_index=8) 165 | { 166 | bool_bit = 0; 167 | rdii ++; 168 | } 169 | } 170 | if(bool_bit) 171 | rdii ++; 172 | 173 | #endif 174 | // 2.byte 175 | #if RX_BYTE_NUM>0 176 | idc = (uint32_t)(rx_pack_ptr->bytes); 177 | idl = RX_BYTE_NUM; 178 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 181 | rdii -= VALUEPACK_BUFFER_SIZE; 182 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 183 | rdii++; 184 | idc++; 185 | } 186 | #endif 187 | // 3.short 188 | #if RX_SHORT_NUM>0 189 | idc = (uint32_t)(rx_pack_ptr->shorts); 190 | idl = RX_SHORT_NUM<<1; 191 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 194 | rdii -= VALUEPACK_BUFFER_SIZE; 195 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 196 | rdii++; 197 | idc++; 198 | } 199 | #endif 200 | // 4.int 201 | #if RX_INT_NUM>0 202 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 203 | idl = RX_INT_NUM<<2; 204 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 207 | rdii -= VALUEPACK_BUFFER_SIZE; 208 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 209 | rdii++; 210 | idc++; 211 | } 212 | #endif 213 | // 5.float 214 | #if RX_FLOAT_NUM>0 215 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 216 | idl = RX_FLOAT_NUM<<2; 217 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 220 | rdii -= VALUEPACK_BUFFER_SIZE; 221 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 222 | rdii++; 223 | idc++; 224 | } 225 | #endif 226 | 227 | // 更新读取计数 228 | rdIndex+=rx_pack_length; 229 | isok = 1; 230 | }else 231 | { 232 | // 校验值错误 则 err+1 且 更新读取计数 233 | rdIndex++; 234 | err++; 235 | } 236 | }else 237 | { 238 | // 包尾错误 则 err+1 且 更新读取计数 239 | rdIndex++; 240 | err++; 241 | } 242 | }else 243 | { 244 | // 包头错误 则 err+1 且 更新读取计数 245 | rdIndex++; 246 | err++; 247 | } 248 | } 249 | return isok; 250 | } 251 | 252 | //------------------------------------------------------------------------------------------------------------------------- 253 | // void sendBuffer(unsigned char *p,unsigned short length) 254 | // 发送数据包 255 | // 传入指针 和 字节长度 256 | 257 | void sendBuffer(unsigned char *p,unsigned short length) 258 | { 259 | for(int i=0;i0 290 | for(loop=0;loopbools[loop]) 293 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 299 | { 300 | valuepack_tx_bit_index = 0; 301 | valuepack_tx_index++; 302 | } 303 | } 304 | if(valuepack_tx_bit_index!=0) 305 | valuepack_tx_index++; 306 | #endif 307 | #if TX_BYTE_NUM>0 308 | 309 | for(loop=0;loopbytes[loop]; 312 | valuepack_tx_index++; 313 | } 314 | #endif 315 | 316 | #if TX_SHORT_NUM>0 317 | for(loop=0;loopshorts[loop]&0xff; 320 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 321 | valuepack_tx_index+=2; 322 | } 323 | #endif 324 | 325 | #if TX_INT_NUM>0 326 | for(loop=0;loopintegers[loop]; 329 | vp_txbuff[valuepack_tx_index] = i&0xff; 330 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 331 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 332 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 333 | valuepack_tx_index+=4; 334 | } 335 | #endif 336 | 337 | #if TX_FLOAT_NUM>0 338 | for(loop=0;loopfloats[loop])); 341 | vp_txbuff[valuepack_tx_index] = i&0xff; 342 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 343 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 344 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 345 | valuepack_tx_index+=4; 346 | } 347 | #endif 348 | 349 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 350 | sum+=vp_txbuff[d]; 351 | 352 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 353 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 354 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 355 | } 356 | 357 | 358 | 359 | -------------------------------------------------------------------------------- /Code/USART+Interruption/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过USART 配合接收中断 进行数据包的接收和发送 4 | // 接收的数据在接收中断中写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | 6 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 7 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 8 | #define VALUEPACK_BUFFER_SIZE 1024 9 | 10 | 11 | /// 2.指定发送数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 12 | /// 13 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 14 | 15 | #define TX_BOOL_NUM 0 16 | #define TX_BYTE_NUM 0 17 | #define TX_SHORT_NUM 0 18 | #define TX_INT_NUM 0 19 | #define TX_FLOAT_NUM 0 20 | 21 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 22 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 23 | 24 | #define RX_BOOL_NUM 0 25 | #define RX_BYTE_NUM 0 26 | #define RX_SHORT_NUM 0 27 | #define RX_INT_NUM 0 28 | #define RX_FLOAT_NUM 0 29 | 30 | 31 | 32 | typedef struct 33 | { 34 | #if TX_BOOL_NUM > 0 35 | unsigned char bools[TX_BOOL_NUM]; 36 | #endif 37 | 38 | #if TX_BYTE_NUM > 0 39 | char bytes[TX_BYTE_NUM]; 40 | #endif 41 | 42 | #if TX_SHORT_NUM > 0 43 | short shorts[TX_SHORT_NUM]; 44 | #endif 45 | 46 | #if TX_INT_NUM > 0 47 | int integers[TX_INT_NUM]; 48 | #endif 49 | 50 | #if TX_FLOAT_NUM > 0 51 | float floats[TX_FLOAT_NUM]; 52 | #endif 53 | char space; //只是为了占一个空,当所有变量数目都为0时确保编译成功 54 | } 55 | TxPack; 56 | typedef struct 57 | { 58 | #if RX_BOOL_NUM > 0 59 | unsigned char bools[RX_BOOL_NUM]; 60 | #endif 61 | 62 | #if RX_BYTE_NUM > 0 63 | char bytes[RX_BYTE_NUM]; 64 | #endif 65 | 66 | #if RX_SHORT_NUM > 0 67 | short shorts[RX_SHORT_NUM]; 68 | #endif 69 | 70 | #if RX_INT_NUM > 0 71 | int integers[RX_INT_NUM]; 72 | #endif 73 | 74 | #if RX_FLOAT_NUM > 0 75 | float floats[RX_FLOAT_NUM]; 76 | #endif 77 | char space; //只是为了占一个空,当所有变量数目都为0时确保编译成功 78 | }RxPack; 79 | // 初始化 valuepack 包括一些必要的硬件外设配置 80 | // 并指定要传输的数据包 81 | void initValuePack(int baudrate); 82 | 83 | // 需要保证至少每秒执行10次该函数 84 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 85 | // 接收到数据包时 返回 1 ,否则返回 0 86 | unsigned char readValuePack(RxPack *rx_pack_ptr); 87 | 88 | 89 | // 发送数据包 90 | void sendValuePack(TxPack *tx_pack_ptr); 91 | 92 | 93 | 94 | #define PACK_HEAD 0xa5 95 | #define PACK_TAIL 0x5a 96 | 97 | #define TX_MODE_SEND_BACK 0 98 | #define TX_MODE_ALWAYS 1 99 | #define TX_MODE_DISABLE 2 100 | -------------------------------------------------------------------------------- /Examples/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XieLazyDog/ValuePack/19c998d7d8b9fa73f1f5d1a3106b1dd938c65c2e/Examples/.DS_Store -------------------------------------------------------------------------------- /Examples/PWM控制彩灯/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XieLazyDog/ValuePack/19c998d7d8b9fa73f1f5d1a3106b1dd938c65c2e/Examples/PWM控制彩灯/main.c -------------------------------------------------------------------------------- /Examples/PWM控制彩灯/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char bits[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 4 | 5 | const unsigned int VALUEPACK_INDEX_RANGE=VALUEPACK_BUFFER_SIZE<<3; 6 | const unsigned short TXPACK_BYTE_SIZE = ((TX_BOOL_NUM+7)>>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 7 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 8 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 9 | 10 | 11 | long rxIndex=0; 12 | long rdIndex=0; 13 | 14 | 15 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 16 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 17 | 18 | 19 | DMA_InitTypeDef dma; 20 | 21 | void initValuePack(int baudrate) 22 | { 23 | 24 | USART_InitTypeDef USART_InitStructure; 25 | GPIO_InitTypeDef GPIO_InitStructure; 26 | 27 | // 时钟初始化 28 | 29 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 30 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 31 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); 32 | 33 | // 引脚初始化 34 | 35 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 36 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 37 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 38 | GPIO_Init(GPIOA, &GPIO_InitStructure); 39 | /* PA10 USART1_Rx */ 40 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 41 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 42 | GPIO_Init(GPIOA, &GPIO_InitStructure); 43 | 44 | // 串口初始化 45 | 46 | USART_InitStructure.USART_BaudRate = baudrate; 47 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 48 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 49 | USART_InitStructure.USART_Parity = USART_Parity_No; 50 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 51 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 52 | 53 | USART_Init(USART1, &USART_InitStructure); 54 | 55 | // DMA初始化 56 | 57 | DMA_DeInit(DMA1_Channel4); 58 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 59 | dma.DMA_M2M = DMA_M2M_Disable; 60 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 61 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 62 | 63 | dma.DMA_Priority = DMA_Priority_High; 64 | dma.DMA_BufferSize = 4; 65 | dma.DMA_MemoryBaseAddr = (uint32_t)0; 66 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 67 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 68 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 69 | dma.DMA_Mode = DMA_Mode_Normal; 70 | DMA_Init(DMA1_Channel4,&dma); 71 | 72 | USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 73 | 74 | DMA_DeInit(DMA1_Channel5); 75 | dma.DMA_DIR = DMA_DIR_PeripheralSRC; 76 | dma.DMA_BufferSize = VALUEPACK_BUFFER_SIZE; 77 | dma.DMA_MemoryBaseAddr = (uint32_t)vp_rxbuff; 78 | dma.DMA_Mode = DMA_Mode_Circular; 79 | DMA_Init(DMA1_Channel5,&dma); 80 | 81 | USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); 82 | USART_Cmd(USART1, ENABLE); 83 | DMA_Cmd(DMA1_Channel5,ENABLE); 84 | 85 | } 86 | 87 | 88 | 89 | unsigned short this_index=0; 90 | unsigned short last_index=0; 91 | unsigned short rdi,rdii,idl,idi; 92 | uint32_t idc; 93 | unsigned int err=0; 94 | unsigned char sum=0; 95 | unsigned char isok; 96 | 97 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 98 | // 99 | //procValuePack 用来处理手机传来的数据 100 | // 101 | 102 | unsigned char readValuePack(RxPack *rx_pack_ptr) 103 | { 104 | isok = 0; 105 | this_index =VALUEPACK_BUFFER_SIZE-DMA1_Channel5->CNDTR; 106 | if(this_index=VALUEPACK_BUFFER_SIZE) 127 | rdi -= VALUEPACK_BUFFER_SIZE; 128 | sum += vp_rxbuff[rdi]; 129 | } 130 | rdi++; 131 | if(rdi>=VALUEPACK_BUFFER_SIZE) 132 | rdi -= VALUEPACK_BUFFER_SIZE; 133 | 134 | if(sum==vp_rxbuff[rdi]) 135 | { 136 | // 提取数据包数据 一共有五步, bool byte short int float 137 | 138 | // 1. bool 139 | #if RX_BOOL_NUM>0 140 | 141 | idc = (uint32_t)rx_pack_ptr->bools; 142 | idl = (RX_BOOL_NUM+7)>>3; 143 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 146 | rdii -= VALUEPACK_BUFFER_SIZE; 147 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 148 | rdii++; 149 | idc++; 150 | } 151 | #endif 152 | // 2.byte 153 | #if RX_BYTE_NUM>0 154 | idc = (uint32_t)(rx_pack_ptr->bytes); 155 | idl = RX_BYTE_NUM; 156 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 159 | rdii -= VALUEPACK_BUFFER_SIZE; 160 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 161 | rdii++; 162 | idc++; 163 | } 164 | #endif 165 | // 3.short 166 | #if RX_SHORT_NUM>0 167 | idc = (uint32_t)(rx_pack_ptr->shorts); 168 | idl = RX_SHORT_NUM<<1; 169 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 172 | rdii -= VALUEPACK_BUFFER_SIZE; 173 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 174 | rdii++; 175 | idc++; 176 | } 177 | #endif 178 | // 4.int 179 | #if RX_INT_NUM>0 180 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 181 | idl = RX_INT_NUM<<2; 182 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 185 | rdii -= VALUEPACK_BUFFER_SIZE; 186 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 187 | rdii++; 188 | idc++; 189 | } 190 | #endif 191 | // 5.float 192 | #if RX_FLOAT_NUM>0 193 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 194 | idl = RX_FLOAT_NUM<<2; 195 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 198 | rdii -= VALUEPACK_BUFFER_SIZE; 199 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 200 | rdii++; 201 | idc++; 202 | } 203 | #endif 204 | err = rdii; 205 | rdIndex+=rx_pack_length; 206 | isok = 1; 207 | }else 208 | { 209 | rdIndex++; 210 | err++; 211 | } 212 | }else 213 | { 214 | rdIndex++; 215 | err++; 216 | } 217 | }else 218 | { 219 | rdIndex++; 220 | err++; 221 | } 222 | } 223 | last_index = this_index; 224 | return isok; 225 | } 226 | 227 | void sendBuffer(unsigned char *p,unsigned short length) 228 | { 229 | DMA_DeInit(DMA1_Channel4); 230 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 231 | dma.DMA_M2M = DMA_M2M_Disable; 232 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 233 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 234 | dma.DMA_Priority = DMA_Priority_High; 235 | dma.DMA_BufferSize = length; 236 | dma.DMA_MemoryBaseAddr = (uint32_t)p; 237 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 238 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 239 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 240 | dma.DMA_Mode = DMA_Mode_Normal; 241 | DMA_Init(DMA1_Channel4,&dma); 242 | DMA_Cmd(DMA1_Channel4,ENABLE); 243 | } 244 | 245 | 246 | 247 | unsigned short loop; 248 | unsigned char valuepack_tx_bit_index; 249 | unsigned char valuepack_tx_index; 250 | 251 | void sendValuePack(TxPack *tx_pack_ptr) 252 | { 253 | int i; 254 | vp_txbuff[0]=0xa5; 255 | sum=0; 256 | // 由于结构体中不同类型的变量在内存空间的排布不是严格对齐的,中间嵌有无效字节,因此需要特殊处理 257 | 258 | valuepack_tx_bit_index = 0; 259 | valuepack_tx_index = 1; 260 | 261 | #if TX_BOOL_NUM>0 262 | 263 | for(loop=0;loopbools[loop]) 266 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 272 | { 273 | valuepack_tx_bit_index = 0; 274 | valuepack_tx_index++; 275 | } 276 | } 277 | if(valuepack_tx_bit_index!=0) 278 | valuepack_tx_index++; 279 | #endif 280 | 281 | #if TX_BYTE_NUM>0 282 | 283 | for(loop=0;loopbytes[loop]; 286 | valuepack_tx_index++; 287 | } 288 | 289 | #endif 290 | 291 | #if TX_SHORT_NUM>0 292 | for(loop=0;loopshorts[loop]&0xff; 295 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 296 | valuepack_tx_index+=2; 297 | } 298 | #endif 299 | 300 | #if TX_INT_NUM>0 301 | for(loop=0;loopintegers[loop]; 304 | 305 | vp_txbuff[valuepack_tx_index] = i&0xff; 306 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 307 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 308 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 309 | 310 | valuepack_tx_index+=4; 311 | } 312 | #endif 313 | 314 | #if TX_FLOAT_NUM>0 315 | for(loop=0;loopfloats[loop])); 318 | 319 | vp_txbuff[valuepack_tx_index] = i&0xff; 320 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 321 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 322 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 323 | 324 | valuepack_tx_index+=4; 325 | } 326 | #endif 327 | 328 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 329 | sum+=vp_txbuff[d]; 330 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 331 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 332 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 333 | } 334 | 335 | 336 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /Examples/PWM控制彩灯/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过DMA和USART 进行数据包的接收和发送 4 | // 接收的数据自动写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | // 数据发送也采用DMA 6 | 7 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 8 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 9 | #define VALUEPACK_BUFFER_SIZE 1024 10 | 11 | 12 | /// 2.指定发送到手机的数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 13 | /// 14 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 15 | 16 | #define TX_BOOL_NUM 0 17 | #define TX_BYTE_NUM 0 18 | #define TX_SHORT_NUM 0 19 | #define TX_INT_NUM 0 20 | #define TX_FLOAT_NUM 0 21 | 22 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 23 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 24 | 25 | #define RX_BOOL_NUM 0 26 | #define RX_BYTE_NUM 3 27 | #define RX_SHORT_NUM 0 28 | #define RX_INT_NUM 0 29 | #define RX_FLOAT_NUM 0 30 | 31 | 32 | 33 | typedef struct 34 | { 35 | #if TX_BOOL_NUM > 0 36 | unsigned char bools[TX_BOOL_NUM]; 37 | #endif 38 | 39 | #if TX_BYTE_NUM > 0 40 | char bytes[TX_BYTE_NUM]; 41 | #endif 42 | 43 | #if TX_SHORT_NUM > 0 44 | short shorts[TX_SHORT_NUM]; 45 | #endif 46 | 47 | #if TX_INT_NUM > 0 48 | int integers[TX_INT_NUM]; 49 | #endif 50 | 51 | #if TX_FLOAT_NUM > 0 52 | float floats[TX_FLOAT_NUM]; 53 | #endif 54 | 55 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 56 | } 57 | TxPack; 58 | typedef struct 59 | { 60 | #if RX_BOOL_NUM > 0 61 | unsigned char bools[RX_BOOL_NUM]; 62 | #endif 63 | 64 | #if RX_BYTE_NUM > 0 65 | char bytes[RX_BYTE_NUM]; 66 | #endif 67 | 68 | #if RX_SHORT_NUM > 0 69 | short shorts[RX_SHORT_NUM]; 70 | #endif 71 | 72 | #if RX_INT_NUM > 0 73 | int integers[RX_INT_NUM]; 74 | #endif 75 | 76 | #if RX_FLOAT_NUM > 0 77 | float floats[RX_FLOAT_NUM]; 78 | #endif 79 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 80 | }RxPack; 81 | // 初始化 valuepack 包括一些必要的硬件外设配置 82 | 83 | void initValuePack(int baudrate); 84 | 85 | // 需要保证至少每秒执行10次该函数 86 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 87 | // 接收到数据包时 返回 1 ,否则返回 0 88 | unsigned char readValuePack(RxPack *rx_pack_ptr); 89 | 90 | 91 | // 发送数据包 92 | void sendValuePack(TxPack *tx_pack_ptr); 93 | 94 | 95 | #define PACK_HEAD 0xa5 96 | #define PACK_TAIL 0x5a 97 | -------------------------------------------------------------------------------- /Examples/STM32F103收发示例/STM32F103仅发送数据包/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | #include "valuepack.h" 3 | 4 | // 定义一个足够大的数组用于存放数据包 5 | unsigned char buffer[50]; 6 | 7 | 8 | int main(void) 9 | { 10 | 11 | // 初始化串口 设置波特率 12 | initValuePack(115200); 13 | 14 | 15 | while(1) 16 | { 17 | 18 | // 延时一段时间 19 | for(int i=0;i<1000000;i++) 20 | {} 21 | 22 | // 开始发送 23 | startValuePack(buffer); 24 | 25 | // 将要回传的值放入,注意顺序为 Bool->Byte->Short->Int->Float 26 | putBool(0); 27 | putBool(1); 28 | putBool(0); 29 | putBool(0); 30 | putShort(3123); 31 | putInt(3124); 32 | putFloat(3125); 33 | 34 | // 通过串口发送,endValuePack返回了数据包的总长度 35 | sendBuffer(buffer,endValuePack()); 36 | 37 | } 38 | } 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Examples/STM32F103收发示例/STM32F103仅发送数据包/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char *valuepack_tx_buffer; 4 | unsigned short valuepack_tx_index; 5 | unsigned char valuepack_tx_bit_index; 6 | unsigned char valuepack_stage; 7 | 8 | void initValuePack(int baudrate) 9 | { 10 | 11 | USART_InitTypeDef USART_InitStructure; 12 | GPIO_InitTypeDef GPIO_InitStructure; 13 | 14 | // 时钟初始化 15 | 16 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 17 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 18 | 19 | // 引脚初始化 20 | 21 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 22 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 23 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 24 | GPIO_Init(GPIOA, &GPIO_InitStructure); 25 | /* PA10 USART1_Rx */ 26 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 27 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 28 | GPIO_Init(GPIOA, &GPIO_InitStructure); 29 | 30 | // 串口初始化 31 | 32 | USART_InitStructure.USART_BaudRate = baudrate; 33 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 34 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 35 | USART_InitStructure.USART_Parity = USART_Parity_No; 36 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 37 | USART_InitStructure.USART_Mode = USART_Mode_Tx; 38 | USART_Init(USART1, &USART_InitStructure); 39 | USART_Cmd(USART1, ENABLE); 40 | } 41 | 42 | 43 | // 1. 开始将数据打包,需传入定义好的数组(需保证数组长度足以存放要发送的数据) 44 | 45 | void startValuePack(unsigned char *buffer) 46 | { 47 | valuepack_tx_buffer = buffer; 48 | valuepack_tx_index = 1; 49 | valuepack_tx_bit_index = 0; 50 | valuepack_tx_buffer[0] = PACK_HEAD; 51 | valuepack_stage = 0; 52 | } 53 | 54 | // 2. 向数据包中放入各类数据,由于数据包的顺序结构是固定的,因此注意严格以如下的顺序进行存放,否则会出现错误 55 | 56 | void putBool(unsigned char b) 57 | { 58 | if(valuepack_stage<=1) 59 | { 60 | if(b) 61 | valuepack_tx_buffer[valuepack_tx_index] |= 0x01<=8) 67 | { 68 | valuepack_tx_bit_index = 0; 69 | valuepack_tx_index++; 70 | } 71 | valuepack_stage = 1; 72 | } 73 | } 74 | 75 | 76 | void putByte(char b) 77 | { 78 | if(valuepack_stage<=2) 79 | { 80 | if(valuepack_tx_bit_index!=0) 81 | { 82 | valuepack_tx_index++; 83 | valuepack_tx_bit_index = 0; 84 | } 85 | valuepack_tx_buffer[valuepack_tx_index] = b; 86 | valuepack_tx_index++; 87 | 88 | valuepack_stage = 2; 89 | } 90 | } 91 | void putShort(short s) 92 | { 93 | if(valuepack_stage<=3) 94 | { 95 | if(valuepack_tx_bit_index!=0) 96 | { 97 | valuepack_tx_index++; 98 | valuepack_tx_bit_index = 0; 99 | } 100 | valuepack_tx_buffer[valuepack_tx_index] = s&0xff; 101 | valuepack_tx_buffer[valuepack_tx_index+1] = s>>8; 102 | 103 | valuepack_tx_index +=2; 104 | valuepack_stage = 3; 105 | } 106 | } 107 | void putInt(int i) 108 | { 109 | if(valuepack_stage<=4) 110 | { 111 | if(valuepack_tx_bit_index!=0) 112 | { 113 | valuepack_tx_index++; 114 | valuepack_tx_bit_index = 0; 115 | } 116 | 117 | valuepack_tx_buffer[valuepack_tx_index] = i&0xff; 118 | valuepack_tx_buffer[valuepack_tx_index+1] = (i>>8)&0xff; 119 | valuepack_tx_buffer[valuepack_tx_index+2] = (i>>16)&0xff; 120 | valuepack_tx_buffer[valuepack_tx_index+3] = (i>>24)&0xff; 121 | 122 | valuepack_tx_index +=4; 123 | 124 | valuepack_stage = 4; 125 | } 126 | } 127 | int fi; 128 | void putFloat(float f) 129 | { 130 | if(valuepack_stage<=5) 131 | { 132 | if(valuepack_tx_bit_index!=0) 133 | { 134 | valuepack_tx_index++; 135 | valuepack_tx_bit_index = 0; 136 | } 137 | 138 | fi = *(int*)(&f); 139 | valuepack_tx_buffer[valuepack_tx_index] = fi&0xff; 140 | valuepack_tx_buffer[valuepack_tx_index+1] = (fi>>8)&0xff; 141 | valuepack_tx_buffer[valuepack_tx_index+2] = (fi>>16)&0xff; 142 | valuepack_tx_buffer[valuepack_tx_index+3] = (fi>>24)&0xff; 143 | valuepack_tx_index +=4; 144 | valuepack_stage = 5; 145 | } 146 | } 147 | 148 | 149 | 150 | 151 | // 3. 结束打包,函数将返回 数据包的总长度 152 | unsigned short endValuePack() 153 | { 154 | unsigned char sum=0; 155 | for(int i=1;i>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 7 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 8 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 9 | 10 | 11 | long rxIndex=0; 12 | long rdIndex=0; 13 | 14 | 15 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 16 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 17 | 18 | 19 | DMA_InitTypeDef dma; 20 | 21 | void initValuePack(int baudrate) 22 | { 23 | 24 | USART_InitTypeDef USART_InitStructure; 25 | GPIO_InitTypeDef GPIO_InitStructure; 26 | 27 | // 时钟初始化 28 | 29 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 30 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 31 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); 32 | 33 | // 引脚初始化 34 | 35 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 36 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 37 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 38 | GPIO_Init(GPIOA, &GPIO_InitStructure); 39 | /* PA10 USART1_Rx */ 40 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 41 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 42 | GPIO_Init(GPIOA, &GPIO_InitStructure); 43 | 44 | // 串口初始化 45 | 46 | USART_InitStructure.USART_BaudRate = baudrate; 47 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 48 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 49 | USART_InitStructure.USART_Parity = USART_Parity_No; 50 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 51 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 52 | 53 | USART_Init(USART1, &USART_InitStructure); 54 | 55 | // DMA初始化 56 | 57 | DMA_DeInit(DMA1_Channel4); 58 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 59 | dma.DMA_M2M = DMA_M2M_Disable; 60 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 61 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 62 | 63 | dma.DMA_Priority = DMA_Priority_High; 64 | dma.DMA_BufferSize = 4; 65 | dma.DMA_MemoryBaseAddr = (uint32_t)0; 66 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 67 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 68 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 69 | dma.DMA_Mode = DMA_Mode_Normal; 70 | DMA_Init(DMA1_Channel4,&dma); 71 | 72 | USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 73 | 74 | DMA_DeInit(DMA1_Channel5); 75 | dma.DMA_DIR = DMA_DIR_PeripheralSRC; 76 | dma.DMA_BufferSize = VALUEPACK_BUFFER_SIZE; 77 | dma.DMA_MemoryBaseAddr = (uint32_t)vp_rxbuff; 78 | dma.DMA_Mode = DMA_Mode_Circular; 79 | DMA_Init(DMA1_Channel5,&dma); 80 | 81 | USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); 82 | USART_Cmd(USART1, ENABLE); 83 | DMA_Cmd(DMA1_Channel5,ENABLE); 84 | 85 | } 86 | 87 | 88 | 89 | unsigned short this_index=0; 90 | unsigned short last_index=0; 91 | unsigned short rdi,rdii,idl,idi; 92 | uint32_t idc; 93 | unsigned int err=0; 94 | unsigned char sum=0; 95 | unsigned char isok; 96 | 97 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 98 | // 99 | //procValuePack 用来处理手机传来的数据 100 | // 101 | 102 | unsigned char readValuePack(RxPack *rx_pack_ptr) 103 | { 104 | isok = 0; 105 | this_index =VALUEPACK_BUFFER_SIZE-DMA1_Channel5->CNDTR; 106 | if(this_index=VALUEPACK_BUFFER_SIZE) 127 | rdi -= VALUEPACK_BUFFER_SIZE; 128 | sum += vp_rxbuff[rdi]; 129 | } 130 | rdi++; 131 | if(rdi>=VALUEPACK_BUFFER_SIZE) 132 | rdi -= VALUEPACK_BUFFER_SIZE; 133 | 134 | if(sum==vp_rxbuff[rdi]) 135 | { 136 | // 提取数据包数据 一共有五步, bool byte short int float 137 | 138 | // 1. bool 139 | #if RX_BOOL_NUM>0 140 | 141 | idc = (uint32_t)rx_pack_ptr->bools; 142 | idl = (RX_BOOL_NUM+7)>>3; 143 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 146 | rdii -= VALUEPACK_BUFFER_SIZE; 147 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 148 | rdii++; 149 | idc++; 150 | } 151 | #endif 152 | // 2.byte 153 | #if RX_BYTE_NUM>0 154 | idc = (uint32_t)(rx_pack_ptr->bytes); 155 | idl = RX_BYTE_NUM; 156 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 159 | rdii -= VALUEPACK_BUFFER_SIZE; 160 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 161 | rdii++; 162 | idc++; 163 | } 164 | #endif 165 | // 3.short 166 | #if RX_SHORT_NUM>0 167 | idc = (uint32_t)(rx_pack_ptr->shorts); 168 | idl = RX_SHORT_NUM<<1; 169 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 172 | rdii -= VALUEPACK_BUFFER_SIZE; 173 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 174 | rdii++; 175 | idc++; 176 | } 177 | #endif 178 | // 4.int 179 | #if RX_INT_NUM>0 180 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 181 | idl = RX_INT_NUM<<2; 182 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 185 | rdii -= VALUEPACK_BUFFER_SIZE; 186 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 187 | rdii++; 188 | idc++; 189 | } 190 | #endif 191 | // 5.float 192 | #if RX_FLOAT_NUM>0 193 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 194 | idl = RX_FLOAT_NUM<<2; 195 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 198 | rdii -= VALUEPACK_BUFFER_SIZE; 199 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 200 | rdii++; 201 | idc++; 202 | } 203 | #endif 204 | err = rdii; 205 | rdIndex+=rx_pack_length; 206 | isok = 1; 207 | }else 208 | { 209 | rdIndex++; 210 | err++; 211 | } 212 | }else 213 | { 214 | rdIndex++; 215 | err++; 216 | } 217 | }else 218 | { 219 | rdIndex++; 220 | err++; 221 | } 222 | } 223 | last_index = this_index; 224 | return isok; 225 | } 226 | 227 | void sendBuffer(unsigned char *p,unsigned short length) 228 | { 229 | DMA_DeInit(DMA1_Channel4); 230 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 231 | dma.DMA_M2M = DMA_M2M_Disable; 232 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 233 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 234 | dma.DMA_Priority = DMA_Priority_High; 235 | dma.DMA_BufferSize = length; 236 | dma.DMA_MemoryBaseAddr = (uint32_t)p; 237 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 238 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 239 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 240 | dma.DMA_Mode = DMA_Mode_Normal; 241 | DMA_Init(DMA1_Channel4,&dma); 242 | DMA_Cmd(DMA1_Channel4,ENABLE); 243 | } 244 | 245 | 246 | 247 | unsigned short loop; 248 | unsigned char valuepack_tx_bit_index; 249 | unsigned char valuepack_tx_index; 250 | 251 | void sendValuePack(TxPack *tx_pack_ptr) 252 | { 253 | int i; 254 | vp_txbuff[0]=0xa5; 255 | sum=0; 256 | // 由于结构体中不同类型的变量在内存空间的排布不是严格对齐的,中间嵌有无效字节,因此需要特殊处理 257 | 258 | valuepack_tx_bit_index = 0; 259 | valuepack_tx_index = 1; 260 | 261 | #if TX_BOOL_NUM>0 262 | 263 | for(loop=0;loopbools[loop]) 266 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 272 | { 273 | valuepack_tx_bit_index = 0; 274 | valuepack_tx_index++; 275 | } 276 | } 277 | if(valuepack_tx_bit_index!=0) 278 | valuepack_tx_index++; 279 | #endif 280 | 281 | #if TX_BYTE_NUM>0 282 | 283 | for(loop=0;loopbytes[loop]; 286 | valuepack_tx_index++; 287 | } 288 | 289 | #endif 290 | 291 | #if TX_SHORT_NUM>0 292 | for(loop=0;loopshorts[loop]&0xff; 295 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 296 | valuepack_tx_index+=2; 297 | } 298 | #endif 299 | 300 | #if TX_INT_NUM>0 301 | for(loop=0;loopintegers[loop]; 304 | 305 | vp_txbuff[valuepack_tx_index] = i&0xff; 306 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 307 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 308 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 309 | 310 | valuepack_tx_index+=4; 311 | } 312 | #endif 313 | 314 | #if TX_FLOAT_NUM>0 315 | for(loop=0;loopfloats[loop])); 318 | 319 | vp_txbuff[valuepack_tx_index] = i&0xff; 320 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 321 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 322 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 323 | 324 | valuepack_tx_index+=4; 325 | } 326 | #endif 327 | 328 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 329 | sum+=vp_txbuff[d]; 330 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 331 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 332 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 333 | } 334 | 335 | 336 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /Examples/STM32F103收发示例/STM32F103基于DMA+USART收发数据/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过DMA和USART 进行数据包的接收和发送 4 | // 接收的数据自动写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | // 数据发送也采用DMA 6 | 7 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 8 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 9 | #define VALUEPACK_BUFFER_SIZE 1024 10 | 11 | 12 | /// 2.指定发送到手机的数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 13 | /// 14 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 15 | 16 | #define TX_BOOL_NUM 1 17 | #define TX_BYTE_NUM 1 18 | #define TX_SHORT_NUM 1 19 | #define TX_INT_NUM 1 20 | #define TX_FLOAT_NUM 1 21 | 22 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 23 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 24 | 25 | #define RX_BOOL_NUM 1 26 | #define RX_BYTE_NUM 1 27 | #define RX_SHORT_NUM 1 28 | #define RX_INT_NUM 1 29 | #define RX_FLOAT_NUM 1 30 | 31 | 32 | 33 | typedef struct 34 | { 35 | #if TX_BOOL_NUM > 0 36 | unsigned char bools[TX_BOOL_NUM]; 37 | #endif 38 | 39 | #if TX_BYTE_NUM > 0 40 | char bytes[TX_BYTE_NUM]; 41 | #endif 42 | 43 | #if TX_SHORT_NUM > 0 44 | short shorts[TX_SHORT_NUM]; 45 | #endif 46 | 47 | #if TX_INT_NUM > 0 48 | int integers[TX_INT_NUM]; 49 | #endif 50 | 51 | #if TX_FLOAT_NUM > 0 52 | float floats[TX_FLOAT_NUM]; 53 | #endif 54 | 55 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 56 | } 57 | TxPack; 58 | typedef struct 59 | { 60 | #if RX_BOOL_NUM > 0 61 | unsigned char bools[RX_BOOL_NUM]; 62 | #endif 63 | 64 | #if RX_BYTE_NUM > 0 65 | char bytes[RX_BYTE_NUM]; 66 | #endif 67 | 68 | #if RX_SHORT_NUM > 0 69 | short shorts[RX_SHORT_NUM]; 70 | #endif 71 | 72 | #if RX_INT_NUM > 0 73 | int integers[RX_INT_NUM]; 74 | #endif 75 | 76 | #if RX_FLOAT_NUM > 0 77 | float floats[RX_FLOAT_NUM]; 78 | #endif 79 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 80 | }RxPack; 81 | // 初始化 valuepack 包括一些必要的硬件外设配置 82 | 83 | void initValuePack(int baudrate); 84 | 85 | // 需要保证至少每秒执行10次该函数 86 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 87 | // 接收到数据包时 返回 1 ,否则返回 0 88 | unsigned char readValuePack(RxPack *rx_pack_ptr); 89 | 90 | 91 | // 发送数据包 92 | void sendValuePack(TxPack *tx_pack_ptr); 93 | 94 | 95 | #define PACK_HEAD 0xa5 96 | #define PACK_TAIL 0x5a 97 | -------------------------------------------------------------------------------- /Examples/STM32F103收发示例/STM32F103基于USART中断收发数据/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | #include "valuepack.h" 3 | 4 | // 首先需要有 发送数据包 和 接收数据包 数据包中有不同类型变量的数组,可以在valuepack.h中定义数据包的结构 5 | 6 | TxPack txpack; 7 | RxPack rxpack; 8 | 9 | int main(void) 10 | { 11 | 12 | // 初始化串口 设置波特率 13 | initValuePack(115200); 14 | 15 | while(1) 16 | { 17 | 18 | // 延时一段时间 19 | for(int i=0;i<100000;i++) 20 | {} 21 | 22 | /////////////////////////////////////////////////////////////////////////////////////////////////////// 23 | /// 数据收发部分 24 | 25 | if(readValuePack(&rxpack)) 26 | { 27 | 28 | // 在此读取手机传来的数据 29 | 30 | // 这里是将接收的数据原样回传 31 | txpack.bools[0] = rxpack.bools[0]; 32 | txpack.bytes[0] = rxpack.bytes[0]; 33 | txpack.shorts[0] = rxpack.shorts[0]; 34 | txpack.integers[0] = rxpack.integers[0]; 35 | txpack.floats[0] = rxpack.floats[0]; 36 | 37 | // 你也可以把 sendValuePack放在这,这样就只有当接收到手机传来的数据包后才回传数据 38 | 39 | 40 | } 41 | 42 | // 在此对数据包赋值并将数据发送到手机 43 | 44 | 45 | sendValuePack(&txpack); 46 | 47 | /// 数据收发结束 48 | /////////////////////////////////////////////////////////////////////////////////////////////////////// 49 | 50 | } 51 | } 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Examples/STM32F103收发示例/STM32F103基于USART中断收发数据/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char bits[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 4 | 5 | 6 | const unsigned int VALUEPACK_INDEX_RANGE=VALUEPACK_BUFFER_SIZE<<3; 7 | const unsigned short TXPACK_BYTE_SIZE = ((TX_BOOL_NUM+7)>>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 8 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 9 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 10 | 11 | long rxIndex=0; 12 | long rdIndex=0; 13 | 14 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 15 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 16 | 17 | void initValuePack(int baudrate) 18 | { 19 | 20 | USART_InitTypeDef USART_InitStructure; 21 | GPIO_InitTypeDef GPIO_InitStructure; 22 | NVIC_InitTypeDef NVIC_InitStructure; 23 | 24 | // 时钟初始化 25 | 26 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 27 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 28 | 29 | // 引脚初始化 30 | 31 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 32 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 33 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 34 | GPIO_Init(GPIOA, &GPIO_InitStructure); 35 | /* PA10 USART1_Rx */ 36 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 37 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 38 | GPIO_Init(GPIOA, &GPIO_InitStructure); 39 | 40 | // 串口初始化 41 | 42 | USART_InitStructure.USART_BaudRate = baudrate; 43 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 44 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 45 | USART_InitStructure.USART_Parity = USART_Parity_No; 46 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 47 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 48 | 49 | USART_Init(USART1, &USART_InitStructure); 50 | 51 | USART_ClearITPendingBit(USART1,USART_IT_RXNE); 52 | USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); 53 | 54 | 55 | NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 56 | NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 57 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 58 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; 59 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 60 | NVIC_Init(&NVIC_InitStructure); 61 | 62 | 63 | USART_Cmd(USART1, ENABLE); 64 | } 65 | 66 | 67 | 68 | unsigned short rdi,rdii,idl,idi; 69 | uint32_t idc; 70 | unsigned int err=0; 71 | unsigned char sum=0; 72 | unsigned char isok; 73 | 74 | unsigned short vp_circle_rx_index; 75 | void USART1_IRQHandler(void) 76 | { 77 | if(USART_GetITStatus(USART1, USART_IT_RXNE)) 78 | { 79 | vp_rxbuff[vp_circle_rx_index] = USART1->DR; 80 | vp_circle_rx_index++; 81 | if(vp_circle_rx_index>=VALUEPACK_BUFFER_SIZE) 82 | vp_circle_rx_index=0; 83 | rxIndex++; 84 | } 85 | USART_ClearITPendingBit(USART1,USART_IT_RXNE); 86 | } 87 | 88 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 89 | // 90 | //procValuePack 用来处理手机传来的数据,并发送数据包 91 | // 92 | 93 | unsigned char readValuePack(RxPack *rx_pack_ptr) 94 | { 95 | 96 | isok = 0; 97 | 98 | 99 | while(rdIndex<(rxIndex-((rx_pack_length)))) 100 | rdIndex+=rx_pack_length; 101 | 102 | while(rdIndex<=(rxIndex-rx_pack_length)) 103 | { 104 | 105 | rdi = rdIndex % VALUEPACK_BUFFER_SIZE; 106 | rdii=rdi+1; 107 | if( vp_rxbuff[rdi]==PACK_HEAD) 108 | { 109 | if(vp_rxbuff[(rdi+RXPACK_BYTE_SIZE+2)%VALUEPACK_BUFFER_SIZE]==PACK_TAIL) 110 | { 111 | // 计算校验和 112 | sum=0; 113 | for(short s=0;s=VALUEPACK_BUFFER_SIZE) 117 | rdi -= VALUEPACK_BUFFER_SIZE; 118 | sum += vp_rxbuff[rdi]; 119 | } 120 | rdi++; 121 | if(rdi>=VALUEPACK_BUFFER_SIZE) 122 | rdi -= VALUEPACK_BUFFER_SIZE; 123 | 124 | if(sum==vp_rxbuff[rdi]) 125 | { 126 | // 提取数据包数据 一共有五步, bool byte short int float 127 | 128 | // 1. bool 129 | #if RX_BOOL_NUM>0 130 | 131 | idc = (uint32_t)rx_pack_ptr->bools; 132 | idl = (RX_BOOL_NUM+7)>>3; 133 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 136 | rdii -= VALUEPACK_BUFFER_SIZE; 137 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 138 | rdii++; 139 | idc++; 140 | } 141 | #endif 142 | // 2.byte 143 | #if RX_BYTE_NUM>0 144 | idc = (uint32_t)(rx_pack_ptr->bytes); 145 | idl = RX_BYTE_NUM; 146 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 149 | rdii -= VALUEPACK_BUFFER_SIZE; 150 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 151 | rdii++; 152 | idc++; 153 | } 154 | #endif 155 | // 3.short 156 | #if RX_SHORT_NUM>0 157 | idc = (uint32_t)(rx_pack_ptr->shorts); 158 | idl = RX_SHORT_NUM<<1; 159 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 162 | rdii -= VALUEPACK_BUFFER_SIZE; 163 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 164 | rdii++; 165 | idc++; 166 | } 167 | #endif 168 | // 4.int 169 | #if RX_INT_NUM>0 170 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 171 | idl = RX_INT_NUM<<2; 172 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 175 | rdii -= VALUEPACK_BUFFER_SIZE; 176 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 177 | rdii++; 178 | idc++; 179 | } 180 | #endif 181 | // 5.float 182 | #if RX_FLOAT_NUM>0 183 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 184 | idl = RX_FLOAT_NUM<<2; 185 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 188 | rdii -= VALUEPACK_BUFFER_SIZE; 189 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 190 | rdii++; 191 | idc++; 192 | } 193 | #endif 194 | err = rdii; 195 | rdIndex+=rx_pack_length; 196 | isok = 1; 197 | }else 198 | { 199 | rdIndex++; 200 | err++; 201 | } 202 | }else 203 | { 204 | rdIndex++; 205 | err++; 206 | } 207 | }else 208 | { 209 | rdIndex++; 210 | err++; 211 | } 212 | } 213 | return isok; 214 | } 215 | 216 | void sendBuffer(unsigned char *p,unsigned short length) 217 | { 218 | for(int i=0;i0 241 | 242 | for(loop=0;loopbools[loop]) 245 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 251 | { 252 | valuepack_tx_bit_index = 0; 253 | valuepack_tx_index++; 254 | } 255 | } 256 | if(valuepack_tx_bit_index!=0) 257 | valuepack_tx_index++; 258 | #endif 259 | 260 | #if TX_BYTE_NUM>0 261 | 262 | for(loop=0;loopbytes[loop]; 265 | valuepack_tx_index++; 266 | } 267 | 268 | #endif 269 | 270 | #if TX_SHORT_NUM>0 271 | for(loop=0;loopshorts[loop]&0xff; 274 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 275 | valuepack_tx_index+=2; 276 | } 277 | #endif 278 | 279 | #if TX_INT_NUM>0 280 | for(loop=0;loopintegers[loop]; 283 | 284 | vp_txbuff[valuepack_tx_index] = i&0xff; 285 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 286 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 287 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 288 | 289 | valuepack_tx_index+=4; 290 | } 291 | #endif 292 | 293 | #if TX_FLOAT_NUM>0 294 | for(loop=0;loopfloats[loop])); 297 | 298 | vp_txbuff[valuepack_tx_index] = i&0xff; 299 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 300 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 301 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 302 | 303 | valuepack_tx_index+=4; 304 | } 305 | #endif 306 | 307 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 308 | sum+=vp_txbuff[d]; 309 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 310 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 311 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 312 | } 313 | 314 | 315 | 316 | -------------------------------------------------------------------------------- /Examples/STM32F103收发示例/STM32F103基于USART中断收发数据/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过USART 配合接收中断 进行数据包的接收和发送 4 | // 接收的数据在接收中断中写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | 6 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 7 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 8 | #define VALUEPACK_BUFFER_SIZE 1024 9 | 10 | 11 | /// 2.指定发送数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 12 | /// 13 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 14 | 15 | #define TX_BOOL_NUM 1 16 | #define TX_BYTE_NUM 1 17 | #define TX_SHORT_NUM 1 18 | #define TX_INT_NUM 1 19 | #define TX_FLOAT_NUM 1 20 | 21 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 22 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 23 | 24 | #define RX_BOOL_NUM 1 25 | #define RX_BYTE_NUM 1 26 | #define RX_SHORT_NUM 1 27 | #define RX_INT_NUM 1 28 | #define RX_FLOAT_NUM 1 29 | 30 | 31 | 32 | typedef struct 33 | { 34 | #if TX_BOOL_NUM > 0 35 | unsigned char bools[TX_BOOL_NUM]; 36 | #endif 37 | 38 | #if TX_BYTE_NUM > 0 39 | char bytes[TX_BYTE_NUM]; 40 | #endif 41 | 42 | #if TX_SHORT_NUM > 0 43 | short shorts[TX_SHORT_NUM]; 44 | #endif 45 | 46 | #if TX_INT_NUM > 0 47 | int integers[TX_INT_NUM]; 48 | #endif 49 | 50 | #if TX_FLOAT_NUM > 0 51 | float floats[TX_FLOAT_NUM]; 52 | #endif 53 | char space; //只是为了占一个空,当所有变量数目都为0时确保编译成功 54 | } 55 | TxPack; 56 | typedef struct 57 | { 58 | #if RX_BOOL_NUM > 0 59 | unsigned char bools[RX_BOOL_NUM]; 60 | #endif 61 | 62 | #if RX_BYTE_NUM > 0 63 | char bytes[RX_BYTE_NUM]; 64 | #endif 65 | 66 | #if RX_SHORT_NUM > 0 67 | short shorts[RX_SHORT_NUM]; 68 | #endif 69 | 70 | #if RX_INT_NUM > 0 71 | int integers[RX_INT_NUM]; 72 | #endif 73 | 74 | #if RX_FLOAT_NUM > 0 75 | float floats[RX_FLOAT_NUM]; 76 | #endif 77 | char space; //只是为了占一个空,当所有变量数目都为0时确保编译成功 78 | }RxPack; 79 | // 初始化 valuepack 包括一些必要的硬件外设配置 80 | // 并指定要传输的数据包 81 | void initValuePack(int baudrate); 82 | 83 | // 需要保证至少每秒执行10次该函数 84 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 85 | // 接收到数据包时 返回 1 ,否则返回 0 86 | unsigned char readValuePack(RxPack *rx_pack_ptr); 87 | 88 | 89 | // 发送数据包 90 | void sendValuePack(TxPack *tx_pack_ptr); 91 | 92 | 93 | 94 | #define PACK_HEAD 0xa5 95 | #define PACK_TAIL 0x5a 96 | 97 | #define TX_MODE_SEND_BACK 0 98 | #define TX_MODE_ALWAYS 1 99 | #define TX_MODE_DISABLE 2 100 | -------------------------------------------------------------------------------- /Examples/心率检测MAX30100/fake_i2c.c: -------------------------------------------------------------------------------- 1 | #include "fake_i2c.h" 2 | 3 | unsigned char address_byte_size; 4 | unsigned char device_8bit_add; 5 | unsigned short delayloop; 6 | unsigned char timeout; 7 | 8 | void fake_i2c_delay(void) 9 | { 10 | for(int i=0;iBSRR = FAKE_I2C_SCL_PIN|FAKE_I2C_SDA_PIN; 29 | 30 | } 31 | 32 | void fake_i2c_sel_device(unsigned char add_8bit) 33 | { 34 | device_8bit_add = add_8bit; 35 | } 36 | 37 | void fake_i2c_start(void) 38 | { 39 | FAKE_SDA_OUT; 40 | FAKE_SDA_H; 41 | FAKE_SCL_H; 42 | fake_i2c_delay(); 43 | FAKE_SDA_L; 44 | fake_i2c_delay(); 45 | } 46 | 47 | unsigned char fake_i2c_send(unsigned char dat) 48 | { 49 | for(u8 i=0;i<8;i++) 50 | { 51 | FAKE_SCL_L; 52 | fake_i2c_delay(); 53 | FAKE_SDA_OUT; 54 | if(dat&0x80) 55 | FAKE_SDA_H; 56 | else 57 | FAKE_SDA_L; 58 | dat = dat<<1; 59 | fake_i2c_delay(); 60 | FAKE_SCL_H; 61 | fake_i2c_delay(); 62 | fake_i2c_delay(); 63 | } 64 | 65 | FAKE_SCL_L; 66 | fake_i2c_delay(); 67 | FAKE_SDA_IN; 68 | fake_i2c_delay(); 69 | FAKE_SCL_H; 70 | fake_i2c_delay(); 71 | 72 | dat = 1; 73 | for(u8 i=0;iCRL &=0x0fffffff;\ 10 | FAKE_I2C_PORT->CRL |=0x80000000;\ 11 | FAKE_SDA_H 12 | 13 | #define FAKE_SDA_OUT FAKE_I2C_PORT->CRL &=0x0fffffff ; FAKE_I2C_PORT->CRL |=0x30000000 14 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 15 | 16 | /////// 下面的宏定义不需要修改 17 | #define FAKE_SDA_H FAKE_I2C_PORT->BSRR=FAKE_I2C_SDA_PIN 18 | #define FAKE_SDA_L FAKE_I2C_PORT->BRR=FAKE_I2C_SDA_PIN 19 | #define FAKE_SDA (((FAKE_I2C_PORT->IDR&FAKE_I2C_SDA_PIN)!=0)?1:0) 20 | #define FAKE_SCL_H FAKE_I2C_PORT->BSRR=FAKE_I2C_SCL_PIN 21 | #define FAKE_SCL_L FAKE_I2C_PORT->BRR=FAKE_I2C_SCL_PIN 22 | 23 | //// 初始化函数 24 | //// delayloop : 用于调整通信频率 25 | //// time_out : 用于等待Ack的时间 26 | //// device_8bit_add : 目标设备的地址(8位,最低位补0) 27 | //// add_byte_size : 寄存器地址占有的字节数, 1:8位地址 2:16位地址 28 | void init_fake_i2c(unsigned short delay_loop,unsigned char time_out,unsigned char device_8bit_add,unsigned char add_byte_size); 29 | 30 | void fake_i2c_sel_device(unsigned char add_8bit); 31 | 32 | void fake_i2c_delay(void); 33 | void fake_i2c_start(void); 34 | unsigned char fake_i2c_send(unsigned char dat); 35 | void fake_i2c_stop(void); 36 | 37 | unsigned char fake_i2c_read(unsigned char ack); 38 | unsigned char fake_i2c_write_reg(u16 reg,unsigned char dat); 39 | unsigned char fake_i2c_read_reg(u16 reg); 40 | unsigned char fake_i2c_read_buff(u16 reg,u16 length,unsigned char *buffer); 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Examples/心率检测MAX30100/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | #include "valuepack.h" 3 | #include "fake_i2c.h" 4 | 5 | #define MAX30100_ADD 0xAe 6 | #define MAX30100_MODE_LED_IR 3 7 | #define MAX30100_MODE_IR 2 8 | 9 | #define MAX30100_FILTERED_VALUE_RANGE 300 10 | 11 | TxPack txpack; 12 | 13 | //------------------------------------------------------------------------------------------------------ 14 | // 15 | // 初始化心率检测模块 MAX30100 16 | // 17 | // 设置模式 : 可设置仅 心率 或 SPO2模式 18 | // 19 | // 设置两种光源的亮度brightness : 配置亮度,范围是0~f 20 | // 21 | void initMAX30100(unsigned char mode,unsigned char ir_led_brightness,unsigned char red_led_brightness) 22 | { 23 | init_fake_i2c(1,2,MAX30100_ADD,1); 24 | 25 | fake_i2c_write_reg(0x06,0x08|mode); //设置模式 26 | fake_i2c_write_reg(0x01,0xF0); //开启中断 27 | fake_i2c_write_reg(0x09,ir_led_brightness|(red_led_brightness<<4)); //LED设置 28 | fake_i2c_write_reg(0x07,0x43); // 配置为16位 29 | fake_i2c_write_reg(0x02,0x00); 30 | fake_i2c_write_reg(0x03,0x00); 31 | fake_i2c_write_reg(0x04,0x00); 32 | } 33 | 34 | 35 | //------------------------------------------------------------------------------------------------------- 36 | // 读取采样值 37 | // 38 | // 这些采样值都是经过一定的滤波处理的 39 | // 将变量地址传入以读出数据 40 | 41 | void MAX30100_ReadValue( float *ir_v, float *red_v) 42 | { 43 | static unsigned short last_ir,last_red; 44 | static float rate_ir,rate_red; 45 | 46 | unsigned char buffer[4]; 47 | unsigned char state; 48 | 49 | unsigned short raw_value_ir; 50 | unsigned short raw_value_red; 51 | 52 | state = fake_i2c_read_reg(0x02); // 读取FIFO新数据的数目,如果非0,说明有新的数据 53 | 54 | if(state) 55 | { 56 | fake_i2c_read_buff(0x05,4,buffer); 57 | fake_i2c_write_reg(0x02,0x00); 58 | fake_i2c_write_reg(0x04,0x00); 59 | 60 | raw_value_ir = (buffer[0]<<8)+buffer[1]; 61 | raw_value_red = (buffer[2]<<8)|buffer[3]; 62 | 63 | if(raw_value_ir!=last_ir) 64 | rate_ir += ((raw_value_ir-last_ir)-rate_ir)*0.18f; 65 | 66 | if(raw_value_red!=last_red) 67 | rate_red += ((raw_value_red-last_red)-rate_red)*0.18f; 68 | 69 | last_ir = raw_value_ir; 70 | last_red = raw_value_red; 71 | } 72 | 73 | (*red_v)+=rate_red; 74 | (*ir_v)+=rate_ir; 75 | (*ir_v)*=0.9f; 76 | (*red_v)*=0.9f; 77 | 78 | if(*ir_v>MAX30100_FILTERED_VALUE_RANGE) 79 | *ir_v = MAX30100_FILTERED_VALUE_RANGE; 80 | if(*ir_v<-MAX30100_FILTERED_VALUE_RANGE) 81 | *ir_v = -MAX30100_FILTERED_VALUE_RANGE; 82 | if(*red_v>MAX30100_FILTERED_VALUE_RANGE) 83 | *red_v = MAX30100_FILTERED_VALUE_RANGE; 84 | if(*red_v<-MAX30100_FILTERED_VALUE_RANGE) 85 | *red_v = -MAX30100_FILTERED_VALUE_RANGE; 86 | } 87 | 88 | 89 | /// ir:红外 red:红光 检测两种光源的反射程度 90 | float ir_value,red_value; 91 | 92 | int main(void) 93 | { 94 | 95 | initMAX30100(MAX30100_MODE_LED_IR,5,5); 96 | initValuePack(115200); 97 | 98 | while(1) 99 | { 100 | 101 | // 延时 102 | for(int i=0;i<20000;i++) 103 | {} 104 | 105 | MAX30100_ReadValue(&ir_value,&red_value); 106 | 107 | txpack.floats[0] = ir_value; 108 | txpack.floats[1] = red_value; 109 | 110 | sendValuePack(&txpack); 111 | 112 | } 113 | } 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /Examples/心率检测MAX30100/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char bits[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 4 | 5 | const unsigned int VALUEPACK_INDEX_RANGE=VALUEPACK_BUFFER_SIZE<<3; 6 | const unsigned short TXPACK_BYTE_SIZE = ((TX_BOOL_NUM+7)>>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 7 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 8 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 9 | 10 | 11 | long rxIndex=0; 12 | long rdIndex=0; 13 | 14 | 15 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 16 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 17 | 18 | 19 | DMA_InitTypeDef dma; 20 | 21 | void initValuePack(int baudrate) 22 | { 23 | 24 | USART_InitTypeDef USART_InitStructure; 25 | GPIO_InitTypeDef GPIO_InitStructure; 26 | 27 | // 时钟初始化 28 | 29 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 30 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 31 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); 32 | 33 | // 引脚初始化 34 | 35 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 36 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 37 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 38 | GPIO_Init(GPIOA, &GPIO_InitStructure); 39 | /* PA10 USART1_Rx */ 40 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 41 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 42 | GPIO_Init(GPIOA, &GPIO_InitStructure); 43 | 44 | // 串口初始化 45 | 46 | USART_InitStructure.USART_BaudRate = baudrate; 47 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 48 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 49 | USART_InitStructure.USART_Parity = USART_Parity_No; 50 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 51 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 52 | 53 | USART_Init(USART1, &USART_InitStructure); 54 | 55 | // DMA初始化 56 | 57 | DMA_DeInit(DMA1_Channel4); 58 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 59 | dma.DMA_M2M = DMA_M2M_Disable; 60 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 61 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 62 | 63 | dma.DMA_Priority = DMA_Priority_High; 64 | dma.DMA_BufferSize = 4; 65 | dma.DMA_MemoryBaseAddr = (uint32_t)0; 66 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 67 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 68 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 69 | dma.DMA_Mode = DMA_Mode_Normal; 70 | DMA_Init(DMA1_Channel4,&dma); 71 | 72 | USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 73 | 74 | DMA_DeInit(DMA1_Channel5); 75 | dma.DMA_DIR = DMA_DIR_PeripheralSRC; 76 | dma.DMA_BufferSize = VALUEPACK_BUFFER_SIZE; 77 | dma.DMA_MemoryBaseAddr = (uint32_t)vp_rxbuff; 78 | dma.DMA_Mode = DMA_Mode_Circular; 79 | DMA_Init(DMA1_Channel5,&dma); 80 | 81 | USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); 82 | USART_Cmd(USART1, ENABLE); 83 | DMA_Cmd(DMA1_Channel5,ENABLE); 84 | 85 | } 86 | 87 | 88 | 89 | unsigned short this_index=0; 90 | unsigned short last_index=0; 91 | unsigned short rdi,rdii,idl,idi; 92 | uint32_t idc; 93 | unsigned int err=0; 94 | unsigned char sum=0; 95 | unsigned char isok; 96 | 97 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 98 | // 99 | //procValuePack 用来处理手机传来的数据 100 | // 101 | 102 | unsigned char readValuePack(RxPack *rx_pack_ptr) 103 | { 104 | isok = 0; 105 | this_index =VALUEPACK_BUFFER_SIZE-DMA1_Channel5->CNDTR; 106 | if(this_index=VALUEPACK_BUFFER_SIZE) 127 | rdi -= VALUEPACK_BUFFER_SIZE; 128 | sum += vp_rxbuff[rdi]; 129 | } 130 | rdi++; 131 | if(rdi>=VALUEPACK_BUFFER_SIZE) 132 | rdi -= VALUEPACK_BUFFER_SIZE; 133 | 134 | if(sum==vp_rxbuff[rdi]) 135 | { 136 | // 提取数据包数据 一共有五步, bool byte short int float 137 | 138 | // 1. bool 139 | #if RX_BOOL_NUM>0 140 | 141 | idc = (uint32_t)rx_pack_ptr->bools; 142 | idl = (RX_BOOL_NUM+7)>>3; 143 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 146 | rdii -= VALUEPACK_BUFFER_SIZE; 147 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 148 | rdii++; 149 | idc++; 150 | } 151 | #endif 152 | // 2.byte 153 | #if RX_BYTE_NUM>0 154 | idc = (uint32_t)(rx_pack_ptr->bytes); 155 | idl = RX_BYTE_NUM; 156 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 159 | rdii -= VALUEPACK_BUFFER_SIZE; 160 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 161 | rdii++; 162 | idc++; 163 | } 164 | #endif 165 | // 3.short 166 | #if RX_SHORT_NUM>0 167 | idc = (uint32_t)(rx_pack_ptr->shorts); 168 | idl = RX_SHORT_NUM<<1; 169 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 172 | rdii -= VALUEPACK_BUFFER_SIZE; 173 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 174 | rdii++; 175 | idc++; 176 | } 177 | #endif 178 | // 4.int 179 | #if RX_INT_NUM>0 180 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 181 | idl = RX_INT_NUM<<2; 182 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 185 | rdii -= VALUEPACK_BUFFER_SIZE; 186 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 187 | rdii++; 188 | idc++; 189 | } 190 | #endif 191 | // 5.float 192 | #if RX_FLOAT_NUM>0 193 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 194 | idl = RX_FLOAT_NUM<<2; 195 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 198 | rdii -= VALUEPACK_BUFFER_SIZE; 199 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 200 | rdii++; 201 | idc++; 202 | } 203 | #endif 204 | err = rdii; 205 | rdIndex+=rx_pack_length; 206 | isok = 1; 207 | }else 208 | { 209 | rdIndex++; 210 | err++; 211 | } 212 | }else 213 | { 214 | rdIndex++; 215 | err++; 216 | } 217 | }else 218 | { 219 | rdIndex++; 220 | err++; 221 | } 222 | } 223 | last_index = this_index; 224 | return isok; 225 | } 226 | 227 | void sendBuffer(unsigned char *p,unsigned short length) 228 | { 229 | DMA_DeInit(DMA1_Channel4); 230 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 231 | dma.DMA_M2M = DMA_M2M_Disable; 232 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 233 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 234 | dma.DMA_Priority = DMA_Priority_High; 235 | dma.DMA_BufferSize = length; 236 | dma.DMA_MemoryBaseAddr = (uint32_t)p; 237 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 238 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 239 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 240 | dma.DMA_Mode = DMA_Mode_Normal; 241 | DMA_Init(DMA1_Channel4,&dma); 242 | DMA_Cmd(DMA1_Channel4,ENABLE); 243 | } 244 | 245 | 246 | 247 | unsigned short loop; 248 | unsigned char valuepack_tx_bit_index; 249 | unsigned char valuepack_tx_index; 250 | 251 | void sendValuePack(TxPack *tx_pack_ptr) 252 | { 253 | int i; 254 | vp_txbuff[0]=0xa5; 255 | sum=0; 256 | // 由于结构体中不同类型的变量在内存空间的排布不是严格对齐的,中间嵌有无效字节,因此需要特殊处理 257 | 258 | valuepack_tx_bit_index = 0; 259 | valuepack_tx_index = 1; 260 | 261 | #if TX_BOOL_NUM>0 262 | 263 | for(loop=0;loopbools[loop]) 266 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 272 | { 273 | valuepack_tx_bit_index = 0; 274 | valuepack_tx_index++; 275 | } 276 | } 277 | if(valuepack_tx_bit_index!=0) 278 | valuepack_tx_index++; 279 | #endif 280 | 281 | #if TX_BYTE_NUM>0 282 | 283 | for(loop=0;loopbytes[loop]; 286 | valuepack_tx_index++; 287 | } 288 | 289 | #endif 290 | 291 | #if TX_SHORT_NUM>0 292 | for(loop=0;loopshorts[loop]&0xff; 295 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 296 | valuepack_tx_index+=2; 297 | } 298 | #endif 299 | 300 | #if TX_INT_NUM>0 301 | for(loop=0;loopintegers[loop]; 304 | 305 | vp_txbuff[valuepack_tx_index] = i&0xff; 306 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 307 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 308 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 309 | 310 | valuepack_tx_index+=4; 311 | } 312 | #endif 313 | 314 | #if TX_FLOAT_NUM>0 315 | for(loop=0;loopfloats[loop])); 318 | 319 | vp_txbuff[valuepack_tx_index] = i&0xff; 320 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 321 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 322 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 323 | 324 | valuepack_tx_index+=4; 325 | } 326 | #endif 327 | 328 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 329 | sum+=vp_txbuff[d]; 330 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 331 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 332 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 333 | } -------------------------------------------------------------------------------- /Examples/心率检测MAX30100/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过DMA和USART 进行数据包的接收和发送 4 | // 接收的数据自动写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | // 数据发送也采用DMA 6 | 7 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 8 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 9 | #define VALUEPACK_BUFFER_SIZE 1024 10 | 11 | 12 | /// 2.指定发送到手机的数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 13 | /// 14 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 15 | 16 | #define TX_BOOL_NUM 0 17 | #define TX_BYTE_NUM 0 18 | #define TX_SHORT_NUM 0 19 | #define TX_INT_NUM 0 20 | #define TX_FLOAT_NUM 2 21 | 22 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 23 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 24 | 25 | #define RX_BOOL_NUM 0 26 | #define RX_BYTE_NUM 0 27 | #define RX_SHORT_NUM 0 28 | #define RX_INT_NUM 0 29 | #define RX_FLOAT_NUM 0 30 | 31 | 32 | 33 | typedef struct 34 | { 35 | #if TX_BOOL_NUM > 0 36 | unsigned char bools[TX_BOOL_NUM]; 37 | #endif 38 | 39 | #if TX_BYTE_NUM > 0 40 | char bytes[TX_BYTE_NUM]; 41 | #endif 42 | 43 | #if TX_SHORT_NUM > 0 44 | short shorts[TX_SHORT_NUM]; 45 | #endif 46 | 47 | #if TX_INT_NUM > 0 48 | int integers[TX_INT_NUM]; 49 | #endif 50 | 51 | #if TX_FLOAT_NUM > 0 52 | float floats[TX_FLOAT_NUM]; 53 | #endif 54 | 55 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 56 | } 57 | TxPack; 58 | typedef struct 59 | { 60 | #if RX_BOOL_NUM > 0 61 | unsigned char bools[RX_BOOL_NUM]; 62 | #endif 63 | 64 | #if RX_BYTE_NUM > 0 65 | char bytes[RX_BYTE_NUM]; 66 | #endif 67 | 68 | #if RX_SHORT_NUM > 0 69 | short shorts[RX_SHORT_NUM]; 70 | #endif 71 | 72 | #if RX_INT_NUM > 0 73 | int integers[RX_INT_NUM]; 74 | #endif 75 | 76 | #if RX_FLOAT_NUM > 0 77 | float floats[RX_FLOAT_NUM]; 78 | #endif 79 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 80 | }RxPack; 81 | // 初始化 valuepack 包括一些必要的硬件外设配置 82 | 83 | void initValuePack(int baudrate); 84 | 85 | // 需要保证至少每秒执行10次该函数 86 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 87 | // 接收到数据包时 返回 1 ,否则返回 0 88 | unsigned char readValuePack(RxPack *rx_pack_ptr); 89 | 90 | 91 | // 发送数据包 92 | void sendValuePack(TxPack *tx_pack_ptr); 93 | 94 | 95 | #define PACK_HEAD 0xa5 96 | #define PACK_TAIL 0x5a 97 | 98 | -------------------------------------------------------------------------------- /Examples/心率检测MAX30102/fake_i2c.c: -------------------------------------------------------------------------------- 1 | #include "fake_i2c.h" 2 | 3 | unsigned char address_byte_size; 4 | unsigned char device_8bit_add; 5 | unsigned short delayloop; 6 | unsigned char timeout; 7 | 8 | void fake_i2c_delay(void) 9 | { 10 | for(int i=0;iBSRR = FAKE_I2C_SCL_PIN|FAKE_I2C_SDA_PIN; 29 | 30 | } 31 | 32 | void fake_i2c_sel_device(unsigned char add_8bit) 33 | { 34 | device_8bit_add = add_8bit; 35 | } 36 | 37 | void fake_i2c_start(void) 38 | { 39 | FAKE_SDA_OUT; 40 | FAKE_SDA_H; 41 | FAKE_SCL_H; 42 | fake_i2c_delay(); 43 | FAKE_SDA_L; 44 | fake_i2c_delay(); 45 | } 46 | 47 | unsigned char fake_i2c_send(unsigned char dat) 48 | { 49 | for(u8 i=0;i<8;i++) 50 | { 51 | FAKE_SCL_L; 52 | fake_i2c_delay(); 53 | FAKE_SDA_OUT; 54 | if(dat&0x80) 55 | FAKE_SDA_H; 56 | else 57 | FAKE_SDA_L; 58 | dat = dat<<1; 59 | fake_i2c_delay(); 60 | FAKE_SCL_H; 61 | fake_i2c_delay(); 62 | fake_i2c_delay(); 63 | } 64 | 65 | FAKE_SCL_L; 66 | fake_i2c_delay(); 67 | FAKE_SDA_IN; 68 | fake_i2c_delay(); 69 | FAKE_SCL_H; 70 | fake_i2c_delay(); 71 | 72 | dat = 1; 73 | for(u8 i=0;iCRL &=0x0fffffff;\ 10 | FAKE_I2C_PORT->CRL |=0x80000000;\ 11 | FAKE_SDA_H 12 | 13 | #define FAKE_SDA_OUT FAKE_I2C_PORT->CRL &=0x0fffffff ; FAKE_I2C_PORT->CRL |=0x30000000 14 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 15 | 16 | /////// 下面的宏定义不需要修改 17 | #define FAKE_SDA_H FAKE_I2C_PORT->BSRR=FAKE_I2C_SDA_PIN 18 | #define FAKE_SDA_L FAKE_I2C_PORT->BRR=FAKE_I2C_SDA_PIN 19 | #define FAKE_SDA (((FAKE_I2C_PORT->IDR&FAKE_I2C_SDA_PIN)!=0)?1:0) 20 | #define FAKE_SCL_H FAKE_I2C_PORT->BSRR=FAKE_I2C_SCL_PIN 21 | #define FAKE_SCL_L FAKE_I2C_PORT->BRR=FAKE_I2C_SCL_PIN 22 | 23 | //// 初始化函数 24 | //// delayloop : 用于调整通信频率 25 | //// time_out : 用于等待Ack的时间 26 | //// device_8bit_add : 目标设备的地址(8位,最低位补0) 27 | //// add_byte_size : 寄存器地址占有的字节数, 1:8位地址 2:16位地址 28 | void init_fake_i2c(unsigned short delay_loop,unsigned char time_out,unsigned char device_8bit_add,unsigned char add_byte_size); 29 | 30 | void fake_i2c_sel_device(unsigned char add_8bit); 31 | 32 | void fake_i2c_delay(void); 33 | void fake_i2c_start(void); 34 | unsigned char fake_i2c_send(unsigned char dat); 35 | void fake_i2c_stop(void); 36 | 37 | unsigned char fake_i2c_read(unsigned char ack); 38 | unsigned char fake_i2c_write_reg(u16 reg,unsigned char dat); 39 | unsigned char fake_i2c_read_reg(u16 reg); 40 | unsigned char fake_i2c_read_buff(u16 reg,u16 length,unsigned char *buffer); 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Examples/心率检测MAX30102/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | #include "valuepack.h" 3 | #include "fake_i2c.h" 4 | 5 | #define MAX30102_ADD 0xAe 6 | #define MAX30102_MODE_LED_IR 3 7 | #define MAX30102_MODE_IR 2 8 | #define MAX30102_FILTERED_VALUE_RANGE 500 9 | 10 | 11 | TxPack txpack; 12 | 13 | //------------------------------------------------------------------------------------------------------ 14 | // 15 | // 初始化心率检测模块 MAX30102 16 | // 17 | // 设置模式 : 可设置仅 心率 或 SPO2模式 18 | // 19 | // 设置两种光源的亮度brightness : 配置亮度,范围是00~ff 20 | // 21 | void initMAX30102(unsigned char mode,unsigned char ir_led_brightness,unsigned char red_led_brightness) 22 | { 23 | init_fake_i2c(1,2,MAX30102_ADD,1); 24 | 25 | fake_i2c_write_reg(0x02,0xf0); 26 | fake_i2c_write_reg(0x03, 0x02); 27 | 28 | fake_i2c_write_reg(0x04, 0x00); 29 | fake_i2c_write_reg(0x05, 0x00); 30 | fake_i2c_write_reg(0x06, 0x00); 31 | 32 | fake_i2c_write_reg(0x08, 0x1f); 33 | fake_i2c_write_reg(0x09, mode); 34 | fake_i2c_write_reg(0x0a, 0x61); 35 | fake_i2c_write_reg(0x0c, ir_led_brightness); 36 | fake_i2c_write_reg(0x0d, red_led_brightness); 37 | } 38 | 39 | 40 | //------------------------------------------------------------------------------------------------------- 41 | // 读取采样值 42 | // 43 | // 这些采样值都是经过一定的滤波处理的 44 | // 将变量地址传入以读出数据 45 | 46 | void MAX30102_ReadValue( float *ir_v, float *red_v) 47 | { 48 | static unsigned short last_ir,last_red; 49 | static float rate_ir,rate_red; 50 | 51 | unsigned char buffer[6]; 52 | unsigned char state; 53 | 54 | unsigned short raw_value_ir; 55 | unsigned short raw_value_red; 56 | 57 | state = fake_i2c_read_reg(0x04); // 读取FIFO新数据的数目,如果非0,说明有新的数据 58 | 59 | if(state) 60 | { 61 | fake_i2c_read_buff(0x07,6,buffer); 62 | fake_i2c_write_reg(0x04,0x00); 63 | fake_i2c_write_reg(0x06,0x00); 64 | 65 | raw_value_ir = (buffer[1]<<8)+buffer[2]; 66 | raw_value_red = (buffer[4]<<8)|buffer[5]; 67 | 68 | if(raw_value_ir!=last_ir) 69 | rate_ir += ((raw_value_ir-last_ir)-rate_ir)*0.18f; 70 | 71 | if(raw_value_red!=last_red) 72 | rate_red += ((raw_value_red-last_red)-rate_red)*0.18f; 73 | 74 | last_ir = raw_value_ir; 75 | last_red = raw_value_red; 76 | } 77 | 78 | (*red_v)+=rate_red; 79 | (*ir_v)+=rate_ir; 80 | (*ir_v)*=0.8f; 81 | (*red_v)*=0.8f; 82 | 83 | if(*ir_v>MAX30102_FILTERED_VALUE_RANGE) 84 | *ir_v = MAX30102_FILTERED_VALUE_RANGE; 85 | if(*ir_v<-MAX30102_FILTERED_VALUE_RANGE) 86 | *ir_v = -MAX30102_FILTERED_VALUE_RANGE; 87 | if(*red_v>MAX30102_FILTERED_VALUE_RANGE) 88 | *red_v = MAX30102_FILTERED_VALUE_RANGE; 89 | if(*red_v<-MAX30102_FILTERED_VALUE_RANGE) 90 | *red_v = -MAX30102_FILTERED_VALUE_RANGE; 91 | } 92 | 93 | 94 | /// ir:红外 red:红光 检测两种光源的反射程度 95 | float ir_value,red_value; 96 | 97 | int main(void) 98 | { 99 | 100 | initMAX30102(MAX30102_MODE_IR,0x66,0x65); 101 | initValuePack(115200); 102 | 103 | while(1) 104 | { 105 | 106 | // 延时 107 | for(int i=0;i<20000;i++) 108 | {} 109 | 110 | MAX30102_ReadValue(&ir_value,&red_value); 111 | 112 | txpack.floats[0] = ir_value; 113 | txpack.floats[1] = red_value; 114 | 115 | sendValuePack(&txpack); 116 | 117 | } 118 | } 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /Examples/心率检测MAX30102/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char bits[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 4 | 5 | const unsigned int VALUEPACK_INDEX_RANGE=VALUEPACK_BUFFER_SIZE<<3; 6 | const unsigned short TXPACK_BYTE_SIZE = ((TX_BOOL_NUM+7)>>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 7 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 8 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 9 | 10 | 11 | long rxIndex=0; 12 | long rdIndex=0; 13 | 14 | 15 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 16 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 17 | 18 | 19 | DMA_InitTypeDef dma; 20 | 21 | void initValuePack(int baudrate) 22 | { 23 | 24 | USART_InitTypeDef USART_InitStructure; 25 | GPIO_InitTypeDef GPIO_InitStructure; 26 | 27 | // 时钟初始化 28 | 29 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 30 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 31 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); 32 | 33 | // 引脚初始化 34 | 35 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 36 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 37 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 38 | GPIO_Init(GPIOA, &GPIO_InitStructure); 39 | /* PA10 USART1_Rx */ 40 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 41 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 42 | GPIO_Init(GPIOA, &GPIO_InitStructure); 43 | 44 | // 串口初始化 45 | 46 | USART_InitStructure.USART_BaudRate = baudrate; 47 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 48 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 49 | USART_InitStructure.USART_Parity = USART_Parity_No; 50 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 51 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 52 | 53 | USART_Init(USART1, &USART_InitStructure); 54 | 55 | // DMA初始化 56 | 57 | DMA_DeInit(DMA1_Channel4); 58 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 59 | dma.DMA_M2M = DMA_M2M_Disable; 60 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 61 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 62 | 63 | dma.DMA_Priority = DMA_Priority_High; 64 | dma.DMA_BufferSize = 4; 65 | dma.DMA_MemoryBaseAddr = (uint32_t)0; 66 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 67 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 68 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 69 | dma.DMA_Mode = DMA_Mode_Normal; 70 | DMA_Init(DMA1_Channel4,&dma); 71 | 72 | USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 73 | 74 | DMA_DeInit(DMA1_Channel5); 75 | dma.DMA_DIR = DMA_DIR_PeripheralSRC; 76 | dma.DMA_BufferSize = VALUEPACK_BUFFER_SIZE; 77 | dma.DMA_MemoryBaseAddr = (uint32_t)vp_rxbuff; 78 | dma.DMA_Mode = DMA_Mode_Circular; 79 | DMA_Init(DMA1_Channel5,&dma); 80 | 81 | USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); 82 | USART_Cmd(USART1, ENABLE); 83 | DMA_Cmd(DMA1_Channel5,ENABLE); 84 | 85 | } 86 | 87 | 88 | 89 | unsigned short this_index=0; 90 | unsigned short last_index=0; 91 | unsigned short rdi,rdii,idl,idi; 92 | uint32_t idc; 93 | unsigned int err=0; 94 | unsigned char sum=0; 95 | unsigned char isok; 96 | 97 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 98 | // 99 | //procValuePack 用来处理手机传来的数据 100 | // 101 | 102 | unsigned char readValuePack(RxPack *rx_pack_ptr) 103 | { 104 | isok = 0; 105 | this_index =VALUEPACK_BUFFER_SIZE-DMA1_Channel5->CNDTR; 106 | if(this_index=VALUEPACK_BUFFER_SIZE) 127 | rdi -= VALUEPACK_BUFFER_SIZE; 128 | sum += vp_rxbuff[rdi]; 129 | } 130 | rdi++; 131 | if(rdi>=VALUEPACK_BUFFER_SIZE) 132 | rdi -= VALUEPACK_BUFFER_SIZE; 133 | 134 | if(sum==vp_rxbuff[rdi]) 135 | { 136 | // 提取数据包数据 一共有五步, bool byte short int float 137 | 138 | // 1. bool 139 | #if RX_BOOL_NUM>0 140 | 141 | idc = (uint32_t)rx_pack_ptr->bools; 142 | idl = (RX_BOOL_NUM+7)>>3; 143 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 146 | rdii -= VALUEPACK_BUFFER_SIZE; 147 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 148 | rdii++; 149 | idc++; 150 | } 151 | #endif 152 | // 2.byte 153 | #if RX_BYTE_NUM>0 154 | idc = (uint32_t)(rx_pack_ptr->bytes); 155 | idl = RX_BYTE_NUM; 156 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 159 | rdii -= VALUEPACK_BUFFER_SIZE; 160 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 161 | rdii++; 162 | idc++; 163 | } 164 | #endif 165 | // 3.short 166 | #if RX_SHORT_NUM>0 167 | idc = (uint32_t)(rx_pack_ptr->shorts); 168 | idl = RX_SHORT_NUM<<1; 169 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 172 | rdii -= VALUEPACK_BUFFER_SIZE; 173 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 174 | rdii++; 175 | idc++; 176 | } 177 | #endif 178 | // 4.int 179 | #if RX_INT_NUM>0 180 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 181 | idl = RX_INT_NUM<<2; 182 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 185 | rdii -= VALUEPACK_BUFFER_SIZE; 186 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 187 | rdii++; 188 | idc++; 189 | } 190 | #endif 191 | // 5.float 192 | #if RX_FLOAT_NUM>0 193 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 194 | idl = RX_FLOAT_NUM<<2; 195 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 198 | rdii -= VALUEPACK_BUFFER_SIZE; 199 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 200 | rdii++; 201 | idc++; 202 | } 203 | #endif 204 | err = rdii; 205 | rdIndex+=rx_pack_length; 206 | isok = 1; 207 | }else 208 | { 209 | rdIndex++; 210 | err++; 211 | } 212 | }else 213 | { 214 | rdIndex++; 215 | err++; 216 | } 217 | }else 218 | { 219 | rdIndex++; 220 | err++; 221 | } 222 | } 223 | last_index = this_index; 224 | return isok; 225 | } 226 | 227 | void sendBuffer(unsigned char *p,unsigned short length) 228 | { 229 | DMA_DeInit(DMA1_Channel4); 230 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 231 | dma.DMA_M2M = DMA_M2M_Disable; 232 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 233 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 234 | dma.DMA_Priority = DMA_Priority_High; 235 | dma.DMA_BufferSize = length; 236 | dma.DMA_MemoryBaseAddr = (uint32_t)p; 237 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 238 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 239 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 240 | dma.DMA_Mode = DMA_Mode_Normal; 241 | DMA_Init(DMA1_Channel4,&dma); 242 | DMA_Cmd(DMA1_Channel4,ENABLE); 243 | } 244 | 245 | 246 | 247 | unsigned short loop; 248 | unsigned char valuepack_tx_bit_index; 249 | unsigned char valuepack_tx_index; 250 | 251 | void sendValuePack(TxPack *tx_pack_ptr) 252 | { 253 | int i; 254 | vp_txbuff[0]=0xa5; 255 | sum=0; 256 | // 由于结构体中不同类型的变量在内存空间的排布不是严格对齐的,中间嵌有无效字节,因此需要特殊处理 257 | 258 | valuepack_tx_bit_index = 0; 259 | valuepack_tx_index = 1; 260 | 261 | #if TX_BOOL_NUM>0 262 | 263 | for(loop=0;loopbools[loop]) 266 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 272 | { 273 | valuepack_tx_bit_index = 0; 274 | valuepack_tx_index++; 275 | } 276 | } 277 | if(valuepack_tx_bit_index!=0) 278 | valuepack_tx_index++; 279 | #endif 280 | 281 | #if TX_BYTE_NUM>0 282 | 283 | for(loop=0;loopbytes[loop]; 286 | valuepack_tx_index++; 287 | } 288 | 289 | #endif 290 | 291 | #if TX_SHORT_NUM>0 292 | for(loop=0;loopshorts[loop]&0xff; 295 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 296 | valuepack_tx_index+=2; 297 | } 298 | #endif 299 | 300 | #if TX_INT_NUM>0 301 | for(loop=0;loopintegers[loop]; 304 | 305 | vp_txbuff[valuepack_tx_index] = i&0xff; 306 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 307 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 308 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 309 | 310 | valuepack_tx_index+=4; 311 | } 312 | #endif 313 | 314 | #if TX_FLOAT_NUM>0 315 | for(loop=0;loopfloats[loop])); 318 | 319 | vp_txbuff[valuepack_tx_index] = i&0xff; 320 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 321 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 322 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 323 | 324 | valuepack_tx_index+=4; 325 | } 326 | #endif 327 | 328 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 329 | sum+=vp_txbuff[d]; 330 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 331 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 332 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 333 | } -------------------------------------------------------------------------------- /Examples/心率检测MAX30102/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过DMA和USART 进行数据包的接收和发送 4 | // 接收的数据自动写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | // 数据发送也采用DMA 6 | 7 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 8 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 9 | #define VALUEPACK_BUFFER_SIZE 1024 10 | 11 | 12 | /// 2.指定发送到手机的数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 13 | /// 14 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 15 | 16 | #define TX_BOOL_NUM 0 17 | #define TX_BYTE_NUM 0 18 | #define TX_SHORT_NUM 0 19 | #define TX_INT_NUM 0 20 | #define TX_FLOAT_NUM 2 21 | 22 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 23 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 24 | 25 | #define RX_BOOL_NUM 0 26 | #define RX_BYTE_NUM 0 27 | #define RX_SHORT_NUM 0 28 | #define RX_INT_NUM 0 29 | #define RX_FLOAT_NUM 0 30 | 31 | 32 | 33 | typedef struct 34 | { 35 | #if TX_BOOL_NUM > 0 36 | unsigned char bools[TX_BOOL_NUM]; 37 | #endif 38 | 39 | #if TX_BYTE_NUM > 0 40 | char bytes[TX_BYTE_NUM]; 41 | #endif 42 | 43 | #if TX_SHORT_NUM > 0 44 | short shorts[TX_SHORT_NUM]; 45 | #endif 46 | 47 | #if TX_INT_NUM > 0 48 | int integers[TX_INT_NUM]; 49 | #endif 50 | 51 | #if TX_FLOAT_NUM > 0 52 | float floats[TX_FLOAT_NUM]; 53 | #endif 54 | 55 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 56 | } 57 | TxPack; 58 | typedef struct 59 | { 60 | #if RX_BOOL_NUM > 0 61 | unsigned char bools[RX_BOOL_NUM]; 62 | #endif 63 | 64 | #if RX_BYTE_NUM > 0 65 | char bytes[RX_BYTE_NUM]; 66 | #endif 67 | 68 | #if RX_SHORT_NUM > 0 69 | short shorts[RX_SHORT_NUM]; 70 | #endif 71 | 72 | #if RX_INT_NUM > 0 73 | int integers[RX_INT_NUM]; 74 | #endif 75 | 76 | #if RX_FLOAT_NUM > 0 77 | float floats[RX_FLOAT_NUM]; 78 | #endif 79 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 80 | }RxPack; 81 | // 初始化 valuepack 包括一些必要的硬件外设配置 82 | 83 | void initValuePack(int baudrate); 84 | 85 | // 需要保证至少每秒执行10次该函数 86 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 87 | // 接收到数据包时 返回 1 ,否则返回 0 88 | unsigned char readValuePack(RxPack *rx_pack_ptr); 89 | 90 | 91 | // 发送数据包 92 | void sendValuePack(TxPack *tx_pack_ptr); 93 | 94 | 95 | #define PACK_HEAD 0xa5 96 | #define PACK_TAIL 0x5a 97 | 98 | -------------------------------------------------------------------------------- /Examples/控制LED灯/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XieLazyDog/ValuePack/19c998d7d8b9fa73f1f5d1a3106b1dd938c65c2e/Examples/控制LED灯/main.c -------------------------------------------------------------------------------- /Examples/控制LED灯/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char bits[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 4 | 5 | const unsigned int VALUEPACK_INDEX_RANGE=VALUEPACK_BUFFER_SIZE<<3; 6 | const unsigned short TXPACK_BYTE_SIZE = ((TX_BOOL_NUM+7)>>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 7 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 8 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 9 | 10 | 11 | long rxIndex=0; 12 | long rdIndex=0; 13 | 14 | 15 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 16 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 17 | 18 | 19 | DMA_InitTypeDef dma; 20 | 21 | void initValuePack(int baudrate) 22 | { 23 | 24 | USART_InitTypeDef USART_InitStructure; 25 | GPIO_InitTypeDef GPIO_InitStructure; 26 | 27 | // 时钟初始化 28 | 29 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 30 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 31 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); 32 | 33 | // 引脚初始化 34 | 35 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 36 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 37 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 38 | GPIO_Init(GPIOA, &GPIO_InitStructure); 39 | /* PA10 USART1_Rx */ 40 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 41 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 42 | GPIO_Init(GPIOA, &GPIO_InitStructure); 43 | 44 | // 串口初始化 45 | 46 | USART_InitStructure.USART_BaudRate = baudrate; 47 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 48 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 49 | USART_InitStructure.USART_Parity = USART_Parity_No; 50 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 51 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 52 | 53 | USART_Init(USART1, &USART_InitStructure); 54 | 55 | // DMA初始化 56 | 57 | DMA_DeInit(DMA1_Channel4); 58 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 59 | dma.DMA_M2M = DMA_M2M_Disable; 60 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 61 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 62 | 63 | dma.DMA_Priority = DMA_Priority_High; 64 | dma.DMA_BufferSize = 4; 65 | dma.DMA_MemoryBaseAddr = (uint32_t)0; 66 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 67 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 68 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 69 | dma.DMA_Mode = DMA_Mode_Normal; 70 | DMA_Init(DMA1_Channel4,&dma); 71 | 72 | USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 73 | 74 | DMA_DeInit(DMA1_Channel5); 75 | dma.DMA_DIR = DMA_DIR_PeripheralSRC; 76 | dma.DMA_BufferSize = VALUEPACK_BUFFER_SIZE; 77 | dma.DMA_MemoryBaseAddr = (uint32_t)vp_rxbuff; 78 | dma.DMA_Mode = DMA_Mode_Circular; 79 | DMA_Init(DMA1_Channel5,&dma); 80 | 81 | USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); 82 | USART_Cmd(USART1, ENABLE); 83 | DMA_Cmd(DMA1_Channel5,ENABLE); 84 | 85 | } 86 | 87 | 88 | 89 | unsigned short this_index=0; 90 | unsigned short last_index=0; 91 | unsigned short rdi,rdii,idl,idi; 92 | uint32_t idc; 93 | unsigned int err=0; 94 | unsigned char sum=0; 95 | unsigned char isok; 96 | 97 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 98 | // 99 | //procValuePack 用来处理手机传来的数据 100 | // 101 | 102 | unsigned char readValuePack(RxPack *rx_pack_ptr) 103 | { 104 | isok = 0; 105 | this_index =VALUEPACK_BUFFER_SIZE-DMA1_Channel5->CNDTR; 106 | if(this_index=VALUEPACK_BUFFER_SIZE) 127 | rdi -= VALUEPACK_BUFFER_SIZE; 128 | sum += vp_rxbuff[rdi]; 129 | } 130 | rdi++; 131 | if(rdi>=VALUEPACK_BUFFER_SIZE) 132 | rdi -= VALUEPACK_BUFFER_SIZE; 133 | 134 | if(sum==vp_rxbuff[rdi]) 135 | { 136 | // 提取数据包数据 一共有五步, bool byte short int float 137 | 138 | // 1. bool 139 | #if RX_BOOL_NUM>0 140 | 141 | idc = (uint32_t)rx_pack_ptr->bools; 142 | idl = (RX_BOOL_NUM+7)>>3; 143 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 146 | rdii -= VALUEPACK_BUFFER_SIZE; 147 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 148 | rdii++; 149 | idc++; 150 | } 151 | #endif 152 | // 2.byte 153 | #if RX_BYTE_NUM>0 154 | idc = (uint32_t)(rx_pack_ptr->bytes); 155 | idl = RX_BYTE_NUM; 156 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 159 | rdii -= VALUEPACK_BUFFER_SIZE; 160 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 161 | rdii++; 162 | idc++; 163 | } 164 | #endif 165 | // 3.short 166 | #if RX_SHORT_NUM>0 167 | idc = (uint32_t)(rx_pack_ptr->shorts); 168 | idl = RX_SHORT_NUM<<1; 169 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 172 | rdii -= VALUEPACK_BUFFER_SIZE; 173 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 174 | rdii++; 175 | idc++; 176 | } 177 | #endif 178 | // 4.int 179 | #if RX_INT_NUM>0 180 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 181 | idl = RX_INT_NUM<<2; 182 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 185 | rdii -= VALUEPACK_BUFFER_SIZE; 186 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 187 | rdii++; 188 | idc++; 189 | } 190 | #endif 191 | // 5.float 192 | #if RX_FLOAT_NUM>0 193 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 194 | idl = RX_FLOAT_NUM<<2; 195 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 198 | rdii -= VALUEPACK_BUFFER_SIZE; 199 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 200 | rdii++; 201 | idc++; 202 | } 203 | #endif 204 | err = rdii; 205 | rdIndex+=rx_pack_length; 206 | isok = 1; 207 | }else 208 | { 209 | rdIndex++; 210 | err++; 211 | } 212 | }else 213 | { 214 | rdIndex++; 215 | err++; 216 | } 217 | }else 218 | { 219 | rdIndex++; 220 | err++; 221 | } 222 | } 223 | last_index = this_index; 224 | return isok; 225 | } 226 | 227 | void sendBuffer(unsigned char *p,unsigned short length) 228 | { 229 | DMA_DeInit(DMA1_Channel4); 230 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 231 | dma.DMA_M2M = DMA_M2M_Disable; 232 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 233 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 234 | dma.DMA_Priority = DMA_Priority_High; 235 | dma.DMA_BufferSize = length; 236 | dma.DMA_MemoryBaseAddr = (uint32_t)p; 237 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 238 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 239 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 240 | dma.DMA_Mode = DMA_Mode_Normal; 241 | DMA_Init(DMA1_Channel4,&dma); 242 | DMA_Cmd(DMA1_Channel4,ENABLE); 243 | } 244 | 245 | 246 | 247 | unsigned short loop; 248 | unsigned char valuepack_tx_bit_index; 249 | unsigned char valuepack_tx_index; 250 | 251 | void sendValuePack(TxPack *tx_pack_ptr) 252 | { 253 | int i; 254 | vp_txbuff[0]=0xa5; 255 | sum=0; 256 | // 由于结构体中不同类型的变量在内存空间的排布不是严格对齐的,中间嵌有无效字节,因此需要特殊处理 257 | 258 | valuepack_tx_bit_index = 0; 259 | valuepack_tx_index = 1; 260 | 261 | #if TX_BOOL_NUM>0 262 | 263 | for(loop=0;loopbools[loop]) 266 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 272 | { 273 | valuepack_tx_bit_index = 0; 274 | valuepack_tx_index++; 275 | } 276 | } 277 | if(valuepack_tx_bit_index!=0) 278 | valuepack_tx_index++; 279 | #endif 280 | 281 | #if TX_BYTE_NUM>0 282 | 283 | for(loop=0;loopbytes[loop]; 286 | valuepack_tx_index++; 287 | } 288 | 289 | #endif 290 | 291 | #if TX_SHORT_NUM>0 292 | for(loop=0;loopshorts[loop]&0xff; 295 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 296 | valuepack_tx_index+=2; 297 | } 298 | #endif 299 | 300 | #if TX_INT_NUM>0 301 | for(loop=0;loopintegers[loop]; 304 | 305 | vp_txbuff[valuepack_tx_index] = i&0xff; 306 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 307 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 308 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 309 | 310 | valuepack_tx_index+=4; 311 | } 312 | #endif 313 | 314 | #if TX_FLOAT_NUM>0 315 | for(loop=0;loopfloats[loop])); 318 | 319 | vp_txbuff[valuepack_tx_index] = i&0xff; 320 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 321 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 322 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 323 | 324 | valuepack_tx_index+=4; 325 | } 326 | #endif 327 | 328 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 329 | sum+=vp_txbuff[d]; 330 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 331 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 332 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 333 | } 334 | 335 | 336 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /Examples/控制LED灯/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过DMA和USART 进行数据包的接收和发送 4 | // 接收的数据自动写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | // 数据发送也采用DMA 6 | 7 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 8 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 9 | #define VALUEPACK_BUFFER_SIZE 1024 10 | 11 | 12 | /// 2.指定发送到手机的数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 13 | /// 14 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 15 | 16 | #define TX_BOOL_NUM 0 17 | #define TX_BYTE_NUM 0 18 | #define TX_SHORT_NUM 0 19 | #define TX_INT_NUM 0 20 | #define TX_FLOAT_NUM 0 21 | 22 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 23 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 24 | 25 | #define RX_BOOL_NUM 1 26 | #define RX_BYTE_NUM 0 27 | #define RX_SHORT_NUM 0 28 | #define RX_INT_NUM 0 29 | #define RX_FLOAT_NUM 0 30 | 31 | 32 | 33 | typedef struct 34 | { 35 | #if TX_BOOL_NUM > 0 36 | unsigned char bools[TX_BOOL_NUM]; 37 | #endif 38 | 39 | #if TX_BYTE_NUM > 0 40 | char bytes[TX_BYTE_NUM]; 41 | #endif 42 | 43 | #if TX_SHORT_NUM > 0 44 | short shorts[TX_SHORT_NUM]; 45 | #endif 46 | 47 | #if TX_INT_NUM > 0 48 | int integers[TX_INT_NUM]; 49 | #endif 50 | 51 | #if TX_FLOAT_NUM > 0 52 | float floats[TX_FLOAT_NUM]; 53 | #endif 54 | 55 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 56 | } 57 | TxPack; 58 | typedef struct 59 | { 60 | #if RX_BOOL_NUM > 0 61 | unsigned char bools[RX_BOOL_NUM]; 62 | #endif 63 | 64 | #if RX_BYTE_NUM > 0 65 | char bytes[RX_BYTE_NUM]; 66 | #endif 67 | 68 | #if RX_SHORT_NUM > 0 69 | short shorts[RX_SHORT_NUM]; 70 | #endif 71 | 72 | #if RX_INT_NUM > 0 73 | int integers[RX_INT_NUM]; 74 | #endif 75 | 76 | #if RX_FLOAT_NUM > 0 77 | float floats[RX_FLOAT_NUM]; 78 | #endif 79 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 80 | }RxPack; 81 | // 初始化 valuepack 包括一些必要的硬件外设配置 82 | 83 | void initValuePack(int baudrate); 84 | 85 | // 需要保证至少每秒执行10次该函数 86 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 87 | // 接收到数据包时 返回 1 ,否则返回 0 88 | unsigned char readValuePack(RxPack *rx_pack_ptr); 89 | 90 | 91 | // 发送数据包 92 | void sendValuePack(TxPack *tx_pack_ptr); 93 | 94 | 95 | #define PACK_HEAD 0xa5 96 | #define PACK_TAIL 0x5a 97 | -------------------------------------------------------------------------------- /Examples/湿度回传/湿度回传-USART+DMA/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | #include "valuepack.h" 3 | 4 | void initHumiditySensor() 5 | { 6 | 7 | ADC_InitTypeDef ADC_InitStructure; 8 | GPIO_InitTypeDef GPIO_InitStructure; 9 | 10 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 11 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); 12 | 13 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 14 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 15 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 16 | GPIO_Init(GPIOA, &GPIO_InitStructure); 17 | 18 | ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 19 | ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 20 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 21 | ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 22 | ADC_InitStructure.ADC_NbrOfChannel = 1; 23 | ADC_InitStructure.ADC_ScanConvMode = DISABLE; 24 | ADC_Init(ADC1,&ADC_InitStructure); 25 | RCC_ADCCLKConfig(RCC_PCLK2_Div8); 26 | ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, 27 | ADC_SampleTime_55Cycles5); 28 | ADC_Cmd(ADC1, ENABLE); 29 | ADC_ResetCalibration(ADC1); 30 | while(ADC_GetResetCalibrationStatus(ADC1)) 31 | {} 32 | ADC_StartCalibration(ADC1); 33 | while(ADC_GetCalibrationStatus(ADC1)) 34 | {} 35 | ADC_SoftwareStartConvCmd(ADC1, ENABLE); 36 | } 37 | 38 | //// 比例系数,将ADC测量值转换为 0~100的百分比 39 | float f = 100.0f/(4096*3/3.3f); 40 | 41 | //// 读取湿度信息,返回的数值为0~100,分辨度为0.1 42 | float readHumidity() 43 | { 44 | return ((int)((ADC1->DR)*f*10))*0.1f; 45 | } 46 | 47 | TxPack txpack; 48 | 49 | int main(void) 50 | { 51 | 52 | initHumiditySensor(); 53 | initValuePack(115200); 54 | 55 | while(1) 56 | { 57 | 58 | // 延时 59 | for(int t=0;t<7200000;t++) 60 | { 61 | } 62 | 63 | 64 | txpack.floats[0] = readHumidity(); 65 | sendValuePack(&txpack); 66 | 67 | } 68 | } 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /Examples/湿度回传/湿度回传-USART+DMA/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char bits[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 4 | 5 | const unsigned int VALUEPACK_INDEX_RANGE=VALUEPACK_BUFFER_SIZE<<3; 6 | const unsigned short TXPACK_BYTE_SIZE = ((TX_BOOL_NUM+7)>>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 7 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 8 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 9 | 10 | 11 | long rxIndex=0; 12 | long rdIndex=0; 13 | 14 | 15 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 16 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 17 | 18 | 19 | DMA_InitTypeDef dma; 20 | 21 | void initValuePack(int baudrate) 22 | { 23 | 24 | USART_InitTypeDef USART_InitStructure; 25 | GPIO_InitTypeDef GPIO_InitStructure; 26 | 27 | // 时钟初始化 28 | 29 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 30 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 31 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); 32 | 33 | // 引脚初始化 34 | 35 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 36 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 37 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 38 | GPIO_Init(GPIOA, &GPIO_InitStructure); 39 | /* PA10 USART1_Rx */ 40 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 41 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 42 | GPIO_Init(GPIOA, &GPIO_InitStructure); 43 | 44 | // 串口初始化 45 | 46 | USART_InitStructure.USART_BaudRate = baudrate; 47 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 48 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 49 | USART_InitStructure.USART_Parity = USART_Parity_No; 50 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 51 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 52 | 53 | USART_Init(USART1, &USART_InitStructure); 54 | 55 | // DMA初始化 56 | 57 | DMA_DeInit(DMA1_Channel4); 58 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 59 | dma.DMA_M2M = DMA_M2M_Disable; 60 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 61 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 62 | 63 | dma.DMA_Priority = DMA_Priority_High; 64 | dma.DMA_BufferSize = 4; 65 | dma.DMA_MemoryBaseAddr = (uint32_t)0; 66 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 67 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 68 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 69 | dma.DMA_Mode = DMA_Mode_Normal; 70 | DMA_Init(DMA1_Channel4,&dma); 71 | 72 | USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 73 | 74 | DMA_DeInit(DMA1_Channel5); 75 | dma.DMA_DIR = DMA_DIR_PeripheralSRC; 76 | dma.DMA_BufferSize = VALUEPACK_BUFFER_SIZE; 77 | dma.DMA_MemoryBaseAddr = (uint32_t)vp_rxbuff; 78 | dma.DMA_Mode = DMA_Mode_Circular; 79 | DMA_Init(DMA1_Channel5,&dma); 80 | 81 | USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); 82 | USART_Cmd(USART1, ENABLE); 83 | DMA_Cmd(DMA1_Channel5,ENABLE); 84 | 85 | } 86 | 87 | 88 | 89 | unsigned short this_index=0; 90 | unsigned short last_index=0; 91 | unsigned short rdi,rdii,idl,idi; 92 | uint32_t idc; 93 | unsigned int err=0; 94 | unsigned char sum=0; 95 | unsigned char isok; 96 | 97 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 98 | // 99 | //procValuePack 用来处理手机传来的数据 100 | // 101 | 102 | unsigned char readValuePack(RxPack *rx_pack_ptr) 103 | { 104 | isok = 0; 105 | this_index =VALUEPACK_BUFFER_SIZE-DMA1_Channel5->CNDTR; 106 | if(this_index=VALUEPACK_BUFFER_SIZE) 127 | rdi -= VALUEPACK_BUFFER_SIZE; 128 | sum += vp_rxbuff[rdi]; 129 | } 130 | rdi++; 131 | if(rdi>=VALUEPACK_BUFFER_SIZE) 132 | rdi -= VALUEPACK_BUFFER_SIZE; 133 | 134 | if(sum==vp_rxbuff[rdi]) 135 | { 136 | // 提取数据包数据 一共有五步, bool byte short int float 137 | 138 | // 1. bool 139 | #if RX_BOOL_NUM>0 140 | 141 | idc = (uint32_t)rx_pack_ptr->bools; 142 | idl = (RX_BOOL_NUM+7)>>3; 143 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 146 | rdii -= VALUEPACK_BUFFER_SIZE; 147 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 148 | rdii++; 149 | idc++; 150 | } 151 | #endif 152 | // 2.byte 153 | #if RX_BYTE_NUM>0 154 | idc = (uint32_t)(rx_pack_ptr->bytes); 155 | idl = RX_BYTE_NUM; 156 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 159 | rdii -= VALUEPACK_BUFFER_SIZE; 160 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 161 | rdii++; 162 | idc++; 163 | } 164 | #endif 165 | // 3.short 166 | #if RX_SHORT_NUM>0 167 | idc = (uint32_t)(rx_pack_ptr->shorts); 168 | idl = RX_SHORT_NUM<<1; 169 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 172 | rdii -= VALUEPACK_BUFFER_SIZE; 173 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 174 | rdii++; 175 | idc++; 176 | } 177 | #endif 178 | // 4.int 179 | #if RX_INT_NUM>0 180 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 181 | idl = RX_INT_NUM<<2; 182 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 185 | rdii -= VALUEPACK_BUFFER_SIZE; 186 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 187 | rdii++; 188 | idc++; 189 | } 190 | #endif 191 | // 5.float 192 | #if RX_FLOAT_NUM>0 193 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 194 | idl = RX_FLOAT_NUM<<2; 195 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 198 | rdii -= VALUEPACK_BUFFER_SIZE; 199 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 200 | rdii++; 201 | idc++; 202 | } 203 | #endif 204 | err = rdii; 205 | rdIndex+=rx_pack_length; 206 | isok = 1; 207 | }else 208 | { 209 | rdIndex++; 210 | err++; 211 | } 212 | }else 213 | { 214 | rdIndex++; 215 | err++; 216 | } 217 | }else 218 | { 219 | rdIndex++; 220 | err++; 221 | } 222 | } 223 | last_index = this_index; 224 | return isok; 225 | } 226 | 227 | void sendBuffer(unsigned char *p,unsigned short length) 228 | { 229 | DMA_DeInit(DMA1_Channel4); 230 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 231 | dma.DMA_M2M = DMA_M2M_Disable; 232 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 233 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 234 | dma.DMA_Priority = DMA_Priority_High; 235 | dma.DMA_BufferSize = length; 236 | dma.DMA_MemoryBaseAddr = (uint32_t)p; 237 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 238 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 239 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 240 | dma.DMA_Mode = DMA_Mode_Normal; 241 | DMA_Init(DMA1_Channel4,&dma); 242 | DMA_Cmd(DMA1_Channel4,ENABLE); 243 | } 244 | 245 | 246 | 247 | unsigned short loop; 248 | unsigned char valuepack_tx_bit_index; 249 | unsigned char valuepack_tx_index; 250 | 251 | void sendValuePack(TxPack *tx_pack_ptr) 252 | { 253 | int i; 254 | vp_txbuff[0]=0xa5; 255 | sum=0; 256 | // 由于结构体中不同类型的变量在内存空间的排布不是严格对齐的,中间嵌有无效字节,因此需要特殊处理 257 | 258 | valuepack_tx_bit_index = 0; 259 | valuepack_tx_index = 1; 260 | 261 | #if TX_BOOL_NUM>0 262 | 263 | for(loop=0;loopbools[loop]) 266 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 272 | { 273 | valuepack_tx_bit_index = 0; 274 | valuepack_tx_index++; 275 | } 276 | } 277 | if(valuepack_tx_bit_index!=0) 278 | valuepack_tx_index++; 279 | #endif 280 | 281 | #if TX_BYTE_NUM>0 282 | 283 | for(loop=0;loopbytes[loop]; 286 | valuepack_tx_index++; 287 | } 288 | 289 | #endif 290 | 291 | #if TX_SHORT_NUM>0 292 | for(loop=0;loopshorts[loop]&0xff; 295 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 296 | valuepack_tx_index+=2; 297 | } 298 | #endif 299 | 300 | #if TX_INT_NUM>0 301 | for(loop=0;loopintegers[loop]; 304 | 305 | vp_txbuff[valuepack_tx_index] = i&0xff; 306 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 307 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 308 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 309 | 310 | valuepack_tx_index+=4; 311 | } 312 | #endif 313 | 314 | #if TX_FLOAT_NUM>0 315 | for(loop=0;loopfloats[loop])); 318 | 319 | vp_txbuff[valuepack_tx_index] = i&0xff; 320 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 321 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 322 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 323 | 324 | valuepack_tx_index+=4; 325 | } 326 | #endif 327 | 328 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 329 | sum+=vp_txbuff[d]; 330 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 331 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 332 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 333 | } 334 | 335 | 336 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /Examples/湿度回传/湿度回传-USART+DMA/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过DMA和USART 进行数据包的接收和发送 4 | // 接收的数据自动写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | // 数据发送也采用DMA 6 | 7 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 8 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 9 | #define VALUEPACK_BUFFER_SIZE 1024 10 | 11 | 12 | /// 2.指定发送到手机的数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 13 | /// 14 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 15 | 16 | #define TX_BOOL_NUM 0 17 | #define TX_BYTE_NUM 0 18 | #define TX_SHORT_NUM 0 19 | #define TX_INT_NUM 0 20 | #define TX_FLOAT_NUM 1 21 | 22 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 23 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 24 | 25 | #define RX_BOOL_NUM 0 26 | #define RX_BYTE_NUM 0 27 | #define RX_SHORT_NUM 0 28 | #define RX_INT_NUM 0 29 | #define RX_FLOAT_NUM 0 30 | 31 | 32 | 33 | typedef struct 34 | { 35 | #if TX_BOOL_NUM > 0 36 | unsigned char bools[TX_BOOL_NUM]; 37 | #endif 38 | 39 | #if TX_BYTE_NUM > 0 40 | char bytes[TX_BYTE_NUM]; 41 | #endif 42 | 43 | #if TX_SHORT_NUM > 0 44 | short shorts[TX_SHORT_NUM]; 45 | #endif 46 | 47 | #if TX_INT_NUM > 0 48 | int integers[TX_INT_NUM]; 49 | #endif 50 | 51 | #if TX_FLOAT_NUM > 0 52 | float floats[TX_FLOAT_NUM]; 53 | #endif 54 | 55 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 56 | } 57 | TxPack; 58 | typedef struct 59 | { 60 | #if RX_BOOL_NUM > 0 61 | unsigned char bools[RX_BOOL_NUM]; 62 | #endif 63 | 64 | #if RX_BYTE_NUM > 0 65 | char bytes[RX_BYTE_NUM]; 66 | #endif 67 | 68 | #if RX_SHORT_NUM > 0 69 | short shorts[RX_SHORT_NUM]; 70 | #endif 71 | 72 | #if RX_INT_NUM > 0 73 | int integers[RX_INT_NUM]; 74 | #endif 75 | 76 | #if RX_FLOAT_NUM > 0 77 | float floats[RX_FLOAT_NUM]; 78 | #endif 79 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 80 | }RxPack; 81 | // 初始化 valuepack 包括一些必要的硬件外设配置 82 | 83 | void initValuePack(int baudrate); 84 | 85 | // 需要保证至少每秒执行10次该函数 86 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 87 | // 接收到数据包时 返回 1 ,否则返回 0 88 | unsigned char readValuePack(RxPack *rx_pack_ptr); 89 | 90 | 91 | // 发送数据包 92 | void sendValuePack(TxPack *tx_pack_ptr); 93 | 94 | 95 | #define PACK_HEAD 0xa5 96 | #define PACK_TAIL 0x5a 97 | -------------------------------------------------------------------------------- /Examples/湿度回传/湿度回传-USART+中断/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | #include "valuepack.h" 3 | 4 | void initHumiditySensor() 5 | { 6 | 7 | ADC_InitTypeDef ADC_InitStructure; 8 | GPIO_InitTypeDef GPIO_InitStructure; 9 | 10 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 11 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); 12 | 13 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 14 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 15 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 16 | GPIO_Init(GPIOA, &GPIO_InitStructure); 17 | 18 | ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 19 | ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 20 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 21 | ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 22 | ADC_InitStructure.ADC_NbrOfChannel = 1; 23 | ADC_InitStructure.ADC_ScanConvMode = DISABLE; 24 | ADC_Init(ADC1,&ADC_InitStructure); 25 | RCC_ADCCLKConfig(RCC_PCLK2_Div8); 26 | ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, 27 | ADC_SampleTime_55Cycles5); 28 | ADC_Cmd(ADC1, ENABLE); 29 | ADC_ResetCalibration(ADC1); 30 | while(ADC_GetResetCalibrationStatus(ADC1)) 31 | {} 32 | ADC_StartCalibration(ADC1); 33 | while(ADC_GetCalibrationStatus(ADC1)) 34 | {} 35 | ADC_SoftwareStartConvCmd(ADC1, ENABLE); 36 | } 37 | 38 | short readHumidity() 39 | { 40 | return ADC1->DR; 41 | } 42 | 43 | TxPack txpack; 44 | 45 | float f = 100.0f/(4096*3/3.3f); 46 | 47 | int main(void) 48 | { 49 | 50 | initHumiditySensor(); 51 | initValuePack(115200); 52 | 53 | while(1) 54 | { 55 | 56 | // 延时 57 | for(int t=0;t<7200000;t++) 58 | { 59 | } 60 | 61 | txpack.floats[0] = ((int)(readHumidity()*f*10))*0.1f; 62 | sendValuePack(&txpack); 63 | 64 | } 65 | } 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /Examples/湿度回传/湿度回传-USART+中断/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char bits[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 4 | 5 | 6 | const unsigned int VALUEPACK_INDEX_RANGE=VALUEPACK_BUFFER_SIZE<<3; 7 | const unsigned short TXPACK_BYTE_SIZE = ((TX_BOOL_NUM+7)>>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 8 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 9 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 10 | 11 | long rxIndex=0; 12 | long rdIndex=0; 13 | 14 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 15 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 16 | 17 | void initValuePack(int baudrate) 18 | { 19 | 20 | USART_InitTypeDef USART_InitStructure; 21 | GPIO_InitTypeDef GPIO_InitStructure; 22 | NVIC_InitTypeDef NVIC_InitStructure; 23 | 24 | // 时钟初始化 25 | 26 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 27 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 28 | 29 | // 引脚初始化 30 | 31 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 32 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 33 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 34 | GPIO_Init(GPIOA, &GPIO_InitStructure); 35 | /* PA10 USART1_Rx */ 36 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 37 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 38 | GPIO_Init(GPIOA, &GPIO_InitStructure); 39 | 40 | // 串口初始化 41 | 42 | USART_InitStructure.USART_BaudRate = baudrate; 43 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 44 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 45 | USART_InitStructure.USART_Parity = USART_Parity_No; 46 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 47 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 48 | 49 | USART_Init(USART1, &USART_InitStructure); 50 | 51 | USART_ClearITPendingBit(USART1,USART_IT_RXNE); 52 | USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); 53 | 54 | 55 | NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 56 | NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 57 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 58 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; 59 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 60 | NVIC_Init(&NVIC_InitStructure); 61 | 62 | 63 | USART_Cmd(USART1, ENABLE); 64 | } 65 | 66 | 67 | 68 | unsigned short rdi,rdii,idl,idi; 69 | uint32_t idc; 70 | unsigned int err=0; 71 | unsigned char sum=0; 72 | unsigned char isok; 73 | 74 | unsigned short vp_circle_rx_index; 75 | void USART1_IRQHandler(void) 76 | { 77 | if(USART_GetITStatus(USART1, USART_IT_RXNE)) 78 | { 79 | vp_rxbuff[vp_circle_rx_index] = USART1->DR; 80 | vp_circle_rx_index++; 81 | if(vp_circle_rx_index>=VALUEPACK_BUFFER_SIZE) 82 | vp_circle_rx_index=0; 83 | rxIndex++; 84 | } 85 | USART_ClearITPendingBit(USART1,USART_IT_RXNE); 86 | } 87 | 88 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 89 | // 90 | //procValuePack 用来处理手机传来的数据,并发送数据包 91 | // 92 | 93 | unsigned char readValuePack(RxPack *rx_pack_ptr) 94 | { 95 | 96 | isok = 0; 97 | 98 | 99 | while(rdIndex<(rxIndex-((rx_pack_length)))) 100 | rdIndex+=rx_pack_length; 101 | 102 | while(rdIndex<=(rxIndex-rx_pack_length)) 103 | { 104 | 105 | rdi = rdIndex % VALUEPACK_BUFFER_SIZE; 106 | rdii=rdi+1; 107 | if( vp_rxbuff[rdi]==PACK_HEAD) 108 | { 109 | if(vp_rxbuff[(rdi+RXPACK_BYTE_SIZE+2)%VALUEPACK_BUFFER_SIZE]==PACK_TAIL) 110 | { 111 | // 计算校验和 112 | sum=0; 113 | for(short s=0;s=VALUEPACK_BUFFER_SIZE) 117 | rdi -= VALUEPACK_BUFFER_SIZE; 118 | sum += vp_rxbuff[rdi]; 119 | } 120 | rdi++; 121 | if(rdi>=VALUEPACK_BUFFER_SIZE) 122 | rdi -= VALUEPACK_BUFFER_SIZE; 123 | 124 | if(sum==vp_rxbuff[rdi]) 125 | { 126 | // 提取数据包数据 一共有五步, bool byte short int float 127 | 128 | // 1. bool 129 | #if RX_BOOL_NUM>0 130 | 131 | idc = (uint32_t)rx_pack_ptr->bools; 132 | idl = (RX_BOOL_NUM+7)>>3; 133 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 136 | rdii -= VALUEPACK_BUFFER_SIZE; 137 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 138 | rdii++; 139 | idc++; 140 | } 141 | #endif 142 | // 2.byte 143 | #if RX_BYTE_NUM>0 144 | idc = (uint32_t)(rx_pack_ptr->bytes); 145 | idl = RX_BYTE_NUM; 146 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 149 | rdii -= VALUEPACK_BUFFER_SIZE; 150 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 151 | rdii++; 152 | idc++; 153 | } 154 | #endif 155 | // 3.short 156 | #if RX_SHORT_NUM>0 157 | idc = (uint32_t)(rx_pack_ptr->shorts); 158 | idl = RX_SHORT_NUM<<1; 159 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 162 | rdii -= VALUEPACK_BUFFER_SIZE; 163 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 164 | rdii++; 165 | idc++; 166 | } 167 | #endif 168 | // 4.int 169 | #if RX_INT_NUM>0 170 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 171 | idl = RX_INT_NUM<<2; 172 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 175 | rdii -= VALUEPACK_BUFFER_SIZE; 176 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 177 | rdii++; 178 | idc++; 179 | } 180 | #endif 181 | // 5.float 182 | #if RX_FLOAT_NUM>0 183 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 184 | idl = RX_FLOAT_NUM<<2; 185 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 188 | rdii -= VALUEPACK_BUFFER_SIZE; 189 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 190 | rdii++; 191 | idc++; 192 | } 193 | #endif 194 | err = rdii; 195 | rdIndex+=rx_pack_length; 196 | isok = 1; 197 | }else 198 | { 199 | rdIndex++; 200 | err++; 201 | } 202 | }else 203 | { 204 | rdIndex++; 205 | err++; 206 | } 207 | }else 208 | { 209 | rdIndex++; 210 | err++; 211 | } 212 | } 213 | return isok; 214 | } 215 | 216 | void sendBuffer(unsigned char *p,unsigned short length) 217 | { 218 | for(int i=0;i0 241 | 242 | for(loop=0;loopbools[loop]) 245 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 251 | { 252 | valuepack_tx_bit_index = 0; 253 | valuepack_tx_index++; 254 | } 255 | } 256 | if(valuepack_tx_bit_index!=0) 257 | valuepack_tx_index++; 258 | #endif 259 | 260 | #if TX_BYTE_NUM>0 261 | 262 | for(loop=0;loopbytes[loop]; 265 | valuepack_tx_index++; 266 | } 267 | 268 | #endif 269 | 270 | #if TX_SHORT_NUM>0 271 | for(loop=0;loopshorts[loop]&0xff; 274 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 275 | valuepack_tx_index+=2; 276 | } 277 | #endif 278 | 279 | #if TX_INT_NUM>0 280 | for(loop=0;loopintegers[loop]; 283 | 284 | vp_txbuff[valuepack_tx_index] = i&0xff; 285 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 286 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 287 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 288 | 289 | valuepack_tx_index+=4; 290 | } 291 | #endif 292 | 293 | #if TX_FLOAT_NUM>0 294 | for(loop=0;loopfloats[loop])); 297 | 298 | vp_txbuff[valuepack_tx_index] = i&0xff; 299 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 300 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 301 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 302 | 303 | valuepack_tx_index+=4; 304 | } 305 | #endif 306 | 307 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 308 | sum+=vp_txbuff[d]; 309 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 310 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 311 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 312 | } 313 | 314 | 315 | 316 | -------------------------------------------------------------------------------- /Examples/湿度回传/湿度回传-USART+中断/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过USART 配合接收中断 进行数据包的接收和发送 4 | // 接收的数据在接收中断中写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | 6 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 7 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 8 | #define VALUEPACK_BUFFER_SIZE 1024 9 | 10 | 11 | /// 2.指定发送数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 12 | /// 13 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 14 | 15 | #define TX_BOOL_NUM 0 16 | #define TX_BYTE_NUM 0 17 | #define TX_SHORT_NUM 0 18 | #define TX_INT_NUM 0 19 | #define TX_FLOAT_NUM 1 20 | 21 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 22 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 23 | 24 | #define RX_BOOL_NUM 0 25 | #define RX_BYTE_NUM 0 26 | #define RX_SHORT_NUM 0 27 | #define RX_INT_NUM 0 28 | #define RX_FLOAT_NUM 0 29 | 30 | 31 | 32 | typedef struct 33 | { 34 | #if TX_BOOL_NUM > 0 35 | unsigned char bools[TX_BOOL_NUM]; 36 | #endif 37 | 38 | #if TX_BYTE_NUM > 0 39 | char bytes[TX_BYTE_NUM]; 40 | #endif 41 | 42 | #if TX_SHORT_NUM > 0 43 | short shorts[TX_SHORT_NUM]; 44 | #endif 45 | 46 | #if TX_INT_NUM > 0 47 | int integers[TX_INT_NUM]; 48 | #endif 49 | 50 | #if TX_FLOAT_NUM > 0 51 | float floats[TX_FLOAT_NUM]; 52 | #endif 53 | char space; //只是为了占一个空,当所有变量数目都为0时确保编译成功 54 | } 55 | TxPack; 56 | typedef struct 57 | { 58 | #if RX_BOOL_NUM > 0 59 | unsigned char bools[RX_BOOL_NUM]; 60 | #endif 61 | 62 | #if RX_BYTE_NUM > 0 63 | char bytes[RX_BYTE_NUM]; 64 | #endif 65 | 66 | #if RX_SHORT_NUM > 0 67 | short shorts[RX_SHORT_NUM]; 68 | #endif 69 | 70 | #if RX_INT_NUM > 0 71 | int integers[RX_INT_NUM]; 72 | #endif 73 | 74 | #if RX_FLOAT_NUM > 0 75 | float floats[RX_FLOAT_NUM]; 76 | #endif 77 | char space; //只是为了占一个空,当所有变量数目都为0时确保编译成功 78 | }RxPack; 79 | // 初始化 valuepack 包括一些必要的硬件外设配置 80 | // 并指定要传输的数据包 81 | void initValuePack(int baudrate); 82 | 83 | // 需要保证至少每秒执行10次该函数 84 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 85 | // 接收到数据包时 返回 1 ,否则返回 0 86 | unsigned char readValuePack(RxPack *rx_pack_ptr); 87 | 88 | 89 | // 发送数据包 90 | void sendValuePack(TxPack *tx_pack_ptr); 91 | 92 | 93 | 94 | #define PACK_HEAD 0xa5 95 | #define PACK_TAIL 0x5a 96 | 97 | #define TX_MODE_SEND_BACK 0 98 | #define TX_MODE_ALWAYS 1 99 | #define TX_MODE_DISABLE 2 100 | -------------------------------------------------------------------------------- /Examples/湿度回传/湿度回传-USART简版/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | #include "valuepack.h" 3 | 4 | void initHumiditySensor() 5 | { 6 | 7 | ADC_InitTypeDef ADC_InitStructure; 8 | GPIO_InitTypeDef GPIO_InitStructure; 9 | 10 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 11 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); 12 | 13 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 14 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 15 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 16 | GPIO_Init(GPIOA, &GPIO_InitStructure); 17 | 18 | ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 19 | ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 20 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 21 | ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 22 | ADC_InitStructure.ADC_NbrOfChannel = 1; 23 | ADC_InitStructure.ADC_ScanConvMode = DISABLE; 24 | ADC_Init(ADC1,&ADC_InitStructure); 25 | RCC_ADCCLKConfig(RCC_PCLK2_Div8); 26 | ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, 27 | ADC_SampleTime_55Cycles5); 28 | ADC_Cmd(ADC1, ENABLE); 29 | ADC_ResetCalibration(ADC1); 30 | while(ADC_GetResetCalibrationStatus(ADC1)) 31 | {} 32 | ADC_StartCalibration(ADC1); 33 | while(ADC_GetCalibrationStatus(ADC1)) 34 | {} 35 | ADC_SoftwareStartConvCmd(ADC1, ENABLE); 36 | } 37 | 38 | short readHumidity() 39 | { 40 | return ADC1->DR; 41 | } 42 | 43 | unsigned char buffer[10]; 44 | float f = 100.0f/(4096*3/3.3f); 45 | 46 | int main(void) 47 | { 48 | 49 | initHumiditySensor(); 50 | initValuePack(115200); 51 | 52 | while(1) 53 | { 54 | 55 | // 延时 56 | for(int t=0;t<7200000;t++) 57 | { 58 | } 59 | 60 | startValuePack(buffer); 61 | putFloat(((int)(readHumidity()*f*10))*0.1f); 62 | sendBuffer(buffer,endValuePack()); 63 | 64 | 65 | } 66 | } 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Examples/湿度回传/湿度回传-USART简版/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char *valuepack_tx_buffer; 4 | unsigned short valuepack_tx_index; 5 | unsigned char valuepack_tx_bit_index; 6 | unsigned char valuepack_stage; 7 | 8 | void initValuePack(int baudrate) 9 | { 10 | 11 | USART_InitTypeDef USART_InitStructure; 12 | GPIO_InitTypeDef GPIO_InitStructure; 13 | 14 | // 时钟初始化 15 | 16 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 17 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 18 | 19 | // 引脚初始化 20 | 21 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 22 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 23 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 24 | GPIO_Init(GPIOA, &GPIO_InitStructure); 25 | /* PA10 USART1_Rx */ 26 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 27 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 28 | GPIO_Init(GPIOA, &GPIO_InitStructure); 29 | 30 | // 串口初始化 31 | 32 | USART_InitStructure.USART_BaudRate = baudrate; 33 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 34 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 35 | USART_InitStructure.USART_Parity = USART_Parity_No; 36 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 37 | USART_InitStructure.USART_Mode = USART_Mode_Tx; 38 | USART_Init(USART1, &USART_InitStructure); 39 | USART_Cmd(USART1, ENABLE); 40 | } 41 | 42 | 43 | // 1. 开始将数据打包,需传入定义好的数组(需保证数组长度足以存放要发送的数据) 44 | 45 | void startValuePack(unsigned char *buffer) 46 | { 47 | valuepack_tx_buffer = buffer; 48 | valuepack_tx_index = 1; 49 | valuepack_tx_bit_index = 0; 50 | valuepack_tx_buffer[0] = PACK_HEAD; 51 | valuepack_stage = 0; 52 | } 53 | 54 | // 2. 向数据包中放入各类数据,由于数据包的顺序结构是固定的,因此注意严格以如下的顺序进行存放,否则会出现错误 55 | 56 | void putBool(unsigned char b) 57 | { 58 | if(valuepack_stage<=1) 59 | { 60 | if(b) 61 | valuepack_tx_buffer[valuepack_tx_index] |= 0x01<=8) 67 | { 68 | valuepack_tx_bit_index = 0; 69 | valuepack_tx_index++; 70 | } 71 | valuepack_stage = 1; 72 | } 73 | } 74 | 75 | 76 | void putByte(char b) 77 | { 78 | if(valuepack_stage<=2) 79 | { 80 | if(valuepack_tx_bit_index!=0) 81 | { 82 | valuepack_tx_index++; 83 | valuepack_tx_bit_index = 0; 84 | } 85 | valuepack_tx_buffer[valuepack_tx_index] = b; 86 | valuepack_tx_index++; 87 | 88 | valuepack_stage = 2; 89 | } 90 | } 91 | void putShort(short s) 92 | { 93 | if(valuepack_stage<=3) 94 | { 95 | if(valuepack_tx_bit_index!=0) 96 | { 97 | valuepack_tx_index++; 98 | valuepack_tx_bit_index = 0; 99 | } 100 | valuepack_tx_buffer[valuepack_tx_index] = s&0xff; 101 | valuepack_tx_buffer[valuepack_tx_index+1] = s>>8; 102 | 103 | valuepack_tx_index +=2; 104 | valuepack_stage = 3; 105 | } 106 | } 107 | void putInt(int i) 108 | { 109 | if(valuepack_stage<=4) 110 | { 111 | if(valuepack_tx_bit_index!=0) 112 | { 113 | valuepack_tx_index++; 114 | valuepack_tx_bit_index = 0; 115 | } 116 | 117 | valuepack_tx_buffer[valuepack_tx_index] = i&0xff; 118 | valuepack_tx_buffer[valuepack_tx_index+1] = (i>>8)&0xff; 119 | valuepack_tx_buffer[valuepack_tx_index+2] = (i>>16)&0xff; 120 | valuepack_tx_buffer[valuepack_tx_index+3] = (i>>24)&0xff; 121 | 122 | valuepack_tx_index +=4; 123 | 124 | valuepack_stage = 4; 125 | } 126 | } 127 | int fi; 128 | void putFloat(float f) 129 | { 130 | if(valuepack_stage<=5) 131 | { 132 | if(valuepack_tx_bit_index!=0) 133 | { 134 | valuepack_tx_index++; 135 | valuepack_tx_bit_index = 0; 136 | } 137 | 138 | fi = *(int*)(&f); 139 | valuepack_tx_buffer[valuepack_tx_index] = fi&0xff; 140 | valuepack_tx_buffer[valuepack_tx_index+1] = (fi>>8)&0xff; 141 | valuepack_tx_buffer[valuepack_tx_index+2] = (fi>>16)&0xff; 142 | valuepack_tx_buffer[valuepack_tx_index+3] = (fi>>24)&0xff; 143 | valuepack_tx_index +=4; 144 | valuepack_stage = 5; 145 | } 146 | } 147 | 148 | 149 | 150 | 151 | // 3. 结束打包,函数将返回 数据包的总长度 152 | unsigned short endValuePack() 153 | { 154 | unsigned char sum=0; 155 | for(int i=1;iCNT = 0; 64 | // 开始计时 65 | TIM_Cmd(TIM2,ENABLE); 66 | 67 | }else // 下降沿 68 | { 69 | // 读取定时器值 70 | c = TIM2->CNT ; 71 | TIM_Cmd(TIM2,DISABLE); 72 | } 73 | // 清除中断标志位 74 | EXTI_ClearITPendingBit(EXTI_Line7); 75 | } 76 | 77 | } 78 | 79 | void delay10us(void) 80 | { 81 | 82 | for(short s=0;s<70;s++) 83 | {} 84 | 85 | } 86 | 87 | 88 | 89 | short procUltraSonic(void) 90 | { 91 | 92 | short distance_mm; 93 | 94 | if(c!=0) 95 | distance_mm = (17*c/10); 96 | GPIO_SetBits(USONIC_PORT,TRIG_PIN); 97 | delay10us(); 98 | GPIO_ResetBits(USONIC_PORT,TRIG_PIN); 99 | 100 | c=0; 101 | return distance_mm; 102 | 103 | } 104 | 105 | 106 | int main(void) 107 | { 108 | 109 | initUltraSonic(); 110 | initValuePack(115200); 111 | 112 | while(1) 113 | { 114 | 115 | // 延时 116 | for(int i=0;i<1000000;i++) 117 | {} 118 | 119 | 120 | txpack.shorts[0] = procUltraSonic();; 121 | 122 | sendValuePack(&txpack); 123 | 124 | 125 | } 126 | } 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /Examples/超声波测距/valuepack.c: -------------------------------------------------------------------------------- 1 | #include "valuepack.h" 2 | 3 | unsigned char bits[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 4 | 5 | const unsigned int VALUEPACK_INDEX_RANGE=VALUEPACK_BUFFER_SIZE<<3; 6 | const unsigned short TXPACK_BYTE_SIZE = ((TX_BOOL_NUM+7)>>3)+TX_BYTE_NUM+(TX_SHORT_NUM<<1)+(TX_INT_NUM<<2)+(TX_FLOAT_NUM<<2); 7 | const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM+7)>>3)+RX_BYTE_NUM+(RX_SHORT_NUM<<1)+(RX_INT_NUM<<2)+(RX_FLOAT_NUM<<2); 8 | unsigned short rx_pack_length = RXPACK_BYTE_SIZE+3; 9 | 10 | 11 | long rxIndex=0; 12 | long rdIndex=0; 13 | 14 | 15 | unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE]; 16 | unsigned char vp_txbuff[TXPACK_BYTE_SIZE+3]; 17 | 18 | 19 | DMA_InitTypeDef dma; 20 | 21 | void initValuePack(int baudrate) 22 | { 23 | 24 | USART_InitTypeDef USART_InitStructure; 25 | GPIO_InitTypeDef GPIO_InitStructure; 26 | 27 | // 时钟初始化 28 | 29 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 30 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 31 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); 32 | 33 | // 引脚初始化 34 | 35 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 36 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 37 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 38 | GPIO_Init(GPIOA, &GPIO_InitStructure); 39 | /* PA10 USART1_Rx */ 40 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 41 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 42 | GPIO_Init(GPIOA, &GPIO_InitStructure); 43 | 44 | // 串口初始化 45 | 46 | USART_InitStructure.USART_BaudRate = baudrate; 47 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 48 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 49 | USART_InitStructure.USART_Parity = USART_Parity_No; 50 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 51 | USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 52 | 53 | USART_Init(USART1, &USART_InitStructure); 54 | 55 | // DMA初始化 56 | 57 | DMA_DeInit(DMA1_Channel4); 58 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 59 | dma.DMA_M2M = DMA_M2M_Disable; 60 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 61 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 62 | 63 | dma.DMA_Priority = DMA_Priority_High; 64 | dma.DMA_BufferSize = 4; 65 | dma.DMA_MemoryBaseAddr = (uint32_t)0; 66 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 67 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 68 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 69 | dma.DMA_Mode = DMA_Mode_Normal; 70 | DMA_Init(DMA1_Channel4,&dma); 71 | 72 | USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 73 | 74 | DMA_DeInit(DMA1_Channel5); 75 | dma.DMA_DIR = DMA_DIR_PeripheralSRC; 76 | dma.DMA_BufferSize = VALUEPACK_BUFFER_SIZE; 77 | dma.DMA_MemoryBaseAddr = (uint32_t)vp_rxbuff; 78 | dma.DMA_Mode = DMA_Mode_Circular; 79 | DMA_Init(DMA1_Channel5,&dma); 80 | 81 | USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); 82 | USART_Cmd(USART1, ENABLE); 83 | DMA_Cmd(DMA1_Channel5,ENABLE); 84 | 85 | } 86 | 87 | 88 | 89 | unsigned short this_index=0; 90 | unsigned short last_index=0; 91 | unsigned short rdi,rdii,idl,idi; 92 | uint32_t idc; 93 | unsigned int err=0; 94 | unsigned char sum=0; 95 | unsigned char isok; 96 | 97 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 98 | // 99 | //procValuePack 用来处理手机传来的数据 100 | // 101 | 102 | unsigned char readValuePack(RxPack *rx_pack_ptr) 103 | { 104 | isok = 0; 105 | this_index =VALUEPACK_BUFFER_SIZE-DMA1_Channel5->CNDTR; 106 | if(this_index=VALUEPACK_BUFFER_SIZE) 127 | rdi -= VALUEPACK_BUFFER_SIZE; 128 | sum += vp_rxbuff[rdi]; 129 | } 130 | rdi++; 131 | if(rdi>=VALUEPACK_BUFFER_SIZE) 132 | rdi -= VALUEPACK_BUFFER_SIZE; 133 | 134 | if(sum==vp_rxbuff[rdi]) 135 | { 136 | // 提取数据包数据 一共有五步, bool byte short int float 137 | 138 | // 1. bool 139 | #if RX_BOOL_NUM>0 140 | 141 | idc = (uint32_t)rx_pack_ptr->bools; 142 | idl = (RX_BOOL_NUM+7)>>3; 143 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 146 | rdii -= VALUEPACK_BUFFER_SIZE; 147 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 148 | rdii++; 149 | idc++; 150 | } 151 | #endif 152 | // 2.byte 153 | #if RX_BYTE_NUM>0 154 | idc = (uint32_t)(rx_pack_ptr->bytes); 155 | idl = RX_BYTE_NUM; 156 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 159 | rdii -= VALUEPACK_BUFFER_SIZE; 160 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 161 | rdii++; 162 | idc++; 163 | } 164 | #endif 165 | // 3.short 166 | #if RX_SHORT_NUM>0 167 | idc = (uint32_t)(rx_pack_ptr->shorts); 168 | idl = RX_SHORT_NUM<<1; 169 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 172 | rdii -= VALUEPACK_BUFFER_SIZE; 173 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 174 | rdii++; 175 | idc++; 176 | } 177 | #endif 178 | // 4.int 179 | #if RX_INT_NUM>0 180 | idc = (uint32_t)(&(rx_pack_ptr->integers[0])); 181 | idl = RX_INT_NUM<<2; 182 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 185 | rdii -= VALUEPACK_BUFFER_SIZE; 186 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 187 | rdii++; 188 | idc++; 189 | } 190 | #endif 191 | // 5.float 192 | #if RX_FLOAT_NUM>0 193 | idc = (uint32_t)(&(rx_pack_ptr->floats[0])); 194 | idl = RX_FLOAT_NUM<<2; 195 | for(idi=0;idi=VALUEPACK_BUFFER_SIZE) 198 | rdii -= VALUEPACK_BUFFER_SIZE; 199 | (*((unsigned char *)idc))= vp_rxbuff[rdii]; 200 | rdii++; 201 | idc++; 202 | } 203 | #endif 204 | err = rdii; 205 | rdIndex+=rx_pack_length; 206 | isok = 1; 207 | }else 208 | { 209 | rdIndex++; 210 | err++; 211 | } 212 | }else 213 | { 214 | rdIndex++; 215 | err++; 216 | } 217 | }else 218 | { 219 | rdIndex++; 220 | err++; 221 | } 222 | } 223 | last_index = this_index; 224 | return isok; 225 | } 226 | 227 | void sendBuffer(unsigned char *p,unsigned short length) 228 | { 229 | DMA_DeInit(DMA1_Channel4); 230 | dma.DMA_DIR = DMA_DIR_PeripheralDST; 231 | dma.DMA_M2M = DMA_M2M_Disable; 232 | dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 233 | dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); 234 | dma.DMA_Priority = DMA_Priority_High; 235 | dma.DMA_BufferSize = length; 236 | dma.DMA_MemoryBaseAddr = (uint32_t)p; 237 | dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 238 | dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 239 | dma.DMA_MemoryInc = DMA_MemoryInc_Enable; 240 | dma.DMA_Mode = DMA_Mode_Normal; 241 | DMA_Init(DMA1_Channel4,&dma); 242 | DMA_Cmd(DMA1_Channel4,ENABLE); 243 | } 244 | 245 | 246 | 247 | unsigned short loop; 248 | unsigned char valuepack_tx_bit_index; 249 | unsigned char valuepack_tx_index; 250 | 251 | void sendValuePack(TxPack *tx_pack_ptr) 252 | { 253 | int i; 254 | vp_txbuff[0]=0xa5; 255 | sum=0; 256 | // 由于结构体中不同类型的变量在内存空间的排布不是严格对齐的,中间嵌有无效字节,因此需要特殊处理 257 | 258 | valuepack_tx_bit_index = 0; 259 | valuepack_tx_index = 1; 260 | 261 | #if TX_BOOL_NUM>0 262 | 263 | for(loop=0;loopbools[loop]) 266 | vp_txbuff[valuepack_tx_index] |= 0x01<=8) 272 | { 273 | valuepack_tx_bit_index = 0; 274 | valuepack_tx_index++; 275 | } 276 | } 277 | if(valuepack_tx_bit_index!=0) 278 | valuepack_tx_index++; 279 | #endif 280 | 281 | #if TX_BYTE_NUM>0 282 | 283 | for(loop=0;loopbytes[loop]; 286 | valuepack_tx_index++; 287 | } 288 | 289 | #endif 290 | 291 | #if TX_SHORT_NUM>0 292 | for(loop=0;loopshorts[loop]&0xff; 295 | vp_txbuff[valuepack_tx_index+1] = tx_pack_ptr->shorts[loop]>>8; 296 | valuepack_tx_index+=2; 297 | } 298 | #endif 299 | 300 | #if TX_INT_NUM>0 301 | for(loop=0;loopintegers[loop]; 304 | 305 | vp_txbuff[valuepack_tx_index] = i&0xff; 306 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 307 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 308 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 309 | 310 | valuepack_tx_index+=4; 311 | } 312 | #endif 313 | 314 | #if TX_FLOAT_NUM>0 315 | for(loop=0;loopfloats[loop])); 318 | 319 | vp_txbuff[valuepack_tx_index] = i&0xff; 320 | vp_txbuff[valuepack_tx_index+1] = (i>>8)&0xff; 321 | vp_txbuff[valuepack_tx_index+2] =(i>>16)&0xff; 322 | vp_txbuff[valuepack_tx_index+3] = (i>>24)&0xff; 323 | 324 | valuepack_tx_index+=4; 325 | } 326 | #endif 327 | 328 | for(unsigned short d=1;d<=TXPACK_BYTE_SIZE;d++) 329 | sum+=vp_txbuff[d]; 330 | vp_txbuff[TXPACK_BYTE_SIZE+1] = sum; 331 | vp_txbuff[TXPACK_BYTE_SIZE+2] = 0x5a; 332 | sendBuffer(vp_txbuff,TXPACK_BYTE_SIZE+3); 333 | } -------------------------------------------------------------------------------- /Examples/超声波测距/valuepack.h: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | 3 | // 本程序通过DMA和USART 进行数据包的接收和发送 4 | // 接收的数据自动写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。 5 | // 数据发送也采用DMA 6 | 7 | /// 1.指定接收缓冲区的大小 ---------------------------------------------------------------------------------- 8 | // 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。 9 | #define VALUEPACK_BUFFER_SIZE 1024 10 | 11 | 12 | /// 2.指定发送到手机的数据包的结构--------------------------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节 13 | /// 14 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 15 | 16 | #define TX_BOOL_NUM 0 17 | #define TX_BYTE_NUM 0 18 | #define TX_SHORT_NUM 1 19 | #define TX_INT_NUM 0 20 | #define TX_FLOAT_NUM 0 21 | 22 | /// 3.指定接收数据包的结构----------------------------------------------------------------------------------- 23 | // 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目 24 | 25 | #define RX_BOOL_NUM 0 26 | #define RX_BYTE_NUM 0 27 | #define RX_SHORT_NUM 0 28 | #define RX_INT_NUM 0 29 | #define RX_FLOAT_NUM 0 30 | 31 | 32 | 33 | typedef struct 34 | { 35 | #if TX_BOOL_NUM > 0 36 | unsigned char bools[TX_BOOL_NUM]; 37 | #endif 38 | 39 | #if TX_BYTE_NUM > 0 40 | char bytes[TX_BYTE_NUM]; 41 | #endif 42 | 43 | #if TX_SHORT_NUM > 0 44 | short shorts[TX_SHORT_NUM]; 45 | #endif 46 | 47 | #if TX_INT_NUM > 0 48 | int integers[TX_INT_NUM]; 49 | #endif 50 | 51 | #if TX_FLOAT_NUM > 0 52 | float floats[TX_FLOAT_NUM]; 53 | #endif 54 | 55 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 56 | } 57 | TxPack; 58 | typedef struct 59 | { 60 | #if RX_BOOL_NUM > 0 61 | unsigned char bools[RX_BOOL_NUM]; 62 | #endif 63 | 64 | #if RX_BYTE_NUM > 0 65 | char bytes[RX_BYTE_NUM]; 66 | #endif 67 | 68 | #if RX_SHORT_NUM > 0 69 | short shorts[RX_SHORT_NUM]; 70 | #endif 71 | 72 | #if RX_INT_NUM > 0 73 | int integers[RX_INT_NUM]; 74 | #endif 75 | 76 | #if RX_FLOAT_NUM > 0 77 | float floats[RX_FLOAT_NUM]; 78 | #endif 79 | char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 80 | }RxPack; 81 | // 初始化 valuepack 包括一些必要的硬件外设配置 82 | 83 | void initValuePack(int baudrate); 84 | 85 | // 需要保证至少每秒执行10次该函数 86 | // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 87 | // 接收到数据包时 返回 1 ,否则返回 0 88 | unsigned char readValuePack(RxPack *rx_pack_ptr); 89 | 90 | 91 | // 发送数据包 92 | void sendValuePack(TxPack *tx_pack_ptr); 93 | 94 | 95 | #define PACK_HEAD 0xa5 96 | #define PACK_TAIL 0x5a -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ValuePack 2 | 3 | ## 数据结构 4 | 5 | **ValuePack要解决的问题是 多个不同类型的变量如何通过串口传输。为了解决这个问题,我定义了一种数据包结构。** 6 | - 包头 7 | - 原数据 8 | - 校验 9 | - 包尾 10 | 11 | 其中包头和包尾分别固定为 0xA5 和 0x5A,校验为所有原数据字节之和的低8位。 12 | 在原数据中: 13 | 定义了五种不同的类型 bool、byte、short、int和float。五种类型的变量按照严格的顺序排列,其中 14 | - bool占1/8字节 15 | - byte占1字节 16 | - short占2字节 17 | - int占4字节 18 | - float占4字节 19 | 20 | ## 执行流程 21 | 22 | **发送时:** 23 | 发送方将要发送的数据按照顺序填入原数据,然后加上包头、校验和包尾,最终得到一串字节串,然后通过串口或其它方式发出。 24 | 25 | **接收时:** 26 | 接收方建立一个较大的缓冲区,一直接收发来的字节,并且定时解析缓冲区中是否已有完整数据包,如果有完整数据包则将数据包中的数据按照顺序一一读出。 27 | 28 | 29 | 30 | -Code: 31 | --Code中是ValuePack的实现代码,三种代码均是STM32上运行的,一般正常使用选择USART+DMA即可。 32 | 33 | -Examples: 34 | --Examples中是一系列围绕 蓝牙调试器 这个安卓应用实现的STM32代码。蓝牙调试器是一款可自由设置收发变量和控件布局的无线调试工具, 35 | 它可以让你在极短时间创建属于自己的“手机+”应用。 36 | 37 | 38 | 详细介绍在此: 39 | https://www.jianshu.com/p/1a8262492619 40 | 只需在工程中添加ValuePack目录下的valuepack.c 和 valuepack.h两个文件就可以通过调用函数的方式实现数据打包。 41 | --------------------------------------------------------------------------------