main
esea_info 2 years ago
parent 2482c2741d
commit 49e26b6df9
  1. 4
      .vscode/launch.json
  2. 341
      DOC/13_SD.md
  3. 71
      DOC/15_modbus.md
  4. 513
      IOC/IOP_407ZET6.ioc
  5. 264
      IOC/UART_407.ioc
  6. 101446
      SVD/STM32F103xx.svd
  7. 1603
      SVD/STM32F407.svd
  8. 69
      bsp/Inc/bsp_led.h
  9. 148
      bsp/Src/bsp_led.c
  10. 80
      device/Inc/ds1302.h
  11. 131
      device/Inc/stmflash.h
  12. 217
      device/Src/ds1302.c
  13. 178
      device/Src/stmflash.c
  14. 488
      libraries/convert.c
  15. 32
      libraries/convert.h
  16. 663
      libraries/file_list.c
  17. 76
      libraries/file_list.h
  18. 70
      libraries/file_list_port.c
  19. 326
      libraries/float.c
  20. 21
      libraries/float.h
  21. 88
      libraries/kfifo.c
  22. 40
      libraries/kfifo.h
  23. 1167
      libraries/menu.c
  24. 198
      libraries/menu.h
  25. 403
      libraries/menu_node.c
  26. 107
      libraries/menu_port.c
  27. 288
      libraries/sd_port.c
  28. 196
      libraries/time_clock.c
  29. 42
      libraries/time_clock.h
  30. 108
      libraries/usbmsc_port.c
  31. 278
      makefile/Makefile
  32. 382
      makefile/MyMakefile.mk
  33. 865
      port/FreeModbus/modbus_app.c
  34. 75
      port/FreeModbus/port.h
  35. 135
      port/FreeModbus/portevent.c
  36. 535
      port/FreeModbus/portserial.c
  37. 363
      port/FreeModbus/porttimer.c

@ -8,8 +8,8 @@
"args": [],
"stopAtEntry": false,
"externalConsole": true,
"cwd": "d:/Mycode/stm32Code/MyStm32Code/device",
"program": "d:/Mycode/stm32Code/MyStm32Code/device/build/Debug/outDebug",
"cwd": "d:/Mycode/stm32Code/MyStm32Code/device/Src",
"program": "d:/Mycode/stm32Code/MyStm32Code/device/Src/build/Debug/outDebug",
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"setupCommands": [

@ -163,7 +163,7 @@ if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
Error_Handler();
}
PE SD_Insert Pull_down Input
PE SD_Insert Pull_down Input PA15 CDZ
检测不到SD卡 不启动
测试记录:
@ -172,3 +172,342 @@ PE SD_Insert Pull_down Input
优先级 SDIO 》DMA 》 USB
### SDIO USB
PA 15 --CDZ GPIO INPUT ,NO PULLUP PULLDOWN
SDIO IT
SDIO DMA RX --DMA2_3
SDIO DMA TX --DMA2_6
USB FS
USB CDC
中断 USB 》 SDIO DMA 》 SDIO
### SD 初始化
***创建文件失败错误***
cubemx 生成代码后需要修改这里
SDIO.c文件
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
hsd.Init.ClockDiv = SDIO_INIT_CLK_DIV; //SDIO_TRANSFER_CLK_DIV;
hsd.Instance = SDIO;
hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
hsd.Init.ClockDiv = 2;
### DMA
FIFO WORD
### 中断
SDIO 优于 DMA 优于 USB
值正好相反
### heap stack
0x1000
ox1500
f_mount等要放任务中,增加了堆栈大小
StartDefaultTask 堆栈要调大 1024
### 最大最小扇区大小
(在cubemx fatfa USB_DEVICE, 可以不改)
512 -> 4096
FATFS 两处地方
USB_Device 两处地方
### USB 的调整
***CubeMX 自动将 MX_USB_DEVICE_Init() 函数放到 StartDefaultTask 中 ***
优于定义了 StartDefaultTask 虚函数, 不执行
需要手动移植到实际函数中
USB_Device初始化函数在默认任务中,所以要增加默认任务 StartDefaultTask 的堆栈,
MX_USB_DEVICE_Init();
### 重写usbd_storage_if.c
*** 不写的话 读取不到Upan信息, 显示upan大小都不对 ***
#define STORAGE_LUN_NBR 1 /* 逻辑单元号,只有一个外部flash,设置为1 */
#define STORAGE_BLK_NBR 2048 /* 扇区的数量,外部flash的大小是8Mbyte,有128块,每块16个扇区,故128*16=2048个扇区 */
#define STORAGE_BLK_SIZ 4096 /* 每个扇区的大小,外部flash扇区的大小为4096byte */
以上通过输出SD信息改写
因为加入了FreeRTOS,fatfs对sd卡读写用的是发送消息机制,
所以usbd_storage_if.c里的读写不能再去调用bsp_driver_sd.c里的读写方法了,
大家有兴趣的可以对比一下有无FreeRTOS,bsp_driver_sd.c源码的内容
读写方法等
STM32F407 开发板没有用到 VUSB 电压检测,所以要在 usb_conf.h 里面 ( USB_DEVICE\Target\usbd_conf.h)
将宏定义:#define VBUS_SENSING_ENABLED,屏蔽掉。
3,通过修改 usbd_conf.h 里面的 MSC_MEDIA_PACKET 定义值大小,可以一定程度提高
USB 读写速度(越大越快),本例程我们设置 12*1024,也就是 12K 大小。
***官方例程不支持大于 4G 的 SD 卡***
Middlewares\ST\STM32_USB_Device_Library\Class\MSC\Src
官方例程不支持大于 4G 的 SD 卡,得修改:
usbd_msc_scsi.c 里面的 或 usbd_msc.h( Cubemx HAl) SCSI_blk_addr 类型为 uint64_t
才可以支持大于 4G 的卡,官方默认是 uint32_t,最大只能支持 4G 卡。
注意:
usbd_msc.h
uint64_t scsi_blk_addr;
uint64_t scsi_blk_len;
usbd_msc_scsi.c 文件,是只读的,得先修改属性,去掉只读属性,才可以更改。
HS FS 标记
#define DEVICE_FS 1
#define DEVICE_HS 0
usb_devioce MSC_MEDIA_PAKCET 改32678 32*1024U
#### usb 编译
-DUSE_USB_OTG_FS
SD_port.c
```C
#include <stdio.h>
#include "stm32f4xx.h"
#include "main.h"
// #include "config.h"
#include "elog.h"
#include "bsp_driver_sd.h"
#include "fatfs.h"
HAL_SD_CardInfoTypeDef SDCardInfo;
extern SD_HandleTypeDef hsd;
FATFS fs; //工作空间
FIL fil; // 文件项目
extern void printf_sdcard_info(void);
extern int Init_FatFas_Mount(void);
extern int creat_file(char * filename);
extern uint8_t BSP_SD_Init(void);
uint8_t BSP_SD_Init(void)
{
uint8_t sd_state = MSD_OK;
/* Check if the SD card is plugged in the slot */
if (BSP_SD_IsDetected() != SD_PRESENT)
{
return MSD_ERROR;
}
/* HAL SD initialization */
sd_state = HAL_SD_Init(&hsd);
/* Configure SD Bus width (4 bits mode selected) */
if (sd_state == MSD_OK)
{
hsd.Init.ClockDiv = 6;
// hsd.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV;
/* Enable wide operation */
if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
{
sd_state = MSD_ERROR;
}
}
return sd_state;
}
void printf_sdcard_info(void)
{
uint64_t CardCap; //SD卡容量
HAL_SD_CardCIDTypeDef SDCard_CID;
char * card_type[8] = {0};
HAL_SD_GetCardCID(&hsd,&SDCard_CID); //获取CID
HAL_SD_GetCardInfo(&hsd,&SDCardInfo); //获取SD卡信息
CardCap=(uint64_t)(SDCardInfo.LogBlockNbr)*(uint64_t)(SDCardInfo.LogBlockSize); //计算SD卡容量
switch(SDCardInfo.CardType)
{
case CARD_SDSC:
{
if(SDCardInfo.CardVersion == CARD_V1_X)
{
memcpy(card_type, (void*)("SDSC V1"),7);
// printf("Card Type:SDSC V1\r\n");
}
else if (SDCardInfo.CardVersion == CARD_V2_X)
{
memcpy(card_type, (void*)("SDSC V2"),7);
// printf("Card Type:SDSC V2\r\n");
}
break;
}
case CARD_SDHC_SDXC:
{
memcpy(card_type, (void*)("SDHC"),4);
printf("Card Type:SDHC\r\n");
break;
}
default:break;
}
#if 1
log_i("Card Type: %s \r\n",card_type); //card 类型
log_i("Card ManufacturerID: %d \r\n",SDCard_CID.ManufacturerID); //制造商ID
log_i("CardVersion: %d \r\n",(uint32_t)(SDCardInfo.CardVersion)); //卡版本号
log_i("Class: %d \r\n",(uint32_t)(SDCardInfo.Class)); //
log_i("Card RCA(RelCardAdd):%d \r\n",SDCardInfo.RelCardAdd); //卡相对地址
log_i("Card BlockNbr: %d \r\n",SDCardInfo.BlockNbr); //块数量
log_i("Card BlockSize: %d \r\n",SDCardInfo.BlockSize); //块大小
log_i("LogBlockNbr: %d \r\n",(uint32_t)(SDCardInfo.LogBlockNbr)); //逻辑块数量
log_i("LogBlockSize: %d \r\n",(uint32_t)(SDCardInfo.LogBlockSize)); //逻辑块大小
log_i("Card Capacity: %d MB\r\n",(uint32_t)(CardCap>>20)); //卡容量
#endif
#if 0
printf("Card ManufacturerID: %d \r\n",SDCard_CID.ManufacturerID); //制造商ID
printf("CardVersion: %d \r\n",(uint32_t)(SDCardInfo.CardVersion)); //卡版本号
printf("Class: %d \r\n",(uint32_t)(SDCardInfo.Class)); //
printf("Card RCA(RelCardAdd):%d \r\n",SDCardInfo.RelCardAdd); //卡相对地址
printf("Card BlockNbr: %d \r\n",SDCardInfo.BlockNbr); //块数量
printf("Card BlockSize: %d \r\n",SDCardInfo.BlockSize); //块大小
printf("LogBlockNbr: %d \r\n",(uint32_t)(SDCardInfo.LogBlockNbr)); //逻辑块数量
printf("LogBlockSize: %d \r\n",(uint32_t)(SDCardInfo.LogBlockSize)); //逻辑块大小
printf("Card Capacity: %d MB\r\n",(uint32_t)(CardCap>>20)); //卡容量
#endif
}
int Init_FatFas_Mount(void)
{
int retSD = f_mount(&fs, "0:", 0);
return retSD;
}
/**
* @brief 创建文件
* @param [in] filename "0:aa.txt"
*
* @details
* creat_file( "0:aa.txt" );
*/
int creat_file(char * filename)
{
// f_mkfs( );
int retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE); //打开文件,权限包括创建、写(如果没有该文件,会创建该文件)
if(retSD==FR_OK)
{
// printf("\r\ncreate file success!!! \r\n");
f_close(&fil); //关闭该文件
return retSD;
}
else
{
// printf("\r\ncreater file error : %d\r\n",retSD);
f_close(&fil); //关闭该文件
return retSD;
}
// f_close(&fil); //关闭该文件
// HAL_Delay(100);
}
void write_file( char * data, uint32_t len )
{
uint32_t byteswritten;
/*##-3- Write data to the text files ###############################*/
int retSD = f_write(&fil, data, len, (void *)&byteswritten);
if(retSD)
printf(" write file error : %d\r\n",retSD);
else
{
printf(" write file sucess!!! \r\n");
printf(" write Data[%d] : %s\r\n",byteswritten,data);
}
/*##-4- Close the open text files ################################*/
retSD = f_close(&fil);
if(retSD)
printf(" close error : %d\r\n",retSD);
else
printf(" close sucess!!! \r\n");
}
void SD_Read_block_Test(void)
{
// uint8_t read_buf[512];
// int sdcard_status = HAL_SD_ReadBlocks(&hsd, (uint8_t *)read_buf, 0, 1, 0xffff);
// if(sdcard_status == HAL_OK)
// {
// printf("Read block data ok! \r\n");
// }
// else
// {
// printf("Read block data fail! status = %d \r\n", sdcard_status);
// }
}
```
***注意CDZ SD_INSERT的检测***
#### USBMSC
新建 usbmsc_port.c
将OTG_FS_IRQHandler(void) 函数提出来
大容量SD ,修改
1. usbd_msc.h
uint64_t scsi_blk_addr;
uint64_t scsi_blk_len;
2. usbd_msc_scsi.c 文件,是只读的,得先修改属性,去掉只读属性,才可以更改。
(uint32_t)params --> (uint64_t)params
3. usbd_conf.h
HS FS 标记
#define DEVICE_FS 1
#define DEVICE_HS 0
4. usb_devioce MSC_MEDIA_PAKCET 改32678 32*1024U, 格式化时分区的大小
如果改成32768 需要至少32K空闲内存 4096 或8192
都改成阻塞式读取数据就可以, 单片机本身就单线程
可以先实验 FATFS DMA读取数据,再实验USBMSC
OTG_FS_IRQHandler 中断函数可以等待信号量,如何释放信号量
#### file_list 分析
创建节点文件 :
72字节:
FIL :
list_head : 32byte
used_node_now: 40byte //< 现在指向的链表节点
free_node_now: 40byte
20 00 00 00 00 00 00 00 -->> 32 ???
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00

@ -540,4 +540,73 @@ eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
return MB_ENOREG;
}
```
```
#### 备注
tim
由于不能在中断中启用timer, 所以不能直接用freertos 定时器去操作
serial
(__HAL_UART_GET_IT_SOURCE(pMobusHuart, UART_IT_RXNE) != RESET
&& __HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) != RESET )
***串口中断优先级别高于 定时器***
不添加 __HAL_UART_GET_IT_SOURCE(pMobusHuart, UART_IT_RXNE , eSndState != STATE_TX_IDLE
具体原因不详
Checks whether the specified UART interrupt source is enabled or not.
启用中断改变的是这个值
#### 启用modbus的不同功能码
eMBRegHoldingCB 函数对应功能码 04
eMBRegInputCB 函数对应功能码 03 06
snd 01 06 00 01 0A 9D 1F 03, 返回同样, 对应的查询值 06 将地址为01的寄存器 写为 0A 9D (2177)
snd 01 10 00 00 00 02 04 87 65 43 21 3A 2C , 返回 01 10 00 00 00 02 41 C8
id func(0x10 16 ), 起始地址 00 寄存器个数2个, 返回4个字节, 0下7654321 CRC16
```C
if((usAddress >= REG_HOLD_START) && ((usAddress+usNRegs) <= (REG_HOLD_START + REG_HOLD_NREGS)))
{
iRegIndex = (int)(usAddress - usRegHoldStart);
switch(eMode)
{
case MB_REG_READ://读寄存器
while(usNRegs > 0)
{
*pucRegBuffer++ = (uint8_t)(usRegHoldBuf[iRegIndex] >> 8);
*pucRegBuffer++ = (uint8_t)(usRegHoldBuf[iRegIndex] & 0xFF);
iRegIndex++;
usNRegs--;
}
break;
case MB_REG_WRITE://写寄存器
while(usNRegs > 0)
{
usRegHoldBuf[iRegIndex] = *pucRegBuffer++ << 8;
usRegHoldBuf[iRegIndex] |= *pucRegBuffer++;
iRegIndex++;
usNRegs--;
}
}
}
```
eMBRegCoilsCB 线圈 01
snd 01 01 00 00 00 03 7C 0B 读三个线圈
rcv 01 01 01 06 D1 8A 返回值为06 (0000 0110)的后三位 ,反过来 0,1,1
eMBRegDiscreteCB 线圈 02
snd 01 02 00 00 00 03 7C 0B 读三个线圈
rcv 01 01 01 06 D1 8A 返回值为06 (0000 0110)的后三位 ,反过来 0,1,1
报告从机状态 17功能码 0x01 0x11
01 11 C0 2C
了解接收机制:xMBRTUReceiveFSM
了解发送机制: xMBRTUTransmitFSM

@ -0,0 +1,513 @@
#MicroXplorer Configuration settings - do not modify
CAD.formats=
CAD.pinconfig=
CAD.provider=
Dma.Request0=USART1_RX
Dma.Request1=USART1_TX
Dma.Request10=USART6_RX
Dma.Request2=USART2_RX
Dma.Request3=USART2_TX
Dma.Request4=USART3_RX
Dma.Request5=USART3_TX
Dma.Request6=SDIO_RX
Dma.Request7=SDIO_TX
Dma.Request8=UART4_RX
Dma.Request9=UART4_TX
Dma.RequestsNb=11
Dma.SDIO_RX.6.Direction=DMA_PERIPH_TO_MEMORY
Dma.SDIO_RX.6.FIFOMode=DMA_FIFOMODE_ENABLE
Dma.SDIO_RX.6.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL
Dma.SDIO_RX.6.Instance=DMA2_Stream3
Dma.SDIO_RX.6.MemBurst=DMA_MBURST_INC4
Dma.SDIO_RX.6.MemDataAlignment=DMA_MDATAALIGN_WORD
Dma.SDIO_RX.6.MemInc=DMA_MINC_ENABLE
Dma.SDIO_RX.6.Mode=DMA_PFCTRL
Dma.SDIO_RX.6.PeriphBurst=DMA_PBURST_INC4
Dma.SDIO_RX.6.PeriphDataAlignment=DMA_PDATAALIGN_WORD
Dma.SDIO_RX.6.PeriphInc=DMA_PINC_DISABLE
Dma.SDIO_RX.6.Priority=DMA_PRIORITY_LOW
Dma.SDIO_RX.6.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst
Dma.SDIO_TX.7.Direction=DMA_MEMORY_TO_PERIPH
Dma.SDIO_TX.7.FIFOMode=DMA_FIFOMODE_ENABLE
Dma.SDIO_TX.7.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL
Dma.SDIO_TX.7.Instance=DMA2_Stream6
Dma.SDIO_TX.7.MemBurst=DMA_MBURST_INC4
Dma.SDIO_TX.7.MemDataAlignment=DMA_MDATAALIGN_WORD
Dma.SDIO_TX.7.MemInc=DMA_MINC_ENABLE
Dma.SDIO_TX.7.Mode=DMA_PFCTRL
Dma.SDIO_TX.7.PeriphBurst=DMA_PBURST_INC4
Dma.SDIO_TX.7.PeriphDataAlignment=DMA_PDATAALIGN_WORD
Dma.SDIO_TX.7.PeriphInc=DMA_PINC_DISABLE
Dma.SDIO_TX.7.Priority=DMA_PRIORITY_LOW
Dma.SDIO_TX.7.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst
Dma.UART4_RX.8.Direction=DMA_PERIPH_TO_MEMORY
Dma.UART4_RX.8.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.UART4_RX.8.Instance=DMA1_Stream2
Dma.UART4_RX.8.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.UART4_RX.8.MemInc=DMA_MINC_ENABLE
Dma.UART4_RX.8.Mode=DMA_NORMAL
Dma.UART4_RX.8.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.UART4_RX.8.PeriphInc=DMA_PINC_DISABLE
Dma.UART4_RX.8.Priority=DMA_PRIORITY_LOW
Dma.UART4_RX.8.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.UART4_TX.9.Direction=DMA_MEMORY_TO_PERIPH
Dma.UART4_TX.9.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.UART4_TX.9.Instance=DMA1_Stream4
Dma.UART4_TX.9.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.UART4_TX.9.MemInc=DMA_MINC_ENABLE
Dma.UART4_TX.9.Mode=DMA_NORMAL
Dma.UART4_TX.9.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.UART4_TX.9.PeriphInc=DMA_PINC_DISABLE
Dma.UART4_TX.9.Priority=DMA_PRIORITY_LOW
Dma.UART4_TX.9.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART1_RX.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART1_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART1_RX.0.Instance=DMA2_Stream2
Dma.USART1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART1_RX.0.MemInc=DMA_MINC_ENABLE
Dma.USART1_RX.0.Mode=DMA_NORMAL
Dma.USART1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_RX.0.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_RX.0.Priority=DMA_PRIORITY_LOW
Dma.USART1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART1_TX.1.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART1_TX.1.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART1_TX.1.Instance=DMA2_Stream7
Dma.USART1_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART1_TX.1.MemInc=DMA_MINC_ENABLE
Dma.USART1_TX.1.Mode=DMA_NORMAL
Dma.USART1_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_TX.1.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_TX.1.Priority=DMA_PRIORITY_LOW
Dma.USART1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART2_RX.2.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART2_RX.2.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART2_RX.2.Instance=DMA1_Stream5
Dma.USART2_RX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART2_RX.2.MemInc=DMA_MINC_ENABLE
Dma.USART2_RX.2.Mode=DMA_NORMAL
Dma.USART2_RX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART2_RX.2.PeriphInc=DMA_PINC_DISABLE
Dma.USART2_RX.2.Priority=DMA_PRIORITY_LOW
Dma.USART2_RX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART2_TX.3.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART2_TX.3.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART2_TX.3.Instance=DMA1_Stream6
Dma.USART2_TX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART2_TX.3.MemInc=DMA_MINC_ENABLE
Dma.USART2_TX.3.Mode=DMA_NORMAL
Dma.USART2_TX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART2_TX.3.PeriphInc=DMA_PINC_DISABLE
Dma.USART2_TX.3.Priority=DMA_PRIORITY_LOW
Dma.USART2_TX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART3_RX.4.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART3_RX.4.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART3_RX.4.Instance=DMA1_Stream1
Dma.USART3_RX.4.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART3_RX.4.MemInc=DMA_MINC_ENABLE
Dma.USART3_RX.4.Mode=DMA_NORMAL
Dma.USART3_RX.4.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART3_RX.4.PeriphInc=DMA_PINC_DISABLE
Dma.USART3_RX.4.Priority=DMA_PRIORITY_LOW
Dma.USART3_RX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART3_TX.5.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART3_TX.5.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART3_TX.5.Instance=DMA1_Stream3
Dma.USART3_TX.5.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART3_TX.5.MemInc=DMA_MINC_ENABLE
Dma.USART3_TX.5.Mode=DMA_NORMAL
Dma.USART3_TX.5.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART3_TX.5.PeriphInc=DMA_PINC_DISABLE
Dma.USART3_TX.5.Priority=DMA_PRIORITY_LOW
Dma.USART3_TX.5.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART6_RX.10.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART6_RX.10.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART6_RX.10.Instance=DMA2_Stream1
Dma.USART6_RX.10.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART6_RX.10.MemInc=DMA_MINC_ENABLE
Dma.USART6_RX.10.Mode=DMA_NORMAL
Dma.USART6_RX.10.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART6_RX.10.PeriphInc=DMA_PINC_DISABLE
Dma.USART6_RX.10.Priority=DMA_PRIORITY_LOW
Dma.USART6_RX.10.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
FATFS.BSP.number=1
FATFS.IPParameters=_CODE_PAGE,_USE_LFN,_USE_LABEL,_MAX_SS,_FS_EXFAT
FATFS._CODE_PAGE=936
FATFS._FS_EXFAT=1
FATFS._MAX_SS=4096
FATFS._USE_LABEL=1
FATFS._USE_LFN=2
FATFS0.BSP.STBoard=false
FATFS0.BSP.api=Unknown
FATFS0.BSP.component=
FATFS0.BSP.condition=
FATFS0.BSP.instance=PA15
FATFS0.BSP.ip=GPIO
FATFS0.BSP.mode=Input
FATFS0.BSP.name=Detect_SDIO
FATFS0.BSP.semaphore=
FATFS0.BSP.solution=PA15
FREERTOS.FootprintOK=true
FREERTOS.IPParameters=Tasks01,FootprintOK,configCHECK_FOR_STACK_OVERFLOW,configUSE_IDLE_HOOK,configUSE_TICK_HOOK,Timers01
FREERTOS.Tasks01=defaultTask,24,1024,StartDefaultTask,As weak,NULL,Dynamic,NULL,NULL;measureTask,8,256,Measure_Task,As weak,NULL,Dynamic,NULL,NULL;viperTask,8,256,Viper_Task,As weak,NULL,Dynamic,NULL,NULL;oscarTask,8,128,Oscar_Task,As weak,NULL,Dynamic,NULL,NULL;sc6Task,8,128,SC6_Task,As weak,NULL,Dynamic,NULL,NULL
FREERTOS.Timers01=measureTimer,measureTimer_Callback,osTimerPeriodic,As weak,NULL,Dynamic,NULL
FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2
FREERTOS.configUSE_IDLE_HOOK=1
FREERTOS.configUSE_TICK_HOOK=1
File.Version=6
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
Mcu.CPN=STM32F407ZET6
Mcu.Family=STM32F4
Mcu.IP0=DMA
Mcu.IP1=FATFS
Mcu.IP10=UART4
Mcu.IP11=USART1
Mcu.IP12=USART2
Mcu.IP13=USART3
Mcu.IP14=USART6
Mcu.IP15=USB_DEVICE
Mcu.IP16=USB_OTG_HS
Mcu.IP2=FREERTOS
Mcu.IP3=I2C1
Mcu.IP4=NVIC
Mcu.IP5=RCC
Mcu.IP6=SDIO
Mcu.IP7=SYS
Mcu.IP8=TIM2
Mcu.IP9=TIM7
Mcu.IPNb=17
Mcu.Name=STM32F407Z(E-G)Tx
Mcu.Package=LQFP144
Mcu.Pin0=PE4
Mcu.Pin1=PE5
Mcu.Pin10=PA4
Mcu.Pin11=PA6
Mcu.Pin12=PA7
Mcu.Pin13=PB2
Mcu.Pin14=PE12
Mcu.Pin15=PE13
Mcu.Pin16=PE14
Mcu.Pin17=PE15
Mcu.Pin18=PB10
Mcu.Pin19=PB11
Mcu.Pin2=PE6
Mcu.Pin20=PB14
Mcu.Pin21=PB15
Mcu.Pin22=PG4
Mcu.Pin23=PG5
Mcu.Pin24=PC6
Mcu.Pin25=PC7
Mcu.Pin26=PC8
Mcu.Pin27=PC9
Mcu.Pin28=PA9
Mcu.Pin29=PA10
Mcu.Pin3=PF0
Mcu.Pin30=PA13
Mcu.Pin31=PA14
Mcu.Pin32=PA15
Mcu.Pin33=PC10
Mcu.Pin34=PC11
Mcu.Pin35=PC12
Mcu.Pin36=PD2
Mcu.Pin37=PB4
Mcu.Pin38=PB5
Mcu.Pin39=PB6
Mcu.Pin4=PH0-OSC_IN
Mcu.Pin40=PB7
Mcu.Pin41=PE0
Mcu.Pin42=PE1
Mcu.Pin43=VP_FATFS_VS_SDIO
Mcu.Pin44=VP_FREERTOS_VS_CMSIS_V2
Mcu.Pin45=VP_SYS_VS_tim6
Mcu.Pin46=VP_TIM2_VS_ClockSourceINT
Mcu.Pin47=VP_TIM7_VS_ClockSourceINT
Mcu.Pin48=VP_USB_DEVICE_VS_USB_DEVICE_MSC_HS
Mcu.Pin5=PH1-OSC_OUT
Mcu.Pin6=PA0-WKUP
Mcu.Pin7=PA1
Mcu.Pin8=PA2
Mcu.Pin9=PA3
Mcu.PinsNb=49
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F407ZETx
MxCube.Version=6.8.1
MxDb.Version=DB.6.0.81
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.DMA1_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream6_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream3_IRQn=true\:10\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream6_IRQn=true\:10\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream7_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.OTG_HS_IRQn=true\:11\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SDIO_IRQn=true\:9\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
NVIC.SavedPendsvIrqHandlerGenerated=true
NVIC.SavedSvcallIrqHandlerGenerated=true
NVIC.SavedSystickIrqHandlerGenerated=true
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false
NVIC.TIM2_IRQn=true\:5\:0\:false\:false\:false\:true\:true\:true\:true
NVIC.TIM6_DAC_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.TIM7_IRQn=true\:5\:0\:false\:false\:false\:true\:true\:true\:true
NVIC.TimeBase=TIM6_DAC_IRQn
NVIC.TimeBaseIP=TIM6
NVIC.UART4_IRQn=true\:5\:0\:false\:false\:false\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:5\:0\:false\:false\:false\:true\:true\:true\:true
NVIC.USART2_IRQn=true\:5\:0\:false\:false\:false\:true\:true\:true\:true
NVIC.USART3_IRQn=true\:5\:0\:false\:false\:false\:true\:true\:true\:true
NVIC.USART6_IRQn=true\:7\:0\:true\:false\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
PA0-WKUP.Mode=Asynchronous
PA0-WKUP.Signal=UART4_TX
PA1.Mode=Asynchronous
PA1.Signal=UART4_RX
PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
PA13.Mode=Serial_Wire
PA13.Signal=SYS_JTMS-SWDIO
PA14.Mode=Serial_Wire
PA14.Signal=SYS_JTCK-SWCLK
PA15.GPIOParameters=GPIO_Label
PA15.GPIO_Label=CDZ
PA15.Locked=true
PA15.Signal=GPIO_Input
PA2.Locked=true
PA2.Mode=Asynchronous
PA2.Signal=USART2_TX
PA3.Locked=true
PA3.Mode=Asynchronous
PA3.Signal=USART2_RX
PA4.GPIOParameters=GPIO_Label
PA4.GPIO_Label=MAX3242_EN
PA4.Locked=true
PA4.Signal=GPIO_Output
PA6.GPIOParameters=GPIO_Label
PA6.GPIO_Label=SENSOR2_EN
PA6.Locked=true
PA6.Signal=GPIO_Output
PA7.GPIOParameters=GPIO_Label
PA7.GPIO_Label=SENSOR4_EN
PA7.Locked=true
PA7.Signal=GPIO_Output
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB10.Locked=true
PB10.Mode=Asynchronous
PB10.Signal=USART3_TX
PB11.Locked=true
PB11.Mode=Asynchronous
PB11.Signal=USART3_RX
PB14.Mode=Device_Only_FS
PB14.Signal=USB_OTG_HS_DM
PB15.Mode=Device_Only_FS
PB15.Signal=USB_OTG_HS_DP
PB2.GPIOParameters=GPIO_Label
PB2.GPIO_Label=BOOT1
PB2.Locked=true
PB2.Signal=GPIO_Input
PB4.GPIOParameters=GPIO_Label
PB4.GPIO_Label=ADDR
PB4.Locked=true
PB4.Signal=GPIO_Output
PB5.GPIOParameters=GPIO_Label
PB5.GPIO_Label=RDY
PB5.Locked=true
PB5.Signal=GPIO_Output
PB6.GPIOParameters=GPIO_Pu
PB6.GPIO_Pu=GPIO_PULLUP
PB6.Mode=I2C
PB6.Signal=I2C1_SCL
PB7.GPIOParameters=GPIO_Pu
PB7.GPIO_Pu=GPIO_PULLUP
PB7.Mode=I2C
PB7.Signal=I2C1_SDA
PC10.Mode=SD_4_bits_Wide_bus
PC10.Signal=SDIO_D2
PC11.Mode=SD_4_bits_Wide_bus
PC11.Signal=SDIO_D3
PC12.Mode=SD_4_bits_Wide_bus
PC12.Signal=SDIO_CK
PC6.Locked=true
PC6.Mode=Asynchronous
PC6.Signal=USART6_TX
PC7.Locked=true
PC7.Mode=Asynchronous
PC7.Signal=USART6_RX
PC8.Mode=SD_4_bits_Wide_bus
PC8.Signal=SDIO_D0
PC9.Mode=SD_4_bits_Wide_bus
PC9.Signal=SDIO_D1
PD2.Mode=SD_4_bits_Wide_bus
PD2.Signal=SDIO_CMD
PE0.GPIOParameters=GPIO_Label
PE0.GPIO_Label=LED0
PE0.Locked=true
PE0.Signal=GPIO_Output
PE1.GPIOParameters=GPIO_Label
PE1.GPIO_Label=LED1
PE1.Locked=true
PE1.Signal=GPIO_Output
PE12.GPIOParameters=GPIO_Label
PE12.GPIO_Label=SENSOR3_EN
PE12.Locked=true
PE12.Signal=GPIO_Output
PE13.GPIOParameters=GPIO_Label
PE13.GPIO_Label=DE485
PE13.Locked=true
PE13.Signal=GPIO_Output
PE14.GPIOParameters=GPIO_Label
PE14.GPIO_Label=HDPLX
PE14.Locked=true
PE14.Signal=GPIO_Output
PE15.GPIOParameters=GPIO_Label
PE15.GPIO_Label=SEL_232/485
PE15.Locked=true
PE15.Signal=GPIO_Output
PE4.GPIOParameters=GPIO_Label
PE4.GPIO_Label=EN_1302
PE4.Locked=true
PE4.Signal=GPIO_Output
PE5.GPIOParameters=GPIO_Label,GPIO_ModeDefaultOutputPP
PE5.GPIO_Label=DA_1302
PE5.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_OD
PE5.Locked=true
PE5.Signal=GPIO_Output
PE6.GPIOParameters=GPIO_Label
PE6.GPIO_Label=SCLK_1302
PE6.Locked=true
PE6.Signal=GPIO_Output
PF0.GPIOParameters=GPIO_Label
PF0.GPIO_Label=PUMP_EN
PF0.Locked=true
PF0.Signal=GPIO_Output
PG4.GPIOParameters=GPIO_Label
PG4.GPIO_Label=SENSOR6_EN
PG4.Locked=true
PG4.Signal=GPIO_Output
PG5.GPIOParameters=GPIO_Label
PG5.GPIO_Label=R/W
PG5.Locked=true
PG5.Signal=GPIO_Output
PH0-OSC_IN.Mode=HSE-External-Oscillator
PH0-OSC_IN.Signal=RCC_OSC_IN
PH1-OSC_OUT.Mode=HSE-External-Oscillator
PH1-OSC_OUT.Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=true
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32F407ZETx
ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.27.1
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x1000
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=0
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=IOP_407ZET6.ioc
ProjectManager.ProjectName=IOP_407ZET6
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x1500
ProjectManager.TargetToolchain=Makefile
ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_I2C1_Init-I2C1-false-HAL-true,5-MX_SDIO_SD_Init-SDIO-false-HAL-true,6-MX_UART4_Init-UART4-false-HAL-true,7-MX_USART1_UART_Init-USART1-false-HAL-true,8-MX_USART2_UART_Init-USART2-false-HAL-true,9-MX_USART3_UART_Init-USART3-false-HAL-true,10-MX_USART6_UART_Init-USART6-false-HAL-true,11-MX_TIM7_Init-TIM7-false-HAL-true,12-MX_FATFS_Init-FATFS-false-HAL-false,13-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,14-MX_TIM2_Init-TIM2-false-HAL-true
RCC.48MHZClocksFreq_Value=48000000
RCC.AHBFreq_Value=168000000
RCC.APB1CLKDivider=RCC_HCLK_DIV4
RCC.APB1Freq_Value=42000000
RCC.APB1TimFreq_Value=84000000
RCC.APB2CLKDivider=RCC_HCLK_DIV2
RCC.APB2Freq_Value=84000000
RCC.APB2TimFreq_Value=168000000
RCC.CortexFreq_Value=168000000
RCC.EthernetFreq_Value=168000000
RCC.FCLKCortexFreq_Value=168000000
RCC.FamilyName=M
RCC.HCLKFreq_Value=168000000
RCC.HSE_VALUE=8000000
RCC.HSI_VALUE=16000000
RCC.I2SClocksFreq_Value=192000000
RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSE_VALUE,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S
RCC.LSE_VALUE=32768
RCC.LSI_VALUE=32000
RCC.MCO2PinFreq_Value=168000000
RCC.PLLCLKFreq_Value=168000000
RCC.PLLM=4
RCC.PLLN=168
RCC.PLLQ=7
RCC.PLLQCLKFreq_Value=48000000
RCC.RTCFreq_Value=32000
RCC.RTCHSEDivFreq_Value=4000000
RCC.SYSCLKFreq_VALUE=168000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.VCOI2SOutputFreq_Value=384000000
RCC.VCOInputFreq_Value=2000000
RCC.VCOOutputFreq_Value=336000000
RCC.VcooutputI2S=192000000
SDIO.ClockDiv=6
SDIO.IPParameters=ClockDiv
TIM2.IPParameters=Prescaler,Period
TIM2.Period=10000-1
TIM2.Prescaler=8400-1
TIM7.IPParameters=Prescaler,Period
TIM7.Period=50-1
TIM7.Prescaler=8400-1
UART4.IPParameters=VirtualMode
UART4.VirtualMode=Asynchronous
USART1.IPParameters=VirtualMode
USART1.VirtualMode=VM_ASYNC
USART2.BaudRate=115200
USART2.IPParameters=VirtualMode,BaudRate
USART2.VirtualMode=VM_ASYNC
USART3.BaudRate=9600
USART3.IPParameters=VirtualMode,BaudRate
USART3.VirtualMode=VM_ASYNC
USART6.BaudRate=9600
USART6.IPParameters=VirtualMode,BaudRate
USART6.VirtualMode=VM_ASYNC
USB_DEVICE.CLASS_NAME_HS=MSC
USB_DEVICE.IPParameters=VirtualMode-MSC_HS,VirtualModeHS,CLASS_NAME_HS,MSC_MEDIA_PACKET-MSC_HS
USB_DEVICE.MSC_MEDIA_PACKET-MSC_HS=4096
USB_DEVICE.VirtualMode-MSC_HS=Msc
USB_DEVICE.VirtualModeHS=Msc_HS
USB_OTG_HS.IPParameters=VirtualMode-Device_Only_FS
USB_OTG_HS.VirtualMode-Device_Only_FS=Device_Only_FS
VP_FATFS_VS_SDIO.Mode=SDIO
VP_FATFS_VS_SDIO.Signal=FATFS_VS_SDIO
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
VP_SYS_VS_tim6.Mode=TIM6
VP_SYS_VS_tim6.Signal=SYS_VS_tim6
VP_TIM2_VS_ClockSourceINT.Mode=Internal
VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
VP_TIM7_VS_ClockSourceINT.Mode=Enable_Timer
VP_TIM7_VS_ClockSourceINT.Signal=TIM7_VS_ClockSourceINT
VP_USB_DEVICE_VS_USB_DEVICE_MSC_HS.Mode=MSC_HS
VP_USB_DEVICE_VS_USB_DEVICE_MSC_HS.Signal=USB_DEVICE_VS_USB_DEVICE_MSC_HS
board=custom
rtos.0.ip=FREERTOS

@ -0,0 +1,264 @@
#MicroXplorer Configuration settings - do not modify
CAD.formats=
CAD.pinconfig=
CAD.provider=
Dma.Request0=USART1_RX
Dma.Request1=USART1_TX
Dma.Request2=USART2_RX
Dma.Request3=USART2_TX
Dma.Request4=USART3_RX
Dma.Request5=USART3_TX
Dma.RequestsNb=6
Dma.USART1_RX.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART1_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART1_RX.0.Instance=DMA2_Stream2
Dma.USART1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART1_RX.0.MemInc=DMA_MINC_ENABLE
Dma.USART1_RX.0.Mode=DMA_NORMAL
Dma.USART1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_RX.0.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_RX.0.Priority=DMA_PRIORITY_LOW
Dma.USART1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART1_TX.1.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART1_TX.1.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART1_TX.1.Instance=DMA2_Stream7
Dma.USART1_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART1_TX.1.MemInc=DMA_MINC_ENABLE
Dma.USART1_TX.1.Mode=DMA_NORMAL
Dma.USART1_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_TX.1.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_TX.1.Priority=DMA_PRIORITY_LOW
Dma.USART1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART2_RX.2.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART2_RX.2.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART2_RX.2.Instance=DMA1_Stream5
Dma.USART2_RX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART2_RX.2.MemInc=DMA_MINC_ENABLE
Dma.USART2_RX.2.Mode=DMA_NORMAL
Dma.USART2_RX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART2_RX.2.PeriphInc=DMA_PINC_DISABLE
Dma.USART2_RX.2.Priority=DMA_PRIORITY_LOW
Dma.USART2_RX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART2_TX.3.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART2_TX.3.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART2_TX.3.Instance=DMA1_Stream6
Dma.USART2_TX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART2_TX.3.MemInc=DMA_MINC_ENABLE
Dma.USART2_TX.3.Mode=DMA_NORMAL
Dma.USART2_TX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART2_TX.3.PeriphInc=DMA_PINC_DISABLE
Dma.USART2_TX.3.Priority=DMA_PRIORITY_LOW
Dma.USART2_TX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART3_RX.4.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART3_RX.4.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART3_RX.4.Instance=DMA1_Stream1
Dma.USART3_RX.4.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART3_RX.4.MemInc=DMA_MINC_ENABLE
Dma.USART3_RX.4.Mode=DMA_NORMAL
Dma.USART3_RX.4.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART3_RX.4.PeriphInc=DMA_PINC_DISABLE
Dma.USART3_RX.4.Priority=DMA_PRIORITY_LOW
Dma.USART3_RX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART3_TX.5.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART3_TX.5.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART3_TX.5.Instance=DMA1_Stream3
Dma.USART3_TX.5.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART3_TX.5.MemInc=DMA_MINC_ENABLE
Dma.USART3_TX.5.Mode=DMA_NORMAL
Dma.USART3_TX.5.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART3_TX.5.PeriphInc=DMA_PINC_DISABLE
Dma.USART3_TX.5.Priority=DMA_PRIORITY_LOW
Dma.USART3_TX.5.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
FREERTOS.FootprintOK=true
FREERTOS.IPParameters=Tasks01,FootprintOK
FREERTOS.Tasks01=defaultTask,24,512,StartDefaultTask,As weak,NULL,Dynamic,NULL,NULL
File.Version=6
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
Mcu.CPN=STM32F407ZGT6
Mcu.Family=STM32F4
Mcu.IP0=DMA
Mcu.IP1=FREERTOS
Mcu.IP2=I2C1
Mcu.IP3=NVIC
Mcu.IP4=RCC
Mcu.IP5=SYS
Mcu.IP6=TIM7
Mcu.IP7=USART1
Mcu.IP8=USART2
Mcu.IP9=USART3
Mcu.IPNb=10
Mcu.Name=STM32F407Z(E-G)Tx
Mcu.Package=LQFP144
Mcu.Pin0=PF2
Mcu.Pin1=PF3
Mcu.Pin10=PA14
Mcu.Pin11=PB6
Mcu.Pin12=PB7
Mcu.Pin13=PE0
Mcu.Pin14=PE1
Mcu.Pin15=VP_FREERTOS_VS_CMSIS_V2
Mcu.Pin16=VP_SYS_VS_tim6
Mcu.Pin17=VP_TIM7_VS_ClockSourceINT
Mcu.Pin2=PF4
Mcu.Pin3=PA2
Mcu.Pin4=PA3
Mcu.Pin5=PB10
Mcu.Pin6=PB11
Mcu.Pin7=PA9
Mcu.Pin8=PA10
Mcu.Pin9=PA13
Mcu.PinsNb=18
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F407ZGTx
MxCube.Version=6.8.1
MxDb.Version=DB.6.0.81
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.DMA1_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream6_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream7_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.I2C1_ER_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.I2C1_EV_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
NVIC.SavedPendsvIrqHandlerGenerated=true
NVIC.SavedSvcallIrqHandlerGenerated=true
NVIC.SavedSystickIrqHandlerGenerated=true
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false
NVIC.TIM6_DAC_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.TIM7_IRQn=true\:5\:0\:false\:false\:false\:true\:true\:true\:true
NVIC.TimeBase=TIM6_DAC_IRQn
NVIC.TimeBaseIP=TIM6
NVIC.USART1_IRQn=true\:5\:0\:false\:false\:false\:true\:true\:true\:true
NVIC.USART2_IRQn=true\:5\:0\:false\:false\:false\:true\:true\:true\:true
NVIC.USART3_IRQn=true\:5\:0\:false\:false\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
PA13.Mode=Serial_Wire
PA13.Signal=SYS_JTMS-SWDIO
PA14.Mode=Serial_Wire
PA14.Signal=SYS_JTCK-SWCLK
PA2.Mode=Asynchronous
PA2.Signal=USART2_TX
PA3.Mode=Asynchronous
PA3.Signal=USART2_RX
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB10.Mode=Asynchronous
PB10.Signal=USART3_TX
PB11.Mode=Asynchronous
PB11.Signal=USART3_RX
PB6.Mode=I2C
PB6.Signal=I2C1_SCL
PB7.Mode=I2C
PB7.Signal=I2C1_SDA
PE0.GPIOParameters=GPIO_Label
PE0.GPIO_Label=LED0
PE0.Locked=true
PE0.Signal=GPIO_Output
PE1.GPIOParameters=GPIO_Label
PE1.GPIO_Label=LED1
PE1.Locked=true
PE1.Signal=GPIO_Output
PF2.GPIOParameters=GPIO_Label
PF2.GPIO_Label=FULLHALF_D
PF2.Locked=true
PF2.Signal=GPIO_Output
PF3.GPIOParameters=GPIO_Label
PF3.GPIO_Label=DE_485
PF3.Locked=true
PF3.Signal=GPIO_Output
PF4.GPIOParameters=GPIO_Label
PF4.GPIO_Label=SEL_232_485
PF4.Locked=true
PF4.Signal=GPIO_Output
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=true
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32F407ZGTx
ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.27.1
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x800
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=0
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=UART_407.ioc
ProjectManager.ProjectName=UART_407
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x1000
ProjectManager.TargetToolchain=Makefile
ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_USART2_UART_Init-USART2-false-HAL-true,6-MX_USART3_UART_Init-USART3-false-HAL-true,7-MX_TIM7_Init-TIM7-false-HAL-true
RCC.48MHZClocksFreq_Value=84000000
RCC.AHBFreq_Value=168000000
RCC.APB1CLKDivider=RCC_HCLK_DIV4
RCC.APB1Freq_Value=42000000
RCC.APB1TimFreq_Value=84000000
RCC.APB2CLKDivider=RCC_HCLK_DIV2
RCC.APB2Freq_Value=84000000
RCC.APB2TimFreq_Value=168000000
RCC.CortexFreq_Value=168000000
RCC.EthernetFreq_Value=168000000
RCC.FCLKCortexFreq_Value=168000000
RCC.FamilyName=M
RCC.HCLKFreq_Value=168000000
RCC.HSE_VALUE=25000000
RCC.HSI_VALUE=16000000
RCC.I2SClocksFreq_Value=192000000
RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSE_VALUE,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQCLKFreq_Value,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S
RCC.LSE_VALUE=32768
RCC.LSI_VALUE=32000
RCC.MCO2PinFreq_Value=168000000
RCC.PLLCLKFreq_Value=168000000
RCC.PLLM=8
RCC.PLLN=168
RCC.PLLQCLKFreq_Value=84000000
RCC.RTCFreq_Value=32000
RCC.RTCHSEDivFreq_Value=12500000
RCC.SYSCLKFreq_VALUE=168000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.VCOI2SOutputFreq_Value=384000000
RCC.VCOInputFreq_Value=2000000
RCC.VCOOutputFreq_Value=336000000
RCC.VcooutputI2S=192000000
TIM7.IPParameters=Prescaler,Period
TIM7.Period=50-1
TIM7.Prescaler=8400-1
USART1.IPParameters=VirtualMode
USART1.VirtualMode=VM_ASYNC
USART2.IPParameters=VirtualMode
USART2.VirtualMode=VM_ASYNC
USART3.IPParameters=VirtualMode
USART3.VirtualMode=VM_ASYNC
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
VP_SYS_VS_tim6.Mode=TIM6
VP_SYS_VS_tim6.Signal=SYS_VS_tim6
VP_TIM7_VS_ClockSourceINT.Mode=Enable_Timer
VP_TIM7_VS_ClockSourceINT.Signal=TIM7_VS_ClockSourceINT
board=custom
rtos.0.ip=FREERTOS

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,69 @@
#ifndef __LED_H
#define __LED_H
#include "stdint.h"
#include "main.h"
#define LED_MAX_NUM 4
typedef enum {
LED_SEQ_0,
LED_COLOR_GREEN,
}MY_LED_COLOR_SEQ;
// 回调需要这个参数,控制时开关还是闪烁,闪烁快慢
enum led_state{
LED_STATE_ON,
LED_STATE_FLICKER_SLOW,
LED_STATE_FLICKER_MEDIUM,
LED_STATE_FLICKER_QUICK,
LED_STATE_OFF
};
// 标准库的 GPIO_TypeDef, 改为HAL库
struct led
{
enum led_state state;
GPIO_TypeDef *gpio;
uint16_t pin;
uint16_t level_on;
};
typedef struct
{
int (*init)();
void (*port)(uint16_t delay_ms);
uint8_t led_num;
uint16_t delay_base_ms;
// struct led *led[LED_MAX_NUM];
// void * led;
}My_LED_TypeDef;
extern My_LED_TypeDef my_led;
int Led_Init( );
void Led_Port( uint16_t delay_ms );
int led_setup(uint8_t seq, GPIO_TypeDef *gpio,uint16_t pin,enum led_state state,uint16_t level_on);
// 依据GPIO 信息注册
// int led_register(struct led *led, GPIO_TypeDef *gpio, uint16_t pin, enum led_state state, uint16_t level_on );
// 初始化状态
int led_set_state(uint8_t seq,enum led_state state);
// int led_set_state(struct led *led,enum led_state state);
// 执行 -- 由状态决定
void led_callback(void);
#endif
/*
my_led.init();
my_led.port( 200);
led_set_state(LED_SEQ_0, LED_STATE_FLICKER_SLOW);
led_set_state(LED_COLOR_GREEN, LED_STATE_FLICKER_SLOW);
*/

@ -0,0 +1,148 @@
#include "bsp_led.h"
// #include "platform.h"
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
static struct led *led_table[LED_MAX_NUM];
static uint32_t p_led_table = 0;
static uint32_t delay_time_ms = 1;
osThreadId_t ledHandle;
const osThreadAttr_t led_attributes = {
.name = "led",
.stack_size = 256 * 4,
.priority = (osPriority_t)osPriorityBelowNormal,
};
My_LED_TypeDef my_led = {
Led_Init,
Led_Port,
0,
0,
// led_table,
};
/* 修改 MY_LED_COLOR_SEQ ,以及在 Led_Init 添加LED*/
int Led_Init()
{
led_setup(LED_SEQ_0, LED_RED_GPIO_Port, LED_RED_Pin, LED_STATE_ON, RESET);
led_set_state(LED_SEQ_0, LED_STATE_FLICKER_MEDIUM);
led_setup(LED_COLOR_GREEN, LED_GRN_GPIO_Port, LED_GRN_Pin, LED_STATE_ON, RESET);
return 0;
}
void Led_Task(void *argument)
{
uint16_t *delay_ms = argument;
for (;;)
{
led_callback();
osDelay(*delay_ms);
// osDelay(200);
}
}
void Led_Port(uint16_t delay_ms)
{
delay_time_ms = delay_ms;
ledHandle = osThreadNew(Led_Task, (void *)(&delay_time_ms), &led_attributes);
return 0;
}
int led_setup(uint8_t seq, GPIO_TypeDef *gpio, uint16_t pin, enum led_state state, uint16_t level_on)
{
if (seq >= LED_MAX_NUM - 1 || seq < 0)
{
return -1;
}
struct led *Handle = (struct led *)malloc(sizeof(struct led));
if (Handle == NULL)
{
return -1;
}
led_table[seq] = Handle;
led_table[seq]->gpio = gpio;
led_table[seq]->pin = pin;
led_table[seq]->state = state;
led_table[seq]->level_on = level_on;
p_led_table++;
return 0;
}
// int led_register(struct led *led, GPIO_TypeDef *gpio,uint16_t pin,enum led_state state,uint16_t level_on)
// {
// if(p_led_table>=LED_MAX_NUM-1){
// return -1;
// }
// led->gpio=gpio;
// led->pin=pin;
// led->state=state;
// led->level_on=level_on;
// led_table[p_led_table++]=led;
// return 0;
// }
int led_set_state(uint8_t seq, enum led_state state)
{
if (led_table[seq] == NULL)
{
return -1;
}
led_table[seq]->state = state;
return 0;
}
/**
* @brief led回调函数 100ms调用一次
*
*/
void led_callback(void)
{
int i;
static uint32_t tick_con = 0;
tick_con++;
for (i = 0; i < p_led_table; i++)
{
switch (led_table[i]->state)
{
case LED_STATE_OFF:
HAL_GPIO_WritePin(led_table[i]->gpio, led_table[i]->pin, (~led_table[i]->level_on) & 1);
// GPIO_WriteBit(led_table[i]->gpio,led_table[i]->pin,(~led_table[i]->level_on)&1);
break;
case LED_STATE_ON:
HAL_GPIO_WritePin(led_table[i]->gpio, led_table[i]->pin, led_table[i]->level_on & 1);
// GPIO_WriteBit(led_table[i]->gpio,led_table[i]->pin,led_table[i]->level_on&1);
break;
case LED_STATE_FLICKER_QUICK:
HAL_GPIO_TogglePin(led_table[i]->gpio, led_table[i]->pin);
// GPIO_WriteBit(led_table[i]->gpio,led_table[i]->pin,!GPIO_ReadOutputDataBit(led_table[i]->gpio,led_table[i]->pin));
break;
case LED_STATE_FLICKER_MEDIUM:
if ((tick_con & 0x01) == 0)
{
HAL_GPIO_TogglePin(led_table[i]->gpio, led_table[i]->pin);
// GPIO_WriteBit(led_table[i]->gpio,led_table[i]->pin,!GPIO_ReadOutputDataBit(led_table[i]->gpio,led_table[i]->pin));
}
break;
case LED_STATE_FLICKER_SLOW:
if ((tick_con & 0x03) == 0)
{
HAL_GPIO_TogglePin(led_table[i]->gpio, led_table[i]->pin);
// GPIO_WriteBit(led_table[i]->gpio,led_table[i]->pin,!GPIO_ReadOutputDataBit(led_table[i]->gpio,led_table[i]->pin));
}
break;
default:
break;
}
}
}

@ -0,0 +1,80 @@
#ifndef DS1302_H_
#define DS1302_H_
#include <stddef.h>
#include <stdint.h>
// #include "config.h"
#include "time_clock.h"
#include "stm32f4xx.h"
/*
ds1302_get_time_s BCD ds1302_read_bytes(&ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_ALL,time_bcd,8),
time_clock_date time_clock_time_to_date(uint64_t time_s,struct time_clock_date *date,int8_t time_zone)
time_clock_date time_clock_date_to_time(struct time_clock_date *date,int8_t time_zone)
ds1302_set_time_s ds1302
uint32_t time_clock_get_time_str(char *buf,int8_t time_zone); buf,
*/
#define Bit_SET SET
#define Bit_RESET RESET
#define GPIO_WriteBit HAL_GPIO_WritePin
#define GPIO_ReadInputDataBit HAL_GPIO_ReadPin
#define DS1302_CMD_MASK (0x80)
#define DS1302_CMD_READ_MASK (0x01)
#define DS1302_CMD_WRITE_MASK (0x00)
#define DS1302_CMD_REG_MASK (0x00)
#define DS1302_CMD_RAM_MASK (0x40)
#define DS1302_REG_SECONDS_CH_MASK (0x80)
#define DS1302_REG_HOUR_12_N24_MASK (0x80)
#define DS1302_REG_HOUR_NAM_PM_MASK (0x20)
#define DS1302_REG_CONTROL_WP_MASK (0x80)
enum ds1302_reg_addr
{
DS1302_REG_ADDR_SECONDS=0x00,
DS1302_REG_ADDR_MINUTES=0x01,
DS1302_REG_ADDR_HOUR=0x02,
DS1302_REG_ADDR_DATE=0x03,
DS1302_REG_ADDR_MONTH=0x04,
DS1302_REG_ADDR_DAY=0x05,
DS1302_REG_ADDR_YEAR=0x06,
DS1302_REG_ADDR_CONTROL=0x07,
DS1302_REG_ADDR_TRICKLE_CHARGER=0x08,
DS1302_REG_ADDR_ALL=0x1f
};
enum ds1302_trickle_charger_tcs{
DS1302_TRICKLE_CHARGER_TCS_OFF=0x00,
DS1302_TRICKLE_CHARGER_TCS_ON=0xa0
};
enum ds1302_trickle_charger_ds{
DS1302_TRICKLE_CHARGER_DS_1=0x04,
DS1302_TRICKLE_CHARGER_DS_2=0x08
};
enum ds1302_trickle_charger_rs{
DS1302_TRICKLE_CHARGER_RS_NONE=0x00,
DS1302_TRICKLE_CHARGER_RS_2K=0x01,
DS1302_TRICKLE_CHARGER_RS_4K=0x02,
DS1302_TRICKLE_CHARGER_RS_8K=0x03
};
struct ds1302
{
struct time_clock_time time_base;
GPIO_TypeDef *gpio_ce;
GPIO_TypeDef *gpio_sclk;
GPIO_TypeDef *gpio_io;
uint16_t pin_ce;
uint16_t pin_sclk;
uint16_t pin_io;
};
struct ds1302* ds1302_init(struct ds1302 *ds1302,GPIO_TypeDef *gpio_ce,GPIO_TypeDef *gpio_sclk,GPIO_TypeDef *gpio_io,uint16_t pin_ce,uint16_t pin_sclk,uint16_t pin_io);
int ds1302_write_bytes(struct ds1302 *ds1302,uint8_t cmd,uint8_t addr,const uint8_t *bytes,uint8_t num);
int ds1302_read_bytes(struct ds1302 *ds1302,uint8_t cmd,uint8_t addr,uint8_t *bytes,uint8_t num);
int ds1302_write_disable(struct ds1302 *ds1302);
int ds1302_write_enable(struct ds1302 *ds1302);
uint64_t ds1302_get_time_s(struct ds1302 *ds1302);
int ds1302_set_time_s(struct ds1302 *ds1302,uint64_t time_s);
int ds1302_read_ram(struct ds1302 *ds1302,uint8_t addr,uint8_t *bytes,uint8_t num);
int ds1302_write_ram(struct ds1302 *ds1302,uint8_t addr,uint8_t *bytes,uint8_t num);
int ds1302_set_charger(struct ds1302 *ds1302,enum ds1302_trickle_charger_tcs tcs,enum ds1302_trickle_charger_ds ds,enum ds1302_trickle_charger_rs rs);
#endif

@ -0,0 +1,131 @@
#ifndef __STMFLASH_H
#define __STMFLASH_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
STM32_F1XX,
STM32_F4XX,
} STM32_FSeries_TypeDef;
typedef enum
{
STM_FALSH_IGT6,
STM_FALSH_ZGT6,
STM_FALSH_ZET6,
STM_FALSH_VET6,
STM_FALSH_RET6,
STM_FALSH_RBT6,
STM_FALSH_RCT6,
STM_FALSH_C8T6,
} STM_FALSH_TypeDef;
#define STM32_FSeries_TYPE STM32_F4XX
#define STM_FALSH_TYPE STM_FALSH_ZGT6
#include "main.h"
//FLASH起始地址
#define STM32_FLASH_BASE 0x08000000 //STM32 FLASH的起始地址
#define FLASH_WAITETIME 50000 //FLASH等待超时时间
#if STM_FALSH_TYPE == STM_FALSH_ZGT6 || STM_FALSH_TYPE == STM_FALSH_IGT6 || STM_FALSH_TYPE == STM_FALSH_ZET6
#define STM32_FLASH_SIZE 0x00100000 //STM32 FLASH的起始地址 1M
#define STM32_PAGE_SIZE 0x00000800 //STM32 页大小 2K
#define STM32_LAST_SECTOR_ADDR 0x080E0000 //STM32 页大小 2K
#define STM32_LAST_SECTOR_SIZE 0x00020000 //STM32 页大小 128K
#endif
//FLASH 扇区的起始地址
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) //扇区0起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) //扇区1起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) //扇区2起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) //扇区3起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) //扇区4起始地址, 64 Kbytes
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) //扇区5起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) //扇区6起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) //扇区7起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) //扇区8起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) //扇区9起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) //扇区10起始地址,128 Kbytes
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) //扇区11起始地址,128 Kbytes
uint32_t STMFLASH_ReadWord(uint32_t faddr); //读出字
void STMFLASH_Write(uint32_t WriteAddr,uint32_t *pBuffer,uint32_t NumToWrite); //从指定地址开始写入指定长度的数据
void STMFLASH_Read(uint32_t ReadAddr,uint32_t *pBuffer,uint32_t NumToRead); //从指定地址开始读出指定长度的数据
int STMFLASH_ErasePage(uint32_t Page_Address); //从指定地址开始擦除页
//测试写入
void Test_Write(uint32_t WriteAddr,uint32_t WriteData);
#ifdef __cplusplus
}
#endif
#endif
/*
F103 F407以扇区为单位操作
FLASH_ErasePage(uint32_t Page_Address); // F407无此函数
HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)
16bit, 8bit 232bit = 2*16bit,
STM32F407ZET6 Flash分区 512K
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) //扇区0起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) //扇区1起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) //扇区2起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) //扇区3起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) //扇区4起始地址, 64 Kbytes
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) //扇区5起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) //扇区6起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) //扇区7起始地址, 128 Kbytes
STM32F407ZGT6 Flash分区 1M
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) //扇区0起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) //扇区1起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) //扇区2起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) //扇区3起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) //扇区4起始地址, 64 Kbytes
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) //扇区5起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) //扇区6起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) //扇区7起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) //扇区8起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) //扇区9起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) //扇区10起始地址,128 Kbytes
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) //扇区11起始地址,128 Kbytes
STM32F429IGT6 Flash分区 --
STM32F103C8T6 Flash分区 64K 64*1024Bytes 1K 0x400
64K (F103C8T6 ) --->>>> 1K 0x400 0x0800FC00
128K (F103RCT6) --->>>> 1K 0x400 0x0801FC00
256K (F103RBT6) --->>> 2K 0x800 0x0803F800
512K (F103RET6), --->>> 2K 0x800 0x0807F800
512K (F103ZET6), --->>> 2K 0x800 0x0807F800
STM32F103VET 6 Flash分区 512K
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) //扇区0起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) //扇区1起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) //扇区2起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) //扇区3起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) //扇区4起始地址, 64 Kbytes
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) //扇区5起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) //扇区6起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) //扇区7起始地址, 128 Kbytes
STM32F103ZET6 Flash分区 512K 2K
-->> FLASH_ErasePage(uint32_t Page_Address);
*/

@ -0,0 +1,217 @@
#include "ds1302.h"
#include "main.h"
#if 0
extern int ds1302_port(void);
struct ds1302 ds1302;
int ds1302_port(void)
{
ds1302_init(&ds1302
, EN_1302_GPIO_Port, SCLK_1302_GPIO_Port, DA_1302_GPIO_Port
, EN_1302_Pin, SCLK_1302_Pin, DA_1302_Pin
);
return 0;
}
void ds1302_delay_us(int us,uint32_t system_clock_mhz)
{
volatile uint32_t con=us*system_clock_mhz/8;
do{
__NOP();
}while(con--);
}
struct ds1302* ds1302_init(struct ds1302 *ds1302,GPIO_TypeDef *gpio_ce,GPIO_TypeDef *gpio_sclk,GPIO_TypeDef *gpio_io,uint16_t pin_ce,uint16_t pin_sclk,uint16_t pin_io)
{
if(ds1302==NULL || gpio_ce==NULL || gpio_io==NULL || gpio_sclk==NULL){
return NULL;
}
ds1302->gpio_ce=gpio_ce;
ds1302->gpio_io=gpio_io;
ds1302->gpio_sclk=gpio_sclk;
ds1302->pin_ce=pin_ce;
ds1302->pin_io=pin_io;
ds1302->pin_sclk=pin_sclk;
return ds1302;
}
int ds1302_write_bytes(struct ds1302 *ds1302,uint8_t cmd,uint8_t addr,const uint8_t *bytes,uint8_t num)
{
int i,j;
uint8_t tmp;
if(ds1302==NULL || bytes==NULL || num==0){
return -1;
}
GPIO_WriteBit(ds1302->gpio_ce,ds1302->pin_ce,Bit_SET);
tmp=cmd|addr<<1|DS1302_CMD_WRITE_MASK;
for(j=0;j<8;j++){
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,tmp&1);
ds1302_delay_us(1,168);
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_SET);
ds1302_delay_us(1,168);
tmp>>=1;
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_RESET);
}
for(i=0;i<num;i++){
tmp=bytes[i];
for(j=0;j<8;j++){
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,tmp&1);
ds1302_delay_us(1,168);
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_SET);
ds1302_delay_us(1,168);
tmp>>=1;
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_RESET);
}
}
GPIO_WriteBit(ds1302->gpio_ce,ds1302->pin_ce,Bit_RESET);
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,Bit_SET);
return 0;
}
int ds1302_read_bytes(struct ds1302 *ds1302,uint8_t cmd,uint8_t addr,uint8_t *bytes, uint8_t num)
{
int i,j;
uint8_t tmp;
if(ds1302==NULL || bytes==NULL || num==0){
return -1;
}
GPIO_WriteBit(ds1302->gpio_ce,ds1302->pin_ce,Bit_SET);
tmp=cmd|addr<<1|DS1302_CMD_READ_MASK;
for(j=0;j<8;j++){
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,tmp&1);
ds1302_delay_us(1,168);
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_SET);
ds1302_delay_us(1,168);
tmp>>=1;
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_RESET);
}
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,Bit_SET);
for(i=0;i<num;i++){
tmp=0;
for(j=0;j<8;j++){
ds1302_delay_us(1,168);
tmp|=GPIO_ReadInputDataBit(ds1302->gpio_io,ds1302->pin_io)<<j;
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_SET);
ds1302_delay_us(1,168);
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_RESET);
}
bytes[i]=tmp;
}
GPIO_WriteBit(ds1302->gpio_ce,ds1302->pin_ce,Bit_RESET);
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,Bit_SET);
return 0;
}
int ds1302_write_enable(struct ds1302 *ds1302)
{
uint8_t data=0x00;
return ds1302_write_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_CONTROL,&data,1);
}
int ds1302_write_disable(struct ds1302 *ds1302)
{
uint8_t data=0x80;
return ds1302_write_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_CONTROL,&data,1);
}
uint64_t ds1302_get_time_s(struct ds1302 *ds1302)
{
uint8_t time_bcd[8];
struct time_clock_date date;
if(ds1302_read_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_ALL,time_bcd,8)!=0){
return 0;
}
if((time_bcd[DS1302_REG_ADDR_SECONDS]&DS1302_REG_SECONDS_CH_MASK)!=0){
return 0;
}
date.sec=(time_bcd[DS1302_REG_ADDR_SECONDS]>>4)*10+(time_bcd[DS1302_REG_ADDR_SECONDS]&0x0f);
date.min=(time_bcd[DS1302_REG_ADDR_MINUTES]>>4)*10+(time_bcd[DS1302_REG_ADDR_MINUTES]&0x0f);
if((time_bcd[DS1302_REG_ADDR_HOUR]&DS1302_REG_HOUR_12_N24_MASK)!=0){
date.hour=((time_bcd[DS1302_REG_ADDR_HOUR]>>4)&1)*10+(time_bcd[DS1302_REG_ADDR_HOUR]&0x0f);
if(date.hour==12){
date.hour-=12;
}
date.hour+=((time_bcd[DS1302_REG_ADDR_HOUR]>>5)&1)*12;
}
else{
date.hour=(time_bcd[DS1302_REG_ADDR_HOUR]>>4)*10+(time_bcd[DS1302_REG_ADDR_HOUR]&0x0f);
}
date.mday=(time_bcd[DS1302_REG_ADDR_DATE]>>4)*10+(time_bcd[DS1302_REG_ADDR_DATE]&0x0f);
date.mon=(time_bcd[DS1302_REG_ADDR_MONTH]>>4)*10+(time_bcd[DS1302_REG_ADDR_MONTH]&0x0f);
date.wday=0;
date.year=(time_bcd[DS1302_REG_ADDR_YEAR]>>4)*10+(time_bcd[DS1302_REG_ADDR_YEAR]&0x0f)+2000;
return time_clock_date_to_time(&date,8);
}
int ds1302_set_time_s(struct ds1302 *ds1302,uint64_t time_s)
{
int ret;
uint8_t time_bcd[8];
struct time_clock_date date;
if((ret=ds1302_write_enable(ds1302))!=0){
return ret;
}
time_clock_time_to_date(time_s,&date,8);
time_bcd[DS1302_REG_ADDR_SECONDS]=((date.sec/10)<<4)+(date.sec%10);
time_bcd[DS1302_REG_ADDR_MINUTES]=((date.min/10)<<4)+(date.min%10);
time_bcd[DS1302_REG_ADDR_HOUR]=((date.hour/10)<<4)+(date.hour%10);
time_bcd[DS1302_REG_ADDR_DATE]=((date.mday/10)<<4)+(date.mday%10);
time_bcd[DS1302_REG_ADDR_MONTH]=((date.mon/10)<<4)+(date.mon%10);
time_bcd[DS1302_REG_ADDR_DAY]=((date.wday/10)<<4)+(date.wday%10)+1;
time_bcd[DS1302_REG_ADDR_YEAR]=(((date.year-2000)/10)<<4)+((date.year-2000)%10);
time_bcd[DS1302_REG_ADDR_CONTROL]=0x80;
ret=ds1302_write_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_ALL,time_bcd,8);
ds1302_write_disable(ds1302);
return ret;
}
int ds1302_read_ram(struct ds1302 *ds1302,uint8_t addr,uint8_t *bytes,uint8_t num)
{
return ds1302_read_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_RAM_MASK,addr,bytes,num);
}
int ds1302_write_ram(struct ds1302 *ds1302,uint8_t addr,uint8_t *bytes,uint8_t num)
{
int ret;
if((ret=ds1302_write_enable(ds1302))!=0){
return ret;
}
ret=ds1302_write_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_RAM_MASK,addr,bytes,num);
ds1302_write_disable(ds1302);
return ret;
}
int ds1302_set_charger(struct ds1302 *ds1302,enum ds1302_trickle_charger_tcs tcs,enum ds1302_trickle_charger_ds ds,enum ds1302_trickle_charger_rs rs)
{
int ret;
uint8_t data=tcs|ds|rs;
if((ret=ds1302_write_enable(ds1302))!=0){
return ret;
}
ret=ds1302_write_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_TRICKLE_CHARGER,&data,1);
ds1302_write_disable(ds1302);
return ret;
}
/*
uint8_t time_bcd[8] ={0};
log_i( "before : %d %d %d %d %d %d %d %d " ,
time_bcd[0] ,time_bcd[1] ,time_bcd[2] ,time_bcd[3],time_bcd[4] ,time_bcd[5] ,time_bcd[6] ,time_bcd[7]);
int a = ds1302_read_bytes(&ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_ALL,time_bcd,8);
// ds1302->time_base 保存了 时间戳 秒数 毫秒数
if(a!=0){
log_i("read error %d", a);
}else{
log_i("read ok");
}
log_i( "after : %d %d %d %d %d %d %d %d " ,
time_bcd[0] ,time_bcd[1] ,time_bcd[2] ,time_bcd[3],time_bcd[4] ,time_bcd[5] ,time_bcd[6] ,time_bcd[7]);
// 修改 ds1302 时间
a = ds1302_set_time_s(&ds1302,1669961325);
log_i("a = %d", a);
uint8_t tmp;
a = ds1302_read_ram(&ds1302,0x00,&tmp,1);
log_i("ds1302_read_ram = %d %d", a, tmp);
log_i( "readout : %d %d %d %d %d %d %d %d " ,
time_bcd[0] ,time_bcd[1] ,time_bcd[2] ,time_bcd[3],time_bcd[4] ,time_bcd[5] ,time_bcd[6] ,time_bcd[7]);
*/
#endif

@ -0,0 +1,178 @@
#include "stmflash.h"
//读取指定地址的字(32位数据)
//faddr:读地址
//返回值:对应数据.
uint32_t STMFLASH_ReadWord(uint32_t faddr)
{
return *(volatile uint32_t*)faddr;
}
//获取某个地址所在的flash扇区
//addr:flash地址
//返回值:0~11,即addr所在的扇区
uint8_t STMFLASH_GetFlashSector(uint32_t addr)
{
if(addr<ADDR_FLASH_SECTOR_1)return FLASH_SECTOR_0;
else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_SECTOR_1;
else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_SECTOR_2;
else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_SECTOR_3;
else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_SECTOR_4;
else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_SECTOR_5;
else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_SECTOR_6;
else if(addr<ADDR_FLASH_SECTOR_8)return FLASH_SECTOR_7;
else if(addr<ADDR_FLASH_SECTOR_9)return FLASH_SECTOR_8;
else if(addr<ADDR_FLASH_SECTOR_10)return FLASH_SECTOR_9;
else if(addr<ADDR_FLASH_SECTOR_11)return FLASH_SECTOR_10;
return FLASH_SECTOR_11;
}
//从指定地址开始写入指定长度的数据
//特别注意:因为STM32F4的扇区实在太大,没办法本地保存扇区数据,所以本函数
// 写地址如果非0XFF,那么会先擦除整个扇区且不保存扇区数据.所以
// 写非0XFF的地址,将导致整个扇区数据丢失.建议写之前确保扇区里
// 没有重要数据,最好是整个扇区先擦除了,然后慢慢往后写.
//该函数对OTP区域也有效!可以用来写OTP区!
//OTP区域地址范围:0X1FFF7800~0X1FFF7A0F(注意:最后16字节,用于OTP数据块锁定,别乱写!!)
//WriteAddr:起始地址(此地址必须为4的倍数!!)
//pBuffer:数据指针
//NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
#if STM32_FSeries_TYPE == STM32_F4XX
void STMFLASH_Write(uint32_t WriteAddr,uint32_t *pBuffer,uint32_t NumToWrite)
{
FLASH_EraseInitTypeDef FlashEraseInit;
HAL_StatusTypeDef FlashStatus=HAL_OK;
uint32_t SectorError=0;
uint32_t addrx=0;
uint32_t endaddr=0;
if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return; //非法地址
HAL_FLASH_Unlock(); //解锁
addrx=WriteAddr; //写入的起始地址
endaddr=WriteAddr+NumToWrite*4; //写入的结束地址
if(addrx<0X1FFF0000)
{
while(addrx<endaddr) //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
{
if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区
{
FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS; //擦除类型,扇区擦除
FlashEraseInit.Sector=STMFLASH_GetFlashSector(addrx); //要擦除的扇区
FlashEraseInit.NbSectors=1; //一次只擦除一个扇区
FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3; //电压范围,VCC=2.7~3.6V之间!!
if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK)
{
break;//发生错误了
}
}else addrx+=4;
FLASH_WaitForLastOperation(FLASH_WAITETIME); //等待上次操作完成
}
}
FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME); //等待上次操作完成
if(FlashStatus==HAL_OK)
{
while(WriteAddr<endaddr)//写数据
{
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,WriteAddr,*pBuffer)!=HAL_OK)//写入数据
{
break; //写入异常
}
WriteAddr+=4;
pBuffer++;
}
}
HAL_FLASH_Lock(); //上锁
}
#endif
// #if STM32_FSeries_TYPE == STM32_F1XX // 103 系列的写,擦除页
// #if STM32_FLASH_SIZE<256
// #define STM_SECTOR_SIZE 1024 //字节
// #else
// #define STM_SECTOR_SIZE 2048
// #endif
// uint16_t STMFLASH_BUF[STM_SECTOR_SIZE/2];//最多是2K字节
// void STMFLASH_Write(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite)
// {
// uint32_t secpos; //扇区地址
// uint16_t secoff; //扇区内偏移地址(16位字计算)
// uint16_t secremain; //扇区内剩余地址(16位字计算)
// uint16_t i;
// uint32_t offaddr; //去掉0X08000000后的地址
// if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
// HAL_FLASH_Unlock(); //解锁
// offaddr=WriteAddr-STM32_FLASH_BASE; //实际偏移地址.
// secpos=offaddr/STM_SECTOR_SIZE; //扇区地址 0~127 for STM32F103RBT6
// secoff=(offaddr%STM_SECTOR_SIZE)/2; //在扇区内的偏移(2个字节为基本单位.)
// secremain=STM_SECTOR_SIZE/2-secoff; //扇区剩余空间大小
// if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
// while(1)
// {
// STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
// for(i=0;i<secremain;i++) //校验数据
// {
// if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除
// }
// if(i<secremain) //需要擦除
// {
// FLASH_PageErase(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE); //擦除这个扇区
// FLASH_WaitForLastOperation(FLASH_WAITETIME); //等待上次操作完成
// CLEAR_BIT(FLASH->CR, FLASH_CR_PER); //清除CR寄存器的PER位,此操作应该在FLASH_PageErase()中完成!
// //但是HAL库里面并没有做,应该是HAL库bug!
// for(i=0;i<secremain;i++)//复制
// {
// STMFLASH_BUF[i+secoff]=pBuffer[i];
// }
// STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区
// }else
// {
// FLASH_WaitForLastOperation(FLASH_WAITETIME); //等待上次操作完成
// STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.
// }
// if(NumToWrite==secremain)break;//写入结束了
// else//写入未结束
// {
// secpos++; //扇区地址增1
// secoff=0; //偏移位置为0
// pBuffer+=secremain; //指针偏移
// WriteAddr+=secremain*2; //写地址偏移(16位数据地址,需要*2)
// NumToWrite-=secremain; //字节(16位)数递减
// if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
// else secremain=NumToWrite;//下一个扇区可以写完了
// }
// };
// HAL_FLASH_Lock(); //上锁
// }
// #endif
//从指定地址开始读出指定长度的数据
//ReadAddr:起始地址
//pBuffer:数据指针
//NumToRead:字(32位)数
void STMFLASH_Read(uint32_t ReadAddr,uint32_t *pBuffer,uint32_t NumToRead)
{
uint32_t i;
for(i=0;i<NumToRead;i++)
{
pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4个字节.
ReadAddr+=4;//偏移4个字节.
}
}
int STMFLASH_ErasePage(uint32_t Page_Address)
{
return FLASH_ErasePage( Page_Address);
}
//////////////////////////////////////////测试用///////////////////////////////////////////
//WriteAddr:起始地址
//WriteData:要写入的数据
void Test_Write(uint32_t WriteAddr,uint32_t WriteData)
{
STMFLASH_Write(WriteAddr,&WriteData,1);//写入一个字
}

@ -0,0 +1,488 @@
/**
* @file convert.c
* @author Chen Jihang (embedded@eseaoptics.com)
* @brief
* @version 1.0
* @date 2022-07-18
*
* @copyright ESEA (c) 2022
*
*/
#include "convert.h"
#include "math.h"
/**
* @brief uint64_t类型数据转换为字符串
*
* @param integer
* @param str
* @param length
* @return unsigned :使 :0
*/
unsigned convert_u64_to_s(uint64_t integer,char *str,unsigned length)
{
unsigned i;
unsigned j=length-1;
while(j<length){
str[j]=integer%10+'0';
integer/=10;
if(integer==0)
break;
j--;
}
if(integer!=0)
return 0;
for(i=0;j<length;i++,j++){
str[i]=str[j];
}
return i;
}
/**
* @brief 64bit无符号整型数据
*
* @param integer
* @param str
* @param length
* @return unsigned : :0
*/
unsigned convert_s_to_u64(uint64_t *integer,char *str,unsigned length)
{
unsigned i;
*integer=0;
for(i=0;i<length;i++){
if(str[i]<'0' || str[i]>'9'){
break;
}
*integer*=10;
*integer+=str[i]-'0';
}
return i;
}
/**
* @brief int64_t类型数据转换为字符串
*
* @param integer
* @param str
* @param length
* @return unsigned :使 :0
*/
unsigned convert_i64_to_s(int64_t integer,char *str,unsigned length)
{
unsigned i=0,j;
if(integer<0){
integer=-integer;
str[i++]='-';
}
j=convert_u64_to_s(integer,&str[i],length-i);
return (j==0)?(0):(j+i);
}
/**
* @brief 64bit有符号整型数据
*
* @param integer
* @param str
* @param length
* @return unsigned : :0
*/
unsigned convert_s_to_i64(int64_t *integer,char *str,unsigned length)
{
unsigned i=0,j;
uint64_t tmp;
if(str[0]=='-'){
i++;
}
j=convert_s_to_u64(&tmp,&str[i],length-i);
if((tmp&((uint64_t)1<<(sizeof(tmp)*8-1)))!=0){
return 0;
}
*integer=(int64_t)tmp;
if(str[0]=='-'){
*integer=-*integer;
}
return (j==0)?(0):(j+i);
}
/**
* @brief uint32_t类型数据转换为字符串
*
* @param integer
* @param str
* @param length
* @return unsigned :使 :0
*/
unsigned convert_u32_to_s(uint32_t integer,char *str,unsigned length)
{
unsigned i;
unsigned j=length-1;
while(j<length){
str[j]=integer%10+'0';
integer/=10;
if(integer==0)
break;
j--;
}
if(integer!=0)
return 0;
for(i=0;j<length;i++,j++){
str[i]=str[j];
}
return i;
}
/**
* @brief 32bit无符号整型数据
*
* @param integer
* @param str
* @param length
* @return unsigned : :0
*/
unsigned convert_s_to_u32(uint32_t *integer,char *str,unsigned length)
{
unsigned i;
*integer=0;
for(i=0;i<length;i++){
if(str[i]<'0' || str[i]>'9'){
break;
}
*integer*=10;
*integer+=str[i]-'0';
}
return i;
}
/**
* @brief int32_t类型数据转换为字符串
*
* @param integer
* @param str
* @param length
* @return unsigned :使 :0
*/
unsigned convert_i32_to_s(int32_t integer,char *str,unsigned length)
{
unsigned i=0,j;
if(integer<0){
integer=-integer;
str[i++]='-';
}
j=convert_u32_to_s(integer,&str[i],length-i);
return (j==0)?(0):(j+i);
}
/**
* @brief 32bit有符号整型数据
*
* @param integer
* @param str
* @param length
* @return unsigned : :0
*/
unsigned convert_s_to_i32(int32_t *integer,char *str,unsigned length)
{
unsigned i=0,j;
uint32_t tmp;
if(str[0]=='-'){
i++;
}
j=convert_s_to_u32(&tmp,&str[i],length-i);
if((tmp&((uint32_t)1<<(sizeof(tmp)*8-1)))!=0){
return 0;
}
*integer=(int32_t)tmp;
if(str[0]=='-'){
*integer=-*integer;
}
return (j==0)?(0):(j+i);
}
/**
* @brief double类型数据转换为字符串
*
* @param double_float
* @param str
* @param length
* @param sig ,465
* @return unsigned :使 :0
*/
unsigned convert_d2s(double double_float,char *str,unsigned length,unsigned sig)
{
unsigned i=0,j;
uint64_t tmp;
unsigned sig_con;
unsigned remainder;
if(sig>16){
sig=16;
}
if(length<sig+3){
return 0;
}
if(double_float<0){
str[i++]='-';
double_float=-double_float;
}
tmp=double_float;
j=convert_u64_to_s(tmp,&str[i],length-i);
if(j==0){
return 0;
}
i+=j;
sig_con=j;
if(tmp==0){
sig_con=0;
}
str[i++]='.';
double_float-=tmp;
tmp=0;
for(;sig_con<=sig;){
double_float*=10;
remainder=double_float;
if(remainder==0 && sig_con==0){
str[i++]=remainder+'0';
}
else{
sig_con++;
}
tmp=tmp*10+remainder;
double_float-=remainder;
}
remainder=tmp%10;
tmp/=10;
if(remainder>5){
remainder=1;
}
else if(remainder<5){
remainder=0;
}
else{
if((tmp&1)==1){
remainder=1;
}
else{
remainder=0;
}
}
tmp+=remainder;
j=convert_u64_to_s(tmp,&str[i],length-i);
return (j==0)?(0):(i+j);
}
/**
* @brief double型数据
*
* @param double_float
* @param str
* @param length
* @param sig
* @return unsigned : :0
*/
unsigned convert_s2d(double *double_float,char *str,unsigned length,unsigned sig)
{
uint64_t tmp_u64;
int64_t mantissa;
int32_t exp=0;
int32_t tmp_i32;
unsigned sig_con=0;
unsigned i=0,j;
if(sig>16){
sig=16;
}
if(str[i]=='-'){
i++;
}
j=convert_s_to_u64(&tmp_u64,&str[i],sig>length-i?length-i:sig);
if(j==0){
return 0;
}
i+=j;
if(tmp_u64!=0){
sig_con+=j;
}
mantissa=tmp_u64;
if(sig_con<sig){
if(i<length && str[i]=='.'){
i++;
for(j=0;j<length-i&&sig_con<sig;j++,sig_con++){
if(str[i+j]>='0' && str[i+j]<='9'){
mantissa*=10;
mantissa+=str[i+j]-'0';
}
else{
break;
}
}
if(j==0){
return 0;
}
i+=j;
exp=-j;
for(j=0;;j++){
if(i+j>=length){
*double_float=mantissa;
*double_float*=pow(10,exp);
if(str[0]=='-'){
*double_float=-*double_float;
}
return i+j;
}
if(str[i+j]>'9' || str[i+j]<'0'){
break;
}
}
i+=j;
}
if(i<length && (str[i]=='e' || str[i]=='E')){
i++;
j=convert_s_to_i32(&tmp_i32,&str[i],length-i);
if(j==0){
return 0;
}
exp+=tmp_i32;
if(exp>1000 || exp<-1000){
return 0;
}
i+=j;
}
}
*double_float=mantissa;
*double_float*=pow(10,exp);
if(str[0]=='-'){
*double_float=-*double_float;
}
return i;
}
/**
* @brief unsigned数据转换为字符串
*
* @param integer
* @param str
* @param length
* @return unsigned
*/
unsigned convert_u2s(unsigned integer,char *str,unsigned length)
{
unsigned i;
unsigned j=length-1;
while(j<length){
str[j]=integer%10+'0';
integer/=10;
if(integer==0)
break;
j--;
}
if(integer!=0)
return 0;
for(i=0;j<length;i++,j++){
str[i]=str[j];
}
return i;
}
/**
* @brief unsigned
*
* @param str
* @param length
* @param integer
* @return unsigned
*/
unsigned convert_s2u(unsigned *integer,char *str,unsigned length)
{
unsigned i;
*integer=0;
for(i=0;i<length;i++){
if(str[i]<'0' || str[i]>'9'){
break;
}
*integer*=10;
*integer+=str[i]-'0';
}
return i;
}
/**
* @brief int数据转换为字符串
*
* @param integer
* @param str
* @param length
* @return unsigned
*/
unsigned convert_i2s(int integer,char *str,unsigned length)
{
unsigned i=0,j;
if(integer<0){
integer=-integer;
str[i++]='-';
}
j=convert_u2s(integer,&str[i],length-i);
return (j==0)?(0):(j+i);
}
/**
* @brief int
*
* @param integer
* @param str
* @param length
* @return unsigned
*/
unsigned convert_s2i(int *integer,char *str,unsigned length)
{
unsigned i=0,j;
unsigned tmp;
if(str[0]=='-'){
i++;
}
j=convert_s2u(&tmp,&str[i],length-i);
if((tmp&((unsigned)1<<(sizeof(tmp)*8-1)))!=0){
return 0;
}
*integer=(int)tmp;
if(str[0]=='-'){
*integer=-*integer;
}
return (j==0)?(0):(j+i);
}
/**
* @brief ip地址转换为整型形式的ip地址
*
* @param ip ip地址的位置的指针
* @param ips ip地址
* @param length
* @return unsigned
*/
unsigned convert_ips2ip(uint32_t *ip,char *ips,unsigned length)
{
int i=0;
unsigned tmp;
*ip=0;
i+=convert_s2u(&tmp,&ips[i],length-i);
if(ips[i++]!='.'){
return 0;
}
*ip|=((tmp&0xff)<<24);
i+=convert_s2u(&tmp,&ips[i],length-i);
if(ips[i++]!='.'){
return 0;
}
*ip|=((tmp&0xff)<<16);
i+=convert_s2u(&tmp,&ips[i],length-i);
if(ips[i++]!='.'){
return 0;
}
*ip|=((tmp&0xff)<<8);
i+=convert_s2u(&tmp,&ips[i],length-i);
*ip|=(tmp&0xff);
return i;
}
/**
* @brief ip地址转换为字符串形式的ip地址
*
* @param ip ip地址
* @param ips ip地址的缓冲区
* @param length
* @return unsigned
*/
unsigned convert_ip2ips(uint32_t ip,char *ips,unsigned length)
{
int i=0;
i+=convert_u2s((ip>>24)&0xff,&ips[i],length-i);
ips[i++]='.';
i+=convert_u2s((ip>>16)&0xff,&ips[i],length-i);
ips[i++]='.';
i+=convert_u2s((ip>>8)&0xff,&ips[i],length-i);
ips[i++]='.';
i+=convert_u2s(ip&0xff,&ips[i],length-i);
return i;
}

@ -0,0 +1,32 @@
/**
* @file convert.h
* @author Chen Jihang (embedded@eseaoptics.com)
* @brief
* @version 1.0
* @date 2022-07-18
*
* @copyright ESEA (c) 2022
*
*/
#ifndef CONVERT_H_
#define CONVERT_H_
#include <stdint.h>
unsigned convert_u64_to_s(uint64_t integer,char *str,unsigned length);
unsigned convert_s_to_u64(uint64_t *integer,char *str,unsigned length);
unsigned convert_i64_to_s(int64_t integer,char *str,unsigned length);
unsigned convert_s_to_i64(int64_t *integer,char *str,unsigned length);
/* 数字 1001 -- 0x31303031*/
unsigned convert_u32_to_s(uint32_t integer,char *str,unsigned length);
unsigned convert_s_to_u32(uint32_t *integer,char *str,unsigned length);
unsigned convert_i32_to_s(int32_t integer,char *str,unsigned length);
unsigned convert_s_to_i32(int32_t *integer,char *str,unsigned length);
unsigned convert_d2s(double double_float,char *str,unsigned length,unsigned sig);
unsigned convert_s2d(double *double_float,char *str,unsigned length,unsigned sig);
unsigned convert_i2s(int integer,char *str,unsigned length);
unsigned convert_s2i(int *integer,char *str,unsigned length);
unsigned convert_u2s(unsigned integer,char *str,unsigned length);
unsigned convert_s2u(unsigned *integer,char *str,unsigned length);
unsigned convert_ips2ip(uint32_t *ip,char *ips,unsigned length);
unsigned convert_ip2ips(uint32_t ip,char *ips,unsigned length);
#endif

@ -0,0 +1,663 @@
/**
* @file file_list.c
* @author Chen Jihang (embedded@eseaoptics.com)
* @brief
* @version 1.0
* @date 2022-08-25
*
* @copyright ESEA (c) 2020
*
*/
#include "file_list.h"
/**
* @brief
*
* @param p_list file_list描述符
* @param p_head
* @return int 0: 0:
*/
int file_list_get_head(struct file_list *p_list,struct file_list_head *p_head)
{
FRESULT ret;
UINT btr;
UINT br;
ret=f_lseek(&p_list->fp,0);
if(ret!=FR_OK){
return -1;
}
btr=sizeof(struct file_list_head);
ret=f_read(&p_list->fp,p_head,btr,&br);
if(ret!=FR_OK || btr!=br){
return -2;
}
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_head
* @return int 0: 0:
*/
int file_list_put_head(struct file_list *p_list,struct file_list_head *p_head)
{
FRESULT ret;
UINT btw;
UINT bw;
ret=f_lseek(&p_list->fp,0);
if(ret!=FR_OK){
return -1;
}
btw=sizeof(struct file_list_head);
ret=f_write(&p_list->fp,p_head,btw,&bw);
if(ret!=FR_OK || btw!=bw){
return -2;
}
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @param file_pointer
* @return int 0: 0:
*/
int file_list_get_node(struct file_list *p_list,struct file_list_node *p_node,uint64_t file_pointer)
{
FRESULT ret;
UINT btr;
UINT br;
ret=f_lseek(&p_list->fp,file_pointer);
if(ret!=FR_OK){
return -1;
}
btr=sizeof(struct file_list_node);
ret=f_read(&p_list->fp,p_node,btr,&br);
if(ret!=FR_OK || btr!=br){
return -2;
}
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @return int 0: 0:
*/
int file_list_put_node(struct file_list *p_list,struct file_list_node *p_node)
{
FRESULT ret;
UINT btw;
UINT bw;
ret=f_lseek(&p_list->fp,p_node->file_pointer_this);
if(ret!=FR_OK){
return -1;
}
btw=sizeof(struct file_list_node);
ret=f_write(&p_list->fp,p_node,btw,&bw);
if(ret!=FR_OK || btw!=bw){
return -2;
}
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @param p_data
* @param base_addr
* @param size
* @return int 0: 0:
*/
int file_list_get_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t *p_data,uint64_t base_addr,uint64_t size)
{
FRESULT ret;
UINT btr;
UINT br;
ret=f_lseek(&p_list->fp,p_node->file_pointer_this+sizeof(struct file_list_node)+base_addr);
if(ret!=FR_OK){
return -1;
}
btr=size;
ret=f_read(&p_list->fp,p_data,btr,&br);
if(ret!=FR_OK || btr!=br){
return -2;
}
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @param p_data
* @param base_addr
* @param size
* @return int 0: 0:
*/
int file_list_put_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t *p_data,uint64_t base_addr,uint64_t size)
{
FRESULT ret;
UINT btw;
UINT bw;
ret=f_lseek(&p_list->fp,p_node->file_pointer_this+sizeof(struct file_list_node)+base_addr);
if(ret!=FR_OK){
return -1;
}
btw=size;
ret=f_write(&p_list->fp,p_data,btw,&bw);
if(ret!=FR_OK || btw!=bw){
return -2;
}
return 0;
}
/**
* @brief 使
*
* @param p_list file_list描述符
* @param p_node
* @param data_to_fill
* @return int 0: 0:
*/
int file_list_fill_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t data_to_fill)
{
FRESULT ret;
UINT btw;
UINT bw;
uint64_t i;
ret=f_lseek(&p_list->fp,p_node->file_pointer_this+sizeof(struct file_list_node));
if(ret!=FR_OK){
return -1;
}
for(i=0;i<p_node->size;i++){
btw=1;
ret=f_write(&p_list->fp,&data_to_fill,btw,&bw);
if(ret!=FR_OK || btw!=bw){
return -2;
}
}
return 0;
}
/**
* @brief 使
*
* @param p_list file_list描述符
* @param path
* @return struct file_list* :p_list :NULL
*/
struct file_list *file_list_create(struct file_list *p_list,char *path)
{
FRESULT ret;
ret=f_open(&p_list->fp,path,FA_CREATE_ALWAYS|FA_READ|FA_WRITE);
if(ret!=FR_OK){
return NULL;
}
p_list->list_head.file_pointer_used_first=0;
p_list->list_head.file_pointer_used_last=0;
p_list->list_head.file_pointer_free_first=sizeof(struct file_list_head);
p_list->list_head.file_pointer_free_last=p_list->list_head.file_pointer_free_first;
p_list->free_node_now.file_pointer_last=0;
p_list->free_node_now.file_pointer_next=0;
p_list->free_node_now.file_pointer_this=p_list->list_head.file_pointer_free_last;
p_list->free_node_now.size=0xffffffffffffffff;
p_list->used_node_now.size_used=0;
p_list->used_node_now.file_pointer_last=0;
p_list->used_node_now.file_pointer_next=0;
p_list->used_node_now.file_pointer_this=0;
p_list->used_node_now.size=0;
p_list->used_node_now.size_used=0;
if(file_list_put_head(p_list,&p_list->list_head)!=0){
return NULL;
}
if(file_list_put_node(p_list,&p_list->free_node_now)!=0){
return NULL;
}
f_sync(&p_list->fp);
return p_list;
}
/**
* @brief 使,
*
* @param p_list file_list描述符
* @param path
* @return struct file_list* :p_list :NULL
*/
struct file_list *file_list_open(struct file_list *p_list,char *path)
{
FRESULT ret;
ret=f_open(&p_list->fp,path,FA_READ|FA_WRITE);
if(ret!=FR_OK){
return file_list_create(p_list,path);
}
if(file_list_get_head(p_list,&p_list->list_head)!=0){
return NULL;
}
if(p_list->list_head.file_pointer_used_first!=0){
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->list_head.file_pointer_used_first)!=0){
return NULL;
}
}
else{
p_list->used_node_now.file_pointer_last=0;
p_list->used_node_now.file_pointer_next=0;
p_list->used_node_now.file_pointer_this=0;
p_list->used_node_now.size=0;
}
if(file_list_get_node(p_list,&p_list->free_node_now,p_list->list_head.file_pointer_free_first)!=0){
return NULL;
}
f_sync(&p_list->fp);
return p_list;
}
/**
* @brief
*
* @param p_list file_list描述符
* @return int 0: 0:
*/
int file_list_close(struct file_list *p_list)
{
FRESULT ret;
ret=f_sync(&p_list->fp);
if(ret!=FR_OK){
return -1;
}
ret=f_close(&p_list->fp);
if(ret!=FR_OK){
return -1;
}
return 0;
}
/**
* @brief 使
*
* @param p_list file_list描述符
* @param p_free_node 使
* @return int 0: 0:
*/
int file_list_merge_free_node(struct file_list *p_list,struct file_list_node *p_free_node)
{
struct file_list_node last_free_node;
struct file_list_node next_free_node;
struct file_list_node this_free_node;
this_free_node.size=p_free_node->size;
this_free_node.file_pointer_last=p_free_node->file_pointer_last;
this_free_node.file_pointer_next=p_free_node->file_pointer_next;
this_free_node.file_pointer_this=p_free_node->file_pointer_this;
if(p_free_node->file_pointer_last!=0){
if(file_list_get_node(p_list,&last_free_node,p_free_node->file_pointer_last)!=0){
return -1;
}
if(last_free_node.file_pointer_this+last_free_node.size+sizeof(struct file_list_node)==last_free_node.file_pointer_next){
// printf("<Merge [%llX,%llX]-->%llX,Size [%llX,%llX]-->%llX\n",last_free_node.file_pointer_this,this_free_node.file_pointer_this,last_free_node.file_pointer_this,last_free_node.size,this_free_node.size,this_free_node.size+last_free_node.size+sizeof(struct file_list_node));
this_free_node.file_pointer_last=last_free_node.file_pointer_last;
this_free_node.file_pointer_this=last_free_node.file_pointer_this;
this_free_node.size+=last_free_node.size+sizeof(struct file_list_node);
}
}
if(p_free_node->file_pointer_next!=0){
if(file_list_get_node(p_list,&next_free_node,p_free_node->file_pointer_next)!=0){
return -1;
}
if(this_free_node.file_pointer_this+this_free_node.size+sizeof(struct file_list_node)==this_free_node.file_pointer_next){
// printf(">Merge [%llX,%llX]-->%llX,Size [%llX,%llX]-->%llX\n",this_free_node.file_pointer_this,next_free_node.file_pointer_this,this_free_node.file_pointer_this,this_free_node.size,next_free_node.size,this_free_node.size+next_free_node.size+sizeof(struct file_list_node));
this_free_node.file_pointer_next=next_free_node.file_pointer_next;
this_free_node.size+=next_free_node.size+sizeof(struct file_list_node);
if(this_free_node.file_pointer_next!=0){
if(file_list_get_node(p_list,&next_free_node,this_free_node.file_pointer_next)!=0){
return -1;
}
next_free_node.file_pointer_last=this_free_node.file_pointer_this;
if(file_list_put_node(p_list,&next_free_node)!=0){
return -1;
}
}
else{
p_list->list_head.file_pointer_free_last=this_free_node.file_pointer_this;
if(file_list_put_head(p_list,&p_list->list_head)!=0){
return -1;
}
}
}
else{
next_free_node.file_pointer_last=this_free_node.file_pointer_this;
}
}
if(file_list_put_node(p_list,&this_free_node)!=0){
return -1;
}
if(this_free_node.file_pointer_next!=0){
if(file_list_put_node(p_list,&next_free_node)!=0){
return -1;
}
}
p_list->free_node_now.file_pointer_last=this_free_node.file_pointer_last;
p_list->free_node_now.file_pointer_next=this_free_node.file_pointer_next;
p_list->free_node_now.file_pointer_this=this_free_node.file_pointer_this;
p_list->free_node_now.size=this_free_node.size;
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param size
* @return struct file_list_node* : :NULL
*/
struct file_list_node *file_list_alloc(struct file_list *p_list,uint64_t size)
{
struct file_list_node last_free_node;
struct file_list_node this_free_node;
struct file_list_node next_free_node;
uint64_t file_pointer;
this_free_node.file_pointer_last=0;
this_free_node.file_pointer_next=0;
this_free_node.file_pointer_this=0;
this_free_node.size=0;
file_pointer=p_list->list_head.file_pointer_free_first;
do{
last_free_node.file_pointer_last=this_free_node.file_pointer_last;
last_free_node.file_pointer_next=this_free_node.file_pointer_next;
last_free_node.file_pointer_this=this_free_node.file_pointer_this;
last_free_node.size=this_free_node.size;
if(file_list_get_node(p_list,&this_free_node,file_pointer)!=0){
return NULL;
}
file_pointer=this_free_node.file_pointer_next;
}while(this_free_node.size<size);
p_list->used_node_now.size=this_free_node.size;
p_list->free_node_now.file_pointer_last=this_free_node.file_pointer_last;
p_list->free_node_now.file_pointer_next=this_free_node.file_pointer_next;
p_list->free_node_now.file_pointer_this=this_free_node.file_pointer_this;
p_list->free_node_now.size=this_free_node.size;
p_list->used_node_now.file_pointer_this=this_free_node.file_pointer_this;
p_list->used_node_now.file_pointer_next=0;
p_list->used_node_now.size_used=size;
if(this_free_node.file_pointer_last!=0){
if(file_list_get_node(p_list,&last_free_node,this_free_node.file_pointer_last)!=0){
return NULL;
}
if(this_free_node.size>=size+sizeof(struct file_list_node)){
p_list->free_node_now.file_pointer_last=last_free_node.file_pointer_this;
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
last_free_node.file_pointer_next=p_list->free_node_now.file_pointer_this;
}
else{
last_free_node.file_pointer_next=this_free_node.file_pointer_next;
}
if(file_list_put_node(p_list,&last_free_node)!=0){
return NULL;
}
}
else{
if(this_free_node.size>=size+sizeof(struct file_list_node)){
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
p_list->list_head.file_pointer_free_first=p_list->free_node_now.file_pointer_this;
}
else{
p_list->list_head.file_pointer_free_first=this_free_node.file_pointer_next;
}
}
if(this_free_node.file_pointer_next!=0){
if(file_list_get_node(p_list,&next_free_node,this_free_node.file_pointer_next)!=0){
return NULL;
}
if(this_free_node.size>=size+sizeof(struct file_list_node)){
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
p_list->free_node_now.file_pointer_next=next_free_node.file_pointer_this;
next_free_node.file_pointer_last=p_list->free_node_now.file_pointer_this;
}
else{
next_free_node.file_pointer_last=this_free_node.file_pointer_last;
}
if(file_list_put_node(p_list,&next_free_node)!=0){
return NULL;
}
}
else{
if(this_free_node.size>=size+sizeof(struct file_list_node)){
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
p_list->list_head.file_pointer_free_last=p_list->free_node_now.file_pointer_this;
}
else{
p_list->list_head.file_pointer_free_last=this_free_node.file_pointer_last;
}
}
if(this_free_node.size>=size+sizeof(struct file_list_node)){
p_list->used_node_now.size=size;
p_list->free_node_now.size-=size+sizeof(struct file_list_node);
if(file_list_put_node(p_list,&p_list->free_node_now)!=0){
return NULL;
}
}
if(file_list_put_head(p_list,&p_list->list_head)!=0){
return NULL;
}
return &p_list->used_node_now;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node_to_free
* @return int 0: 0:
*/
int file_list_free_node(struct file_list *p_list,struct file_list_node *p_node_to_free)
{
struct file_list_node last_free_node;
struct file_list_node next_free_node;
uint64_t file_pointer;
next_free_node.file_pointer_this=0;
next_free_node.file_pointer_last=0;
next_free_node.size=0;
file_pointer=p_list->list_head.file_pointer_free_first;
do{
last_free_node.file_pointer_last=next_free_node.file_pointer_last;
last_free_node.file_pointer_this=next_free_node.file_pointer_this;
last_free_node.size=next_free_node.size;
if(file_list_get_node(p_list,&next_free_node,file_pointer)!=0){
return -1;
}
file_pointer=next_free_node.file_pointer_next;
}while(next_free_node.file_pointer_this<p_node_to_free->file_pointer_this);
if(last_free_node.file_pointer_this!=0){
last_free_node.file_pointer_next=p_node_to_free->file_pointer_this;
if(file_list_put_node(p_list,&last_free_node)!=0){
return -1;
}
}
else{
p_list->list_head.file_pointer_free_first=p_node_to_free->file_pointer_this;
}
next_free_node.file_pointer_last=p_node_to_free->file_pointer_this;
p_node_to_free->file_pointer_last=last_free_node.file_pointer_this;
p_node_to_free->file_pointer_next=next_free_node.file_pointer_this;
if(file_list_put_node(p_list,&next_free_node)!=0){
return -1;
}
if(file_list_put_node(p_list,p_node_to_free)!=0){
return -1;
}
return file_list_merge_free_node(p_list,p_node_to_free);
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_used_node
* @return int 0: 0:
*/
int file_list_del_node(struct file_list *p_list,struct file_list_node *p_used_node)
{
struct file_list_node last_used_node;
struct file_list_node next_used_node;
if(p_used_node->file_pointer_last!=0){
if(file_list_get_node(p_list,&last_used_node,p_used_node->file_pointer_last)!=0){
return -1;
}
last_used_node.file_pointer_next=p_used_node->file_pointer_next;
if(file_list_put_node(p_list,&last_used_node)!=0){
return -1;
}
}
else{
p_list->list_head.file_pointer_used_first=p_used_node->file_pointer_next;
}
if(p_used_node->file_pointer_next!=0){
if(file_list_get_node(p_list,&next_used_node,p_used_node->file_pointer_next)!=0){
return -1;
}
next_used_node.file_pointer_last=p_used_node->file_pointer_last;
if(file_list_put_node(p_list,&next_used_node)!=0){
return -1;
}
}
else{
p_list->list_head.file_pointer_used_last=p_used_node->file_pointer_last;
}
if(file_list_put_head(p_list,&p_list->list_head)!=0){
return -1;
}
return file_list_free_node(p_list,p_used_node);
}
/**
* @brief
*
* @param p_list file_list描述符
* @param size
* @return struct file_list_node* : :NULL
*/
struct file_list_node *file_list_add_node(struct file_list *p_list,uint64_t size)
{
struct file_list_node last_used_node;
struct file_list_node *pnode;
pnode=file_list_alloc(p_list,size);
if(pnode==NULL){
return NULL;
}
pnode->file_pointer_last=0;
pnode->file_pointer_next=0;
if(p_list->list_head.file_pointer_used_last!=0){
pnode->file_pointer_last=p_list->list_head.file_pointer_used_last;
if(file_list_get_node(p_list,&last_used_node,pnode->file_pointer_last)!=0){
return NULL;
}
last_used_node.file_pointer_next=pnode->file_pointer_this;
if(file_list_put_node(p_list,&last_used_node)!=0){
return NULL;
}
}
p_list->list_head.file_pointer_used_last=pnode->file_pointer_this;
if(p_list->list_head.file_pointer_used_first==0){
p_list->list_head.file_pointer_used_first=pnode->file_pointer_this;
}
if(file_list_put_head(p_list,&p_list->list_head)!=0){
return NULL;
}
if(file_list_put_node(p_list,pnode)!=0){
return NULL;
}
f_sync(&p_list->fp);
return pnode;
}
/**
* @brief
*
* @param p_list file_list描述符
* @return struct file_list_node* : :NULL
*/
struct file_list_node *file_list_get_first_node(struct file_list *p_list)
{
if(p_list->list_head.file_pointer_used_first==0){
return NULL;
}
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->list_head.file_pointer_used_first)!=0){
return NULL;
}
return &p_list->used_node_now;
}
/**
* @brief
*
* @param p_list file_list描述符
* @return struct file_list_node* : :NULL
*/
struct file_list_node *file_list_get_next_node(struct file_list *p_list)
{
if(p_list->used_node_now.file_pointer_next==0){
return NULL;
}
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->used_node_now.file_pointer_next)!=0){
return NULL;
}
return &p_list->used_node_now;
}
/**
* @brief
*
* @param p_list file_list描述符
* @return struct file_list_node* : :NULL
*/
struct file_list_node *file_list_get_last_node(struct file_list *p_list)
{
if(p_list->used_node_now.file_pointer_last==0){
return NULL;
}
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->used_node_now.file_pointer_last)!=0){
return NULL;
}
return &p_list->used_node_now;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @return uint64_t
*/
uint64_t file_list_get_node_size(struct file_list *p_list,struct file_list_node *p_node)
{
return p_node->size_used;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @param buf
* @param base_addr
* @param size
* @return uint64_t
*/
uint64_t file_list_get_node_data(struct file_list *p_list,struct file_list_node *p_node,void *buf,uint64_t base_addr,uint64_t size)
{
size=(base_addr+size>p_node->size_used)?p_node->size_used-base_addr:size;
if(file_list_get_data(p_list,p_node,buf,base_addr,size)!=0){
return 0;
}
return size;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @param buf
* @param base_addr
* @param size
* @return uint64_t
*/
uint64_t file_list_put_node_data(struct file_list *p_list,struct file_list_node *p_node,void *buf,uint64_t base_addr,uint64_t size)
{
size=(base_addr+size>p_node->size_used)?p_node->size_used-base_addr:size;
if(file_list_put_data(p_list,p_node,buf,base_addr,size)!=0){
return 0;
}
f_sync(&p_list->fp);
return size;
}

@ -0,0 +1,76 @@
/**
* @file file_list.h
* @author Chen Jihang (embedded@eseaoptics.com)
* @brief
* @version 1.0
* @date 2022-08-25
*
* @copyright ESEA (c) 2020
* @details
*
*
*
*
*
*
*
*/
#ifndef FILE_LIST_H_
#define FILE_LIST_H_
#include <stdint.h>
#include <stddef.h>
#include "ff.h"
/**
* @brief
*
*/
struct file_list_head
{
uint64_t file_pointer_used_first; //< 链表头指针
uint64_t file_pointer_used_last; //< 链表尾指针
uint64_t file_pointer_free_first; //< 空闲链表头指针
uint64_t file_pointer_free_last; //< 空闲链表尾指针
};
/**
* @brief
*
*/
struct file_list_node
{
uint64_t file_pointer_last; //< 上一个链表节点在文件中的位置
uint64_t file_pointer_this; //< 这个链表节点在文件中的位置
uint64_t file_pointer_next; //< 下一个链表节点在文件中断位置
uint64_t size; //< 链表节点分配的大小
uint64_t size_used; //< 链表节点实际使用的大小
};
/**
* @brief
*
*/
struct file_list
{
FIL fp; //< 文件描述符
struct file_list_head list_head; //< 链表头
struct file_list_node used_node_now; //< 现在指向的链表节点
struct file_list_node free_node_now; //< 现在指向的空闲链表节点
};
int file_list_get_head(struct file_list *p_list,struct file_list_head *p_head);
int file_list_put_head(struct file_list *p_list,struct file_list_head *p_head);
int file_list_get_node(struct file_list *p_list,struct file_list_node *p_node,uint64_t file_pointer);
int file_list_put_node(struct file_list *p_list,struct file_list_node *p_node);
int file_list_get_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t *p_data,uint64_t base_addr,uint64_t size);
int file_list_put_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t *p_data,uint64_t base_addr,uint64_t size);
struct file_list *file_list_create(struct file_list *p_list,char *path);
struct file_list *file_list_open(struct file_list *p_list,char *path);
int file_list_close(struct file_list *p_list);
int file_list_merge_free_node(struct file_list *p_list,struct file_list_node *p_free_node);
struct file_list_node *file_list_alloc(struct file_list *p_list,uint64_t size);
int file_list_del_node(struct file_list *p_list,struct file_list_node *p_used_node);
struct file_list_node *file_list_add_node(struct file_list *p_list,uint64_t size);
struct file_list_node *file_list_get_first_node(struct file_list *p_list);
struct file_list_node *file_list_get_next_node(struct file_list *p_list);
struct file_list_node *file_list_get_last_node(struct file_list *p_list);
uint64_t file_list_get_node_size(struct file_list *p_list,struct file_list_node *p_node);
uint64_t file_list_get_node_data(struct file_list *p_list,struct file_list_node *p_node,void *buf,uint64_t base_addr,uint64_t size);
uint64_t file_list_put_node_data(struct file_list *p_list,struct file_list_node *p_node,void *buf,uint64_t base_addr,uint64_t size);
#endif

@ -0,0 +1,70 @@
#include "file_list.h"
struct file_list file_list;
static struct file_list_node *p_node;
/* File_List_Port( "/list" ) */
int File_List_Port( char * fpath )
{
if(file_list_open(&file_list,"fpath")==NULL){
return -1;
// log_w("File List Open Failed");
}
else{
return 0;
// log_i("file list open ok.. ");
}
}
// int File_List_Put_Data( uint8_t* buf, uint16_t size )
// {
// log_d("Save Info Packet");
// /* 先添加节点空间, 空间大小 */
// p_node=file_list_add_node(&file_list,size);
// if(p_node==NULL){
// log_e("File List Create Node Error");
// }
// /* 数据打包 */
// /* 往节点空间放数据 */
// file_list_put_node_data(&file_list,p_node,buf,0,size);
// }
// int File_List_Get_Data( uint8_t* buf, uint16_t size )
// {
// p_node=file_list_get_first_node(&file_list);
// if(p_node==NULL){
// log_d("File List No Node");
// return 1;
// }
// log_d("File List Get Node");
// size=file_list_get_node_size(&file_list,p_node);
// size_tmp=file_list_get_node_data(&file_list,p_node,packet_head,0,15);
// if(size_tmp<15){
// log_w("File List Read Failed");
// size=0;
// }
// base_addr=0;
// size_tmp=file_list_get_node_data(&file_list,p_node,send_buf,base_addr,2000);
// log_d("Send Packet %d,%d",base_addr,size_tmp);
// size-=size_tmp;
// base_addr+=size_tmp;
// if(size==0){
// log_d("Send Packet Succeed");
// }
// /* 确认处理完成 删除节点 */
// if(file_list_del_node(&file_list,p_node)<0){
// log_e("File List Delete Node Error");
// }
// }

@ -0,0 +1,326 @@
#include "float.h"
//定义浮点数组 最大数组长度
#define StrExtFloat_flen 64
//定义最大字符串长度
#define StrExtFloat_slen 512
/**
* @brief ,
* @param [in] num
* @param [in] Str
*
* @details ,
* usage
* char Str[100]="235.654hjfv92.88u98fj3wjf09w43f0f3f963.369";
* float num[StrExtFloat_flen] = {0.};
* StrExtFloat(num,Str);
*/
void StrExtFloat(float *num,char* Str)
{
//遍历深度
int Fflag = 0;
//数字个数
int Fnum = 0;
char num_start = 0,num_point = 0;
float NorP = 1; /* 正数 负数 */
//遍历到字符串尾部
while ( *Str != '\0' )
{
Fflag++;
//防止查询超过边界
if(Fflag>StrExtFloat_slen)
break;
//判断是不是数字
if( *Str == '-' )
{
NorP = -1;
}
else if(*Str >='0' && *Str <= '9')
{
//printf("%c",*Str);
//判断数字存在
num_start = 1;
//判断是否存在小数点
if(num_point >= 1)
{
num_point++;
//当前小数部分的数值
float fpoint = *Str - '0';
for(int i = 1;i<num_point;i++)
{
fpoint = fpoint/10.;
}
//加入小数部分
num[Fnum+1] = num[Fnum+1] + fpoint;
}
else
{
//加入整数部分
num[Fnum+1] = num[Fnum+1]*10+(*Str - '0');
}
}
else if(*Str == '.') //判断为小数点
{
if(num_start==1)//发现存在小数点
{
num_point=1;
}
}
else //判断为其他字符
{
if (num_start == 1)
{
num[Fnum+1] = num[Fnum+1] * NorP;
Fnum++;//统计个数加一
NorP = 1;
}
//清空字符统计与小数点统计
num_start = 0;
num_point = 0;
}
//指针移动
*(Str++);
}
//如果不是以字符结尾
if (num_start == 1)
{
Fnum++;//统计个数加一
}
//放入提取到的数字个数
num[0] = Fnum;
}
/**
* @brief
* @param [in] num
* @param [in] Str
*
* @details
* char Str2[100]="235.654";
* float *pFnum = (float*)malloc(sizeof(float));
* Str2Float(pFnum, Str2);
* printf(" f HEX %08X\r\n", (uint32_t *) &f);
*/
void Str2Float(float *num, char* Str)
{
//遍历深度
int Fflag = 0;
//数字个数
int Fnum = 0;
char num_start = 0,num_point = 0;
float NorP = 1; /* 正数 负数 */
*num = 0.0;
//遍历到字符串尾部
while ( *Str != '\0' )
{
Fflag++;
// //防止查询超过边界
// if(Fflag>StrExtFloat_slen)
// break;
//判断是不是数字
if( *Str == '-' )
{
NorP = -1;
}
else if(*Str >='0' && *Str <= '9')
{
// printf(".... %c \r\n",*Str);
//判断数字存在
num_start = 1;
//判断是否存在小数点
if(num_point >= 1)
{
num_point++;
//当前小数部分的数值
float fpoint = *Str - '0';
for(int i = 1;i<num_point;i++)
{
fpoint = fpoint/10.;
}
//加入小数部分
*num = *num + fpoint;
}
else
{
//加入整数部分
*num = *num*10+(*Str - '0');
}
}
else if( *Str == '.') //判断为小数点
{
if(num_start==1)//发现存在小数点
{
num_point=1;
}
}
else //判断为其他字符
{
if (num_start == 1)
{
// num[Fnum+1] = num[Fnum+1] * NorP;
Fnum++;//统计个数加一
NorP = 1;
}
break;
}
//指针移动
*(Str++);
}
*num = (*num) * NorP;
// printf(" ----------2222 end %f \r\n", *num);
}
/* 整数除 10^coeff 后的浮点数*/
void Int2FloatByCoeff( float *funm, uint32_t num, uint8_t coeff)
{
uint32_t i_v = num;
float f_v = 0.;
uint32_t n = num;
for (size_t i = 0; i < coeff; i++)
{
f_v = (f_v + i_v%10)/10;
i_v = i_v/10;
printf( " %d %f ", i_v, f_v) ;
}
*funm = (float)i_v + f_v;
}
void Float2Str(float fnum, char *str)
{
uint32_t i_v = fnum;
float f_v = 0.;
i_v = i_v/1;
f_v = fnum - (float) i_v;
int i = 0;
while(1)
{
}
// sprintf(str, "%f", fnum );
}
/*需要转换的值*//*结果存储数组*//*小数位长度*/
/**
* @brief
* @param [in] value
* @param [in] cSendBuff
* @param [in] Decimals
*
* @details
*/
void float2char(float value, char* cSendBuff, int Decimals) {
int i = 1, k = 0;
int integer = abs(value);//????
int decimal = (fabs(value) - integer)*(int)pow(10, Decimals);//????
int temp = integer;
if (value < 0)cSendBuff[k++] = '-';//????0,????
while (temp /= 10)
{
i*=10;
}
while (i) {
cSendBuff[k++] = integer / i + '0';
integer %= i;
i /= 10;
}
if (Decimals == 0) { //如果没有小数位,直接返回
cSendBuff[k++] = '\0';
return;
}
cSendBuff[k++] = '.'; //加上小数点
temp = decimal;
i = 1;
while (temp /= 10)
{
i *= 10;
}
while (i) {
cSendBuff[k++] = decimal / i + '0';
decimal %= i;
i /= 10;
}
cSendBuff[k++] = '\0';
}
void test_float(){
log_i( "test f begin");
// float f[1] ={6.14};
float f = 6.28 ;
char aa[20] = "3.1415";
// float2char(f[0], aa , 4);
float2char( f , aa , 4);
log_i(" s %s \r\n", aa);
// log_i(" f addr %d \r\n", f );
// log_i(" f HEX %08X\r\n", f) ;
uint32_t * pp = &f ;
log_i(" ff HEX %08X\r\n", *pp);
log_i(" *** str to f test *** ");
Str2Float( &f, aa);
if (f <4)
{
log_i(" str 2 float failure ");
}else
{
log_i("str 2 float ok");
}
// double ff = 7.12;
// ff= strtod(aa, end);
// uint32_t addr = &f;
// // sprintf(aa, "%f", f);
// log_i( "test f %d add :%d --- %08X",sizeof(f) , addr, (char*)f);
// log_i( "test f end %s",aa);
// f[0] = f[0]+8;
// if (ff <4)
// {
// log_i("f<4");
// }else
// { log_i(">6");}
// log_i(" after f HEX %08X\r\n", (uint32_t *) f);
}
/* strtod用法
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
int main(void)
{
// parsing with error handling
const char *p = "111.11 -2.22 Nan nan(2) inF 0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz";
printf("Parsing '%s':\n", p);
char *end;
for (double f = strtod(p, &end); p != end; f = strtod(p, &end))
{
printf("'%.*s' -> ", (int)(end-p), p);
p = end;
if (errno == ERANGE){
printf("range error, got ");
errno = 0;
}
printf("%f\n", f);
}
// parsing without error handling
printf("\" -0.0000000123junk\" --> %g\n", strtod(" -0.0000000123junk", NULL));
printf("\"junk\" --> %g\n", strtod("junk", NULL));
}
*/

@ -0,0 +1,21 @@
#ifndef __FLOAT_H_
#define __FLOAT_H_
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "main.h"
#include "stm32f4xx.h"
#include "elog.h"
void StrExtFloat(float *num,char* Str);
void Str2Float(float *num,char* Str);
void Int2FloatByCoeff(float *fnum, uint32_t num, uint8_t coeff);
void Float2Str(float fnum, char *str);
void float2char(float value,char* cSendBuff, int Decimals);
void test_float();
#endif

@ -0,0 +1,88 @@
#include "kfifo.h"
void *memcpy(void *__dest, void *__src, int __n)
{
int i = 0;
uint8_t *d = (uint8_t *)__dest, *s = (uint8_t *)__src;
for (i = __n >> 3; i > 0; i--) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1 << 2) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1 << 1) {
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1)
*d++ = *s++;
return __dest;
}
void kfifo_init(kfifo_t *fifo, uint8_t *pFifoBuffer, uint16_t fifoSize)
{
fifo->buffer = pFifoBuffer;
fifo->size = fifoSize;
fifo->in = fifo->out = 0;
}
uint16_t __kfifo_put(kfifo_t *fifo, uint8_t *buffer, uint16_t len)
{
unsigned int l;
len = min(len, fifo->size - fifo->in + fifo->out);
/* first put the data starting from fifo->in to buffer end */
l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
/* then put the rest (if any) at the beginning of the buffer */
memcpy(fifo->buffer, buffer + l, len - l);
printf( "buf 11 12 %02x %02x ", fifo->buffer[11], fifo->buffer[12]);
fifo->in += len;
return len;
}
void __kfifo_put_singlebyte(kfifo_t *fifo, uint8_t data)
{
fifo->buffer[(fifo->in++) & (fifo->size - 1)] = data;
}
uint16_t __kfifo_get(kfifo_t *fifo, uint8_t *buffer, uint16_t len)//uint8_t
{
unsigned int l;
len = min(len, fifo->in - fifo->out);
/* first get the data from fifo->out until the end of the buffer */
l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
/* then get the rest (if any) from the beginning of the buffer */
memcpy(buffer + l, fifo->buffer, len - l);
fifo->out += len;
return len;
}

@ -0,0 +1,40 @@
#ifndef __KFIFO_H
#define __KFIFO_H
#include "stdint.h"
// #include "stm32f407xx.h"
// #include "main.h"
// #include "base.h"
#ifndef min
#define min(x,y) ((x) < (y) ? x : y)
#endif
typedef struct _kfifo {
uint8_t *buffer; /* the buffer holding the data */
uint16_t size; /* the size of the allocated buffer */
uint16_t in; /* data is added at offset (in % size) */
uint16_t out; /* data is extracted from off. (out % size) */
}kfifo_t;
static inline unsigned int __kfifo_len(kfifo_t *fifo)
{
return fifo->in - fifo->out;
}
// extern kfifo_t recvfifo;
// extern uint8_t USART_Receive_Buf[64];
extern void kfifo_init(kfifo_t *fifo, uint8_t *pFifoBuffer, uint16_t fifoSize);
extern uint16_t __kfifo_put(kfifo_t *fifo, uint8_t *buffer, uint16_t len);
extern void __kfifo_put_singlebyte(kfifo_t *fifo, uint8_t data);
extern uint16_t __kfifo_get(kfifo_t *fifo, uint8_t *buffer, uint16_t len);
// extern uint16_t __kfifo_put(kfifo_t *fifo, uint8_t *buffer, uint16_t len);
// extern void __kfifo_put_singlebyte(kfifo_t *fifo, uint8_t data);
// extern uint16_t __kfifo_get(kfifo_t *fifo, uint8_t *buffer, uint16_t len);
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,198 @@
/**
* @file menu.h
* @author Chen Jihang (embedded@eseaoptics.com)
* @brief
* @note menu_builder使用
* @version 1.0
* @date 2023-01-04
*
* @copyright ESEA (c) 2020
*
*/
#ifndef MENU_H_
#define MENU_H_
#include <stdint.h>
#include <stddef.h>
#include "config.h"
#ifndef MENU_ECHO //< 回显开关 当为1时,在菜单使能的情况下会将用户输入的信息发送回去
#define MENU_ECHO (1)
#endif
#ifndef MENU_TERMINAL_WIDTH //< 默认的菜单终端宽度
#define MENU_TERMINAL_WIDTH (80)
#endif
#ifndef MENU_CHINESE_CHARACTER_WIDTH //< 中文字符的宽度
#define MENU_CHINESE_CHARACTER_WIDTH (2)
#endif
#ifndef MENU_FILL_CHARACTER //< 菜单填充字符
#define MENU_FILL_CHARACTER ('=')
#endif
#ifndef MENU_INPUT_BUF_SIZE //< 输入缓冲区大小
#define MENU_INPUT_BUF_SIZE (256)
#else
#if MENU_INPUT_BUF_SIZE>256
#error "\'MENU_INPUT_BUF_SIZE\'最大为256Byte"
#endif
#endif
#ifndef MENU_OUTPUT_BUF_SIZE //< 输出缓冲区大小
#define MENU_OUTPUT_BUF_SIZE ((MENU_TERMINAL_WIDTH)*3)
#endif
struct menu;
typedef int (*menu_send_function_type)(void *send_class,char *buf,uint32_t size); //< 发送函数指针类型
typedef int (*menu_check_passwd_function_type)(struct menu *menu,char *passwd,uint32_t size); //< 密码检查函数指针类型
enum menu_data_type{ //< 菜单数据类型
MENU_DATA_TYPE_CHAR, //< 字符型
MENU_DATA_TYPE_RO_CHAR, //< 字符型 只读
MENU_DATA_TYPE_UINT8, //< 8bit无符号整数
MENU_DATA_TYPE_RO_UINT8, //< 8bit无符号整数 只读
MENU_DATA_TYPE_INT8, //< 8bit有符号整数
MENU_DATA_TYPE_RO_INT8, //< 8bit有符号整数 只读
MENU_DATA_TYPE_UINT16, //< 16bit无符号整数
MENU_DATA_TYPE_RO_UINT16, //< 16bit无符号整数 只读
MENU_DATA_TYPE_INT16, //< 16bit有符号整数
MENU_DATA_TYPE_RO_INT16, //< 16bit有符号整数 只读
MENU_DATA_TYPE_UINT32, //< 32bit无符号整数
MENU_DATA_TYPE_RO_UINT32, //< 32bit无符号整数 只读
MENU_DATA_TYPE_INT32, //< 32bit有符号整数
MENU_DATA_TYPE_RO_INT32, //< 32bit有符号整数 只读
MENU_DATA_TYPE_IPV4, //< ipv4 以32bit无符号整数形式存储
MENU_DATA_TYPE_RO_IPV4 //< ipv4 以32bit无符号整数形式存储 只读
};
struct menu_tree_node //< 菜单树节点
{
enum menu_data_type data_type; //< 数据类型
uint32_t max_value; //< 允许的最大值
uint32_t min_value; //< 允许的最小值
uint16_t next; //< 下一个节点
uint16_t child; //< 子节点
uint16_t father; //< 父节点
uint16_t num; //< 数据数量
char *info_str; //< 信息
void *data; //< 数据指针
};
struct menu //< 菜单
{
const struct menu_tree_node *menu_tree; //< 菜单树
void *send_class; //< send函数的第一个参数
menu_send_function_type send; //< send函数
menu_check_passwd_function_type check_passwd; //< 密码检查函数
uint16_t node; //< 当前节点
uint16_t child_node; //< 当前子节点
uint8_t child_con; //< 子节点计数
uint8_t input_con; //< 输入字符计数
uint8_t terminal_width; //< 终端宽度
uint8_t flag_ready; //< 用户输入完成标志
uint8_t flag_flush; //< 菜单刷新标志
char input_buf[MENU_INPUT_BUF_SIZE]; //< 用户输入缓冲区
char output_buf[MENU_OUTPUT_BUF_SIZE]; //< 输出缓冲区
};
struct menu *menu_init(struct menu *menu,const struct menu_tree_node *menu_tree,void *send_class,menu_send_function_type send);
int menu_set_terminal_width(struct menu *menu,uint8_t terminal_width);
int menu_send(struct menu *menu,char *buf,uint32_t size);
int menu_set_hook_passwd(struct menu *menu,menu_check_passwd_function_type check_passwd);
int menu_get_state(struct menu *menu);
void menu_print_callback(struct menu *menu);
void menu_parse_callback(struct menu *menu,char *buf,uint32_t size);
void menu_exit(struct menu *menu) ;
#endif
// /**
// * @file menu.h
// * @author Chen Jihang (embedded@eseaoptics.com)
// * @brief 串口菜单
// * @note 须配合对应版本的menu_builder使用
// * @version 1.0
// * @date 2023-01-04
// *
// * @copyright ESEA (c) 2020
// *
// */
// #ifndef MENU_H_
// #define MENU_H_
// #include <stdint.h>
// #include <stddef.h>
// #include "config.h"
// #include "main.h"
// #ifndef MENU_ECHO //< 回显开关 当为1时,在菜单使能的情况下会将用户输入的信息发送回去
// #define MENU_ECHO (1)
// #endif
// #ifndef MENU_TERMINAL_WIDTH //< 默认的菜单终端宽度
// #define MENU_TERMINAL_WIDTH (80)
// #endif
// #ifndef MENU_CHINESE_CHARACTER_WIDTH //< 中文字符的宽度
// #define MENU_CHINESE_CHARACTER_WIDTH (2)
// #endif
// #ifndef MENU_FILL_CHARACTER //< 菜单填充字符
// #define MENU_FILL_CHARACTER ('=')
// #endif
// #ifndef MENU_INPUT_BUF_SIZE //< 输入缓冲区大小
// #define MENU_INPUT_BUF_SIZE (256)
// #else
// #if MENU_INPUT_BUF_SIZE>256
// #error "\'MENU_INPUT_BUF_SIZE\'最大为256Byte"
// #endif
// #endif
// #ifndef MENU_OUTPUT_BUF_SIZE //< 输出缓冲区大小
// #define MENU_OUTPUT_BUF_SIZE ((MENU_TERMINAL_WIDTH)*3)
// #endif
// struct menu;
// typedef int (*menu_send_function_type)(void *send_class,char *buf,uint32_t size); //< 发送函数指针类型
// typedef int (*menu_check_passwd_function_type)(struct menu *menu,char *passwd,uint32_t size); //< 密码检查函数指针类型
// enum menu_data_type{ //< 菜单数据类型
// MENU_DATA_TYPE_CHAR, //< 字符型
// MENU_DATA_TYPE_RO_CHAR, //< 字符型 只读
// MENU_DATA_TYPE_UINT8, //< 8bit无符号整数
// MENU_DATA_TYPE_RO_UINT8, //< 8bit无符号整数 只读
// MENU_DATA_TYPE_INT8, //< 8bit有符号整数
// MENU_DATA_TYPE_RO_INT8, //< 8bit有符号整数 只读
// MENU_DATA_TYPE_UINT16, //< 16bit无符号整数
// MENU_DATA_TYPE_RO_UINT16, //< 16bit无符号整数 只读
// MENU_DATA_TYPE_INT16, //< 16bit有符号整数
// MENU_DATA_TYPE_RO_INT16, //< 16bit有符号整数 只读
// MENU_DATA_TYPE_UINT32, //< 32bit无符号整数
// MENU_DATA_TYPE_RO_UINT32, //< 32bit无符号整数 只读
// MENU_DATA_TYPE_INT32, //< 32bit有符号整数
// MENU_DATA_TYPE_RO_INT32, //< 32bit有符号整数 只读
// MENU_DATA_TYPE_IPV4, //< ipv4 以32bit无符号整数形式存储
// MENU_DATA_TYPE_RO_IPV4 //< ipv4 以32bit无符号整数形式存储 只读
// };
// struct menu_tree_node //< 菜单树节点
// {
// enum menu_data_type data_type; //< 数据类型
// uint32_t max_value; //< 允许的最大值
// uint32_t min_value; //< 允许的最小值
// uint16_t next; //< 下一个节点
// uint16_t child; //< 子节点
// uint16_t father; //< 父节点
// uint16_t num; //< 数据数量
// char *info_str; //< 信息
// void *data; //< 数据指针
// };
// struct menu //< 菜单
// {
// const struct menu_tree_node *menu_tree; //< 菜单树
// void *send_class; //< send函数的第一个参数
// menu_send_function_type send; //< send函数
// menu_check_passwd_function_type check_passwd; //< 密码检查函数
// uint16_t node; //< 当前节点
// uint16_t child_node; //< 当前子节点
// uint8_t child_con; //< 子节点计数
// uint8_t input_con; //< 输入字符计数
// uint8_t terminal_width; //< 终端宽度
// uint8_t flag_ready; //< 用户输入完成标志
// uint8_t flag_flush; //< 菜单刷新标志
// char input_buf[MENU_INPUT_BUF_SIZE]; //< 用户输入缓冲区
// char output_buf[MENU_OUTPUT_BUF_SIZE]; //< 输出缓冲区
// };
// // struct menu *menu_init(struct menu *menu,const struct menu_tree_node *menu_tree,void *send_class,menu_send_function_type send);
// struct menu *menu_init(struct menu *menu,const struct menu_tree_node *menu_tree );
// int menu_set_terminal_width(struct menu *menu,uint8_t terminal_width);
// int menu_send(struct menu *menu,char *buf,uint32_t size);
// int menu_set_hook_passwd(struct menu *menu,menu_check_passwd_function_type check_passwd);
// int menu_get_state(struct menu *menu);
// void menu_print_callback(struct menu *menu);
// void menu_parse_callback(struct menu *menu,char *buf,uint32_t size);
// #endif

@ -0,0 +1,403 @@
#include "main.h"
#include "menu.h"
#include "state.h"
/**
* menu_tree 01
* father
* next 0
* child
*
* char pre_command[64] MENU_DATA_TYPE_CHAR
*
*/
extern struct operating_state op_state;
const struct menu_tree_node menu_tree[] = {
{
.data_type=MENU_DATA_TYPE_CHAR,
.max_value=0,
.min_value=0,
.father=0,
.next=0,
.child=1,
.info_str="\r\n ███████╗███████╗███████╗ █████╗ \r\n ██╔════╝██╔════╝██╔════╝██╔══██╗\r\n █████╗ ███████╗█████╗ ███████║\r\n ██╔══╝ ╚════██║██╔══╝ ██╔══██║\r\n ███████╗███████║███████╗██║ ██║\r\n ╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝\r\n\r\n 逸海光学(青岛)科技有限公司\r\n\r\n 手持式光辐射测量装置\r\n",
.data=NULL,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT8,
.max_value=0,
.min_value=0,
.father=0,
.next=0,
.child=2,
.info_str="菜单",
.data=NULL,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT8,
.max_value=0,
.min_value=0,
.father=1,
.next=7,
.child=3,
.info_str="串口配置",
.data=NULL,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT32,
.max_value=4000000,
.min_value=2400,
.father=2,
.next=4,
.child=0,
.info_str="波特率",
.data=&config.uart.baudrate,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=11,
.min_value=7,
.father=2,
.next=5,
.child=0,
.info_str="数据位",
.data=&config.uart.databits,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=1536,
.min_value=0,
.father=2,
.next=6,
.child=0,
.info_str="奇偶校验\r\n不校验:0\r\n奇校验:1024\r\n偶校验:1536",
.data=&config.uart.parity,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=12288,
.min_value=0,
.father=2,
.next=0,
.child=0,
.info_str="停止位\r\n1bit:0\r\n0.5bit:4096\r\n2bit:8192\r\n1.5bit:12288",
.data=&config.uart.stopbits,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT8,
.max_value=0,
.min_value=0,
.father=1,
.next=15,
.child=8,
.info_str="协议配置",
.data=NULL,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=2,
.min_value=0,
.father=7,
.next=9,
.child=0,
.info_str="协议类型 0:RTU 1:HEX 2:ASCII",
.data=&config.protocol.type,
.num=0
},
{
.data_type=MENU_DATA_TYPE_CHAR,
.max_value=0,
.min_value=0,
.father=7,
.next=10,
.child=0,
.info_str="预命令",
.data=config.protocol.pre_command,
.num=64
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=65535,
.min_value=0,
.father=7,
.next=11,
.child=0,
.info_str="预命令超时",
.data=&config.protocol.pre_timeout,
.num=0
},
{
.data_type=MENU_DATA_TYPE_CHAR,
.max_value=0,
.min_value=0,
.father=7,
.next=12,
.child=0,
.info_str="命令",
.data=config.protocol.command,
.num=64
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=65535,
.min_value=0,
.father=7,
.next=13,
.child=0,
.info_str="超时",
.data=&config.protocol.timeout,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=0,
.min_value=0,
.father=7,
.next=14,
.child=0,
.info_str="数据解析",
.data=&config.protocol.parser,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=1,
.min_value=0,
.father=7,
.next=0,
.child=0,
.info_str="大小端",
.data=&config.protocol.endian,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT8,
.max_value=0,
.min_value=0,
.father=1,
.next=21,
.child=16,
.info_str="输出配置",
.data=NULL,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=0,
.min_value=0,
.father=14,
.next=17,
.child=0,
.info_str="开始字节",
.data=&config.output.begin_byte,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=0,
.min_value=0,
.father=14,
.next=18,
.child=0,
.info_str="长度",
.data=&config.output.begin_byte,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=0,
.min_value=0,
.father=14,
.next=19,
.child=0,
.info_str="结束字节",
.data=&config.output.end_byte,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=0,
.min_value=0,
.father=14,
.next=20,
.child=0,
.info_str="输出位置",
.data=&config.output.place,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=0,
.min_value=0,
.father=14,
.next=0,
.child=0,
.info_str="输出数目",
.data=&config.output.number,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT8,
.max_value=1,
.min_value=0,
.father=1,
.next=26,
.child=22,
.info_str="菜单串口",
.data=NULL,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT32,
.max_value=4000000,
.min_value=2400,
.father=21,
.next=23,
.child=0,
.info_str="波特率",
.data=&config.menu.baudrate,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=11,
.min_value=7,
.father=21,
.next=24,
.child=0,
.info_str="数据位",
.data=&config.menu.databits,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=1536,
.min_value=0,
.father=21,
.next=25,
.child=0,
.info_str="奇偶校验\r\n不校验:0\r\n奇校验:1024\r\n偶校验:1536",
.data=&config.menu.parity,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=12288,
.min_value=0,
.father=21,
.next=0,
.child=0,
.info_str="停止位\r\n1bit:0\r\n0.5bit:4096\r\n2bit:8192\r\n1.5bit:12288",
.data=&config.menu.stopbits,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT8,
.max_value=1,
.min_value=0,
.father=1,
.next=31,
.child=27,
.info_str="Modbus串口",
.data=NULL,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT32,
.max_value=4000000,
.min_value=2400,
.father=26,
.next=28,
.child=0,
.info_str="波特率",
.data=&config.modbus.baudrate,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=11,
.min_value=7,
.father=26,
.next=29,
.child=0,
.info_str="数据位",
.data=&config.modbus.databits,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=1536,
.min_value=0,
.father=26,
.next=30,
.child=0,
.info_str="奇偶校验\r\n不校验:0\r\n奇校验:1024\r\n偶校验:1536",
.data=&config.modbus.parity,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT16,
.max_value=12288,
.min_value=0,
.father=26,
.next=0,
.child=0,
.info_str="停止位\r\n1bit:0\r\n0.5bit:4096\r\n2bit:8192\r\n1.5bit:12288",
.data=&config.modbus.stopbits,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT8,
.max_value=1,
.min_value=0,
.father=1,
.next=32,
.child=0,
.info_str="保存配置",
.data=&op_state.flag_save_cfg,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT8,
.max_value=1,
.min_value=0,
.father=1,
.next=33,
.child=0,
.info_str="恢复出厂配置",
.data=&op_state.flag_save_cfg,
.num=0
},
{
.data_type=MENU_DATA_TYPE_CHAR,
.max_value=0,
.min_value=0,
.father=1,
.next=34,
.child=0,
.info_str="设置系统时间\r\nFormat:20230707120101",
.data=op_state.flag_time,
.num=0
},
{
.data_type=MENU_DATA_TYPE_UINT8,
.max_value=1,
.min_value=0,
.father=1,
.next=0,
.child=0,
.info_str="重启",
.data=&op_state.flag_reboot,
.num=0
}
};

@ -0,0 +1,107 @@
#include "menu_port.h"
#include "elog.h"
// #define Max_MenuBuf_Size 256
extern UART_HandleTypeDef huart3;
extern const struct menu_tree_node menu_tree[];
// extern osMessageQueueId_t menuMsgQueueHandle;
// extern osSemaphoreId_t elog_menuHandle;
uint8_t Menu_Buf[Max_MenuBuf_Size];
UART_HandleTypeDef *Menuhuart = &huart3;
MenuPort_t *menuport;
MenuPort_t * MenuPort_Init( )
{
MenuPort_t *Handle = (MenuPort_t *)malloc(sizeof(MenuPort_t));
if (Handle == NULL)
{
Menuport_Error("fail to create MenuPort");
return NULL;
}
Handle->menu = (struct menu *)malloc(sizeof(struct menu));
return Handle;
}
void MenuPort_Setup( MenuPort_t *menuport, UART_HandleTypeDef *huart, GPIO_TypeDef *gpio, uint16_t pin, uint8_t mode ,uint8_t trans_mode)
{
menuport->huart = huart;
menuport->gpio = gpio;
menuport->pin = pin;
menuport->mode = mode;
menuport->trans_mode = trans_mode;
}
/* 待传入的函数 实际函数*/
int MenuPort_Send(MenuPort_t *menuport, uint8_t * buf, uint32_t size){
if( menuport->mode ==1 ) {
HAL_GPIO_WritePin(menuport->gpio,menuport->pin , SET);
}
switch (menuport->trans_mode)
{
case 1:
HAL_UART_Transmit_IT(menuport->huart, buf, size);
break;
case 2:
HAL_UART_Transmit_DMA(menuport->huart, buf, size);
break;
default:
HAL_UART_Transmit(menuport->huart, buf, size,0xFFFF);
}
if( menuport->mode ==1 ) {
HAL_GPIO_WritePin( menuport->gpio, menuport->pin , RESET );
}
return 0;
}
void Menuport_receive_callback(MenuPort_t *menuport, uint8_t *buf,uint32_t size)
{
/* 接收回调 中断直接调用menu, 不经过menuport回调*/
menu_parse_callback( menuport->menu, (char *)buf, size );
}
void menuport_exit( MenuPort_t *menuport)
{
if ( menu_get_state(menuport->menu) != 0 )
{
// osSemaphoreRelease(elog_menuHandle); /* 一直持有到菜单结束才释放*/
menu_exit(menuport->menu );
}
}
void Menuport_Error(char *error)
{
/* 定制输出 error内容*/
// printf (error);
while (1);
}
void menu_entry( void *argument)
{
// osStatus_t status;
// uint8_t recv_buff[Max_MenuBuf_Size] ={0};
menuport = MenuPort_Init();
MenuPort_Setup( menuport, Menuhuart, NULL, 0, 0, 0 ); /* poll 模式发送,DMA IT 模式会出问题*/
menu_init( menuport->menu, menu_tree, (void*)menuport, ( menu_send_function_type ) MenuPort_Send );
}
void Menu_Task( MenuPort_t *menuport){
menu_print_callback(menuport->menu);
// for ( ; ; )
// {
// osDelay(10);
// menu_print_callback(((MenuPort_t *)argument)->menu);
// }
}

@ -0,0 +1,288 @@
#include <stdio.h>
#include "stm32f4xx.h"
#include "main.h"
// #include "config.h"
#include "elog.h"
#include "bsp_driver_sd.h"
#include "fatfs.h"
extern osSemaphoreId_t SD_lockHandle;
osSemaphoreId_t SD_lockHandle;
const osSemaphoreAttr_t SD_lock_attributes = {
.name = "SD_lock"};
// osSemaphoreAcquire(SD_lockHandle, osWaitForever);
// osSemaphoreRelease(SD_lockHandle);
HAL_SD_CardInfoTypeDef SDCardInfo;
extern SD_HandleTypeDef hsd;
extern DMA_HandleTypeDef hdma_sdio_rx;
extern DMA_HandleTypeDef hdma_sdio_tx;
FATFS fs; //工作空间
FIL fil; // 文件项目
extern void printf_sdcard_info(void);
extern int Init_FatFas_Mount(void);
extern int creat_file(char * filename);
extern uint8_t BSP_SD_Init(void);
extern void SD_Test( void);
extern void SD_Mount( void);
uint8_t BSP_SD_Init(void)
{
uint8_t sd_state = MSD_OK;
/* Check if the SD card is plugged in the slot */
osSemaphoreRelease(SD_lockHandle);
osSemaphoreAcquire(SD_lockHandle, osWaitForever);
if (BSP_SD_IsDetected() != SD_PRESENT)
{
return MSD_ERROR;
}
/* HAL SD initialization */
sd_state = HAL_SD_Init(&hsd);
/* Configure SD Bus width (4 bits mode selected) */
if (sd_state == MSD_OK)
{
hsd.Init.ClockDiv = 10;
// hsd.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV;
/* Enable wide operation */
if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
{
sd_state = MSD_ERROR;
}
}
osSemaphoreRelease(SD_lockHandle);
return sd_state;
}
void printf_sdcard_info(void)
{
uint64_t CardCap; //SD卡容量
HAL_SD_CardCIDTypeDef SDCard_CID;
char * card_type[8] = {0};
HAL_SD_GetCardCID(&hsd,&SDCard_CID); //获取CID
HAL_SD_GetCardInfo(&hsd,&SDCardInfo); //获取SD卡信息
CardCap=(uint64_t)(SDCardInfo.LogBlockNbr)*(uint64_t)(SDCardInfo.LogBlockSize); //计算SD卡容量
switch(SDCardInfo.CardType)
{
case CARD_SDSC:
{
if(SDCardInfo.CardVersion == CARD_V1_X)
{
memcpy(card_type, (void*)("SDSC V1"),7);
// printf("Card Type:SDSC V1\r\n");
}
else if (SDCardInfo.CardVersion == CARD_V2_X)
{
memcpy(card_type, (void*)("SDSC V2"),7);
// printf("Card Type:SDSC V2\r\n");
}
break;
}
case CARD_SDHC_SDXC:
{
memcpy(card_type, (void*)("SDHC"),4);
// printf("Card Type:SDHC\r\n");
break;
}
default:break;
}
#if 1
log_i("Card Type: %s ",card_type); //card 类型
log_i("Card ManufacturerID: %d ",SDCard_CID.ManufacturerID); //制造商ID
log_i("CardVersion: %d ",(uint32_t)(SDCardInfo.CardVersion)); //卡版本号
log_i("Class: %d ",(uint32_t)(SDCardInfo.Class)); //
log_i("Card RCA(RelCardAdd):%d ",SDCardInfo.RelCardAdd); //卡相对地址
log_i("Card BlockNbr: %d ",SDCardInfo.BlockNbr); //块数量
log_i("Card BlockSize: %d ",SDCardInfo.BlockSize); //块大小
log_i("LogBlockNbr: %d ",(uint32_t)(SDCardInfo.LogBlockNbr)); //逻辑块数量
log_i("LogBlockSize: %d ",(uint32_t)(SDCardInfo.LogBlockSize)); //逻辑块大小
log_i("Card Capacity: %d MB",(uint32_t)(CardCap>>20)); //卡容量
#endif
#if 0
printf("Card ManufacturerID: %d \r\n",SDCard_CID.ManufacturerID); //制造商ID
printf("CardVersion: %d \r\n",(uint32_t)(SDCardInfo.CardVersion)); //卡版本号
printf("Class: %d \r\n",(uint32_t)(SDCardInfo.Class)); //
printf("Card RCA(RelCardAdd):%d \r\n",SDCardInfo.RelCardAdd); //卡相对地址
printf("Card BlockNbr: %d \r\n",SDCardInfo.BlockNbr); //块数量
printf("Card BlockSize: %d \r\n",SDCardInfo.BlockSize); //块大小
printf("LogBlockNbr: %d \r\n",(uint32_t)(SDCardInfo.LogBlockNbr)); //逻辑块数量
printf("LogBlockSize: %d \r\n",(uint32_t)(SDCardInfo.LogBlockSize)); //逻辑块大小
printf("Card Capacity: %d MB\r\n",(uint32_t)(CardCap>>20)); //卡容量
#endif
}
int Init_FatFas_Mount(void)
{
int retSD = f_mount(&fs, "0:", 1);
return retSD;
}
/**
* @brief
* @param [in] filename "0:aa.txt"
*
* @details
* creat_file( "0:aa.txt" );
*/
int creat_file(char * filename)
{
// f_mkfs( );
int retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE); //打开文件,权限包括创建、写(如果没有该文件,会创建该文件)
if(retSD==FR_OK)
{
// printf("\r\ncreate file success!!! \r\n");
// log_i("\r\ncreate file success!!! \r\n");
f_close(&fil); //关闭该文件
return retSD;
}
else
{
// printf("\r\ncreater file error : %d\r\n",retSD);
// log_i("\r\ncreater file error : %d\r\n",retSD);
f_close(&fil); //关闭该文件
return retSD;
}
// f_close(&fil); //关闭该文件
// HAL_Delay(100);
}
void write_file( char * data, uint32_t len )
{
uint32_t byteswritten;
/*##-3- Write data to the text files ###############################*/
int retSD = f_write(&fil, data, len, (void *)&byteswritten);
if(retSD)
printf(" write file error : %d\r\n",retSD);
else
{
printf(" write file sucess!!! \r\n");
printf(" write Data[%d] : %s\r\n",byteswritten,data);
}
/*##-4- Close the open text files ################################*/
retSD = f_close(&fil);
if(retSD)
printf(" close error : %d\r\n",retSD);
else
printf(" close sucess!!! \r\n");
}
void SD_Read_block_Test(void)
{
// uint8_t read_buf[512];
// int sdcard_status = HAL_SD_ReadBlocks(&hsd, (uint8_t *)read_buf, 0, 1, 0xffff);
// if(sdcard_status == HAL_OK)
// {
// printf("Read block data ok! \r\n");
// }
// else
// {
// printf("Read block data fail! status = %d \r\n", sdcard_status);
// }
}
void SD_Mount( void)
{
int res;
res = BSP_SD_Init();
if (res == 0 )
{
log_i(" BSP_SD_Init ok .. ");
}
else
{
log_i(" BSP_SD_Init failure.. " );
}
printf_sdcard_info( );
res = Init_FatFas_Mount();
if (res == 0 )
{
log_i(" mount success .. ");
}
else
{
log_i(" mount failure.. res %d",res);
}
}
void SD_Test( void)
{
int res;
printf_sdcard_info( );
res = creat_file("0:aa.txt");
if (res==0)
{
log_i(" create file success .. ");
}
else
{
log_i(" create file failure .. res : %d",res);
}
}
void SDIO_IRQHandler(void)
{
log_i(" SDIO_IRQHandler .. sd status %d", hsd.State);
HAL_SD_IRQHandler(&hsd);
}
void DMA2_Stream3_IRQHandler(void)
{
log_i(" hdma_sdio_rx it .. sd status %d", hsd.State);
hsd.State = HAL_SD_STATE_READY;
HAL_DMA_IRQHandler(&hdma_sdio_rx);
}
void DMA2_Stream6_IRQHandler(void)
{
log_i(" hdma_sdio_tx it .. ");
hsd.State = HAL_SD_STATE_READY;
HAL_DMA_IRQHandler(&hdma_sdio_tx);
}
// void SDIO_IRQHandler(void)
// {
// HAL_SD_IRQHandler(&hsd);
// }
// void DMA2_Stream3_IRQHandler(void)
// {
// HAL_DMA_IRQHandler(&hdma_sdio_rx);
// }
// void DMA2_Stream6_IRQHandler(void)
// {
// HAL_DMA_IRQHandler(&hdma_sdio_tx);
// }

@ -0,0 +1,196 @@
/**
* @file time_clock.c
* @author Chen Jihang (embedded@eseaoptics.com)
* @brief
* @version 0.1
* @date 2022-07-18
*
* @copyright ESEA (c) 2020
*
*/
#include "time_clock.h"
struct time_clock
{
volatile uint64_t time_s;
volatile uint32_t time_ms;
volatile int64_t time_offset_ms;
};
static struct time_clock tc={0};
/**
* @brief ()
*
* @return uint64_t ()
*/
uint64_t time_clock_get_time_s(void)
{
return tc.time_s;
}
/**
* @brief ()
*
* @return uint32_t ()
*/
uint32_t time_clock_get_time_ms(void)
{
return tc.time_ms;
}
/**
* @brief
*
* @param ptime struct time_clock_time
* @return struct time_clock_time* ptime
*/
struct time_clock_time *time_clock_get_time(struct time_clock_time *ptime)
{
ptime->time_s=tc.time_s;
ptime->time_ms=tc.time_ms;
if(ptime->time_s!=tc.time_s){
ptime->time_ms=0;
ptime->time_s++;
}
return ptime;
}
/**
* @brief struct time_clock_time ()
*
* @param ptime struct time_clock_time
* @return int64_t ()
*/
int64_t time_clock_get_time_offset_ms(struct time_clock_time *ptime)
{
int64_t time_s;
int32_t time_ms;
time_s=tc.time_s;
time_ms=tc.time_ms;
if(time_s!=tc.time_s){
time_s++;
time_ms=0;
}
return ((int64_t)time_s-(int64_t)ptime->time_s)*1000+((int32_t)time_ms-(int32_t)ptime->time_ms);
}
/**
* @brief ()
*
* @param time_s ()
* @return int64_t ()
*/
int64_t time_clock_get_time_offset_s(uint64_t time_s)
{
return (int64_t)tc.time_s-(int64_t)time_s;
}
/**
* @brief
*
* @param time_to_set
* @param ptime
*/
void time_clock_set_time(struct time_clock_time *time_to_set,struct time_clock_time *ptime)
{
int64_t time_offset_ms;
time_offset_ms=time_clock_get_time_offset_ms(time_to_set);
time_offset_ms-=time_clock_get_time_offset_ms(ptime);
tc.time_offset_ms=time_offset_ms;
}
/**
* @brief
*
* @param time_s ()
* @param date
* @param time_zone
* @return struct time_clock_date* date
*/
struct time_clock_date *time_clock_time_to_date(uint64_t time_s,struct time_clock_date *date,int8_t time_zone)
{
struct tm *time_tm;
time_t time_tmp=time_s+(int64_t)time_zone*60*60;
time_tm=gmtime(&time_tmp);
date->year=time_tm->tm_year+1900;
date->mon=time_tm->tm_mon+1;
date->mday=time_tm->tm_mday;
date->hour=time_tm->tm_hour;
date->min=time_tm->tm_min;
date->sec=time_tm->tm_sec;
date->wday=time_tm->tm_wday;
date->yday=time_tm->tm_yday+1;
return date;
}
/**
* @brief ()
*
* @param date
* @param time_zone
* @return uint64_t ()
*/
uint64_t time_clock_date_to_time(struct time_clock_date *date,int8_t time_zone)
{
struct tm time_tm;
time_tm.tm_year=date->year-1900;
time_tm.tm_mon=date->mon-1;
time_tm.tm_mday=date->mday;
time_tm.tm_hour=date->hour;
time_tm.tm_min=date->min;
time_tm.tm_sec=date->sec;
time_tm.tm_wday=date->wday-1;
time_tm.tm_yday=date->yday-1;
time_tm.tm_isdst=0;
return mktime(&time_tm)-(int64_t)time_zone*60*60;
}
/**
* @brief
*
* @param buf
* @param time_zone
* @return uint32_t
*/
uint32_t time_clock_get_time_str(char *buf,int8_t time_zone)
{
int i=0;
struct time_clock_date date_tmp;
struct time_clock_time time_tmp;
time_clock_get_time(&time_tmp);
time_clock_time_to_date(time_tmp.time_s,&date_tmp,time_zone);
buf[i++]=date_tmp.year/1000+'0';
buf[i++]=(date_tmp.year/100)%10+'0';
buf[i++]=(date_tmp.year/10)%10+'0';
buf[i++]=date_tmp.year%10+'0';
buf[i++]='/';
buf[i++]=date_tmp.mon/10+'0';
buf[i++]=date_tmp.mon%10+'0';
buf[i++]='/';
buf[i++]=date_tmp.mday/10+'0';
buf[i++]=date_tmp.mday%10+'0';
buf[i++]=' ';
buf[i++]=date_tmp.hour/10+'0';
buf[i++]=date_tmp.hour%10+'0';
buf[i++]=':';
buf[i++]=date_tmp.min/10+'0';
buf[i++]=date_tmp.min%10+'0';
buf[i++]=':';
buf[i++]=date_tmp.sec/10+'0';
buf[i++]=date_tmp.sec%10+'0';
buf[i++]='.';
buf[i++]=time_tmp.time_ms/100+'0';
buf[i++]=(time_tmp.time_ms/10)%10+'0';
buf[i++]=time_tmp.time_ms%10+'0';
buf[i++]='\0';
return i;
}
/**
* @brief 1ms调用一次
*
*/
void time_clock_tick_callback(void)
{
tc.time_ms++;
if(tc.time_offset_ms!=0){
tc.time_s-=tc.time_offset_ms/1000;
tc.time_s--;
tc.time_ms+=1000;
tc.time_ms-=tc.time_offset_ms%1000;
tc.time_offset_ms=0;
}
while(tc.time_ms>=1000){
tc.time_s++;
tc.time_ms-=1000;
}
}

@ -0,0 +1,42 @@
/**
* @file time_clock.h
* @author Chen Jihang (embedded@eseaoptics.com)
* @brief
* @version 0.1
* @date 2022-07-18
*
* @copyright ESEA (c) 2020
*
*/
#ifndef TIME_CLOCK_H_
#define TIME_CLOCK_H_
#include "stdint.h"
#include "time.h"
struct time_clock_time
{
uint64_t time_s;
uint32_t time_ms;
};
struct time_clock_date
{
uint8_t sec;
uint8_t min;
uint8_t hour;
uint8_t mday;
uint8_t wday;
uint8_t mon;
uint16_t year;
uint16_t yday;
};
uint64_t time_clock_get_time_s(void);
uint32_t time_clock_get_time_ms(void);
struct time_clock_time *time_clock_get_time(struct time_clock_time *ptime);
int64_t time_clock_get_time_offset_ms(struct time_clock_time *ptime);
int64_t time_clock_get_time_offset_s(uint64_t time_s);
void time_clock_set_time(struct time_clock_time *ptime_to_set,struct time_clock_time *ptime);
struct time_clock_date *time_clock_time_to_date(uint64_t time_s,struct time_clock_date *date,int8_t time_zone);
uint64_t time_clock_date_to_time(struct time_clock_date *date,int8_t time_zone);
uint32_t time_clock_get_time_str(char *buf,int8_t time_zone);
void time_clock_tick_callback(void);
#endif

@ -0,0 +1,108 @@
#include <stdio.h>
#include "stm32f4xx.h"
#include "main.h"
#include "elog.h"
#include "bsp_driver_sd.h"
#include "fatfs.h"
#include "usbd_storage_if.h"
static void FILE_MGT_USB_CHECK_TASK(const void *arg) ;
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
void OTG_FS_IRQHandler(void)
{
// log_i(" OTG_FS_IRQHandler ...");
HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
FILE_MGT_USB_CHECK_TASK(NULL); // 自定义的函数
// #ifdef USE_STM32F4_VCP
// HAL_PCD_IRQHandler(&hpcd_USB_OTG_VCP);
// #endif /* USE_STM32F4_VCP */
// #ifdef USE_STM32F4_DEVICE_HID
// HAL_PCD_IRQHandler(&hpcd_USB_OTG_HID);
// #endif
// #ifdef USE_STM32F4_HOST_MSC
// HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
// #endif
// #ifdef USE_STM32F4_HOST_HID
// HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
// #endif
}
// // USB连接状态检测
static void FILE_MGT_USB_CHECK_TASK(const void *arg) {
uint8_t dev_state = 0;
osEvent event;
// FatFs_Check();
// 等待信号量 acquire , 判断FATFA是否在使用SD 卡; umount 文件系统
// 执行下面操作完成后释放信号量?
// for (;;) {
// event = osMessageGet(usbStateQueueHandle, osWaitForever);
// if (event.status == osEventMessage) {
// osMutexWait(sdFreeMutexHandle, osWaitForever);
// printf("hUsbDeviceFS:%d\n", (uint8_t) event.value.v);
// if ((uint8_t) event.value.v == USBD_STATE_ADDRESSED) {
// dev_state = USBD_STATE_ADDRESSED;
// } else if ((dev_state == USBD_STATE_ADDRESSED)
// && ((uint8_t) event.value.v == USBD_STATE_CONFIGURED)) {
// Set_SD_WriteOrRead(0);
// printf("usb connect\n");
// } else {
// dev_state = 0;
// Set_SD_WriteOrRead(1);
// printf("usb disconnect\n");
// }
// osMutexRelease(sdFreeMutexHandle);
// }
// }
}
// // 文件操作测试
// static void FILE_MGT_SD_TEST_TASK(const void *arg) {
// osDelay(500);
// for (;;) {
// osDelay(500);
// osMutexWait(sdFreeMutexHandle, osWaitForever);
// if (SDCard_EN) {
// FatFs_FileTest();
// } else {
// printf("禁止使用SD卡\n");
// }
// osMutexRelease(sdFreeMutexHandle);
// }
// }
// // 使能/禁止SD卡读写 1允许 0禁止
// static void Set_SD_WriteOrRead(uint8_t en) {
// if (en == 1) {
// SD_Create_Queue();
// SDCard_EN = 1;
// } else {
// SD_Delet_Queue();
// SDCard_EN = 0;
// }
// }
// void SD_Delet_Queue(void) {
// osMessageDelete(SDQueueID);
// }
// void SD_Create_Queue(void) {
// osMessageQDef(SD_Queue, QUEUE_SIZE, uint16_t);
// SDQueueID = osMessageCreate(osMessageQ(SD_Queue), NULL);
// }

@ -0,0 +1,278 @@
##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [4.1.0] date: [Mon Oct 16 20:04:02 CST 2023]
##########################################################################################################################
# ------------------------------------------------
# Generic Makefile (based on gcc)
#
# ChangeLog :
# 2017-02-10 - Several enhancements + project update mode
# 2015-07-22 - first version
# ------------------------------------------------
######################################
# target
######################################
TARGET = 429IGT6
######################################
# building variables
######################################
# debug build?
DEBUG = 1
# optimization
OPT = -Og
#######################################
# paths
#######################################
# Build path
BUILD_DIR = build
######################################
# source
######################################
# C sources
C_SOURCES = \
Core/Src/main.c \
Core/Src/gpio.c \
Core/Src/freertos.c \
Core/Src/dma.c \
Core/Src/fmc.c \
Core/Src/i2c.c \
Core/Src/spi.c \
Core/Src/tim.c \
Core/Src/usart.c \
Core/Src/stm32f4xx_it.c \
Core/Src/stm32f4xx_hal_msp.c \
Core/Src/stm32f4xx_hal_timebase_tim.c \
FATFS/Target/user_diskio.c \
FATFS/App/fatfs.c \
USB_DEVICE/App/usb_device.c \
USB_DEVICE/App/usbd_desc.c \
USB_DEVICE/App/usbd_storage_if.c \
USB_DEVICE/Target/usbd_conf.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \
Core/Src/system_stm32f4xx.c \
Middlewares/Third_Party/FatFs/src/diskio.c \
Middlewares/Third_Party/FatFs/src/ff.c \
Middlewares/Third_Party/FatFs/src/ff_gen_drv.c \
Middlewares/Third_Party/FatFs/src/option/syscall.c \
Middlewares/Third_Party/FatFs/src/option/cc936.c \
Middlewares/Third_Party/FreeRTOS/Source/croutine.c \
Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \
Middlewares/Third_Party/FreeRTOS/Source/list.c \
Middlewares/Third_Party/FreeRTOS/Source/queue.c \
Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c \
Middlewares/Third_Party/FreeRTOS/Source/tasks.c \
Middlewares/Third_Party/FreeRTOS/Source/timers.c \
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \
Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \
Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \
Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \
Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c \
Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c \
Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c \
Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c \
Core/Src/dma2d.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c \
Core/Src/ltdc.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc_ex.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dsi.c
# ASM sources
ASM_SOURCES = \
startup_stm32f429xx.s
#######################################
# binaries
#######################################
PREFIX = arm-none-eabi-
# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
#######################################
# CFLAGS
#######################################
# cpu
CPU = -mcpu=cortex-m4
# fpu
FPU = -mfpu=fpv4-sp-d16
# float-abi
FLOAT-ABI = -mfloat-abi=hard
# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
# macros for gcc
# AS defines
AS_DEFS =
# C defines
C_DEFS = \
-DUSE_HAL_DRIVER \
-DSTM32F429xx
# AS includes
AS_INCLUDES = \
-ICore/Inc
# C includes
C_INCLUDES = \
-ICore/Inc \
-IFATFS/Target \
-IFATFS/App \
-IUSB_DEVICE/App \
-IUSB_DEVICE/Target \
-IDrivers/STM32F4xx_HAL_Driver/Inc \
-IDrivers/STM32F4xx_HAL_Driver/Inc/Legacy \
-IMiddlewares/Third_Party/FreeRTOS/Source/include \
-IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \
-IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \
-IMiddlewares/Third_Party/FatFs/src \
-IMiddlewares/ST/STM32_USB_Device_Library/Core/Inc \
-IMiddlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc \
-IDrivers/CMSIS/Device/ST/STM32F4xx/Include \
-IDrivers/CMSIS/Include
# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
#######################################
# LDFLAGS
#######################################
# link script
LDSCRIPT = STM32F429IGTx_FLASH.ld
# libraries
LIBS = -lc -lm -lnosys
LIBDIR =
LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
export C_SOURCES C_INCLUDES CFLAGS C_DEFS LDFLAGS
include MyMakefile.mk
# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
#######################################
# build the application
#######################################
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
$(SZ) $@
$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(HEX) $< $@
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(BIN) $< $@
$(BUILD_DIR):
mkdir $@
#######################################
# clean up
#######################################
clean:
-rm -fR $(BUILD_DIR)
#######################################
# dependencies
#######################################
-include $(wildcard $(BUILD_DIR)/*.d)
#######################################
# upload
#######################################
upload:
# @openocd -f openocd_script/openocd_stlink_stm32f1.cfg -c init -c halt -c "flash write_image erase $(BUILD_DIR)/$(TARGET).bin 0x08000000" -c reset -c shutdown
# @openocd -f openocd_script/openocd_stlink_stm32f1.cfg -c init -c halt -c "program $(BUILD_DIR)/$(TARGET).bin exit 0x08000000" -c reset -c shutdown
# @openocd -f openocd_script/openocd_stlink_stm32f1.cfg -c init -c halt -c "program $(BUILD_DIR)/$(TARGET).elf verify reset exit" -c reset -c shutdown
# @openocd -f interface/stlink.cfg \
# -f target/stm32f4x.cfg \
# -c init -c reset -c halt \
# -c "program $(BUILD_DIR)/YH-F429.bin exit 0x08000000" \
# -c reset \
# -c shutdown
@openocd -f interface/stlink.cfg \
-f target/stm32f4x.cfg \
-c init -c reset -c halt \
-c "program $(BUILD_DIR)/$(TARGET).bin exit 0x08000000" \
-c reset \
-c shutdown
# *** EOF ***

@ -0,0 +1,382 @@
#######################################
# 定义模块块相关开关
# 注意可能需要修改端口及代码,配置文件
#######################################
Easylogger := ON
# Easylogger_Buff := OFF
# Easylogger_Asyn := OFF
MODBUS := OFF
# MODBUS_ASII := OFF
# MODBUS_IP := OFF
LVGL_On_Off := OFF
FPU_OnOff := OFF
#######################################
# 中文编码支持
#######################################
CFLAGS += -fexec-charset=UTF-8 -finput-charset=UTF-8 -std=c99
LDFLAGS += -Wl,-u_printf_float
# C_SOURCES += Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c \
# Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c \
# Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c \
# C_SOURCES += Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c
#######################################
# FPU支持
# C_DEFS += -D__TARGET_FPU_VFP -DARM_MATH_CM4
# C_DEFS += -D__TARGET_FPU_VFP -D__FPU_USED=1 -D__FPU_PRESENT=1 -DARM_MATH_CM4
#######################################
ifeq ($(FPU_OnOff),ON)
C_DEFS += -D__TARGET_FPU_VFP -DARM_MATH_CM4
endif
######################################
# 自己代码 FATFS add
######################################
C_SOURCES += $(wildcard *.c FATFS/Target/nandflash_diskio.c)
# C_INCLUDES += -ICode/base/Inc
######################################
# 自己代码 base
######################################
C_SOURCES += $(wildcard *.c Code/base/Src/*.c)
C_INCLUDES += -ICode/base/Inc
C_SOURCES += $(wildcard *.c Code/bsp/Src/*.c)
C_INCLUDES += -ICode/bsp/Inc
C_SOURCES += $(wildcard *.c Code/device/Src/*.c)
C_INCLUDES += -ICode/device/Inc
C_SOURCES += $(wildcard *.c Code/libraries/Src/*.c)
C_INCLUDES += -ICode/libraries/Inc
C_SOURCES += $(wildcard *.c Code/font/Src/*.c)
C_INCLUDES += -ICode/font/Inc
C_SOURCES += $(wildcard *.c Code/touch/Src/*.c)
C_INCLUDES += -ICode/touch/Inc
C_SOURCES += $(wildcard *.c Code/UI/Src/*.c)
C_INCLUDES += -ICode/UI/Inc
# #######################################
# ### Easylogger 相关
# Middlewares/Third_Party/easylogger
# #######################################
ifeq ($(Easylogger),ON)
C_SOURCES += $(wildcard *.c Code/port/easylogger/*.c)
C_INCLUDES += -ICode/port/easylogger
C_INCLUDES += -IMiddlewares/Third_Party/easylogger/inc
C_SOURCES += \
Middlewares/Third_Party/easylogger/src/elog.c \
Middlewares/Third_Party/easylogger/src/elog_utils.c \
Middlewares/Third_Party/easylogger/src/elog_buf.c \
Middlewares/Third_Party/easylogger/src/elog_async.c
endif
ifeq ($(Easylogger_Buff),ON)
C_SOURCES += \
Middlewares/Third_Party/easylogger/src/elog_buf.c
endif
ifeq ($(Easylogger_Asyn),ON)
C_SOURCES += \
Middlewares/Third_Party/easylogger/src/elog_async.c
endif
# #######################################
# ### Modbus 相关
# #######################################
ifeq ($(MODBUS),ON)
C_SOURCES += $(wildcard *.c Code/port/FreeModbus/*.c)
C_INCLUDES += -ICode/port/FreeModbus
C_INCLUDES += -IMiddlewares/Third_Party/FreeModbus/include
C_INCLUDES += -IMiddlewares/Third_Party/FreeModbus/rtu
# C_INCLUDES += -IMiddlewares/Third_Party/FreeModbus/port
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/FreeModbus/functions/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/FreeModbus/rtu/*.c)
# C_SOURCES += $(wildcard *.c Middlewares/Third_Party/FreeModbus/port/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/FreeModbus/*.c)
endif
# #######################################
# ### LVGL 相关
# #######################################
ifeq ($(LVGL_On_Off),ON)
C_DEFS += -DLV_LVGL_H_INCLUDE_SIMPLE
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/demos/*.c)
# C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/demos/benchmark/*.c)
# C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/demos/benchmark/assets/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/demos/keypad_encoder/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/demos/music/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/demos/music/assets/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/demos/stress/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/demos/widgets/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/demos/widgets/assets/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/anim/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/arduino/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/arduino/LVGL_Arduino/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/assets/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/assets/emoji/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/assets/font/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/event/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/get_started/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/layouts/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/layouts/flex/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/layouts/grid/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/libs/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/libs/bmp/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/libs/ffmpeg/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/libs/freetype/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/libs/gif/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/libs/png/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/libs/qrcode/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/libs/rlottie/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/libs/sjpg/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/others/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/others/fragment/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/others/gridnav/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/others/ime/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/others/imgfont/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/others/monkey/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/others/msg/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/others/snapshot/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/porting/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/scroll/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/styles/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/animimg/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/arc/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/bar/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/btn/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/btnmatrix/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/calendar/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/canvas/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/chart/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/checkbox/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/colorwheel/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/dropdown/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/img/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/imgbtn/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/keyboard/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/label/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/led/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/line/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/list/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/menu/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/meter/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/msgbox/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/obj/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/roller/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/slider/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/span/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/spinbox/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/spinner/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/switch/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/table/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/tabview/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/textarea/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/tileview/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/examples/widgets/win/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/port/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/core/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/draw/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/draw/arm2d/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/draw/nxp/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/draw/nxp/pxp/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/draw/nxp/vglite/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/draw/renesas/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/draw/sdl/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/draw/stm32_dma2d/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/draw/sw/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/draw/swm341_dma2d/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/layouts/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/layouts/flex/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/layouts/grid/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/libs/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/libs/bmp/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/libs/ffmpeg/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/libs/freetype/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/libs/fsdrv/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/libs/gif/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/libs/png/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/libs/qrcode/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/libs/rlottie/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/libs/sjpg/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/others/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/others/fragment/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/others/gridnav/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/others/ime/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/others/imgfont/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/others/monkey/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/others/msg/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/others/snapshot/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/themes/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/themes/basic/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/themes/default/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/themes/mono/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/animimg/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/calendar/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/chart/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/colorwheel/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/imgbtn/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/keyboard/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/led/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/list/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/menu/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/meter/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/msgbox/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/span/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/spinbox/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/spinner/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/tabview/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/tileview/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/extra/widgets/win/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/font/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/hal/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/misc/*.c)
C_SOURCES += $(wildcard *.c Middlewares/Third_Party/lvgl/src/widgets/*.c)
C_INCLUDES += -IMiddlewares/Third_Party/lvgl
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/demos
# C_INCLUDES += -IMiddlewares/Third_Party/lvgl/demos/benchmark
# C_INCLUDES += -IMiddlewares/Third_Party/lvgl/demos/benchmark/assets
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/demos/keypad_encoder
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/demos/music
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/demos/music/assets
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/demos/stress
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/demos/widgets
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/demos/widgets/assets
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/anim
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/arduino
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/arduino/LVGL_Arduino
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/assets
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/assets/emoji
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/assets/font
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/event
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/get_started
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/layouts
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/layouts/flex
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/layouts/grid
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/libs
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/libs/bmp
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/libs/ffmpeg
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/libs/freetype
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/libs/gif
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/libs/png
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/libs/qrcode
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/libs/rlottie
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/libs/sjpg
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/others
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/others/fragment
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/others/gridnav
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/others/ime
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/others/imgfont
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/others/monkey
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/others/msg
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/others/snapshot
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/porting
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/scroll
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/styles
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/animimg
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/arc
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/bar
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/btn
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/btnmatrix
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/calendar
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/canvas
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/chart
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/checkbox
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/colorwheel
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/dropdown
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/img
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/imgbtn
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/keyboard
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/label
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/led
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/line
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/list
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/menu
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/meter
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/msgbox
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/obj
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/roller
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/slider
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/span
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/spinbox
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/spinner
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/switch
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/table
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/tabview
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/textarea
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/tileview
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/examples/widgets/win
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/port
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/core
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/draw
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/draw/arm2d
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/draw/nxp
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/draw/nxp/pxp
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/draw/nxp/vglite
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/draw/renesas
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/draw/sdl
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/draw/stm32_dma2d
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/draw/sw
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/draw/swm341_dma2d
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/layouts
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/layouts/flex
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/layouts/grid
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/libs
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/libs/bmp
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/libs/ffmpeg
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/libs/freetype
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/libs/fsdrv
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/libs/gif
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/libs/png
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/libs/qrcode
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/libs/rlottie
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/libs/sjpg
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/others
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/others/fragment
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/others/gridnav
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/others/ime
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/others/imgfont
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/others/monkey
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/others/msg
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/others/snapshot
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/themes
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/themes/basic
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/themes/default
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/themes/mono
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/animimg
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/calendar
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/chart
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/colorwheel
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/imgbtn
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/keyboard
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/led
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/list
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/menu
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/meter
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/msgbox
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/span
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/spinbox
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/spinner
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/tabview
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/tileview
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/extra/widgets/win
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/font
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/hal
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/misc
C_INCLUDES += -IMiddlewares/Third_Party/lvgl/src/widgets
endif

@ -0,0 +1,865 @@
#include "mb.h"
#include "mbport.h"
#include "port.h"
#include "elog.h"
extern void Modbus_Port( );
extern void Modbus_Task(void * argument);
osThreadId_t modbus_taskHandle;
const osThreadAttr_t modbus_task_attributes = {
.name = "modbus_task",
.stack_size = 512,
.priority = (osPriority_t) osPriorityLow,
};
void Modbus_Port( )
{
modbus_taskHandle = osThreadNew( Modbus_Task, NULL, &modbus_task_attributes );
}
/* ----------------------- Defines ------------------------------------------*/
// 输入寄存器
#define REG_INPUT_START 0
#define REG_INPUT_NREGS 6
// 保持寄存器
#define REG_HOLD_START 0
#define REG_HOLD_NREGS 10
// 线圈
#define REG_COILS_START 0
#define REG_COILS_NREGS 4
// 开关寄存器
#define REG_DISCRETE_START 0
#define REG_DISCRETE_NREGS 4
/* ----------------------- Static variables ---------------------------------*/
static USHORT usRegInputStart = REG_INPUT_START;
static USHORT usRegHoldStart = REG_HOLD_START;
static USHORT usRegCoilsStart = REG_COILS_START;
static USHORT usRegDiscreteStart = REG_DISCRETE_START;
//static
uint16_t usRegInputBuf[REG_INPUT_NREGS];
uint16_t InputBuff[5]; // 这个buf 传递给usRegInputBuf
uint16_t usRegHoldBuf[REG_HOLD_NREGS];
uint16_t HoldBuff[10];
static uint8_t usRegCoilsBuf[REG_COILS_NREGS];
static uint8_t usRegDiscreteBuf[REG_DISCRETE_NREGS];
void Modbus_Set_HoldingBuff(uint8_t* buf, uint16_t size, uint16_t begin)
{
/* 设置 Holding 寄存器, usRegHoldBuf , 16 位寄存器 */
/* 判断是否超长 */
if (size > 2*(REG_HOLD_NREGS - begin))
{
return;
}
ENTER_CRITICAL_SECTION();
memcpy( (uint8_t*) (usRegHoldBuf+begin) , buf, size);
EXIT_CRITICAL_SECTION();
}
void Modbus_Task(void * argument)
{
/* ABCDEF */
InputBuff[0] = 0x11;
InputBuff[1] = 0x22;
InputBuff[2] = 0x33;
InputBuff[3] = 0x44;
InputBuff[4] = 0x55;
InputBuff[5] = 0x66;
usRegHoldBuf[0] = 0x99;
usRegHoldBuf[1] = 0x22;
usRegHoldBuf[2] = 0x33;
usRegHoldBuf[3] = 0x44;
usRegHoldBuf[4] = 0x55;
usRegHoldBuf[5] = 0x66;
usRegHoldBuf[6] = 0x77;
usRegHoldBuf[7] = 0x88;
usRegHoldBuf[8] = 0x99;
usRegHoldBuf[9] = 0xBB;
usRegCoilsBuf[0] = 0;
usRegCoilsBuf[1] = 1;
usRegCoilsBuf[2] = 1;
usRegCoilsBuf[3] =1;
usRegDiscreteBuf[0] = 1;
usRegDiscreteBuf[1] = 0;
usRegDiscreteBuf[2] = 0;
usRegDiscreteBuf[3] =1;
eMBInit(MB_RTU, 0x01, 0x00, 9600, MB_PAR_NONE);
eMBEnable();
for(;;)
{
eMBPoll();
osDelay(2);
}
}
// /****************************************************************************
// * 名 称:eMBRegInputCB 输入寄存器,如模拟量输入
// * 功 能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister
// * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
// * usAddress: 寄存器地址
// * usNRegs: 要读取的寄存器个数
// * 出口参数:
// * 注 意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
// * +StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)
// * +LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
// * +CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)
// 功 能 码:04
// ****************************************************************************/
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
eMBErrorCode eStatus = MB_ENOERR;
int iRegIndex;
int i;
// 动态改变 Input
// InputBuff[0] = 0x11;
// InputBuff[1] = 0x22;
// InputBuff[2] = 0x33;
// InputBuff[3] = 0x44;
// InputBuff[4] = 0x55;
// InputBuff[5] = 0x66;
if( ( usAddress >= REG_INPUT_START )
&& ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
{
iRegIndex = ( int )( usAddress - usRegInputStart );
for(i=0;i<usNRegs;i++)
{
*pucRegBuffer=InputBuff[i+usAddress-1]>>8;
pucRegBuffer++;
*pucRegBuffer=InputBuff[i+usAddress-1]&0xff;
pucRegBuffer++;
}
}
else
{
eStatus = MB_ENOREG;
}
return eStatus;
}
/****************************************************************************
* eMBRegHoldingCB
* 06 eMBFuncWriteHoldingRegister
* 16 eMBFuncWriteMultipleHoldingRegister
* 03 eMBFuncReadHoldingRegister
* 23 eMBFuncReadWriteMultipleHoldingRegister
* pucRegBuffer:
* usAddress:
* usNRegs:
* eMode:
*
* 03 06 16
****************************************************************************/
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
{
eMBErrorCode eStatus = MB_ENOERR;
int iRegIndex;
usAddress = usAddress - 1;
// log_i("eMBRegHoldingCB eMode %d usNRegs %d usAddress :%d",eMode, usNRegs,usAddress);
// usRegHoldBuf[0] = 0x99;
// usRegHoldBuf[1] = 0x22;
// usRegHoldBuf[2] = 0x33;
// usRegHoldBuf[3] = 0x44;
// usRegHoldBuf[4] = 0x55;
// usRegHoldBuf[5] = 0x66;
// usRegHoldBuf[6] = 0x77;
// usRegHoldBuf[7] = 0x88;
// usRegHoldBuf[8] = 0x99;
// usRegHoldBuf[9] = 0xBB;
if((usAddress >= REG_HOLD_START) && ((usAddress+usNRegs) <= (REG_HOLD_START + REG_HOLD_NREGS)))
{
iRegIndex = (int)(usAddress - usRegHoldStart);
switch(eMode)
{
case MB_REG_READ://读寄存器
while(usNRegs > 0)
{
*pucRegBuffer++ = (uint8_t)(usRegHoldBuf[iRegIndex] >> 8);
*pucRegBuffer++ = (uint8_t)(usRegHoldBuf[iRegIndex] & 0xFF);
iRegIndex++;
usNRegs--;
}
break;
case MB_REG_WRITE://写寄存器
ENTER_CRITICAL_SECTION();
while(usNRegs > 0)
{
// log_i("eMBRegHoldingCB iRegIndex %d %02X %02X ",iRegIndex,(uint8_t)(*pucRegBuffer),(uint8_t)(*(pucRegBuffer+1)));
// log_i("eMBRegHoldingCB iRegIndex %d %02X %02X ",iRegIndex,(uint8_t)(*pucRegBuffer++ << 8),(uint8_t)(*pucRegBuffer++));
usRegHoldBuf[iRegIndex] = *pucRegBuffer++ << 8;
usRegHoldBuf[iRegIndex] |= *pucRegBuffer++;
// log_i("eMBRegHoldingCB %02X %02X",(uint8_t)(usRegHoldBuf[iRegIndex] >> 8), (uint8_t)(usRegHoldBuf[iRegIndex] & 0xFF ));
iRegIndex++;
usNRegs--;
}
EXIT_CRITICAL_SECTION();
}
}
else//错误
{
eStatus = MB_ENOREG;
}
// for (size_t i = 0; i < 10; i++)
// {
// log_i(" i : %d val : %04X", i, usRegHoldBuf[i]);
// }
return eStatus;
}
/****************************************************************************
* eMBRegCoilsCB
* 01 线 eMBFuncReadCoils
* 05 线 eMBFuncWriteCoil
* 15 线 eMBFuncWriteMultipleCoils
* pucRegBuffer:
* usAddress: 线
* usNCoils: 线
* eMode:
*
* 01
*
****************************************************************************/
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
{
eMBErrorCode eStatus = MB_ENOERR;
USHORT iRegIndex;
USHORT usCoilGroups = ((usNCoils - 1) / 8 + 1);
UCHAR ucStatus = 0;
UCHAR ucBits = 0;
UCHAR ucDisp = 0;
usAddress = usAddress - 1;
log_i("eMBRegCoilsCB eMode %d usNCoils %d usAddress :%d",eMode, usNCoils,usAddress);
if((usAddress >= REG_COILS_START) && ((usAddress + usNCoils) <= (REG_COILS_START + REG_COILS_NREGS)))
{
iRegIndex = (int)(usAddress - usRegCoilsStart);
switch(eMode)
{
case MB_REG_READ://读线圈
while(usCoilGroups--)
{
ucDisp = 0;
ucBits = 8;
while((usNCoils--) != 0 && (ucBits--) != 0)
{
ucStatus |= (usRegCoilsBuf[iRegIndex++] << (ucDisp++));
}
*pucRegBuffer++ = ucStatus;
}
break;
case MB_REG_WRITE://写线圈
// ENTER_CRITICAL_SECTION();
while(usCoilGroups--)
{
ucStatus = *pucRegBuffer++;
ucBits = 8;
while((usNCoils--) != 0 && (ucBits--) != 0)
{
usRegCoilsBuf[iRegIndex++] = ucStatus & 0X01;
ucStatus >>= 1;
}
}
// EXIT_CRITICAL_SECTION();
}
}
else//错误
{
eStatus = MB_ENOREG;
}
return eStatus;
}
/****************************************************************************
* eMBRegDiscreteCB
* 02 eMBFuncReadDiscreteInputs
* pucRegBuffer:
* usAddress:
* usNDiscrete:
*
* 02
****************************************************************************/
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
eMBErrorCode eStatus = MB_ENOERR;
USHORT iRegIndex;
USHORT usDiscreteGroups = ((usNDiscrete - 1) / 8 + 1);
UCHAR ucStatus = 0;
UCHAR ucBits = 0;
UCHAR ucDisp = 0;
usAddress = usAddress - 1;
log_i("eMBRegDiscreteCB usAddress :%d usNDiscrete : %d", usAddress, usNDiscrete);
if((usAddress >= REG_DISCRETE_START) && ((usAddress + usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_NREGS)))
{
iRegIndex = (int)(usAddress - usRegDiscreteStart);
log_i("eMBRegDiscreteCB iRegIndex :%d usNDiscrete : %d", iRegIndex, usNDiscrete);
while(usDiscreteGroups--)
{
ucDisp = 0;
ucBits = 8;
while((usNDiscrete--) != 0 && (ucBits--) != 0)
{
log_i("val :%d %d ", iRegIndex, usRegDiscreteBuf[iRegIndex]);
if(usRegDiscreteBuf[iRegIndex])
{
ucStatus |= (1 << ucDisp);
}
iRegIndex++;
ucDisp++;
}
*pucRegBuffer++ = ucStatus;
}
}
else//错误
{
eStatus = MB_ENOREG;
}
return eStatus;
}
// ----------------------------------------------------
// #include "mb.h"
// #include "mbport.h"
// #include "main.h"
// #if !defined(LOG_TAG)
// #define LOG_TAG "Modbus"
// #endif
// #undef LOG_LVL
// #if defined(XX_LOG_LVL)
// #define LOG_LVL XX_LOG_LVL
// #endif
// #include "elog.h"
// //输入寄存器
// #define REG_INPUT_START 3000
// #define REG_INPUT_NREGS 4
// //保持寄存器
// #define REG_HOLD_START 4000
// #define REG_HOLD_NREGS 10
// //线圈
// #define REG_COILS_START 0
// #define REG_COILS_NREGS 4
// //开关寄存器
// #define REG_DISCRETE_START 1000
// #define REG_DISCRETE_NREGS 4
// /* ----------------------- Static variables ---------------------------------*/
// static USHORT usRegInputStart = REG_INPUT_START;
// static USHORT usRegInputBuf[REG_INPUT_NREGS];
// static USHORT usRegHoldStart = REG_HOLD_START;
// static USHORT usRegHoldBuf[REG_HOLD_NREGS];
// static USHORT usRegCoilsStart = REG_COILS_START;
// static uint8_t usRegCoilsBuf[REG_COILS_NREGS];
// static USHORT usRegDiscreteStart = REG_DISCRETE_START;
// static uint8_t usRegDiscreteBuf[REG_DISCRETE_NREGS];
// /** 初始化供调用*/
// void ModbusRTUTask(void const * argument)
// {
// eMBPoll();
// }
// void ModbusRTUInit(void const * argument)
// {
// /* ABCDEF */
// usRegInputBuf[0] = 11;
// usRegInputBuf[1] = 22;
// usRegInputBuf[2] = 33;
// usRegInputBuf[3] = 44;
// usRegInputBuf[4] = 55;
// usRegInputBuf[5] = 66;
// usRegInputBuf[6] = 77;
// usRegInputBuf[7] = 88;
// // 初始化modbus为RTU方式,地址0x01, 波特率9600,无校验
// eMBErrorCode eStatus = eMBInit( MB_RTU, 1, 3, 19200, MB_PAR_NONE );
// // 使能modbus协议栈
// eStatus = eMBEnable();
// // log_i("usRegInputBuf 0 8: %d %d ", usRegInputBuf[0], usRegInputBuf[7] );
// }
// /****************************************************************************
// * 名 称:eMBRegInputCB
// * 功 能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister
// * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
// * usAddress: 寄存器地址
// * usNRegs: 要读取的寄存器个数
// * 出口参数:
// * 注 意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
// * +StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)
// * +LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
// * +CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)
// * 3 区
// ****************************************************************************/
// eMBErrorCode
// eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
// {
// eMBErrorCode eStatus = MB_ENOERR;
// int iRegIndex;
// usAddress = usAddress - 1;
// if( ( usAddress >= REG_INPUT_START ) && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
// {
// iRegIndex = ( int )( usAddress - usRegInputStart );
// while( usNRegs > 0 )
// {
// *pucRegBuffer++ = ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 );
// *pucRegBuffer++ = ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );
// iRegIndex++;
// usNRegs--;
// }
// }
// else
// {
// eStatus = MB_ENOREG;
// }
// return eStatus;
// }
// /****************************************************************************
// * 名 称:eMBRegHoldingCB
// * 功 能:对应功能码有:06 写保持寄存器 eMBFuncWriteHoldingRegister
// * 16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister
// * 03 读保持寄存器 eMBFuncReadHoldingRegister
// * 23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister
// * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
// * usAddress: 寄存器地址
// * usNRegs: 要读写的寄存器个数
// * eMode: 功能码
// * 出口参数:
// * 注 意:4 区
// ****************************************************************************/
// eMBErrorCode
// eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
// {
// eMBErrorCode eStatus = MB_ENOERR;
// int iRegIndex;
// usAddress = usAddress - 1;
// if((usAddress >= REG_HOLD_START) && ((usAddress+usNRegs) <= (REG_HOLD_START + REG_HOLD_NREGS)))
// {
// iRegIndex = (int)(usAddress - usRegHoldStart);
// switch(eMode)
// {
// case MB_REG_READ://读寄存器
// while(usNRegs > 0)
// {
// *pucRegBuffer++ = (uint8_t)(usRegHoldBuf[iRegIndex] >> 8);
// *pucRegBuffer++ = (uint8_t)(usRegHoldBuf[iRegIndex] & 0xFF);
// iRegIndex++;
// usNRegs--;
// }
// break;
// case MB_REG_WRITE://写寄存器
// while(usNRegs > 0)
// {
// usRegHoldBuf[iRegIndex] = *pucRegBuffer++ << 8;
// usRegHoldBuf[iRegIndex] |= *pucRegBuffer++;
// iRegIndex++;
// usNRegs--;
// }
// }
// }
// else//错误
// {
// eStatus = MB_ENOREG;
// }
// return eStatus;
// }
// /****************************************************************************
// * 名 称:eMBRegCoilsCB
// * 功 能:对应功能码有:01 读线圈 eMBFuncReadCoils
// * 05 写线圈 eMBFuncWriteCoil
// * 15 写多个线圈 eMBFuncWriteMultipleCoils
// * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
// * usAddress: 线圈地址
// * usNCoils: 要读写的线圈个数
// * eMode: 功能码
// * 出口参数:
// * 注 意:如继电器
// * 0 区
// ****************************************************************************/
// eMBErrorCode
// eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
// {
// eMBErrorCode eStatus = MB_ENOERR;
// USHORT iRegIndex;
// USHORT usCoilGroups = ((usNCoils - 1) / 8 + 1);
// UCHAR ucStatus = 0;
// UCHAR ucBits = 0;
// UCHAR ucDisp = 0;
// usAddress = usAddress - 1;
// if((usAddress >= REG_COILS_START) && ((usAddress + usNCoils) <= (REG_COILS_START + REG_COILS_NREGS)))
// {
// iRegIndex = (int)(usAddress - usRegCoilsStart);
// switch(eMode)
// {
// case MB_REG_READ://读线圈
// while(usCoilGroups--)
// {
// ucDisp = 0;
// ucBits = 8;
// while((usNCoils--) != 0 && (ucBits--) != 0)
// {
// ucStatus |= (usRegCoilsBuf[iRegIndex++] << (ucDisp++));
// }
// *pucRegBuffer++ = ucStatus;
// }
// break;
// case MB_REG_WRITE://写线圈
// while(usCoilGroups--)
// {
// ucStatus = *pucRegBuffer++;
// ucBits = 8;
// while((usNCoils--) != 0 && (ucBits--) != 0)
// {
// usRegCoilsBuf[iRegIndex++] = ucStatus & 0X01;
// ucStatus >>= 1;
// }
// }
// }
// }
// else//错误
// {
// eStatus = MB_ENOREG;
// }
// return eStatus;
// }
// /****************************************************************************
// * 名 称:eMBRegDiscreteCB
// * 功 能:读取离散寄存器,对应功能码有:02 读离散寄存器 eMBFuncReadDiscreteInputs
// * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
// * usAddress: 寄存器地址
// * usNDiscrete: 要读取的寄存器个数
// * 出口参数:
// * 注 意:1 区
// ****************************************************************************/
// eMBErrorCode
// eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
// {
// eMBErrorCode eStatus = MB_ENOERR;
// USHORT iRegIndex;
// USHORT usDiscreteGroups = ((usNDiscrete - 1) / 8 + 1);
// UCHAR ucStatus = 0;
// UCHAR ucBits = 0;
// UCHAR ucDisp = 0;
// usAddress = usAddress - 1;
// if((usAddress >= REG_DISCRETE_START) && ((usAddress + usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_NREGS)))
// {
// iRegIndex = (int)(usAddress - usRegDiscreteStart);
// while(usDiscreteGroups--)
// {
// ucDisp = 0;
// ucBits = 8;
// while((usNDiscrete--) != 0 && (ucBits--) != 0)
// {
// if(usRegDiscreteBuf[iRegIndex])
// {
// ucStatus |= (1 << ucDisp);
// }
// ucDisp++;
// }
// *pucRegBuffer++ = ucStatus;
// }
// }
// else//错误
// {
// eStatus = MB_ENOREG;
// }
// return eStatus;
// }
// // extern UART_HandleTypeDef huart2; // 引入串口
// // // 十路输入寄存器
// // #define REG_INPUT_SIZE 10
// // uint16_t REG_INPUT_BUF[REG_INPUT_SIZE];
// // // 十路保持寄存器
// // #define REG_HOLDING_START 0x0000
// // #define REG_HOLD_SIZE 8
// // // uint16_t REG_HOLD_BUF[REG_HOLD_SIZE];
// // uint16_t usRegHoldingBuf[REG_HOLD_SIZE] = {0x147b, 0x3f8e, 0x147b, 0x400e, 0x1eb8, 0x4055, 0x147b, 0x408e};
// // // 十路线圈
// // #define REG_COILS_SIZE 10
// // uint8_t REG_COILS_BUF[REG_COILS_SIZE] = {1, 1, 1, 1, 0, 0, 0, 0, 1, 1};
// // // 十路离散量
// // #define REG_DISC_SIZE 10
// // uint8_t REG_DISC_BUF[REG_DISC_SIZE] = {1, 1, 1, 1, 0, 0, 0, 0, 1, 1};
// // /// CMD4命令处理回调函数
// // eMBErrorCode eMBRegInputCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs)
// // {
// // USHORT usRegIndex = usAddress - 1;
// // // 非法检测
// // if ((usRegIndex + usNRegs) > REG_INPUT_SIZE)
// // {
// // return MB_ENOREG;
// // }
// // // 循环读取
// // while (usNRegs > 0)
// // {
// // *pucRegBuffer++ = (unsigned char)(REG_INPUT_BUF[usRegIndex] >> 8);
// // *pucRegBuffer++ = (unsigned char)(REG_INPUT_BUF[usRegIndex] & 0xFF);
// // usRegIndex++;
// // usNRegs--;
// // }
// // // 模拟输入寄存器被改变
// // for (usRegIndex = 0; usRegIndex < REG_INPUT_SIZE; usRegIndex++)
// // {
// // REG_INPUT_BUF[usRegIndex]++;
// // }
// // return MB_ENOERR;
// // }
// // /// CMD6、3、16命令处理回调函数
// // eMBErrorCode eMBRegHoldingCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode)
// // {
// // // 错误状态
// // eMBErrorCode eStatus = MB_ENOERR;
// // // 偏移量
// // int16_t iRegIndex;
// // // 判断寄存器是不是在范围内
// // if (((int16_t)usAddress >= REG_HOLDING_START) && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLD_SIZE))
// // {
// // // 计算偏移量
// // iRegIndex = (int16_t)(usAddress - REG_HOLDING_START);
// // switch (eMode)
// // {
// // // 读处理函数
// // case MB_REG_READ:
// // while (usNRegs > 0)
// // {
// // *pucRegBuffer++ = (uint8_t)(usRegHoldingBuf[iRegIndex] >> 8);
// // *pucRegBuffer++ = (uint8_t)(usRegHoldingBuf[iRegIndex] & 0xFF);
// // iRegIndex++;
// // usNRegs--;
// // }
// // break;
// // // 写处理函数
// // case MB_REG_WRITE:
// // while (usNRegs > 0)
// // {
// // usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
// // usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
// // iRegIndex++;
// // usNRegs--;
// // }
// // break;
// // }
// // }
// // else
// // {
// // // 返回错误状态
// // eStatus = MB_ENOREG;
// // }
// // return eStatus;
// // // USHORT usRegIndex = usAddress - 1;
// // // // 非法检测
// // // if((usRegIndex + usNRegs) > REG_HOLD_SIZE)
// // // {
// // // return MB_ENOREG;
// // // }
// // // // 写寄存器
// // // if(eMode == MB_REG_WRITE)
// // // {
// // // while( usNRegs > 0 )
// // // {
// // // usRegHoldingBuf[usRegIndex] = (pucRegBuffer[0] << 8) | pucRegBuffer[1];
// // // pucRegBuffer += 2;
// // // usRegIndex++;
// // // usNRegs--;
// // // }
// // // }
// // // // 读寄存器
// // // else
// // // {
// // // while( usNRegs > 0 )
// // // {
// // // *pucRegBuffer++ = ( unsigned char )( usRegHoldingBuf[usRegIndex] >> 8 );
// // // *pucRegBuffer++ = ( unsigned char )( usRegHoldingBuf[usRegIndex] & 0xFF );
// // // usRegIndex++;
// // // usNRegs--;
// // // }
// // // }
// // // return MB_ENOERR;
// // }
// // /// CMD1、5、15命令处理回调函数
// // eMBErrorCode eMBRegCoilsCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode)
// // {
// // USHORT usRegIndex = usAddress - 1;
// // UCHAR ucBits = 0;
// // UCHAR ucState = 0;
// // UCHAR ucLoops = 0;
// // // 非法检测
// // if ((usRegIndex + usNCoils) > REG_COILS_SIZE)
// // {
// // return MB_ENOREG;
// // }
// // if (eMode == MB_REG_WRITE)
// // {
// // ucLoops = (usNCoils - 1) / 8 + 1;
// // while (ucLoops != 0)
// // {
// // ucState = *pucRegBuffer++;
// // ucBits = 0;
// // while (usNCoils != 0 && ucBits < 8)
// // {
// // REG_COILS_BUF[usRegIndex++] = (ucState >> ucBits) & 0X01;
// // usNCoils--;
// // ucBits++;
// // }
// // ucLoops--;
// // }
// // }
// // else
// // {
// // ucLoops = (usNCoils - 1) / 8 + 1;
// // while (ucLoops != 0)
// // {
// // ucState = 0;
// // ucBits = 0;
// // while (usNCoils != 0 && ucBits < 8)
// // {
// // if (REG_COILS_BUF[usRegIndex])
// // {
// // ucState |= (1 << ucBits);
// // }
// // usNCoils--;
// // usRegIndex++;
// // ucBits++;
// // }
// // *pucRegBuffer++ = ucState;
// // ucLoops--;
// // }
// // }
// // return MB_ENOERR;
// // }
// // /// CMD2命令处理回调函数
// // eMBErrorCode eMBRegDiscreteCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNDiscrete)
// // {
// // USHORT usRegIndex = usAddress - 1;
// // UCHAR ucBits = 0;
// // UCHAR ucState = 0;
// // UCHAR ucLoops = 0;
// // // 非法检测
// // if ((usRegIndex + usNDiscrete) > REG_DISC_SIZE)
// // {
// // return MB_ENOREG;
// // }
// // ucLoops = (usNDiscrete - 1) / 8 + 1;
// // while (ucLoops != 0)
// // {
// // ucState = 0;
// // ucBits = 0;
// // while (usNDiscrete != 0 && ucBits < 8)
// // {
// // if (REG_DISC_BUF[usRegIndex])
// // {
// // ucState |= (1 << ucBits);
// // }
// // usNDiscrete--;
// // usRegIndex++;
// // ucBits++;
// // }
// // *pucRegBuffer++ = ucState;
// // ucLoops--;
// // }
// // // 模拟离散量输入被改变
// // for (usRegIndex = 0; usRegIndex < REG_DISC_SIZE; usRegIndex++)
// // {
// // REG_DISC_BUF[usRegIndex] = !REG_DISC_BUF[usRegIndex];
// // }
// // return MB_ENOERR;
// // }

@ -0,0 +1,75 @@
/*
* FreeModbus Libary: BARE Port
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id$
*/
#ifndef _PORT_H
#define _PORT_H
#include <assert.h>
#include <inttypes.h>
#include "main.h"
#include "cmsis_os2.h"
#include "FreeRTOSConfig.h"
#define MODBUS_USED_FREERTOS 1
#define INLINE inline
#define PR_BEGIN_EXTERN_C \
extern "C" \
{
#define PR_END_EXTERN_C }
#define ENTER_CRITICAL_SECTION() ( __disable_irq() )
#define EXIT_CRITICAL_SECTION() ( __enable_irq() )
typedef uint8_t BOOL;
typedef unsigned char UCHAR;
typedef char CHAR;
typedef uint16_t USHORT;
typedef int16_t SHORT;
typedef uint32_t ULONG;
typedef int32_t LONG;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
// 是否在中断中函数 cmsis_gcc.h __get_IPSR()
// cmsis_os2.c 已经定义了这个函数 IS_IRQ()
#ifndef IS_IRQ()
static inline BOOL IS_IRQ(void) //使用内联函数提高速度
{
if (__get_IPSR()) {
return TRUE;
}
return FALSE;
}
#endif
#endif

@ -0,0 +1,135 @@
/*
* FreeModbus Libary: BARE Port
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id$
*/
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "port.h"
#if MODBUS_USED_FREERTOS
#include <FreeRTOS.h>
// #include <task.h>
// #include <queue.h>
osEventFlagsId_t modbusEventHandle;
const osEventFlagsAttr_t modbusEvent_attributes = {
.name = "modbusEvent"
};
BOOL xMBPortEventInit(void) {
ENTER_CRITICAL_SECTION();
modbusEventHandle = osEventFlagsNew(&modbusEvent_attributes);
EXIT_CRITICAL_SECTION();
if (modbusEventHandle != NULL) {
// MODBUS_DEBUG("xMBPortEventInit Success!\r\n");
} else {
// MODBUS_DEBUG("xMBPortEventInit Faild !\r\n");
return FALSE;
}
return TRUE;
}
void
vMBPortEventClose( void )
{
if(modbusEventHandle != NULL )
{
osEventFlagsDelete( modbusEventHandle );
modbusEventHandle = NULL;
}
}
BOOL xMBPortEventPost(eMBEventType eEvent) {
BaseType_t flag;
// osEventFlagsSet 兼容了是否在中断中的操作,否则需要判断是否在中断中
if (modbusEventHandle != NULL) {
osEventFlagsSet(modbusEventHandle,eEvent);
}
return TRUE;
}
BOOL xMBPortEventGet(eMBEventType *eEvent) {
uint32_t recvedEvent;
/* waiting forever OS event */
recvedEvent = osEventFlagsWait (modbusEventHandle,
EV_READY | EV_FRAME_RECEIVED | EV_EXECUTE |
EV_FRAME_SENT, /* 接收任务感兴趣的事件 */
0,
portMAX_DELAY); /* 指定超时事件,无限等待 */
switch (recvedEvent) {
case EV_READY:
*eEvent = EV_READY;
break;
case EV_FRAME_RECEIVED:
*eEvent = EV_FRAME_RECEIVED;
break;
case EV_EXECUTE:
*eEvent = EV_EXECUTE;
break;
case EV_FRAME_SENT:
*eEvent = EV_FRAME_SENT;
break;
}
return TRUE;
}
#else
// /* ----------------------- Variables ----------------------------------------*/
// static eMBEventType eQueuedEvent;
// static BOOL xEventInQueue;
// /* ----------------------- Start implementation -----------------------------*/
// BOOL
// xMBPortEventInit( void )
// {
// xEventInQueue = FALSE;
// return TRUE;
// }
// BOOL
// xMBPortEventPost( eMBEventType eEvent )
// {
// xEventInQueue = TRUE;
// eQueuedEvent = eEvent;
// return TRUE;
// }
// BOOL
// xMBPortEventGet( eMBEventType * eEvent )
// {
// BOOL xEventHappened = FALSE;
// if( xEventInQueue )
// {
// *eEvent = eQueuedEvent;
// xEventInQueue = FALSE;
// xEventHappened = TRUE;
// }
// return xEventHappened;
// }
#endif

@ -0,0 +1,535 @@
/*
* FreeModbus Libary: BARE Port
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id$
*/
#include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "main.h"
#include "usart.h"
#include "elog.h"
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);
/* ----------------------- variables ---------------------------------*/
#define Modbus_USE_485 1
#define Modbus_UART_IRQHandler USART2_IRQHandler
UART_HandleTypeDef *pMobusHuart = &huart2;
#if Modbus_USE_485
#define MODBUS_485_Receive_Enable() HAL_GPIO_WritePin( NULL, 0, RESET );
#define MODBUS_485_Send_Enable() HAL_GPIO_WritePin( NULL, 0, SET );
#endif
volatile uint32_t it_num = 0;
volatile uint32_t aa = 0;
volatile uint32_t bb = 0;
volatile uint32_t cc = 0;
#ifndef FREERTOS_USED
/* ----------------------- Start implementation -----------------------------*/
void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
{
if (xRxEnable)
{
#if Modbus_USE_485
for (size_t i = 0; i < 22000; i++); // 485 拉低准备接收 延时以免漏掉发送的最后字节
MODBUS_485_Receive_Enable();
#endif
__HAL_UART_ENABLE_IT(pMobusHuart, UART_IT_RXNE);
}
else
{
#if Modbus_USE_485
MODBUS_485_Send_Enable();
#endif
__HAL_UART_DISABLE_IT(pMobusHuart, UART_IT_RXNE);
}
if (xTxEnable)
{
#if Modbus_USE_485
MODBUS_485_Send_Enable();
#endif
__HAL_UART_ENABLE_IT(pMobusHuart, UART_IT_TXE);
}
else
{
#if Modbus_USE_485
MODBUS_485_Send_Enable();
#endif
__HAL_UART_DISABLE_IT(pMobusHuart, UART_IT_TXE);
}
}
BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity)
{
// pMobusHuart->Instance = USART2;
pMobusHuart->Init.BaudRate = ulBaudRate;
pMobusHuart->Init.StopBits = UART_STOPBITS_1;
pMobusHuart->Init.Mode = UART_MODE_TX_RX;
pMobusHuart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
pMobusHuart->Init.OverSampling = UART_OVERSAMPLING_16;
switch (eParity)
{
// 奇校验
case MB_PAR_ODD:
pMobusHuart->Init.Parity = UART_PARITY_ODD;
pMobusHuart->Init.WordLength = UART_WORDLENGTH_9B; // 带奇偶校验数据位为9bits
break;
// 偶校验
case MB_PAR_EVEN:
pMobusHuart->Init.Parity = UART_PARITY_EVEN;
pMobusHuart->Init.WordLength = UART_WORDLENGTH_9B; // 带奇偶校验数据位为9bits
break;
// 无校验
default:
pMobusHuart->Init.Parity = UART_PARITY_NONE;
pMobusHuart->Init.WordLength = UART_WORDLENGTH_8B; // 无奇偶校验数据位为8bits
break;
}
/* 防止启用时进入中断*/
__HAL_UART_CLEAR_FLAG(pMobusHuart, UART_FLAG_RXNE);
__HAL_UART_CLEAR_FLAG(pMobusHuart, UART_FLAG_TXE);
__HAL_UART_DISABLE_IT(pMobusHuart, UART_IT_RXNE);
__HAL_UART_DISABLE_IT(pMobusHuart, UART_IT_TXE);
return HAL_UART_Init(pMobusHuart) == HAL_OK ? TRUE : FALSE;
}
BOOL xMBPortSerialPutByte(CHAR ucByte)
{
/* Put a byte in the UARTs transmit buffer. This function is called
* by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
* called. */
pMobusHuart->Instance->DR = ucByte;
return TRUE;
// return (HAL_OK == HAL_UART_Transmit(pMobusHuart, (uint8_t *)&ucByte, 1, 10));
}
BOOL xMBPortSerialGetByte(CHAR *pucByte)
{
/* Return the byte in the UARTs receive buffer. This function is called
* by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
*/
*pucByte = (uint8_t)(pMobusHuart->Instance->DR & (uint8_t)0x00FF);
return TRUE;
}
/* Create an interrupt handler for the transmit buffer empty interrupt
* (or an equivalent) for your target processor. This function should then
* call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
* a new character can be sent. The protocol stack will then call
* xMBPortSerialPutByte( ) to send the character.
*/
static void prvvUARTTxReadyISR(void)
{
pxMBFrameCBTransmitterEmpty();
}
/* Create an interrupt handler for the receive interrupt for your target
* processor. This function should then call pxMBFrameCBByteReceived( ). The
* protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
* character.
*/
static void prvvUARTRxISR(void)
{
// log_i( " modbus rcv one byte....... ");
pxMBFrameCBByteReceived();
}
void USART2_IRQHandler(void)
{
aa++;
// if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE)) // 接收非空中断标记被置位
// {
// bb++;
// __HAL_UART_CLEAR_FLAG(pMobusHuart, UART_FLAG_RXNE); // 清除中断标记
// prvvUARTRxISR(); // 通知modbus有数据到达
// }
// if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_TXE)) // 发送为空中断标记被置位
// {
// cc++;
// __HAL_UART_CLEAR_FLAG(pMobusHuart, UART_FLAG_TXE); // 清除中断标记
// prvvUARTTxReadyISR(); // 通知modbus数据可以发松
// }
if (__HAL_UART_GET_IT_SOURCE(pMobusHuart, UART_IT_RXNE) != RESET
&& __HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) != RESET )
{
bb++;
__HAL_UART_CLEAR_FLAG(pMobusHuart, UART_FLAG_RXNE); // 清除中断标记
prvvUARTRxISR(); // 通知freemodbus有数据到达
}
if (__HAL_UART_GET_IT_SOURCE(pMobusHuart, UART_IT_TXE) != RESET
&& __HAL_UART_GET_FLAG(&huart2, UART_FLAG_TXE) != RESET )
{
cc++;
__HAL_UART_CLEAR_FLAG(pMobusHuart, UART_FLAG_TXE); // 清除中断标记
prvvUARTTxReadyISR(); // 通知modbus数据可以发松
}
if (__HAL_UART_GET_FLAG(pMobusHuart, UART_FLAG_ORE))
{
/* deal with uart rcv buffer ORE*/
// uint16_t pucByte = (uint16_t)((pMobusHuart)->Instance->DR & (uint16_t)0x01FF);
__HAL_UART_CLEAR_OREFLAG(pMobusHuart);
}
HAL_UART_IRQHandler(pMobusHuart);
}
#else
/* ----------------------- System includes ----------------------------------*/
#include <FreeRTOS.h>
#include <task.h>
#include <queue.h>
/* ----------------------- Static variables ---------------------------------*/
/* software simulation serial transmit IRQ handler thread */
static TaskHandle_t thread_serial_soft_trans_irq = NULL;
/* serial event */
static EventGroupHandle_t event_serial; /* 消息队列取代 */
/* modbus slave serial device */
static UART_HandleTypeDef *serial;
/*
* Serial FIFO mode
*/
static volatile uint8_t rx_buff[FIFO_SIZE_MAX];
static Serial_fifo Slave_serial_rx_fifo;
/* ----------------------- Defines ------------------------------------------*/
/* serial transmit event */
#define EVENT_SERIAL_TRANS_START (1 << 0)
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);
static void serial_soft_trans_irq(void *parameter);
static void Slave_TxCpltCallback(struct __UART_HandleTypeDef *huart);
static void Slave_RxCpltCallback(struct __UART_HandleTypeDef *huart);
static int stm32_getc(void);
static int stm32_putc(CHAR c);
/* ----------------------- Start implementation -----------------------------*/
BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
eMBParity eParity)
{
/**
* set 485 mode receive and transmit control IO
* @note MODBUS_SLAVE_RT_CONTROL_PIN_INDEX need be defined by user
*/
// rt_pin_mode(MODBUS_SLAVE_RT_CONTROL_PIN_INDEX, PIN_MODE_OUTPUT);
/* set serial name */
if (ucPORT == 1)
{
#if defined(USING_UART1)
extern UART_HandleTypeDef huart1;
serial = &huart1;
MODBUS_DEBUG("Slave using uart1!\r\n");
#endif
}
else if (ucPORT == 2)
{
#if defined(USING_UART2)
extern UART_HandleTypeDef huart2;
serial = &huart2;
MODBUS_DEBUG("Slave using uart2!\r\n");
#endif
}
else if (ucPORT == 3)
{
#if defined(USING_UART3)
extern UART_HandleTypeDef huart3;
serial = &huart3;
MODBUS_DEBUG("Slave using uart3!\r\n");
#endif
}
/* set serial configure */
serial->Init.StopBits = UART_STOPBITS_1;
serial->Init.BaudRate = ulBaudRate;
switch (eParity)
{
case MB_PAR_NONE:
{
serial->Init.WordLength = UART_WORDLENGTH_8B;
serial->Init.Parity = UART_PARITY_NONE;
break;
}
case MB_PAR_ODD:
{
serial->Init.WordLength = UART_WORDLENGTH_9B;
serial->Init.Parity = UART_PARITY_ODD;
break;
}
case MB_PAR_EVEN:
{
serial->Init.WordLength = UART_WORDLENGTH_9B;
serial->Init.Parity = UART_PARITY_EVEN;
break;
}
}
if (HAL_UART_Init(serial) != HAL_OK)
{
Error_Handler();
}
__HAL_UART_DISABLE_IT(serial, UART_IT_RXNE);
__HAL_UART_DISABLE_IT(serial, UART_IT_TC);
/*registe recieve callback*/
HAL_UART_RegisterCallback(serial, HAL_UART_RX_COMPLETE_CB_ID,
Slave_RxCpltCallback);
/* software initialize */
Slave_serial_rx_fifo.buffer = rx_buff;
Slave_serial_rx_fifo.get_index = 0;
Slave_serial_rx_fifo.put_index = 0;
/* 创建串口发送线程*/
event_serial = xEventGroupCreate(); // 创建事件
if (NULL != event_serial)
{
MODBUS_DEBUG("Create Slave event_serial Event success!\r\n");
}
else
{
MODBUS_DEBUG("Create Slave event_serial Event Faild!\r\n");
}
BaseType_t xReturn =
xTaskCreate((TaskFunction_t)serial_soft_trans_irq, /* 任务函数*/
(const char *)"slave trans", /* 任务名称*/
(uint16_t)128, /* 栈*/
(void *)NULL, /* 入口参数 */
(UBaseType_t)12, /* 优先级*/
(TaskHandle_t *)&thread_serial_soft_trans_irq); /*任务句柄*/
if (xReturn == pdPASS)
{
MODBUS_DEBUG("xTaskCreate slave trans success\r\n");
}
return TRUE;
}
void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
{
/*清除中断标志,这一步不要省略*/
__HAL_UART_CLEAR_FLAG(serial, UART_FLAG_RXNE);
__HAL_UART_CLEAR_FLAG(serial, UART_FLAG_TC);
if (xRxEnable)
{
/* enable RX interrupt */
__HAL_UART_ENABLE_IT(serial, UART_IT_RXNE);
/* switch 485 to receive mode */
MODBUS_DEBUG("RS485_RX_MODE\r\n");
SLAVE_RS485_RX_MODE;
}
else
{
/* switch 485 to transmit mode */
MODBUS_DEBUG("RS485_TX_MODE\r\n");
SLAVE_RS485_TX_MODE;
/* disable RX interrupt */
__HAL_UART_DISABLE_IT(serial, UART_IT_RXNE);
}
if (xTxEnable)
{
/* start serial transmit */
xEventGroupSetBits(event_serial, EVENT_SERIAL_TRANS_START);
}
else
{
/* stop serial transmit */
xEventGroupClearBits(event_serial, EVENT_SERIAL_TRANS_START);
/*测试帧数*/
// printf("ms=%.2f,fps=%.2f\r\n", __HAL_TIM_GetCounter(&htim7) / 100.f,
// 1000.f / (__HAL_TIM_GetCounter(&htim7) / 100.f));
}
}
void vMBPortClose(void) { __HAL_UART_DISABLE(serial); }
/*Send a byte*/
BOOL xMBPortSerialPutByte(CHAR ucByte)
{
stm32_putc(ucByte);
return TRUE;
}
/*Get a byte from fifo*/
BOOL xMBPortSerialGetByte(CHAR *pucByte)
{
Get_from_fifo(&Slave_serial_rx_fifo, (uint8_t *)pucByte, 1);
return TRUE;
}
void prvvUARTTxReadyISR(void) { pxMBFrameCBTransmitterEmpty(); }
void prvvUARTRxISR(void) { pxMBFrameCBByteReceived(); }
/**
* Software simulation serial transmit IRQ handler.
*
* @param parameter parameter
*/
static void serial_soft_trans_irq(void *parameter)
{
uint32_t recved_event;
while (1)
{
/* waiting for serial transmit start */
xEventGroupWaitBits(event_serial, /* 事件对象句柄 */
EVENT_SERIAL_TRANS_START, /* 接收任务感兴趣的事件 */
pdFALSE, /* 退出时清除事件?? */
pdFALSE, /* 满足感兴趣的所有事?? */
portMAX_DELAY); /* 指定超时事件,无限等待 */
/* execute modbus callback */
prvvUARTTxReadyISR();
}
}
/**
* @brief Rx Transfer completed callbacks.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
void Slave_RxCpltCallback(UART_HandleTypeDef *huart)
{
int ch = -1;
while (1)
{
ch = stm32_getc();
if (ch == -1)
break;
Put_in_fifo(&Slave_serial_rx_fifo, (uint8_t *)&ch, 1);
}
prvvUARTRxISR();
}
/*UART发送一个字节*/
static int stm32_putc(CHAR c)
{
serial->Instance->DR = c;
while (!(serial->Instance->SR & UART_FLAG_TC))
;
return TRUE;
}
/*UART接收一个字节*/
static int stm32_getc(void)
{
int ch;
ch = -1;
if (serial->Instance->SR & UART_FLAG_RXNE)
{
ch = serial->Instance->DR & 0xff;
}
return ch;
}
/*put bytes in buff*/
void Put_in_fifo(Serial_fifo *buff, uint8_t *putdata, int length)
{
portDISABLE_INTERRUPTS();
while (length--)
{
buff->buffer[buff->put_index] = *putdata;
buff->put_index += 1;
if (buff->put_index >= MB_SIZE_MAX)
buff->put_index = 0;
/* if the next position is read index, discard this 'read char' */
if (buff->put_index == buff->get_index)
{
buff->get_index += 1;
if (buff->get_index >= MB_SIZE_MAX)
buff->get_index = 0;
}
}
portENABLE_INTERRUPTS();
}
/*get bytes from buff*/
int Get_from_fifo(Serial_fifo *buff, uint8_t *getdata, int length)
{
int size = length;
/* read from software FIFO */
while (length)
{
int ch;
/* disable interrupt */
portDISABLE_INTERRUPTS();
if (buff->get_index != buff->put_index)
{
ch = buff->buffer[buff->get_index];
buff->get_index += 1;
if (buff->get_index >= MB_SIZE_MAX)
buff->get_index = 0;
}
else
{
/* no data, enable interrupt and break out */
portENABLE_INTERRUPTS();
break;
}
*getdata = ch & 0xff;
getdata++;
length--;
/* enable interrupt */
portENABLE_INTERRUPTS();
}
return size - length;
}
/**
* @brief This function handles USART2 global interrupt.
*/
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
if (__HAL_UART_GET_FLAG(pMobusHuart, UART_FLAG_RXNE))
{
huart2.RxCpltCallback(pMobusHuart);
__HAL_UART_CLEAR_FLAG(pMobusHuart, UART_FLAG_RXNE);
}
if (__HAL_UART_GET_FLAG(pMobusHuart, UART_FLAG_ORE))
{
uint16_t pucByte = (uint16_t)((pMobusHuart)->Instance->DR & (uint16_t)0x01FF);
__HAL_UART_CLEAR_OREFLAG(pMobusHuart);
}
if (__HAL_UART_GET_FLAG(pMobusHuart, UART_FLAG_TC))
{
__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_TC);
}
/* USER CODE END USART2_IRQn 0 */
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
#endif

@ -0,0 +1,363 @@
/*
* FreeModbus Libary: BARE Port
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id$
*/
/* ----------------------- Platform includes --------------------------------*/
#include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "main.h"
#include "tim.h"
#include "elog.h"
/* ----------------------- static functions ---------------------------------*/
static void prvvTIMERExpiredISR(void);
/* ----------------------- variables ---------------------------------*/
#if MODBUS_USED_FREERTOS
/* ----------------------- variables ---------------------------------*/
extern TIM_HandleTypeDef htim7;
TIM_HandleTypeDef *pModbusTim = &htim7;
volatile uint16_t timeout = 0;
volatile uint16_t counter = 0;
volatile uint32_t dd = 0;
/* ----------------------- Start implementation -----------------------------*/
BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
{
TIM_MasterConfigTypeDef sMasterConfig;
pModbusTim->Instance = TIM7;
pModbusTim->Init.Prescaler = ( 2 * 50 * HAL_RCC_GetPCLK1Freq() / 1000000) - 1;
pModbusTim->Init.CounterMode = TIM_COUNTERMODE_UP;
pModbusTim->Init.Period = usTim1Timerout50us - 1;
pModbusTim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
timeout = usTim1Timerout50us; // 赋值timeout 多少个周期
if (HAL_TIM_Base_Init(pModbusTim) != HAL_OK)
{
return FALSE;
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(pModbusTim, &sMasterConfig) != HAL_OK)
{
return FALSE;
}
/* 避免一开始进入了超时中断,关闭中断,停止计数,归0 */
// HAL_NVIC_SetPriority(TIM7_IRQn, 5, 0);
// HAL_NVIC_EnableIRQ(TIM7_IRQn);
__HAL_TIM_CLEAR_FLAG( &htim7, TIM_FLAG_UPDATE ); // 先清除一下定时器的中断标记,防止使能中断后直接触发中断
__HAL_TIM_CLEAR_IT( &htim7, TIM_IT_UPDATE );
__HAL_TIM_ENABLE_IT(&htim7, TIM_IT_UPDATE); // 使能定时器更新中断
// __HAL_TIM_DISABLE(&htim7);
// __HAL_TIM_CLEAR_FLAG( pModbusTim, TIM_FLAG_UPDATE );
// __HAL_TIM_SET_COUNTER( pModbusTim, 0 );
// __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE );
// HAL_TIM_Base_Stop( pModbusTim );
// __HAL_TIM_SET_COUNTER( pModbusTim, 0 );
// HAL_TIM_Base_Stop_IT( pModbusTim );
return TRUE;
}
inline void
vMBPortTimersEnable()
{
/* Enable the timer with the timeout passed to xMBPortTimersInit( ) */
counter = 0; // 启用定时器时,
// HAL_TIM_Base_Start_IT(pModbusTim);
// __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器
// __HAL_TIM_SET_COUNTER( pModbusTim, 0 );
// __HAL_TIM_ENABLE_IT( pModbusTim,TIM_FLAG_UPDATE );
// HAL_TIM_Base_Start( pModbusTim );
__HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE);
__HAL_TIM_ENABLE_IT(&htim7,TIM_IT_UPDATE);
__HAL_TIM_SET_COUNTER(&htim7,0);
__HAL_TIM_ENABLE(&htim7);
// __HAL_TIM_SET_COUNTER(&htim7, 0); // 清空计数器
// __HAL_TIM_ENABLE(&htim7); // 使能定时器
}
inline void
vMBPortTimersDisable()
{
/* Disable any pending timers. */
// HAL_TIM_Base_Stop_IT(pModbusTim);
// __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器
// __HAL_TIM_SET_COUNTER( pModbusTim, 0 );
// __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE );
// HAL_TIM_Base_Stop( pModbusTim );
// __HAL_TIM_SET_COUNTER( pModbusTim, 0 );
__HAL_TIM_DISABLE(&htim7);
__HAL_TIM_SET_COUNTER(&htim7,0);
__HAL_TIM_DISABLE_IT(&htim7,TIM_IT_UPDATE);
__HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE);
// __HAL_TIM_DISABLE(&htim7); // 禁能定时器
}
/* Create an ISR which is called whenever the timer has expired. This function
* must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that
* the timer has expired.
*/
static void prvvTIMERExpiredISR(void)
{
(void)pxMBPortCBTimerExpired();
}
void TIM7_IRQHandler(void)
{
if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE) != RESET && __HAL_TIM_GET_IT_SOURCE(&htim7, TIM_IT_UPDATE) !=RESET)
// if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE)) // 更新中断标记被置位
{
dd++;
__HAL_TIM_CLEAR_FLAG(&htim7, TIM_FLAG_UPDATE); // 清除中断标记
__HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE);
__HAL_TIM_SET_COUNTER(&htim7, 0);
prvvTIMERExpiredISR(); // 通知modbus3.5个字符等待时间到
}
HAL_TIM_IRQHandler( &htim7 );
}
#else
#include <FreeRTOS.h>
// #include <timers.h>
/* ----------------------- static functions ---------------------------------*/
osTimerId_t modbusTimerHandle;
const osTimerAttr_t modbusTimer_attributes = {
.name = "modbusTimer"
};
// static TimerHandle_t timer;
volatile uint32_t timer_ticks = 0;
volatile uint32_t dd = 0;
static void prvvTIMERExpiredISR( void );
static void timer_timeout_ind( void* parameter );
/* ----------------------- Start implementation -----------------------------*/
BOOL xMBPortTimersInit( USHORT usTim1Timerout50us ) {
/*
Freertos can't create timer in isr!
So,I use hardware timer here! req=1Mhz
*/
timer_ticks = (50 * usTim1Timerout50us) / (1000 * 1000 / configTICK_RATE_HZ) + 1;
modbusTimerHandle = osTimerNew(
timer_timeout_ind,
osTimerOnce, // osTimerOnce osTimerPeriodic
NULL,
&modbusTimer_attributes );
// modbusTimerHandle = xTimerCreate(
// "Slave timer",
// (50 * usTim1Timerout50us) / (1000 * 1000 / configTICK_RATE_HZ) + 1,
// pdFALSE, (void *)2, timer_timeout_ind);
if (modbusTimerHandle == NULL)
return FALSE;
// osTimerStart( modbusTimerHandle, (50 * usTim1Timerout50us) / (1000 * 1000 / configTICK_RATE_HZ) + 1);
return TRUE;
}
void vMBPortTimersEnable() {
// log_i(" enable timer...... %d", timer_ticks );
osTimerStart( modbusTimerHandle, timer_ticks );
if( osTimerIsRunning(modbusTimerHandle) !=)
{
log_i(" timer running... %d", timer_ticks );
}
// osTimerStart 已经包含 (IS_IRQ()
}
void vMBPortTimersDisable() {
// log_i(" disbale timer...... " );
osTimerStop(modbusTimerHandle);
// osTimerStop 已经包含 (IS_IRQ()
}
void prvvTIMERExpiredISR(void)
{
(void)pxMBPortCBTimerExpired();
}
static void timer_timeout_ind( void* parameter )
{
dd++;
// log_i( " timer timout...... " );
prvvTIMERExpiredISR( );
}
#endif
#if 0
/* ----------------------- variables ---------------------------------*/
extern TIM_HandleTypeDef htim7;
TIM_HandleTypeDef *pModbusTim = &htim7;
volatile uint16_t timeout = 0;
volatile uint16_t counter = 0;
volatile uint32_t dd = 0;
/* ----------------------- Start implementation -----------------------------*/
BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
{
TIM_MasterConfigTypeDef sMasterConfig;
pModbusTim->Instance = TIM7;
pModbusTim->Init.Prescaler = ( 2 * 50 * HAL_RCC_GetPCLK1Freq() / 1000000) - 1;
pModbusTim->Init.CounterMode = TIM_COUNTERMODE_UP;
pModbusTim->Init.Period = usTim1Timerout50us - 1;
pModbusTim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
timeout = usTim1Timerout50us; // 赋值timeout 多少个周期
if (HAL_TIM_Base_Init(pModbusTim) != HAL_OK)
{
return FALSE;
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(pModbusTim, &sMasterConfig) != HAL_OK)
{
return FALSE;
}
/* 避免一开始进入了超时中断,关闭中断,停止计数,归0 */
// HAL_NVIC_SetPriority(TIM7_IRQn, 5, 0);
// HAL_NVIC_EnableIRQ(TIM7_IRQn);
__HAL_TIM_CLEAR_FLAG( &htim7, TIM_FLAG_UPDATE ); // 先清除一下定时器的中断标记,防止使能中断后直接触发中断
__HAL_TIM_CLEAR_IT( &htim7, TIM_IT_UPDATE );
__HAL_TIM_ENABLE_IT(&htim7, TIM_IT_UPDATE); // 使能定时器更新中断
// __HAL_TIM_DISABLE(&htim7);
// __HAL_TIM_CLEAR_FLAG( pModbusTim, TIM_FLAG_UPDATE );
// __HAL_TIM_SET_COUNTER( pModbusTim, 0 );
// __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE );
// HAL_TIM_Base_Stop( pModbusTim );
// __HAL_TIM_SET_COUNTER( pModbusTim, 0 );
// HAL_TIM_Base_Stop_IT( pModbusTim );
return TRUE;
}
inline void
vMBPortTimersEnable()
{
/* Enable the timer with the timeout passed to xMBPortTimersInit( ) */
counter = 0; // 启用定时器时,
// HAL_TIM_Base_Start_IT(pModbusTim);
// __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器
// __HAL_TIM_SET_COUNTER( pModbusTim, 0 );
// __HAL_TIM_ENABLE_IT( pModbusTim,TIM_FLAG_UPDATE );
// HAL_TIM_Base_Start( pModbusTim );
__HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE);
__HAL_TIM_ENABLE_IT(&htim7,TIM_IT_UPDATE);
__HAL_TIM_SET_COUNTER(&htim7,0);
__HAL_TIM_ENABLE(&htim7);
// __HAL_TIM_SET_COUNTER(&htim7, 0); // 清空计数器
// __HAL_TIM_ENABLE(&htim7); // 使能定时器
}
inline void
vMBPortTimersDisable()
{
/* Disable any pending timers. */
// HAL_TIM_Base_Stop_IT(pModbusTim);
// __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器
// __HAL_TIM_SET_COUNTER( pModbusTim, 0 );
// __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE );
// HAL_TIM_Base_Stop( pModbusTim );
// __HAL_TIM_SET_COUNTER( pModbusTim, 0 );
__HAL_TIM_DISABLE(&htim7);
__HAL_TIM_SET_COUNTER(&htim7,0);
__HAL_TIM_DISABLE_IT(&htim7,TIM_IT_UPDATE);
__HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE);
// __HAL_TIM_DISABLE(&htim7); // 禁能定时器
}
/* Create an ISR which is called whenever the timer has expired. This function
* must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that
* the timer has expired.
*/
static void prvvTIMERExpiredISR(void)
{
(void)pxMBPortCBTimerExpired();
}
void TIM7_IRQHandler(void)
{
// if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE) != RESET && __HAL_TIM_GET_IT_SOURCE(&htim7, TIM_IT_UPDATE) !=RESET)
if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE)) // 更新中断标记被置位
{
dd++;
__HAL_TIM_CLEAR_FLAG(&htim7, TIM_FLAG_UPDATE); // 清除中断标记
__HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE);
__HAL_TIM_SET_COUNTER(&htim7, 0);
prvvTIMERExpiredISR(); // 通知modbus3.5个字符等待时间到
}
HAL_TIM_IRQHandler( &htim7 );
}
#endif
Loading…
Cancel
Save