实例介绍
【实例简介】
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; }
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论