当前位置:   article > 正文

CH395Q之CH395Q驱动库移植与驱动库分析(二)

CH395Q之CH395Q驱动库移植与驱动库分析(二)

本节主要介绍以下内容:

一、CH395Q驱动库移植

二、源码分析

一、CH395Q驱动库移植

驱动库移植主要有两个途径,一个是南京沁恒官方网址,一个是通过正点原子官方,原子官方对沁横官方提供的驱动库进行了完善与修改。自用的话推荐原子官方。

 原子与沁横官网相比主要有以下区别:

(1)在沁恒的基础上对格式进行了规范,并且条件编译相对较少

(2)统一了接口,并且添加了部分辅助功能。

1.1 移植流程

 1.2 准备工程

在裸机例程中,以跑马灯实验作为移植基础工程

重命名工程为《网络实验1 CH395移植实验》

按照以下结构新建文件夹:

在原子的例程中拷贝ch395.c/.hch395cmd.c/.hch395inc.h到新工程的Drivers\BSP\CH395Q路径下 

1.3 文件添加 

打开工程,在Drivers/BSP分组下添加CH395Q驱动库

1.4 新建文件

 新建ch395q_demo.c/,h文件,此文件用来编写测试代码。

1.5 验证测试

ch395q_demo.c文件下编写以下测试代码

void ch395_demo(void)

{

do

{

if (ch395_int_pin_wire == 0)

{

  ch395q_handler(); /* 中断处理函数 */

}

  } while (g_ch395q_sta.dhcp_status == DHCP_STA); /* 获取DHCP */

   

while(1)

{

  ch395q_handler();

}

}

mian.c

  1. #include "./SYSTEM/sys/sys.h"
  2. #include "./SYSTEM/usart/usart.h"
  3. #include "./SYSTEM/delay/delay.h"
  4. #include "./BSP/LED/led.h"
  5. #include "./BSP/LCD/lcd.h"
  6. #include "./BSP/KEY/key.h"
  7. #include "./MALLOC/malloc.h"
  8. #include "./BSP/SRAM/sram.h"
  9. #include "./BSP/CH395Q/ch395.h"
  10. #include "./APP/ch395_demo.h"
  11. int main(void)
  12. {
  13. HAL_Init(); /* 初始化HAL库 */
  14. sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
  15. delay_init(72); /* 延时初始化 */
  16. usart_init(115200); /* 串口初始化为115200 */
  17. led_init(); /* 初始化LED */
  18. lcd_init(); /* 初始化LCD */
  19. key_init(); /* 初始化按键 */
  20. sram_init(); /* 初始化外部SRAM */
  21. my_mem_init(SRAMIN); /* 初始化内部内存 */
  22. my_mem_init(SRAMEX); /* 初始化外部内存 */
  23. ch395_hardware_init(); /* ch395初始化 */
  24. ch395_demo(); /* 例程测试 */
  25. }

验证通过可按照上图对IP、网关掩码等进行打印。

接下来,对IP进行ping包,ping通则表示验证成功,则移植完毕。 

二、驱动库分析

2.1 驱动文件介绍

文件

说明

ch395inc.h

定义CH395Q相关命令及类型

ch395cmd.c

定义CH395Q相关命令函数

ch395cmd.h

声明函数提供外部文件调用

ch395.c

实现UDPTCP连接等相关功能

ch395.h

声明函数、结构体等信息

接下来分文件去介绍

 ch395inc.h

ch395cmd.c/.h 

ch395.h 

ch395.c 

2.2 代码分析

2.2.1 ch395_hardware_init();ch395初始化

我们go to 进去

  1. **
  2. * @brief ch395_tcp初始化
  3. * @param 无
  4. * @retval 无
  5. */
  6. void ch395_hardware_init(void)
  7. {
  8. uint8_t i;
  9. ch395_gpio_init();
  10. spi1_init();
  11. g_ch395q_sta.ch395_error = ch395_error;
  12. g_ch395q_sta.ch395_phy_cb = ch395_phy_status;
  13. g_ch395q_sta.ch395_reconnection = ch395_reconnection;
  14. g_ch395q_sta.dhcp_status = DHCP_STA;
  15. i = ch395_cmd_check_exist(0x65); /* 测试命令,用于测试硬件以及接口通讯 */
  16. if (i != 0x9a)
  17. {
  18. g_ch395q_sta.ch395_error(i); /* ch395q检测错误 */
  19. }
  20. ch395_cmd_reset(); /* 对ch395q复位 */
  21. delay_ms(100); /* 这里必须等待100以上延时 */
  22. g_ch395q_sta.ch395_error(ch395_cmd_init()); /* 初始化ch395q命令 */
  23. ch395_socket_r_s_buf_modify(); /* 设置socket接口的接收与发送缓冲区*/
  24. // ch395_set_tcpmss(536);
  25. // ch395_set_start_para(FUN_PARA_FLAG_TCP_SERVER | SOCK_CTRL_FLAG_SOCKET_CLOSE);
  26. do
  27. {
  28. g_ch395q_sta.phy_status = ch395_cmd_get_phy_status(); /* 获取PHY状态 */
  29. g_ch395q_sta.ch395_phy_cb(g_ch395q_sta.phy_status); /* 判断双工和网速模式 */
  30. }
  31. while(g_ch395q_sta.phy_status == PHY_DISCONN);
  32. g_ch395q_sta.version = ch395_cmd_get_ver(); /* 获取版本 */
  33. printf("CH395VER : %2x\r\n", (uint16_t)g_ch395q_sta.version);
  34. i = ch395_dhcp_enable(1); /* 开启DHCP */
  35. g_ch395q_sta.ch395_error(i); /* ch395q检测错误 */
  36. delay_ms(1000); /* ch395q初始化延时 */
  37. }

接下来对该函数进行逐行解读,首先是ch395_gpio_init

  1. /**
  2. * @brief ch395_gpio初始化
  3. * @param 无
  4. * @retval 无
  5. */
  6. void ch395_gpio_init( void )
  7. {
  8. GPIO_InitTypeDef gpio_init_struct;
  9. CH395_SCS_GPIO_CLK_ENABLE(); /* 使能SCS时钟 */
  10. CH395_INT_GPIO_CLK_ENABLE(); /* 使能INT时钟 */
  11. CH395_RST_GPIO_CLK_ENABLE(); /* 使能RST时钟 */
  12. /* SCS */
  13. gpio_init_struct.Pin = CH395_SCS_GPIO_PIN;
  14. gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM;
  15. gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推拉输出 */
  16. HAL_GPIO_Init( CH395_SCS_GPIO_PORT, &gpio_init_struct );
  17. /* 初始化中断引脚 */
  18. gpio_init_struct.Pin = CH395_INT_GPIO_PIN;
  19. gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */
  20. gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
  21. gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
  22. HAL_GPIO_Init( CH395_INT_GPIO_PORT, &gpio_init_struct );
  23. gpio_init_struct.Pin = CH395_RST_GPIO_PIN;
  24. gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 输出 */
  25. gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
  26. gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
  27. HAL_GPIO_Init( CH395_RST_GPIO_PORT, &gpio_init_struct );
  28. HAL_GPIO_WritePin(CH395_RST_GPIO_PORT, CH395_RST_GPIO_PIN, GPIO_PIN_SET);
  29. delay_ms(20);
  30. }

这部分没什么说的,就是对GPIO进行配置,注意模式就行

接下来是spi1_init();

  1. /**
  2. * @brief SPI初始化代码
  3. * @note 主机模式,8位数据,禁止硬件片选
  4. * @param 无
  5. * @retval 无
  6. */
  7. void spi1_init(void)
  8. {
  9. SPI1_SPI_CLK_ENABLE(); /* SPI1时钟使能 */
  10. g_spi1_handler.Instance = SPI1_SPI; /* SPI1 */
  11. g_spi1_handler.Init.Mode = SPI_MODE_MASTER; /* 设置SPI工作模式,设置为主模式 */
  12. g_spi1_handler.Init.Direction = SPI_DIRECTION_2LINES; /* 设置SPI单向或者双向的数据模式:SPI设置为双线模式 */
  13. g_spi1_handler.Init.DataSize = SPI_DATASIZE_8BIT; /* 设置SPI的数据大小:SPI发送接收8位帧结构 */
  14. g_spi1_handler.Init.CLKPolarity = SPI_POLARITY_HIGH; /* 串行同步时钟的空闲状态为高电平 */
  15. g_spi1_handler.Init.CLKPhase = SPI_PHASE_2EDGE; /* 串行同步时钟的第二个跳变沿(上升或下降)数据被采样 */
  16. g_spi1_handler.Init.NSS = SPI_NSS_SOFT; /* NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 */
  17. g_spi1_handler.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; /* 定义波特率预分频的值:波特率预分频值为256 */
  18. g_spi1_handler.Init.FirstBit = SPI_FIRSTBIT_MSB; /* 指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 */
  19. g_spi1_handler.Init.TIMode = SPI_TIMODE_DISABLE; /* 关闭TI模式 */
  20. g_spi1_handler.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; /* 关闭硬件CRC校验 */
  21. g_spi1_handler.Init.CRCPolynomial = 7; /* CRC值计算的多项式 */
  22. HAL_SPI_Init(&g_spi1_handler); /* 初始化 */
  23. spi1_set_speed(SPI_BAUDRATEPRESCALER_2);
  24. __HAL_SPI_ENABLE(&g_spi1_handler); /* 使能SPI2 */
  25. spi1_read_write_byte(0Xff); /* 启动传输, 实际上就是产生8个时钟脉冲, 达到清空DR的作用, 非必需 */
  26. }

对SPI进行配置和使能,这块也没什么要改的,SPI一般都这样配置

  1. g_ch395q_sta.ch395_error = ch395_error;
  2. g_ch395q_sta.ch395_phy_cb = ch395_phy_status;
  3. g_ch395q_sta.ch395_reconnection = ch395_reconnection;
  4. g_ch395q_sta.dhcp_status = DHCP_STA;

这块是对结构体成员函数进行赋值,g_ch395q_sta是一个结构体

struct ch395q_t g_ch395q_sta;

结构体定义如下:

  1. struct ch395q_t
  2. {
  3. uint8_t version; /* 版本信息 */
  4. uint8_t phy_status; /* PHY状态 */
  5. uint8_t dhcp_status; /* DHCP状态 */
  6. uint8_t ipinf_buf[20]; /* 获取IP信息 */
  7. struct
  8. {
  9. ch395_socket config; /* 配置信息 */
  10. } socket[8]; /* Socket状态 */
  11. void (*ch395_error)(uint8_t i); /* ch395q错误检测函数 */
  12. void (*ch395_phy_cb)(uint8_t phy_status); /* ch395q phy状态回调函数 */
  13. void (*ch395_reconnection)(void); /* ch395q 重新连接函数 */
  14. };

 接下来首先是是对CH395进行检测,该命令前面讲过,传入0x65,返回值按位取反得到0x9a,如果不是0x9a,则利用以下代码对错误码进行打印。

  1. /**
  2. * @brief 调试使用,显示错误代码,并停机
  3. * @param ierror 检测命令
  4. * @retval 无
  5. */
  6. void ch395_error(uint8_t ierror)
  7. {
  8. if (ierror == CMD_ERR_SUCCESS)
  9. {
  10. return; /* 操作成功 */
  11. }
  12. printf("Error: %02X\r\n", (uint16_t)ierror); /* 显示错误 */
  13. while ( 1 )
  14. {
  15. delay_ms(200);
  16. delay_ms(200);
  17. }
  18. }

接下来CH395进行复位,为硬件复位

  1. /**
  2. * @brief 复位ch395芯片
  3. * @param 无
  4. * @retval 无
  5. */
  6. void ch395_cmd_reset(void)
  7. {
  8. ch395_write_cmd(CMD00_RESET_ALL);
  9. ch395_scs_hign;
  10. }

该命令使CH395执行硬件复位。通常情况下,硬件复位在50mS 时间之内完成。所以我们此处在初始化后面延时了100ms,保证初始化完成。

如果初始化失败,对错误码进行打印,这个上面说过,此处不作赘述。

g_ch395q_sta.ch395_error(ch395_cmd_init()); 

接下来对ch395_socket_r_s_buf_modify();  函数进行讲解,该函数对socket接口的接收与发送缓冲区大小进行设置,一共0-7,8个socket,将24K内存分成0-47,48块,每块为512K字节。比如说设置socket0的recv_buf,第一个参数是0,就是设置socket0的recv_buf,第二个参数是0,表示从块的0索引值开始,最后一个参数是4,表示分配4块,4*512= 2k,也就是说recv_buf分配了2k内存。send_buf同理,设置socket0的send_buff从4索引值开始,分配2块内存。

  1. **
  2. * @brief 设置socket接口的接收与发送缓冲区
  3. * @param 无
  4. * @retval 无
  5. * 0-47块 每块为512K字节
  6. */
  7. void ch395_socket_r_s_buf_modify(void)
  8. {
  9. ch395_set_socket_recv_buf(0,0,4); /* Socket 0 ,接收缓冲区4*512 = 2K,发送缓冲区2*512 = 1K*/
  10. ch395_set_socket_send_buf(0,4,2);
  11. ch395_set_socket_recv_buf(1,6,4); /* Socket 1 */
  12. ch395_set_socket_send_buf(1,10,2);
  13. ch395_set_socket_recv_buf(2,12,4); /* Socket 2 */
  14. ch395_set_socket_send_buf(2,16,2);
  15. ch395_set_socket_recv_buf(3,18,4); /* Socket 3 */
  16. ch395_set_socket_send_buf(3,22,2);
  17. ch395_set_socket_recv_buf(4,24,4); /* Socket 4 */
  18. ch395_set_socket_send_buf(4,28,2);
  19. ch395_set_socket_recv_buf(5,30,4); /* Socket 5 */
  20. ch395_set_socket_send_buf(5,34,2);
  21. ch395_set_socket_recv_buf(6,36,4); /* Socket 6 */
  22. ch395_set_socket_send_buf(6,40,2);
  23. ch395_set_socket_recv_buf(7,42,4); /* Socket 7 */
  24. ch395_set_socket_send_buf(7,46,2);
  25. }
  1. /**
  2. * @brief 设置socket接收缓冲区
  3. * @param sockindex socket索引,址,blknum
  4. * @param startblk 起始地
  5. * @param 单位缓冲区个数 ,单位为512字节
  6. * @retval 无
  7. */
  8. void ch395_set_socket_recv_buf(uint8_t sockindex, uint8_t startblk, uint8_t blknum)
  9. {
  10. ch395_write_cmd(CMD30_SET_RECV_BUF);
  11. ch395_write_data(sockindex);
  12. ch395_write_data(startblk);
  13. ch395_write_data(blknum);
  14. }
  1. /**
  2. * @brief 设置socket发送缓冲区
  3. * @param sockindex socket索引
  4. * @param startblk 起始地址
  5. * @param blknum 单位缓冲区个数
  6. * @retval 无
  7. */
  8. void ch395_set_socket_send_buf(uint8_t sockindex, uint8_t startblk, uint8_t blknum)
  9. {
  10. ch395_write_cmd(CMD30_SET_SEND_BUF);
  11. ch395_write_data(sockindex);
  12. ch395_write_data(startblk);
  13. ch395_write_data(blknum);
  14. }
  1. do
  2. {
  3. g_ch395q_sta.phy_status = ch395_cmd_get_phy_status(); /* 获取PHY状态 */
  4. g_ch395q_sta.ch395_phy_cb(g_ch395q_sta.phy_status); /* 判断双工和网速模式 */
  5. }
  6. while(g_ch395q_sta.phy_status == PHY_DISCONN);

首先对phy的状态进行获取,接下来phy状态回调函数检测phy的状态,如果断开就一致检测

  1. g_ch395q_sta.version = ch395_cmd_get_ver(); /* 获取版本 */
  2. printf("CH395VER : %2x\r\n", (uint16_t)g_ch395q_sta.version);

连接成功就对395Q的固件库版本进行检测并进行打印。

  1. i = ch395_dhcp_enable(1); /* 开启DHCP */
  2. g_ch395q_sta.ch395_error(i);
  1. /**
  2. * @brief 启动/停止dhcp
  3. * @param flag:0 / 1, 具体含义如下:
  4. * @arg 1:启动dhcp
  5. * @arg 0:停止dhcp
  6. * @retval 执行状态
  7. */
  8. uint8_t ch395_dhcp_enable(uint8_t flag)
  9. {
  10. uint8_t i = 0;
  11. uint8_t s;
  12. ch395_write_cmd(CMD10_DHCP_ENABLE);
  13. ch395_write_data(flag);
  14. ch395_scs_hign;
  15. while (1)
  16. {
  17. delay_ms(20);
  18. s = ch395_get_cmd_status(); /* 不能过于频繁查询 */
  19. if (s != CH395_ERR_BUSY)
  20. {
  21. break; /* 如果ch395芯片返回忙状态 */
  22. }
  23. if (i++ > 200)
  24. {
  25. return CH395_ERR_UNKNOW; /* 超时退出 */
  26. }
  27. }
  28. return s;
  29. }

启动dhcp,如果启动失败就对错误值进行打印。

2.2.3 void ch395_demo(void) 例程测试

接下来对测试例程进行分析

  1. /**
  2. * @brief 例程测试
  3. * @param 无
  4. * @retval 无
  5. */
  6. void ch395_demo(void)
  7. {
  8. ch395_show_mesg(); /* 显示信息 */
  9. do
  10. {
  11. if (ch395_int_pin_wire == 0) /*判断INT这个引脚是否处于低 低则有异常状态发生*/
  12. {
  13. ch395q_handler(); /* 中断处理函数 */
  14. }
  15. }
  16. while (g_ch395q_sta.dhcp_status == DHCP_STA); /* 获取DHCP */
  17. while(1)
  18. {
  19. ch395q_handler();
  20. }
  21. }

第一句是加了个打印这个不看

下来进来先判断int的引脚,判断INT这个引脚是否处于低 低则有异常状态发生,则进入ch395q_handler()函数,该函数为CH395全局管理函数,该函数实现为

  1. /**
  2. * @brief CH395全局管理函数
  3. * @param 无
  4. * @retval 无
  5. */
  6. void ch395q_handler(void)
  7. {
  8. if (ch395_int_pin_wire == 0)
  9. {
  10. ch395_interrupt_handler(); /* 中断处理函数 */
  11. }
  12. g_ch395q_sta.ch395_reconnection(); /* 检测PHY状态,并重新连接 */
  13. }

首先是又判断了一下int引脚,如果为低,则进入异常中断处理函数ch395_interrupt_handler();  该函数实现为

  1. /**
  2. * @brief CH395全局中断函数
  3. * @param 无
  4. * @retval 无
  5. */
  6. void ch395_interrupt_handler(void)
  7. {
  8. uint16_t init_status;
  9. uint8_t i;
  10. init_status = ch395_cmd_get_glob_int_status_all();
  11. if (init_status & GINT_STAT_UNREACH) /* 不可达中断,读取不可达信息 */
  12. {
  13. ch395_cmd_get_unreachippt(g_ch395q_sta.ipinf_buf);
  14. }
  15. if (init_status & GINT_STAT_IP_CONFLI) /* 产生IP冲突中断,建议重新修改CH395的 IP,并初始化CH395 */
  16. {
  17. }
  18. if (init_status & GINT_STAT_PHY_CHANGE) /* 产生PHY改变中断 */
  19. {
  20. g_ch395q_sta.phy_status = ch395_cmd_get_phy_status(); /* 获取PHY状态 */
  21. }
  22. if (init_status & GINT_STAT_DHCP) /* 处理DHCP中断 */
  23. {
  24. i = ch395_get_dhcp_status();
  25. switch (i)
  26. {
  27. case DHCP_UP:
  28. ch395_get_ipinf(g_ch395q_sta.ipinf_buf);
  29. printf("IP:%02d.%02d.%02d.%02d\r\n", (uint16_t)g_ch395q_sta.ipinf_buf[0], (uint16_t)g_ch395q_sta.ipinf_buf[1], (uint16_t)g_ch395q_sta.ipinf_buf[2], (uint16_t)g_ch395q_sta.ipinf_buf[3]);
  30. printf("GWIP:%02d.%02d.%02d.%02d\r\n", (uint16_t)g_ch395q_sta.ipinf_buf[4], (uint16_t)g_ch395q_sta.ipinf_buf[5], (uint16_t)g_ch395q_sta.ipinf_buf[6], (uint16_t)g_ch395q_sta.ipinf_buf[7]);
  31. printf("Mask:%02d.%02d.%02d.%02d\r\n", (uint16_t)g_ch395q_sta.ipinf_buf[8], (uint16_t)g_ch395q_sta.ipinf_buf[9], (uint16_t)g_ch395q_sta.ipinf_buf[10], (uint16_t)g_ch395q_sta.ipinf_buf[11]);
  32. printf("DNS1:%02d.%02d.%02d.%02d\r\n", (uint16_t)g_ch395q_sta.ipinf_buf[12], (uint16_t)g_ch395q_sta.ipinf_buf[13], (uint16_t)g_ch395q_sta.ipinf_buf[14], (uint16_t)g_ch395q_sta.ipinf_buf[15]);
  33. printf("DNS2:%02d.%02d.%02d.%02d\r\n", (uint16_t)g_ch395q_sta.ipinf_buf[16], (uint16_t)g_ch395q_sta.ipinf_buf[17], (uint16_t)g_ch395q_sta.ipinf_buf[18], (uint16_t)g_ch395q_sta.ipinf_buf[19]);
  34. g_ch395q_sta.dhcp_status = DHCP_UP;
  35. break;
  36. default:
  37. g_ch395q_sta.dhcp_status = DHCP_DOWN;
  38. /* 设置默认IP地址信息 */
  39. printf("静态IP信息.....................................\r\n");
  40. break;
  41. }
  42. }
  43. if (init_status & GINT_STAT_SOCK0)
  44. {
  45. ch395_socket_interrupt(CH395Q_SOCKET_0); /* 处理socket 0中断 */
  46. }
  47. if (init_status & GINT_STAT_SOCK1)
  48. {
  49. ch395_socket_interrupt(CH395Q_SOCKET_1); /* 处理socket 1中断 */
  50. }
  51. if (init_status & GINT_STAT_SOCK2)
  52. {
  53. ch395_socket_interrupt(CH395Q_SOCKET_2); /* 处理socket 2中断 */
  54. }
  55. if (init_status & GINT_STAT_SOCK3)
  56. {
  57. ch395_socket_interrupt(CH395Q_SOCKET_3); /* 处理socket 3中断 */
  58. }
  59. if (init_status & GINT_STAT_SOCK4)
  60. {
  61. ch395_socket_interrupt(CH395Q_SOCKET_4); /* 处理socket 4中断 */
  62. }
  63. if (init_status & GINT_STAT_SOCK5)
  64. {
  65. ch395_socket_interrupt(CH395Q_SOCKET_5); /* 处理socket 5中断 */
  66. }
  67. if (init_status & GINT_STAT_SOCK6)
  68. {
  69. ch395_socket_interrupt(CH395Q_SOCKET_6); /* 处理socket 6中断 */
  70. }
  71. if (init_status & GINT_STAT_SOCK7)
  72. {
  73. ch395_socket_interrupt(CH395Q_SOCKET_7); /* 处理socket 7中断 */
  74. }
  75. }

udp只有前面三个中断,后面时针对TCP/IP的,如果插拔网线之类的,就会进入产生PHY改变中断,那么 会获取PHY状态, 检测PHY状态,执行ch395_reconnection()并重新连接 

  1. /**
  2. * @brief 检测PHY状态,并重新连接
  3. * @param 无
  4. * @retval 无
  5. */
  6. void ch395_reconnection(void)
  7. {
  8. for (uint8_t socket_index = CH395Q_SOCKET_0 ; socket_index <= CH395Q_SOCKET_7 ; socket_index ++ )
  9. {
  10. if (g_ch395q_sta.phy_status == PHY_DISCONN && (g_ch395q_sta.dhcp_status == DHCP_UP || g_ch395q_sta.dhcp_status == DHCP_DOWN || g_ch395q_sta.dhcp_status == DHCP_STA))
  11. {
  12. if (g_ch395q_sta.socket[socket_index].config.socket_enable == CH395Q_ENABLE)
  13. {
  14. ch395_close_socket(g_ch395q_sta.socket[socket_index].config.socket_index); /*关闭socker接口*/
  15. g_ch395q_sta.ch395_error(ch395_dhcp_enable(0)); /*对DHCP进行失能*/ /* ch395q检测错误 */
  16. g_ch395q_sta.socket[socket_index].config.socket_enable = CH395Q_DISABLE; /*socket失能*/
  17. g_ch395q_sta.dhcp_status = DHCP_STA;
  18. /*这里可以加打印 比如网络断开等*/
  19. }
  20. }
  21. else/*下面是重连机制 比如网线重连*/
  22. {
  23. if (g_ch395q_sta.phy_status != PHY_DISCONN && g_ch395q_sta.socket[socket_index].config.socket_enable == CH395Q_DISABLE)
  24. {
  25. if (g_ch395q_sta.dhcp_status == DHCP_STA) /*DHCP是否处于开启状态*/
  26. {
  27. ch395_cmd_reset(); /* 对ch395q复位 */
  28. delay_ms(100); /* 这里必须等待100以上延时 */
  29. ch395_cmd_init();
  30. delay_ms(100); /* 这里必须等待100以上延时 */
  31. ch395_socket_r_s_buf_modify();
  32. // ch395_set_tcpmss(536);
  33. // ch395_set_start_para(FUN_PARA_FLAG_TCP_SERVER | SOCK_CTRL_FLAG_SOCKET_CLOSE);
  34. g_ch395q_sta.ch395_error(ch395_dhcp_enable(1)); /* 开启DHCP */
  35. }
  36. do
  37. {
  38. if (ch395_int_pin_wire == 0)
  39. {
  40. ch395_interrupt_handler(); /* 中断处理函数 */
  41. }
  42. }
  43. while (g_ch395q_sta.dhcp_status == DHCP_STA); /* 获取DHCP */
  44. switch(g_ch395q_sta.socket[socket_index].config.proto)
  45. {
  46. case CH395Q_SOCKET_UDP:
  47. /* socket 为UDP模式 */
  48. ch395_set_socket_desip(socket_index, g_ch395q_sta.socket[socket_index].config.des_ip); /* 设置socket 0目标IP地址 */
  49. ch395_set_socket_prot_type(socket_index, PROTO_TYPE_UDP); /* 设置socket 0协议类型 */
  50. ch395_set_socket_desport(socket_index, g_ch395q_sta.socket[socket_index].config.des_port); /* 设置socket 0目的端口 */
  51. ch395_set_socket_sourport(socket_index, g_ch395q_sta.socket[socket_index].config.sour_port); /* 设置socket 0源端口 */
  52. g_ch395q_sta.ch395_error(ch395_open_socket(socket_index)); /* 检查是否成功 */
  53. break;
  54. case CH395Q_SOCKET_TCP_CLIENT:
  55. /* socket 为TCPClient模式 */
  56. ch395_keeplive_set(); /* 保活设置 */
  57. ch395_set_socket_desip(socket_index, g_ch395q_sta.socket[socket_index].config.des_ip); /* 设置socket 0目标IP地址 */
  58. ch395_set_socket_prot_type(socket_index, PROTO_TYPE_TCP); /* 设置socket 0协议类型 */
  59. ch395_set_socket_desport(socket_index,g_ch395q_sta.socket[socket_index].config.des_port); /* 设置socket 0目的端口 */
  60. ch395_set_socket_sourport(socket_index,g_ch395q_sta.socket[socket_index].config.sour_port); /* 设置socket 0源端口 */
  61. g_ch395q_sta.ch395_error(ch395_open_socket(socket_index)); /* 检查sokect是否打开成功 */
  62. g_ch395q_sta.ch395_error(ch395_tcp_connect(socket_index)); /* 检查tcp连接是否成功 */
  63. break;
  64. case CH395Q_SOCKET_TCP_SERVER:
  65. /* socket 为TCPServer模式 */
  66. ch395_set_socket_desip(socket_index, g_ch395q_sta.socket[socket_index].config.des_ip); /* 设置socket 0目标IP地址 */
  67. ch395_set_socket_prot_type(socket_index, PROTO_TYPE_TCP); /* 设置socket 0协议类型 */
  68. ch395_set_socket_sourport(socket_index, g_ch395q_sta.socket[socket_index].config.sour_port); /* 设置socket 0源端口 */
  69. g_ch395q_sta.ch395_error(ch395_open_socket(socket_index)); /* 检查sokect是否打开成功 */
  70. g_ch395q_sta.ch395_error(ch395_tcp_listen(socket_index)); /* 监听tcp连接 */
  71. break;
  72. case CH395Q_SOCKET_MAC_RAW:
  73. ch395_set_socket_prot_type(socket_index, PROTO_TYPE_MAC_RAW); /* 设置socket 0协议类型 */
  74. g_ch395q_sta.ch395_error(ch395_open_socket(socket_index)); /* 检查sokect是否打开成功 */
  75. break;
  76. default:
  77. ch395_set_socket_prot_type(socket_index, PROTO_TYPE_TCP);
  78. ch395_set_socket_sourport(socket_index, 8080); /* 设置socket 1~7源端口 */
  79. break;
  80. }
  81. g_ch395q_sta.socket[socket_index].config.socket_enable = CH395Q_ENABLE;
  82. }
  83. }
  84. }
  85. }

里面也比较简单,注释都在后面写着大家可以参考~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/52106
推荐阅读
相关标签
  

闽ICP备14008679号