在好例子网,分享、交流、成长!
您当前所在位置:首页C/C++ 开发实例嵌入式开发 → 基于wk2124,STM32,SPI转4路串口程序

基于wk2124,STM32,SPI转4路串口程序

嵌入式开发

下载此实例
  • 开发语言:C/C++
  • 实例大小:6.02KB
  • 下载次数:13
  • 浏览次数:94
  • 发布时间:2021-07-24
  • 实例类别:嵌入式开发
  • 发 布 人:Leoon
  • 文件格式:.rar
  • 所需积分:2
 相关标签: STM32 STM3 串口程序 SPI stm WK2124

实例介绍

【实例简介】

WK2124是SPI
TM 接口的4通道UART器件。WK2124实现SPI桥接/扩展4个增强功能串口
(UART)的功能。
扩展的子通道的UART具备如下功能特点:
每个子通道UART的波特率、字长、校验格式可以独立设置,最高可以提供2Mbps
的通信速率。
每个子通道可以独立设置工作在IrDA红外通信。
每个子通道具备收/发独立的256 级FIFO,FIFO的中断可按用户需求进行编程触
发点且具备超时中断功能。
WK2124采用SSOP20绿色环保的无铅封装,可以工作在2.5~5.0V的宽工作电压范围,
具备可配置自动休眠/唤醒功能。

【实例截图】
【核心代码】
/***************************************************************************/
#include "wk2xxx.h"
#include "spi.h"
#include "usart.h"
#include "delay.h"

void WK2XXX_RST_Init(void)
{
 GPIO_InitTypeDef  GPIO_InitStructure;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 //使能PA,PD端口时钟
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;				 //PA.4 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOA, &GPIO_InitStructure);					 //根据设定参数初始化GPIOA.4
 GPIO_SetBits(GPIOA,GPIO_Pin_3);						 //PA.4 输出高	
}
void WK2XXX_Reset_Init(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_3);//1
GPIO_ResetBits(GPIOA,GPIO_Pin_3);//0
delay_ms(10);
GPIO_SetBits(GPIOA,GPIO_Pin_3);//1	
delay_ms(100);
	
}
/*************************************************************************/
//函数功能:初始化SPI片选信号CS,并把CS的默认状态设置为高电平
//
//
/*************************************************************************/
void SPI_CS_Init(void)
{
// GPIO_InitTypeDef  GPIO_InitStructure;
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 //使能PA,PD端口时钟
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_3;	//PA.4 端口配置
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
// GPIO_Init(GPIOA, &GPIO_InitStructure);					 //根据设定参数初始化GPIOA.4
// GPIO_SetBits(GPIOA,GPIO_Pin_4);						 //PA.4 输出高	
	
	  GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;  // PB12 推挽 
 	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_12);
	
}
/*************************************************************************/
//函数功能:初始化SPI总线,设置SPI总线为0模式
/*************************************************************************/
void SPI_BUS_Init(void)
{

	SPI1_Init();		   //初始化SPI
	SPI1_SetSpeed(SPI_BaudRatePrescaler_8);	//设置为10M时钟,高速模式
}
/*************************************************************************/
//函数功能:设置CS信号为高电平
/*************************************************************************/
void SPI_CS_H(void)
{
	GPIO_SetBits(GPIOB,GPIO_Pin_12);
}
/*************************************************************************/
//函数功能:设置CS信号为低电平
/*************************************************************************/
void SPI_CS_L(void)
{
	GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}
/*************************************************************************/
//函数功能:初始化SPI接口
/*************************************************************************/
void WK2XXX_SPI_Init(void)
{
	SPI_CS_Init();
	SPI_BUS_Init();
	
	
}

/*************************************************************************/
//函数功能:写寄存器函数(前提是该寄存器可写,某些寄存器如果你写1,可能会自动置1,具体见数据手册)
//参数:port:为子串口的数(C0C1)
//      reg:为寄存器的地址(A3A2A1A0)
//      dat:为写入寄存器的数据
//注意:在子串口被打通的情况下,向FDAT写入的数据会通过TX引脚输出
//*************************************************************************/
void Wk2xxxWriteReg(unsigned char port,unsigned char reg,unsigned char dat)
{	 
	 SPI_CS_L();//片选使能
	 SPI1_ReadWriteByte(((port-1)<<4) reg); //写控制字节
	 SPI1_ReadWriteByte(dat); //写数据
	 SPI_CS_H();//片选无效
}


/*************************************************************************/
//函数功能:读寄存器函数
//参数:port:为子串口的数(C0C1)
//      reg:为寄存器的地址(A3A2A1A0)
//      rec_data:为读取到的寄存器值
//注意:在子串口被打通的情况下,读FDAT,实际上就是读取uart的rx接收的数据
/*************************************************************************/
unsigned char Wk2xxxReadReg(unsigned char port,unsigned char reg)
{	
	unsigned char rec_data; 
	SPI_CS_L();	//片选使能
	SPI1_ReadWriteByte(0x40 ((port-1)<<4) reg);//写控制字节,控制命令构成见数据手册
	rec_data=SPI1_ReadWriteByte(0);//接收返回的数据
	SPI_CS_H();	//片选无效	
	return rec_data;
}
/**************************** Wk2xxxWriteFifo*********************************************/
//函数功能:该函数为写FIFO函数,通过该函数写入的数据会直接进入子串口的发送FIFO,然后通过TX引脚发送
//参数:port:为子串口的端口号(C0\C1)
//      *wbuf:写入数据部分
//      len:  写入数据长度
//
/*************************************************************************/
void Wk2xxxWriteFifo(unsigned char port,unsigned char *wbuf,unsigned int len)
{	 unsigned char n;
	 SPI_CS_L(); // 片选有效
	 SPI1_ReadWriteByte(0x80 ((port-1)<<4)); //写FIFO控制指令
	  for(n=0;n<len;n  )
	    {
	     SPI1_ReadWriteByte(*(wbuf n));
		} 
	 SPI_CS_H();	//片选无效

}

/**************************** Wk2xxxReadFifo*********************************************/
//函数功能:该函数为读FIFO函数,通过该函数可以一次读出多个接收FIFO中的数据,最多256个字节
//参数:port:为子串口的端口号(C0\C1)
//      *rbuf:写入数据部分
//      len:  写入数据长度
//
/*************************************************************************/
void Wk2xxxReadFifo(unsigned char port,unsigned char *rbuf,unsigned int len)
{	 unsigned char n;
	 SPI_CS_L();//片选有效
	 SPI1_ReadWriteByte(0xc0 ((port-1)<<4));	//写读fifo控制指令
	 for(n=0;n<len;n  )
	   {
		*(rbuf n)=SPI1_ReadWriteByte(0); 
	   }
	 SPI_CS_H();//片选无效										
	 //return 0;
}

/*************************************************************************/
//函数功能:此函数主要是通过读写wk2xxx的寄存器来判断主接口的通信时序是否有问题
//参数:无
//返回值:rv表示返回值,0成功  
/*************************************************************************/
 unsigned char Wk2xxxTest(void)
 {
	unsigned char rec_data,rv;
//主接口为SPI	
	rec_data=Wk2xxxReadReg(WK2XXX_GPORT,WK2XXX_GENA);
	if(rec_data==0x30)
		return rv;
	else
		{
			rv=1;
			return rv;
		}

 }
/******************************Wk2xxxInit*******************************************/
//函数功能:本函数主要会初始化一些芯片基本寄存器;
/*********************************************************************************/
void Wk2xxxInit(unsigned char port)
{
    unsigned char gena,grst,gier,sier,scr;
	//使能子串口时钟
    gena=Wk2xxxReadReg(WK2XXX_GPORT,WK2XXX_GENA); 
	switch (port)
    {
          case 1://使能子串口1的时钟
              gena|=WK2XXX_UT1EN;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GENA,gena);
              break;
		  case 2://使能子串口2的时钟
              gena|=WK2XXX_UT2EN;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GENA,gena);
              break;
		   case 3://使能子串口3的时钟
              gena|=WK2XXX_UT3EN;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GENA,gena);
              break;
		   case 4://使能子串口4的时钟
              gena|=WK2XXX_UT4EN;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GENA,gena);
              break;
	 }	
	//软件复位子串口
	grst=Wk2xxxReadReg(WK2XXX_GPORT,WK2XXX_GRST); 
	switch (port)
    {
          case 1://软件复位子串口1
              grst|=WK2XXX_UT1RST;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GRST,grst);
              break;
		  case 2://软件复位子串口2
              grst|=WK2XXX_UT2RST;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GRST,grst);
              break;
		   case 3://软件复位子串口3
              grst|=WK2XXX_UT3RST;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GRST,grst);
              break;
		   case 4://软件复位子串口4
             grst|=WK2XXX_UT4RST;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GRST,grst);
              break;
	 }	
  //使能子串口中断,包括子串口总中断和子串口内部的接收中断,和设置中断触点
	gier=Wk2xxxReadReg(WK2XXX_GPORT,WK2XXX_GIER); 
	switch (port)
    {
          case 1://子串口1中断使能
              gier|=WK2XXX_UT1IE;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GIER,gier);
              break;
		  case 2://子串口2中断使能
              gier|=WK2XXX_UT2IE;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GIER,gier);
              break;
		   case 3://子串口3中断使能
              gier|=WK2XXX_UT3IE;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GIER,gier);
              break;
		   case 4://子串口4中断使能
              gier|=WK2XXX_UT4IE;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GIER,gier);
              break;
	 }	 
	 //使能子串口接收触点中断和超时中断
	 sier=Wk2xxxReadReg(port,WK2XXX_SIER); 
//	 sier |= WK2XXX_RFTRIG_IEN|WK2XXX_RXOUT_IEN;
	 sier |= WK2XXX_RFTRIG_IEN;
	 Wk2xxxWriteReg(port,WK2XXX_SIER,sier);
	 // 初始化FIFO和设置固定中断触点
	 Wk2xxxWriteReg(port,WK2XXX_FCR,0XFF);
	 //设置任意中断触点,如果下面的设置有效,那么上面FCR寄存器中断的固定中断触点将失效
	 Wk2xxxWriteReg(port,WK2XXX_SPAGE,1);//切换到page1
	 Wk2xxxWriteReg(port,WK2XXX_RFTL,0X08);//设置接收触点8个字节
	 Wk2xxxWriteReg(port,WK2XXX_TFTL,0X10);//设置发送触点为16个字节
	 Wk2xxxWriteReg(port,WK2XXX_SPAGE,0);//切换到page0 
	 //使能子串口的发送和接收使能
	 scr=Wk2xxxReadReg(port,WK2XXX_SCR); 
	 scr|=WK2XXX_TXEN|WK2XXX_RXEN;
	 Wk2xxxWriteReg(port,WK2XXX_SCR,scr);
}

/******************************Wk2xxxClose*******************************************/
//函数功能:本函数会关闭当前子串口,和复位初始值;
/*********************************************************************************/

void Wk2xxxClose(unsigned char port)
{
    unsigned char gena,grst;
	//复位子串口
	grst=Wk2xxxReadReg(WK2XXX_GPORT,WK2XXX_GRST); 
	switch (port)
    {
          case 1://软件复位子串口1
              grst|=WK2XXX_UT1RST;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GRST,grst);
              break;
		  case 2://软件复位子串口2
              grst|=WK2XXX_UT2RST;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GRST,grst);
              break;
		   case 3://软件复位子串口3
              grst|=WK2XXX_UT3RST;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GRST,grst);
              break;
		   case 4://软件复位子串口4
              grst|=WK2XXX_UT4RST;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GRST,grst);
              break;
	 }	
	//关闭子串口时钟
    gena=Wk2xxxReadReg(WK2XXX_GPORT,WK2XXX_GENA); 
	switch (port)
    {
          case 1://使能子串口1的时钟
              gena&=~WK2XXX_UT1EN;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GENA,gena);
              break;
		  case 2://使能子串口2的时钟
              gena&=~WK2XXX_UT2EN;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GENA,gena);
              break;
		   case 3://使能子串口3的时钟
              gena&=~WK2XXX_UT3EN;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GENA,gena);
              break;
		   case 4://使能子串口4的时钟
              gena&=~WK2XXX_UT4EN;
		      Wk2xxxWriteReg(WK2XXX_GPORT,WK2XXX_GENA,gena);
              break;
	 }	
}






/**************************Wk2xxxSetBaud*******************************************************/
//函数功能:设置子串口波特率函数、此函数中波特率的匹配值是根据11.0592Mhz下的外部晶振计算的
// port:子串口号
// baud:波特率大小.波特率表示方式,
//
/**************************Wk2xxxSetBaud*******************************************************/
void Wk2xxxSetBaud(unsigned char port,int baud)
{  
	unsigned char baud1,baud0,pres,scr;
	//如下波特率相应的寄存器值,是在外部时钟为11.0592的情况下计算所得,如果使用其他晶振,需要重新计算
	switch (baud) 
	{
      case 600:
			baud1=0x4;
			baud0=0x7f;
			pres=0;
      break;
      case 1200:
			baud1=0x2;
			baud0=0x3F;
			pres=0;
			break;
      case 2400:
			baud1=0x1;
			baud0=0x1f;
			pres=0;
			break;
      case 4800:
			baud1=0x00;
			baud0=0x8f;
			pres=0;
			break;
      case 9600:
			baud1=0x00;
			baud0=0x47;
			pres=0;
			break;
      case 19200:
			baud1=0x00;
			baud0=0x23;
			pres=0;
			break;
      case 38400:
			baud1=0x00;
			baud0=0x11;
			pres=0;
			break;
			
      case 76800:
			baud1=0x00;
			baud0=0x08;
			pres=0;
			break; 
       
      case 1800:
			baud1=0x01;
			baud0=0x7f;
			pres=0;
			break;
      case 3600:
			baud1=0x00;
			baud0=0xbf;
			pres=0;
			break;
      case 7200:
			baud1=0x00;
			baud0=0x5f;
			pres=0;
			break;
      case 14400:
			baud1=0x00;
			baud0=0x2f;
			pres=0;
			break;
      case 28800:
			baud1=0x00;
			baud0=0x17;
			pres=0;
			break;
      case 57600:
			baud1=0x00;
			baud0=0x0b;
			pres=0;
      break;
      case 115200:
			baud1=0x00;
			baud0=0x05;
			pres=0;
			break;
      case 230400:
			baud1=0x00;
			baud0=0x02;
			pres=0;
			break;
      default:
			baud1=0x00;
			baud0=0x00;
			pres=0;
    }
	//关掉子串口收发使能
	scr=Wk2xxxReadReg(port,WK2XXX_SCR); 
	Wk2xxxWriteReg(port,WK2XXX_SCR,0);
	//设置波特率相关寄存器
	Wk2xxxWriteReg(port,WK2XXX_SPAGE,1);//切换到page1
	Wk2xxxWriteReg(port,WK2XXX_BAUD1,baud1);
	Wk2xxxWriteReg(port,WK2XXX_BAUD0,baud0);
	Wk2xxxWriteReg(port,WK2XXX_PRES,pres);
	Wk2xxxWriteReg(port,WK2XXX_SPAGE,0);//切换到page0 
	//使能子串口收发使能
	Wk2xxxWriteReg(port,WK2XXX_SCR,scr);
	
	
}
/*****************************Wk2xxxSendBuf****************************************/
//本函数为子串口发送数据的函数,发送数据到子串口的FIFO.然后通过再发送
//参数说明:port:子串口端口号
//          *sendbuf:需要发送的数据buf
//          len:需要发送数据的长度
// 函数返回值:实际成功发送的数据
//说明:调用此函数只是把数据写入子串口的发送FIFO,然后再发送。1、首先确认子串口的发送FIFO有多少数据,根据具体情况、
//确定写入FIFO数据的个数,
/*********************************************************************/
unsigned int Wk2xxxSendBuf(unsigned char port,unsigned char *sendbuf,unsigned int len)
{
	 unsigned int ret,tfcnt,sendlen;
	 unsigned char  fsr;
	  
	 fsr=Wk2xxxReadReg(port,WK2XXX_FSR);
	 if(~fsr&WK2XXX_TFULL )//子串口发送FIFO未满
	 {

	     tfcnt=Wk2xxxReadReg(port,WK2XXX_TFCNT);//读子串口发送fifo中数据个数
		 sendlen=256-tfcnt;//FIFO能写入的最多字节数
		 
		 if(sendlen<len)
		 {
			ret=sendlen; 
			Wk2xxxWriteFifo(port,sendbuf,sendlen);
		 }
		 else
		 {
			 Wk2xxxWriteFifo(port,sendbuf,len);
			 ret=len;
		 }
	  }
	 
	 return ret;
}

/*****************************Wk2xxxGetBuf****************************************/
//本函数为子串口接收数据函数
//参数说明:port:子串口端口号
//          *getbuf:接收到的数据buf
// 函数返回值:实际接收到的数据个数
/*********************************************************************/
unsigned int Wk2xxxGetBuf(unsigned char port,unsigned char *getbuf)
{
	unsigned int ret=0,rfcnt;
	unsigned char fsr;
	fsr=Wk2xxxReadReg(port,WK2XXX_FSR);
	if(fsr&WK2XXX_RDAT )//子串口发送FIFO未满
	  {
	     rfcnt=Wk2xxxReadReg(port,WK2XXX_RFCNT);//读子串口发送fifo中数据个数
		 if(rfcnt==0)//当RFCNT寄存器为0的时候,有两种情况,可能是256或者是0,这个时候通过FSR来判断,如果FSR显示接收FIFO不为空,就为256个字节
		 {rfcnt=256;}
		 Wk2xxxReadFifo(port,getbuf,rfcnt);
		 ret=rfcnt;
	   }
	 return ret;	
}


实例下载地址

基于wk2124,STM32,SPI转4路串口程序

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警