STM32驱动WK2168串口扩展芯片完整教程

一、WK2168介绍
WK2168是首款具备256级FIFO的低功耗并支持 UART/SPITM/IIC/8位并行总线接口的
4通道UART器件。可以通过模式选择使得该芯片工作于以上任何一种主接口模式,将选
定的主接口扩展为4个增强功能的UART。
扩展的子通道的UART具备如下功能特点:
1.每个子通道UART的波特率、字长、校验格式可以独立设置,最高可以提供2Mbps
的通信速率。
2.每个子通道可以独立设置工作在IrDA红外通信、 RS-485自动收发控制、 9位网络
地址自动识别、软件/硬件自动流量控制等高级工作模式下。
3.每个子通道具备收/发独立的256 级FIFO, FIFO的中断可按用户需求进行编程触
发点且具备超时中断功能。
WK2168采用LQFP48绿色环保的无铅封装,可以工作在2.5~5.0V的宽工作电压范围,
具备可配置自动休眠/唤醒功能
二、硬件连接
在这里插入图片描述
在这里插入图片描述
三、驱动代码
main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h" 
#include "wk2168.h"





int main(void)
{	
	//wk2xxx相关定义
	u8 sendTimeCnt;
	u16 ledCnt;
	u8 dat1;
	u8 sendData[5]={0x01,0x02,0x03,0x04,0x05};
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	delay_init();	
	uart_init(115200);
	led_init();	
	wk2168_init();	
	wk2168_exit_init();

/*读写GNEA,测试主接口通信是否成功*/
	dat1=wk2168_read_g_reg(WK2XXX_GENA);
	printf("gena=0x%x.\r\n",dat1);


	/*初始化子串口*/
	wk2168_sub_uart_init(1);
	wk2168_sub_uart_init(2);
	wk2168_sub_uart_init(3);
	wk2168_sub_uart_init(4);
	/*设置子串口波特率*/
	wk2168_set_baudrate(1,B9600);
	wk2168_set_baudrate(2,B9600);
	wk2168_set_baudrate(3,B9600);
	wk2168_set_baudrate(4,B9600);
	/*使能485*/
	wk2168_set_rs485(1);
	wk2168_set_rs485(2);
	wk2168_set_rs485(3);
	wk2168_set_rs485(4);

	
	while(1)
	{
		
		sendTimeCnt++;
		if(sendTimeCnt>=100)
		{
			sendTimeCnt=0;
			wk2168_exti_disable();		
			wk2168_write_s_fifo(1,sendData,sizeof(sendData));
			wk2168_write_s_fifo(2,sendData,sizeof(sendData));
			wk2168_write_s_fifo(3,sendData,sizeof(sendData));
			wk2168_write_s_fifo(4,sendData,sizeof(sendData));
			wk2168_exti_enable();				
			
		}
	
		
		ledCnt++;
		if(ledCnt>=50)
		{
			ledCnt=0;
			turn_prog_led();
		}
		
		delay_ms(10);
	}
}

wk2168.c

#include "wk2168.h"
#include "delay.h"


void wk2168_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	SPI_InitTypeDef SPI_InitStructure;
	
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB | RCC_APB2Periph_SPI1, ENABLE );	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PA0--INT#
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_Init( GPIOB, &GPIO_InitStructure );
	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//SPI1_RST
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_Init( GPIOB, &GPIO_InitStructure );
	GPIO_SetBits(GPIOB,GPIO_Pin_0);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//SPI1_CS
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_Init( GPIOA, &GPIO_InitStructure );
	GPIO_SetBits(GPIOA,GPIO_Pin_4);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//SPI1_SCK
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStructure );	

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//SPI1_MISO
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;		
	GPIO_Init( GPIOA, &GPIO_InitStructure );	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//SPI1_MOSI
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStructure );
	
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;	
	
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;	

	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;	
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;	
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;	
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	
	SPI_InitStructure.SPI_CRCPolynomial = 7;
	SPI_Init( SPI1, &SPI_InitStructure );

	SPI_Cmd( SPI1, ENABLE );
	

	wk2168_rst=0;
	delay_ms(50);
	wk2168_rst=1;
	delay_ms(10);
	
}
 
void wk2168_exit_init()
{
 	EXTI_InitTypeDef EXTI_InitStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能复用功能时钟

    
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);//下降沿触发

  	EXTI_InitStructure.EXTI_Line=EXTI_Line1;	
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);	 	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;			//使能按键KEY2所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;	//抢占优先级2, 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;					//子优先级2
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);	
}
void wk2168_exti_enable(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;			//使能按键KEY2所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;	//抢占优先级2, 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;					//子优先级2
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);
}

void wk2168_exti_disable(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;			//使能按键KEY2所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;	//抢占优先级2, 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;					//子优先级2
  	NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);
}
//外部中断0服务程序 
void EXTI1_IRQHandler(void)
{
	u8 gifr,rxbuf[256];
	int rxlen;	
	if(EXTI_GetFlagStatus(EXTI_Line1)!= RESET)
	{
		gifr=wk2168_read_g_reg(WK2XXX_GIFR);/**/
		do{
			if(gifr&WK2XXX_UT1INT)//判断子串口1是否有中断
			{ 
				/*数据处理*/
				/*数据接收*/
				rxlen=wk2168_rec_data(1,rxbuf);//一次接收的数据不会超过256Byte
				/*数据发送*/
				//把接收的数据发送出去
				wk2168_send_data(1,rxlen,rxbuf);

			}
			
			if(gifr&WK2XXX_UT2INT)//判断子串口2是否有中断
			{
				/*数据接收*/
				rxlen=wk2168_rec_data(2,rxbuf);//一次接收的数据不会超过256Byte
				/*数据发送*/
				//把接收的数据发送出去
				wk2168_send_data(2,rxlen,rxbuf);
			
			  }
			if(gifr&WK2XXX_UT3INT)//判断子串口3是否有中断
			{
				/*数据接收*/
				rxlen=wk2168_rec_data(3,rxbuf);//一次接收的数据不会超过256Byte
				/*数据发送*/
				//把接收的数据发送出去
				wk2168_send_data(3,rxlen,rxbuf);
				// printf("port!!!!\n");
			}
			if(gifr&WK2XXX_UT4INT)//判断子串口4是否有中断
			{
				/*数据接收*/
				rxlen=wk2168_rec_data(4,rxbuf);//一次接收的数据不会超过256Byte
				/*数据发送*/
				//把接收的数据发送出去
				wk2168_send_data(4,rxlen,rxbuf);
			}
			
			gifr=wk2168_read_g_reg(WK2XXX_GIFR);
			//printf("IN EXTI2_IRQ GIFR:0X%X !!!\n",gifr);
		}while(gifr&0x0f);					
		EXTI_ClearITPendingBit(EXTI_Line1); //清除LINE0上的中断标志位  
	}
}
/* SPI交换一个字节接口 */
u8 wk2168_spi_read_write_byte(u8 TxData)
{
	u8 retry=0;				 	
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
	{
		retry++;
		if(retry>200)return 0;
	}			  
	SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
	retry=0;

	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
	{
		retry++;
		if(retry>200)return 0;
	}	  						    
	return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据	
}

/*************************************************************************/
//函数功能:设置CS信号为高电平
/*************************************************************************/
void wk2168_cs_high(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_4);
}
/*************************************************************************/
//函数功能:设置CS信号为低电平
/*************************************************************************/
void wk2168_cs_low(void)
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_4);
}
/***************************wk2168_write_g_reg***********************************/
//函数功能:写全局寄存器函数(前提是该寄存器可写,
//某些寄存器如果你写1,可能会自动置1,具体见数据手册)
//参数:
//      greg:为全局寄存器的地址
//      dat:为写入寄存器的数据
//***********************************************************************/
void wk2168_write_g_reg(unsigned char greg,unsigned char dat)
{	 
	u8 cmd;
	cmd=0|greg;
	wk2168_cs_low();//拉低cs信号
	wk2168_spi_read_write_byte(cmd);	//写指令,对于指令的构成见数据手册
	wk2168_spi_read_write_byte(dat);//写数据
	wk2168_cs_high();//拉高cs信号
}
/****************************wk2168_read_g_reg***********************************/
//函数功能:读全局寄存器
//参数:
//      greg:为全局寄存器的地址
//      rec:返回的寄存器值
//***********************************************************************/
u8 wk2168_read_g_reg(unsigned char greg)
{	 
	u8 cmd,rec;
	cmd=0x40|greg;
	wk2168_cs_low();//拉低cs信号
	wk2168_spi_read_write_byte(cmd);	//写指令,对于指令的构成见数据手册
	rec=wk2168_spi_read_write_byte(0);//写数据
	wk2168_cs_high();//拉高cs信号							
	return rec;
}

/**************************wk2168_write_s_reg***********************************/
//函数功能:
//参数:port:为子串口
//      sreg:为子串口寄存器
//      dat:为写入寄存器的数据
//注意:在子串口被打通的情况下,向FDAT写入的数据会通过TX引脚输出
//**********************************************************************/
void wk2168_write_s_reg(u8 port,u8 sreg,u8 dat)
{	 
	u8 cmd;
	cmd=0x0|((port-1)<<4)|sreg;
	wk2168_cs_low();//拉低cs信号
	wk2168_spi_read_write_byte(cmd);	//写指令,对于指令的构成见数据手册
	wk2168_spi_read_write_byte(dat);//写数据
	wk2168_cs_high();//拉高cs信号
}

/**************************wk2168_read_s_reg***********************************/
//函数功能:读子串口寄存器
//参数:port为子串口端口号
//      sreg:为子串口寄存器地址
//      rec:返回的寄存器值
//**********************************************************************/
u8 wk2168_read_s_reg(u8 port,u8 sreg)
{	 
	u8 cmd,rec;
	cmd=0x40|((port-1)<<4)|sreg;
	wk2168_cs_low();//拉低cs信号
	wk2168_spi_read_write_byte(cmd);	//写指令,对于指令的构成见数据手册
	rec=wk2168_spi_read_write_byte(0);//写数据
	wk2168_cs_high();	//拉高cs信号							
	return rec;
}
/************************wk2168_write_s_fifo***********************************/
//函数功能:向子串口fifo写入需要发送的数据
//参数:port:为子串口
//      *dat:写入数据
//      num:为写入数据的个数,单次不超过256
//注意:通过该方式写入的数据,被直接写入子串口的缓存FIFO,然后被发送
//*********************************************************************/
void wk2168_write_s_fifo(u8 port,u8 *dat,int num)
{	 
	u8 cmd;
	int i;
	cmd=0x80|((port-1)<<4);
	if(num>0)
	{
		wk2168_cs_low();//拉低cs信号
		wk2168_spi_read_write_byte(cmd); //写指令,对于指令构成见数据手册
		for(i=0;i<num;i++)
		{
			wk2168_spi_read_write_byte( *(dat+i));//写数据
		}
		wk2168_cs_high();//拉高cs信号
	}
}

/************************wk2168_read_s_fifo***********************************/
//函数功能:从子串口的fifo中读出接收到的数据
//参数:port:为子串口
//      *rec:接收到的数据
//      num:读出的数据个数。
//注意:通过该方式读出子串口缓存中的数据。单次不能超过256
//*********************************************************************/
void wk2168_read_s_fifo(u8 port,u8 *rec,int num)
{
	u8 cmd;
	int n;
	cmd=0xc0|((port-1)<<4);
	if(num>0)
	{
		wk2168_cs_low();//拉低cs信号
		wk2168_spi_read_write_byte(cmd);
		for(n=0;n<num;n++)
		{	
			*(rec+n)=wk2168_spi_read_write_byte(0);	
		}
		wk2168_cs_high();//拉高cs信号
	}
}


/*******WkInit*******************************************/
//函数功能:初始化子串口
/*******************************************************/
void wk2168_sub_uart_init(u8 port)
{
	u8 gena,grst,gier,sier,scr;
	//使能子串口时钟
	gena=wk2168_read_g_reg(WK2XXX_GENA);
	gena=gena|(1<<(port-1));
	wk2168_write_g_reg(WK2XXX_GENA,gena);
	//软件复位子串口
	grst=wk2168_read_g_reg(WK2XXX_GRST);
	grst=grst|(1<<(port-1));
	wk2168_write_g_reg(WK2XXX_GRST,grst);
	//使能串口总中断
	gier=wk2168_read_g_reg(WK2XXX_GIER);
	gier=gier|(1<<(port-1));
	wk2168_write_g_reg(WK2XXX_GIER,gier);
	//使能子串口接收触点中断和超时中断
	sier=wk2168_read_s_reg(port,WK2XXX_SIER); 
	sier |= WK2XXX_RFTRIG_IEN|WK2XXX_RXOUT_IEN;
	wk2168_write_s_reg(port,WK2XXX_SIER,sier);
	//初始化FIFO和设置固定中断触点
	wk2168_write_s_reg(port,WK2XXX_FCR,0XFF);  
	//设置任意中断触点,如果下面的设置有效,
	//那么上面FCR寄存器中断的固定中断触点将失效
	wk2168_write_s_reg(port,WK2XXX_SPAGE,1);//切换到page1
	wk2168_write_s_reg(port,WK2XXX_RFTL,0X40);//设置接收触点为64个字节
	wk2168_write_s_reg(port,WK2XXX_TFTL,0X10);//设置发送触点为16个字节
	wk2168_write_s_reg(port,WK2XXX_SPAGE,0);//切换到page0 
	//使能子串口的发送和接收使能
	scr=wk2168_read_s_reg(port,WK2XXX_SCR); 
	scr|=WK2XXX_TXEN|WK2XXX_RXEN;
	wk2168_write_s_reg(port,WK2XXX_SCR,scr);	  		
}

/******************************wk2168_sub_uart_deinit*******************************************/
//函数功能:初始化子串口
/*********************************************************************************/
void wk2168_sub_uart_deinit(u8 port)
{
	u8 gena,grst,gier;
	//关闭子串口总时钟
	gena=wk2168_read_g_reg(WK2XXX_GENA);
	gena=gena&(~(1<<(port-1)));
	wk2168_write_g_reg(WK2XXX_GENA,gena);
	//使能子串口总中断
	gier=wk2168_read_g_reg(WK2XXX_GIER);
	gier=gier&(~(1<<(port-1)));
	wk2168_write_g_reg(WK2XXX_GIER,gier);
	//软件复位子串口
	grst=wk2168_read_g_reg(WK2XXX_GRST);
	grst=grst|(1<<(port-1));
	wk2168_write_g_reg(WK2XXX_GRST,grst);
	
}

/**************************wk2168_set_baudrate*******************************************************/
//函数功能:设置子串口波特率函数、此函数中波特率的匹配值是根据11.0592Mhz下的外部晶振计算的
// port:子串口号
// baud:波特率大小.波特率表示方式,
/**************************Wk2114SetBaud*******************************************************/
void wk2168_set_baudrate(u8 port,enum WKBaud baud)
{  
	unsigned char baud1,baud0,pres,scr;
	//如下波特率相应的寄存器值,是在外部时钟为11.0592mhz的情况下计算所得,如果使用其他晶振,需要重新计算
	switch (baud) 
	{
		case B600:
			baud1=0x4;
			baud0=0x7f;
			pres=0;
			break;
		case B1200:
			baud1=0x2;
			baud0=0x3F;
			pres=0;
			break;
		case B2400:
			baud1=0x1;
			baud0=0x1f;
			pres=0;
			break;
		case B4800:
			baud1=0x00;
			baud0=0x8f;
			pres=0;
			break;
		case B9600:
			baud1=0x00;
			baud0=0x47;
			pres=0;
			break;
		case B19200:
			baud1=0x00;
			baud0=0x23;
			pres=0;
			break;
		case B38400:
			baud1=0x00;
			baud0=0x11;
			pres=0;
			break;
		case B76800:
			baud1=0x00;
			baud0=0x08;
			pres=0;
			break;        
		case B1800:
			baud1=0x01;
			baud0=0x7f;
			pres=0;
			break;
		case B3600:
			baud1=0x00;
			baud0=0xbf;
			pres=0;
			break;
		case B7200:
			baud1=0x00;
			baud0=0x5f;
			pres=0;
			break;
		case B14400:
			baud1=0x00;
			baud0=0x2f;
			pres=0;
			break;
		case B28800:
			baud1=0x00;
			baud0=0x17;
			pres=0;
			break;
		case B57600:
			baud1=0x00;
			baud0=0x0b;
			pres=0;
			break;
		case B115200:
			baud1=0x00;
			baud0=0x05;
			pres=0;
			break;
		case B230400:
			baud1=0x00;
			baud0=0x02;
			pres=0;
			break;
		default:
			baud1=0x00;
			baud0=0x00;
			pres=0;
    }
	//关掉子串口收发使能
	scr=wk2168_read_s_reg(port,WK2XXX_SCR); 
	wk2168_write_s_reg(port,WK2XXX_SCR,0);
	//设置波特率相关寄存器
	wk2168_write_s_reg(port,WK2XXX_SPAGE,1);//切换到page1
	wk2168_write_s_reg(port,WK2XXX_BAUD1,baud1);
	wk2168_write_s_reg(port,WK2XXX_BAUD0,baud0);
	wk2168_write_s_reg(port,WK2XXX_PRES,pres);
	wk2168_write_s_reg(port,WK2XXX_SPAGE,0);//切换到page0 
	//使能子串口收发使能
	wk2168_write_s_reg(port,WK2XXX_SCR,scr);
}
/**************************wk2168_get_tx_len*******************************************/
//函数功能:获取子串口发送FIFO剩余空间长度
// port:端口号
// 返回值:发送FIFO剩余空间长度
/**************************WK_Len********************************************/
int wk2168_get_tx_len(u8 port)
{
	u8 fsr,tfcnt;
	int len=0;
	fsr  =wk2168_read_s_reg(port,WK2XXX_FSR);
	tfcnt=wk2168_read_s_reg(port,WK2XXX_TFCNT);
	if(fsr& WK2XXX_TFULL)
	{ 
		len=0;
	}
	else
	{
		len=256-tfcnt;
	}
	return len;
}

/**************************wk2168_send_data*******************************************/
//函数功能:通过子串口发送固定长度数据
// port:端口号
// len:单次发送长度不超过256
// 
/**************************wk2168_send_data********************************************/
int wk2168_send_data(u8 port,int len,u8 *sendbuf)
{
	
#if 1
	wk2168_write_s_fifo(port,sendbuf,len);//通过fifo方式发送数据
#else
	int num=len;
	for(num=0;num<len;num++)
	{
		wk2168_write_s_reg(port,WK2XXX_FDAT,*(sendbuf+num));
	}
#endif	
	return 0;
}

/**************************wk2168_rec_data*******************************************/
//函数功能:读取子串口fifo中的数据
// port:端口号
// recbuf:接收到的数据
// 返回值:接收数据的长度
/**************************wk2168_rec_data********************************************/
int wk2168_rec_data(u8 port,u8 *recbuf)
{
	u8  fsr=0,rfcnt=0,rfcnt2=0,sifr=0;
	int len=0;
	sifr=wk2168_read_s_reg(port,WK2XXX_SIFR);
	

	if((sifr&WK2XXX_RFTRIG_INT)||(sifr&WK2XXX_RXOVT_INT))//有接收中断和接收超时中断
	{ 
		fsr  =wk2168_read_s_reg(port,WK2XXX_FSR);
		rfcnt=wk2168_read_s_reg(port,WK2XXX_RFCNT);
		rfcnt2=wk2168_read_s_reg(port,WK2XXX_RFCNT);
		//printf("rfcnt=0x%x.\n",rfcnt);
		/*判断fifo中数据个数*/
		if(fsr& WK2XXX_RDAT)
		{ 
			if(!(rfcnt2>=rfcnt))
			{
				rfcnt=rfcnt2;
			}
			len=(rfcnt==0)?256:rfcnt;
		}
#if 1
		wk2168_read_s_fifo(port,recbuf,len);
#else
		for(n=0;n<len;n++)
		 *(recbuf+n)=wk2168_read_s_reg(port,WK2XXX_FDAT);
#endif	
		return len;
	}
	else
	{
		len=0;
		return len;
	}
}

/**************************wk2168_set_rs485*******************************************************/
//函数功能:设置子串口RS485的收发转换函数,使用RTS引脚控制485电平转换芯片的收发
// port:子串口号
// 
//注意:只有WK2168/WK2204支持该功能
/**************************wk2168_set_rs485*******************************************************/
void wk2168_set_rs485(u8 port)
{   
	wk2168_write_s_reg(port,WK2XXX_RS485,0x02);//
	//wk2168_write_s_reg(port,WK2XXX_RS485,0x03);//
	wk2168_write_s_reg(port,WK2XXX_SPAGE,1);//切换到page1
	wk2168_write_s_reg(port,WK2XXX_RTSDLY,0x01);
	wk2168_write_s_reg(port,WK2XXX_SPAGE,0);//切换到page0 
}
/**************************wk2168_rts_cts*******************************************************/
//函数功能:硬件自动流量控制,需要子设备的支持
// port:子串口号
// 
//注意:只有WK2168/WK2204支持该功能
/**************************wk2168_rts_cts*******************************************************/
void wk2168_rts_cts(u8 port)
{   
	wk2168_write_s_reg(port,WK2XXX_FWCR,0x30);//
	wk2168_write_s_reg(port,WK2XXX_SPAGE,1);//切换到page1
	wk2168_write_s_reg(port,WK2XXX_FWTH,0XF0);//停止接收触点
	wk2168_write_s_reg(port,WK2XXX_FWTL,0X20);//继续接收触点
	wk2168_write_s_reg(port,WK2XXX_SPAGE,0);//切换到page0 
}

四、完整工程下载

完整工程下载,请点击

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: wk2168 是一款基于STM32 HAL的嵌入式开发板。STM32 HAL(Hardware Abstraction Layer)是STMicroelectronics推出的一种针对STM32系列微控制器的硬件抽象层。它提供了一系列函数库,使得开发者可以更加方便地进行底层硬件的操作和驱动开发。 在使用wk2168开发板时,我们可以充分利用STM32 HAL提供的丰富函数库来实现各种功能。例如,通过HAL库可以轻松地配置GPIO(通用输入输出端口),设置为输入或输出,并进行读写操作。还可以使用HAL库配置定时器,产生各种中断信号或PWM波形。HAL还提供了USART(串行通信)和I2C(串行总线通信)等外设的配置和操作函数,方便进行串口通信和外部设备的数据交互。 在使用STM32 HAL开发时,我们可以通过CubeMX(一个专门用于STM32硬件配置的图形化工具)来自动生成初始化代码,包括时钟配置、引脚定义、外设配置等。然后,我们可以在主函数中进行逻辑代码的编写和实现。 总之,wk2168开发板在STM32 HAL的支持下,提供了丰富的硬件抽象函数库,方便开发者进行底层硬件的操作和驱动开发。使用HAL库,可以大大提高开发效率,减少开发周期,实现各种功能的快速开发。 ### 回答2: 在STM32 HAL下,wk2168 可以代表很多不同的含义,例如作为一个变量名、函数名或者别的标识符。在这种情况下,需要更多的背景信息才能给出一个具体的回答。 STM32是一款由STMicroelectronics(意法半导体)开发的32位单片机系列。HAL(Hardware Abstraction Layer)是STM32的一个软件库,用于提供对硬件抽象的支持。通过HAL库,开发人员可以简化底层硬件的配置和操作。 如果wk2168是作为一个变量名,它代表一个存储器中的数据。在STM32 HAL中,可以使用相关的HAL库函数来访问和操作这个变量,例如读取、写入或修改。 如果wk2168是作为一个函数名,它可能代表某个特定的功能。在STM32 HAL中,可以通过调用函数名为wk2168的函数来执行这个功能。需要查阅相关的HAL文档,以了解这个函数的具体用法和参数。 总的来说,STM32 HAL提供了一种简化STM32开发的方法,可以更加方便地配置硬件和进行软件开发。无论wk2168是代表变量名、函数名或其他标识符,在STM32 HAL下都可以通过相关的支持库来操作它。需要进一步的信息才能给出更加具体的回答。 ### 回答3: wk2168是一种STM32开发板,它基于STM32 HAL(硬件抽象层)开发环境。 STM32 HAL是STMicroelectronics为STM32系列微控制器提供的一种软件库。它提供了一套易于使用的API(应用程序接口),帮助开发人员更快地创建应用程序和驱动程序。HAL库包含了许多常用的功能,例如GPIO(通用输入/输出)、UART(通用异步收发器)、SPI(串行外围接口)和I2C(串行外围设备接口)等。 使用wk2168开发板,我们可以在STM32 HAL下进行开发。首先,我们需要将WK2168开发板与电脑连接,并安装好相应的开发环境,例如Keil MDK或者STM32CubeIDE。然后,我们可以通过HAL库提供的API来访问开发板上的各种外围设备,例如LED、按键、串口等。 例如,如果我们想要控制开发板上的一个LED灯,我们可以调用HAL_GPIO_WritePin()函数来设置LED的状态,使用HAL库提供的其他函数来配置GPIO引脚的工作模式和电平。 另外,使用STM32 HAL开发环境还可以轻松地开发其他各种功能。我们可以使用HAL库来实现定时器功能、中断处理、AD转换等各种应用。同时,HAL库还提供了一些便利的功能,例如时钟配置、DMA(直接内存访问)传输等。 总之,WK2168STM32 HAL下为我们提供了一种便捷的开发环境。我们可以利用HAL库快速开发各种应用程序,并充分利用STM32系列微控制器的性能和功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小灰灰搞电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值