找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1204|回复: 1
打印 上一主题 下一主题
收起左侧

STM32F407VET6单片机串口扩展WK2124程序

[复制链接]
跳转到指定楼层
楼主
/***********************************************************************
文件名称:main.C
功    能:
编写时间:
编 写 人:
注    意:
***********************************************************************/
#include "main.h"
#include "wk2xxx.h"
#include "wk2xxx_test.h"
//#include "sdcard.h"
//#include "ff.h"
//#include "LCD.h"
//#include "MM1_240.h"
//#include "MM3_240.h"
/*
目前stm32和WK2XXX 硬件连接关系
复位RST:PB8
cs:PA4
clk:PA5
mosi:PA7
miso:PA6
*/
void EXTI9_5_IRQHandler (void)
{
  u8 gifr,rxbuf[256];
  int rxlen;
  printf("IN EXTI2_IRQ!!!!\n");
/*关闭LED灯*/
// LED1(LED_OFF);
// LED2(LED_OFF);
// LED3(LED_OFF);
// LED4(LED_OFF);
if(EXTI_GetFlagStatus(EXTI_Line9)!= RESET)
{    EXTI_ClearITPendingBit(EXTI_Line9); //清除LINE1上的中断标志位  
   gifr=WkReadGReg(WK2XXX_GIFR);/**/
  do{
   if(gifr&WK2XXX_UT1INT)//判断子串口1是否有中断
   { /*数据处理*/
      /*数据接收*/
      rxlen=wk_RxChars(1,rxbuf);//一次接收的数据不会超过256Byte
      /*数据发送*/
      //把接收的数据发送出去
      wk_TxChars(1,rxlen,rxbuf);
   }
   
   if(gifr&WK2XXX_UT2INT)//判断子串口2是否有中断
   {
    /*数据接收*/
      rxlen=wk_RxChars(2,rxbuf);//一次接收的数据不会超过256Byte
      /*数据发送*/
      //把接收的数据发送出去
      wk_TxChars(2,rxlen,rxbuf);
   
     }
   if(gifr&WK2XXX_UT3INT)//判断子串口3是否有中断
   {
    /*数据接收*/
      rxlen=wk_RxChars(3,rxbuf);//一次接收的数据不会超过256Byte
      /*数据发送*/
      //把接收的数据发送出去
      wk_TxChars(3,rxlen,rxbuf);
       // printf("port!!!!\n");
   }
   if(gifr&WK2XXX_UT4INT)//判断子串口4是否有中断
   {
    /*数据接收*/
      rxlen=wk_RxChars(4,rxbuf);//一次接收的数据不会超过256Byte
      /*数据发送*/
      //把接收的数据发送出去
       //wk_TxChars(4,rxlen,rxbuf);
   }
   
  gifr=WkReadGReg(WK2XXX_GIFR);
  //printf("IN EXTI2_IRQ GIFR:0X%X !!!\n",gifr);
  }while(gifr&0x0f);
  printf("IN EXTI2_IRQ over! !!!\n");
}
}






int main(void)
{
//wk2xxx相关定义
  unsigned char dat1,sendbuf[256]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x12};
unsigned char tmp_buf[1];
/*
  ST固件库中的启动文件已经执行了 SystemInit() 函数,该函数在 system_stm32f4xx.c 文件,主要功能是
  配置CPU系统的时钟,内部Flash访问时序,配置FSMC用于外部SRAM等。
*/
  SysTick_Configuration();  //延时初始化  
USART_Configuration();
//   Key_Configuration();
// LED_Configuration();
//  SPI1_Init( ) ;
  WK_SPI_Init();//初始化SPI总线
/*读写GNEA,测试主接口通信是否成功*/
dat1=WkReadGReg(WK2XXX_GENA);
printf("gena=0x%x.\n",dat1);
/*硬件复位芯片*/
WK_RstInit();
/*初始化子串口*/
Wk_Init(1);
Wk_Init(2);
Wk_Init(3);
Wk_Init(4);
/*设置子串口波特率*/
Wk_SetBaud(1,115200);
Wk_SetBaud(2,115200);
Wk_SetBaud(3,115200);
Wk_SetBaud(4,115200);
/*使能485*/
//WK_RS485(1);
//WK_RS485(2);
//WK_RS485(3);
//WK_RS485(4);
EXTIX_Init();//初始化CPU外部中断

while(1)
{


  delay_ms(1000);


  Exti_Disable();/*关闭外部中断响应*/
/*中断屏蔽区,这样可以防止中断响应打乱spi的操作时序*/
/*通常在中断函数外部操作读写寄存器的时候,最好关断中断响应,但是这个时间也不要过长,过长导致子串口溢出,从而导致数据丢失*/
/*如果对于大数据需要发送,一次操作不要超过256,最好不要让程序阻塞在发送中*/
//len=wk_TxLen(4);/*判断子串口4能写入数据的个数*/
//wk_TxChars(4,len,sendbuf);/*写入len个数据进入发送fifo*/
WkWriteSFifo(1,sendbuf,10);
Exti_Enable();/*开启外部中断响应*/


//wk_TxChars(1,10,"0123456789");
wk_test1(2);






}



}

#include "spi.h"
#include "stm32f4xx.h"
SPI_InitTypeDef  SPI_InitStructure;
//串行外设接口SPI的初始化,SPI配置成主模式         
//本例程选用SPI1对NRF24L01进行读写操作,先对SPI1进行初始化
void SPI1_Init(void)
{  
GPIO_InitTypeDef  GPIO_InitStructure;
  //打开所用GPIO的时钟
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);   //使能GPIOA时钟
  
  //配置的IO是PB12 PB13 PB15,SPI的CS CLK MOSI
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;  //管脚SPI复用 (<STM32F4为>PA5:SPI1_SCK,PA6:SPI1_MISO,PA7:SPI1_MOSI)              
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
  //配置的IO是PA6,SPI的MISO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;     //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);

}  
/**************************************************************************************
* 描  述 : 模拟SPI写入一个字节
* 入  参 : uint8_t date
* 返回值 :
**************************************************************************************/
void SPI_WriteByte(uint8_t date)
{
  uint8_t temp,i;
  temp = date;  
  for (i = 0; i < 8; i++)
{
      SPI_SCLK(0);
     if((temp&0x80)==0x80)
     { SPI_MOSI(1); }
     else
     { SPI_MOSI(0); }
     SPI_SCLK(1) ;
     temp <<= 1;
   }
  SPI_SCLK(0);
   SPI_MOSI(0);   
  
}
/**************************************************************************************
* 描  述 : 模拟SPI读取一个字节
* 入  参 : 无
* 返回值 : 读取uint8_t数据
**************************************************************************************/
uint8_t SPI_ReadByte(void)
{
  uint8_t temp=0;
  uint8_t i,SDI;
  SPI_SCLK(0) ;                 
  for(i = 0; i < 8; i++)
{
    temp <<= 1;
    SPI_SCLK(1) ;        
    SDI = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);   //MISO接收数据
  if(SDI)
    {temp++; }
   SPI_SCLK(0) ;
   }
  SPI_SCLK(0) ;
   return(temp);
}




void SPI1_SetSpeed(u8 SpeedSet)
{
// SPI_InitStructure.SPI_BaudRatePrescaler = SpeedSet ;
//  SPI_Init(SPI1, &SPI_InitStructure);
// SPI_Cmd(SPI1,ENABLE);
}


/*************************************************************************/
//函数功能:初始化SPI片选信号CS,并把CS的默认状态设置为高电平
//
//
/*************************************************************************/
void SPI_CS_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = SPI1_CS;   
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init( GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIO_SPI1,SPI1_CS);
}
/*************************************************************************/
//函数功能:初始化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(GPIOA,GPIO_Pin_4);
}
/*************************************************************************/
//函数功能:设置CS信号为低电平
/*************************************************************************/
void SPI_CS_L(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
}
/*************************************************************************/
//函数功能:初始化SPI接口
/*************************************************************************/
void WK_SPI_Init(void)
{
SPI_CS_Init();
SPI_BUS_Init();
}








//u8 SPI1_ReadWriteByte(u8 TxData)                                        //SPI读写数据函数
//{  
// u8 retry=0;      
// /* Loop while DR register in not emplty */
// while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)      //发送缓存标志位为空
//  {
//  retry++;
//  if(retry>200)return 0;
//  }     
// /* Send byte through the SPI1 peripheral */
// SPI_I2S_SendData(SPI1, TxData);                                    //通过外设SPI1发送一个数据
// retry=0;
// /* Wait to receive a byte */
// while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)  //接收缓存标志位不为空
//  {
//  retry++;
//  if(retry>200)return 0;
//  }            
// /* Return the byte read from the SPI bus */
// return SPI_I2S_ReceiveData(SPI1);                                 //通过SPI1返回接收数据        
//}




#include "wk2xxx.h"
#include "delay.h"
#include "spi.h"
#include "sys.h"
#include "SCI.h"
#include "wk2xxx_test.h"
#include "exti.h"
/**************************************WK_RstInit***********************************/
//函数功能:wk芯片需要用MCU的GPIO去控制RST引脚,本函数通过stm32的PB.8引脚连接WK的RST引脚
//初始化STM32的PB8引脚。
//      
//*************************************************************************/
void WK_RstInit(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;

RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE);   
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;          //PB.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);          //根据设定参数初始化GPIOB.8
GPIO_SetBits(GPIOA,GPIO_Pin_8);               //PB.8 输出高
delay_ms(50);
GPIO_ResetBits(GPIOA,GPIO_Pin_8);          //PB.8 输出低
delay_ms(10);
GPIO_SetBits(GPIOA,GPIO_Pin_8);       //PB.8 输出高
delay_ms(10);
}
/***************************WkWriteGReg***********************************/
//函数功能:写全局寄存器函数(前提是该寄存器可写,
//某些寄存器如果你写1,可能会自动置1,具体见数据手册)
//参数:
//      greg:为全局寄存器的地址
//      dat:为写入寄存器的数据
//***********************************************************************/
void WkWriteGReg(unsigned char greg,unsigned char dat)
{  u8 cmd;
  cmd=0|greg;
  SPI_CS_L();//拉低cs信号
  SPI_WriteByte(cmd); //写指令,对于指令的构成见数据手册
  SPI_WriteByte(dat);//写数据
   SPI_CS_H();//拉高cs信号
}
/****************************WkReadGReg***********************************/
//函数功能:读全局寄存器
//参数:
//      greg:为全局寄存器的地址
//      rec:返回的寄存器值
//***********************************************************************/
u8 WkReadGReg(unsigned char greg)
{  u8 cmd,rec;
  cmd=0x40|greg;
  SPI_CS_L();//拉低cs信号
  SPI_WriteByte(cmd); //写指令,对于指令的构成见数据手册
  rec=SPI_ReadByte();//写数据
   SPI_CS_H();//拉高cs信号      
  return rec;
}
/**************************WkWriteSReg***********************************/
//函数功能:
//参数:port:为子串口
//      sreg:为子串口寄存器
//      dat:为写入寄存器的数据
//注意:在子串口被打通的情况下,向FDAT写入的数据会通过TX引脚输出
//**********************************************************************/
void WkWriteSReg(u8 port,u8 sreg,u8 dat)
{  u8 cmd;
  cmd=0x0|((port-1)<<4)|sreg;
  SPI_CS_L();//拉低cs信号
  SPI_WriteByte(cmd); //写指令,对于指令的构成见数据手册
  SPI_WriteByte(dat);//写数据
   SPI_CS_H();//拉高cs信号
}
/**************************WkReadSReg***********************************/
//函数功能:读子串口寄存器
//参数:port为子串口端口号
//      sreg:为子串口寄存器地址
//      rec:返回的寄存器值
//**********************************************************************/
u8 WkReadSReg(u8 port,u8 sreg)
{  u8 cmd,rec;
  cmd=0x40|((port-1)<<4)|sreg;
  SPI_CS_L();//拉低cs信号
  SPI_WriteByte(cmd); //写指令,对于指令的构成见数据手册
  rec=SPI_ReadByte();//写数据
   SPI_CS_H(); //拉高cs信号      
  return rec;
}
/************************WkWriteSFifo***********************************/
//函数功能:向子串口fifo写入需要发送的数据
//参数:port:为子串口
//      *dat:写入数据
//      num:为写入数据的个数,单次不超过256
//注意:通过该方式写入的数据,被直接写入子串口的缓存FIFO,然后被发送
//*********************************************************************/
void WkWriteSFifo(u8 port,u8 *dat,int num)
{  
  u8 cmd;
  int i;
  cmd=0x80|((port-1)<<4);
  if(num>0)
  {
    SPI_CS_L();//拉低cs信号
    SPI_WriteByte(cmd); //写指令,对于指令构成见数据手册
    for(i=0;i<num;i++)
    {
     SPI_WriteByte( *(dat+i));//写数据
    }
    SPI_CS_H();//拉高cs信号
   }
}
/************************WkReadSFifo***********************************/
//函数功能:从子串口的fifo中读出接收到的数据
//参数:port:为子串口
//      *rec:接收到的数据
//      num:读出的数据个数。
//注意:通过该方式读出子串口缓存中的数据。单次不能超过256
//*********************************************************************/
void WkReadSFifo(u8 port,u8 *rec,int num)
{
  u8 cmd;
  int n;
   cmd=0xc0|((port-1)<<4);
  if(num>0)
  {
    SPI_CS_L();//拉低cs信号
     SPI_WriteByte(cmd);
    for(n=0;n<num;n++)
    {
     *(rec+n)= SPI_ReadByte();
    }
    SPI_CS_H();//拉高cs信号
   }
}

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

}
/**************************Wk_SetBaud*******************************************************/
//函数功能:设置子串口波特率函数、此函数中波特率的匹配值是根据11.0592Mhz下的外部晶振计算的
// port:子串口号
// baud:波特率大小.波特率表示方式,
/**************************Wk2114SetBaud*******************************************************/
uint8_t Wk_SetBaud(u8 port,uint32_t baudrate)
{  
  uint32_t temp,freq;
  uint8_t scr;
  uint8_t baud1,baud0,pres;
  freq=11059200;/*芯片外部时钟频率*/
// freq=32000000;/*芯片外部时钟频率*/
   if(freq>=(baudrate*16))
  {
   temp=(freq)/(baudrate*16);
   temp=temp-1;
   baud1=(uint8_t)((temp>>8)&0xff);
   baud0=(uint8_t)(temp&0xff);
   temp=(((freq%(baudrate*16))*100)/(baudrate));
   pres=(temp+100/2)/100;
   printf("Wk_SetBaud---freq:%d,baudrate:%d\n",freq,baudrate);
   printf("Wk_SetBaud---baud1:%x,baud0:%x,pres:%x\n",baud1,baud0,pres);
   //关掉子串口收发使能
   scr=WkReadSReg(port,WK2XXX_SCR);
   WkWriteSReg(port,WK2XXX_SCR,0);
   //设置波特率相关寄存器
   WkWriteSReg(port,WK2XXX_SPAGE,1);//切换到page1
   WkWriteSReg(port,WK2XXX_BAUD1,baud1);
   WkWriteSReg(port,WK2XXX_BAUD0,baud0);
   WkWriteSReg(port,WK2XXX_PRES,pres);
   WkWriteSReg(port,WK2XXX_SPAGE,0);//切换到page0
   //使能子串口收发使能
   WkWriteSReg(port,WK2XXX_SCR,scr);
   return 0;
  }
  else
  {
   printf("Wk_SetBaud error!!!!\n");
   return 1;
  }
}
/**************************WK_TxLen*******************************************/
//函数功能:获取子串口发送FIFO剩余空间长度
// port:端口号
// 返回值:发送FIFO剩余空间长度
/**************************WK_Len********************************************/
int wk_TxLen(u8 port)
{
u8 fsr,tfcnt;
int len=0;
fsr  =WkReadSReg(port,WK2XXX_FSR);
tfcnt=WkReadSReg(port,WK2XXX_TFCNT);
if(fsr& WK2XXX_TFULL)
  { len=0;}
else
   {len=256-tfcnt;}
  return len;
}
/**************************WK_TxChars*******************************************/
//函数功能:通过子串口发送固定长度数据
// port:端口号
// len:单次发送长度不超过256
//
/**************************WK_TxChars********************************************/
int wk_TxChars(u8 port,int len,u8 *sendbuf)
{

#if 1
WkWriteSFifo(port,sendbuf,len);//通过fifo方式发送数据
#else
int num=len;
for(num=0;num<len;num++)
{
  WkWriteSReg(port,WK2XXX_FDAT,*(sendbuf+num));
}
#endif
}
/**************************WK_RxChars*******************************************/
//函数功能:读取子串口fifo中的数据
// port:端口号
// recbuf:接收到的数据
// 返回值:接收数据的长度
/**************************WK_RxChars********************************************/
int wk_RxChars(u8 port,u8 *recbuf)
{
u8  fsr=0,rfcnt=0,rfcnt2=0,sifr=0;
  int n,len=0;
sifr=WkReadSReg(port,WK2XXX_SIFR);

if((sifr&WK2XXX_RFTRIG_INT)||(sifr&WK2XXX_RXOVT_INT))//有接收中断和接收超时中断
{
   fsr  =WkReadSReg(port,WK2XXX_FSR);
   rfcnt=WkReadSReg(port,WK2XXX_RFCNT);
   rfcnt2=WkReadSReg(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
   WkReadSFifo(port,recbuf,len);
  #else
   for(n=0;n<len;n++)
    *(recbuf+n)=WkReadSReg(port,WK2XXX_FDAT);
  #endif
   return len;
  }
else
{
  len=0;
  return len;
}
}
/**************************WK_RS485*******************************************************/
//函数功能:设置子串口RS485的收发转换函数,使用RTS引脚控制485电平转换芯片的收发
// port:子串口号
//
//注意:只有WK2168/WK2204支持该功能
/**************************WK_RS485*******************************************************/
void WK_RS485(u8 port)
{   
   WkWriteSReg(port,WK2XXX_RS485,0x02);//默认高电平
   //WkWriteSReg(port,WK2XXX_RS485,0x03);//默认低电平
  WkWriteSReg(port,WK2XXX_SPAGE,1);//切换到page1
  WkWriteSReg(port,WK2XXX_RTSDLY,0X10);
  WkWriteSReg(port,WK2XXX_SPAGE,0);//切换到page0
}
/**************************WK_RTSCTS*******************************************************/
//函数功能:硬件自动流量控制,需要子设备的支持
// port:子串口号
//
//注意:只有WK2168/WK2204支持该功能
/**************************WK_RTSCTS*******************************************************/
void WK_RTSCTS(u8 port)
{   
   WkWriteSReg(port,WK2XXX_FWCR,0x30);//
  WkWriteSReg(port,WK2XXX_SPAGE,1);//切换到page1
  WkWriteSReg(port,WK2XXX_FWTH,0XF0);//停止接收触点
  WkWriteSReg(port,WK2XXX_FWTL,0X20);//继续接收触点
  WkWriteSReg(port,WK2XXX_SPAGE,0);//切换到page0
}
/**************************WK_IrqApp*******************************************/
//函数功能:中断处理的一般流程,可以根据需要修改
//
//
//
/**************************WK_IrqApp********************************************/
//u8 WK_IrqApp(void)
//{
// u8 gifr,sier,sifr;
// gifr=WkReadGReg(WK2XXX_GIFR);
// if(gifr&WK2XXX_UT1INT)//判断子串口1是否有中断
// {
//  sifr =WkReadSReg(1,WK2XXX_SIFR);
//  if()
// }
// if(gifr&WK2XXX_UT2INT)//判断子串口2是否有中断
// {
//  
// }
// if(gifr&WK2XXX_UT3INT)//判断子串口3是否有中断
// {
//  
// }
// if(gifr&WK2XXX_UT4INT)//判断子串口4是否有中断
// {
//  
// }
//
//
//}
程序运行正常,将TX2与RX2短接,测试数据如下

#include "wk2xxx.h"
#include "delay.h"
#include "spi.h"
#include "sys.h"
#include "SCI.h"
#include "wk2xxx_test.h"
#include "exti.h"
/**************************************WK_RstInit***********************************/
//函数功能:wk芯片需要用MCU的GPIO去控制RST引脚,本函数通过stm32的PB.8引脚连接WK的RST引脚
//初始化STM32的PB8引脚。
//      
//*************************************************************************/
void WK_RstInit(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;

RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE);   
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;          //PB.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);          //根据设定参数初始化GPIOB.8
GPIO_SetBits(GPIOA,GPIO_Pin_8);               //PB.8 输出高
delay_ms(50);
GPIO_ResetBits(GPIOA,GPIO_Pin_8);          //PB.8 输出低
delay_ms(10);
GPIO_SetBits(GPIOA,GPIO_Pin_8);       //PB.8 输出高
delay_ms(10);
}
/***************************WkWriteGReg***********************************/
//函数功能:写全局寄存器函数(前提是该寄存器可写,
//某些寄存器如果你写1,可能会自动置1,具体见数据手册)
//参数:
//      greg:为全局寄存器的地址
//      dat:为写入寄存器的数据
//***********************************************************************/
void WkWriteGReg(unsigned char greg,unsigned char dat)
{  u8 cmd;
  cmd=0|greg;
  SPI_CS_L();//拉低cs信号
  SPI_WriteByte(cmd); //写指令,对于指令的构成见数据手册
  SPI_WriteByte(dat);//写数据
   SPI_CS_H();//拉高cs信号
}
/****************************WkReadGReg***********************************/
//函数功能:读全局寄存器
//参数:
//      greg:为全局寄存器的地址
//      rec:返回的寄存器值
//***********************************************************************/
u8 WkReadGReg(unsigned char greg)
{  u8 cmd,rec;
  cmd=0x40|greg;
  SPI_CS_L();//拉低cs信号
  SPI_WriteByte(cmd); //写指令,对于指令的构成见数据手册
  rec=SPI_ReadByte();//写数据
   SPI_CS_H();//拉高cs信号      
  return rec;
}
/**************************WkWriteSReg***********************************/
//函数功能:
//参数:port:为子串口
//      sreg:为子串口寄存器
//      dat:为写入寄存器的数据
//注意:在子串口被打通的情况下,向FDAT写入的数据会通过TX引脚输出
//**********************************************************************/
void WkWriteSReg(u8 port,u8 sreg,u8 dat)
{  u8 cmd;
  cmd=0x0|((port-1)<<4)|sreg;
  SPI_CS_L();//拉低cs信号
  SPI_WriteByte(cmd); //写指令,对于指令的构成见数据手册
  SPI_WriteByte(dat);//写数据
   SPI_CS_H();//拉高cs信号
}
/**************************WkReadSReg***********************************/
//函数功能:读子串口寄存器
//参数:port为子串口端口号
//      sreg:为子串口寄存器地址
//      rec:返回的寄存器值
//**********************************************************************/
u8 WkReadSReg(u8 port,u8 sreg)
{  u8 cmd,rec;
  cmd=0x40|((port-1)<<4)|sreg;
  SPI_CS_L();//拉低cs信号
  SPI_WriteByte(cmd); //写指令,对于指令的构成见数据手册
  rec=SPI_ReadByte();//写数据
   SPI_CS_H(); //拉高cs信号      
  return rec;
}
/************************WkWriteSFifo***********************************/
//函数功能:向子串口fifo写入需要发送的数据
//参数:port:为子串口
//      *dat:写入数据
//      num:为写入数据的个数,单次不超过256
//注意:通过该方式写入的数据,被直接写入子串口的缓存FIFO,然后被发送
//*********************************************************************/
void WkWriteSFifo(u8 port,u8 *dat,int num)
{  
  u8 cmd;
  int i;
  cmd=0x80|((port-1)<<4);
  if(num>0)
  {
    SPI_CS_L();//拉低cs信号
    SPI_WriteByte(cmd); //写指令,对于指令构成见数据手册
    for(i=0;i<num;i++)
    {
     SPI_WriteByte( *(dat+i));//写数据
    }
    SPI_CS_H();//拉高cs信号
   }
}
/************************WkReadSFifo***********************************/
//函数功能:从子串口的fifo中读出接收到的数据
//参数:port:为子串口
//      *rec:接收到的数据
//      num:读出的数据个数。
//注意:通过该方式读出子串口缓存中的数据。单次不能超过256
//*********************************************************************/
void WkReadSFifo(u8 port,u8 *rec,int num)
{
  u8 cmd;
  int n;
   cmd=0xc0|((port-1)<<4);
  if(num>0)
  {
    SPI_CS_L();//拉低cs信号
     SPI_WriteByte(cmd);
    for(n=0;n<num;n++)
    {
     *(rec+n)= SPI_ReadByte();
    }
    SPI_CS_H();//拉高cs信号
   }
}

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

}
/**************************Wk_SetBaud*******************************************************/
//函数功能:设置子串口波特率函数、此函数中波特率的匹配值是根据11.0592Mhz下的外部晶振计算的
// port:子串口号
// baud:波特率大小.波特率表示方式,
/**************************Wk2114SetBaud*******************************************************/
uint8_t Wk_SetBaud(u8 port,uint32_t baudrate)
{  
  uint32_t temp,freq;
  uint8_t scr;
  uint8_t baud1,baud0,pres;
  freq=11059200;/*芯片外部时钟频率*/
// freq=32000000;/*芯片外部时钟频率*/
   if(freq>=(baudrate*16))
  {
   temp=(freq)/(baudrate*16);
   temp=temp-1;
   baud1=(uint8_t)((temp>>8)&0xff);
   baud0=(uint8_t)(temp&0xff);
   temp=(((freq%(baudrate*16))*100)/(baudrate));
   pres=(temp+100/2)/100;
   printf("Wk_SetBaud---freq:%d,baudrate:%d\n",freq,baudrate);
   printf("Wk_SetBaud---baud1:%x,baud0:%x,pres:%x\n",baud1,baud0,pres);
   //关掉子串口收发使能
   scr=WkReadSReg(port,WK2XXX_SCR);
   WkWriteSReg(port,WK2XXX_SCR,0);
   //设置波特率相关寄存器
   WkWriteSReg(port,WK2XXX_SPAGE,1);//切换到page1
   WkWriteSReg(port,WK2XXX_BAUD1,baud1);
   WkWriteSReg(port,WK2XXX_BAUD0,baud0);
   WkWriteSReg(port,WK2XXX_PRES,pres);
   WkWriteSReg(port,WK2XXX_SPAGE,0);//切换到page0
   //使能子串口收发使能
   WkWriteSReg(port,WK2XXX_SCR,scr);
   return 0;
  }
  else
  {
   printf("Wk_SetBaud error!!!!\n");
   return 1;
  }
}
/**************************WK_TxLen*******************************************/
//函数功能:获取子串口发送FIFO剩余空间长度
// port:端口号
// 返回值:发送FIFO剩余空间长度
/**************************WK_Len********************************************/
int wk_TxLen(u8 port)
{
u8 fsr,tfcnt;
int len=0;
fsr  =WkReadSReg(port,WK2XXX_FSR);
tfcnt=WkReadSReg(port,WK2XXX_TFCNT);
if(fsr& WK2XXX_TFULL)
  { len=0;}
else
   {len=256-tfcnt;}
  return len;
}
/**************************WK_TxChars*******************************************/
//函数功能:通过子串口发送固定长度数据
// port:端口号
// len:单次发送长度不超过256
//
/**************************WK_TxChars********************************************/
int wk_TxChars(u8 port,int len,u8 *sendbuf)
{

#if 1
WkWriteSFifo(port,sendbuf,len);//通过fifo方式发送数据
#else
int num=len;
for(num=0;num<len;num++)
{
  WkWriteSReg(port,WK2XXX_FDAT,*(sendbuf+num));
}
#endif
}
/**************************WK_RxChars*******************************************/
//函数功能:读取子串口fifo中的数据
// port:端口号
// recbuf:接收到的数据
// 返回值:接收数据的长度
/**************************WK_RxChars********************************************/
int wk_RxChars(u8 port,u8 *recbuf)
{
u8  fsr=0,rfcnt=0,rfcnt2=0,sifr=0;
  int n,len=0;
sifr=WkReadSReg(port,WK2XXX_SIFR);

if((sifr&WK2XXX_RFTRIG_INT)||(sifr&WK2XXX_RXOVT_INT))//有接收中断和接收超时中断
{
   fsr  =WkReadSReg(port,WK2XXX_FSR);
   rfcnt=WkReadSReg(port,WK2XXX_RFCNT);
   rfcnt2=WkReadSReg(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
   WkReadSFifo(port,recbuf,len);
  #else
   for(n=0;n<len;n++)
    *(recbuf+n)=WkReadSReg(port,WK2XXX_FDAT);
  #endif
   return len;
  }
else
{
  len=0;
  return len;
}
}
/**************************WK_RS485*******************************************************/
//函数功能:设置子串口RS485的收发转换函数,使用RTS引脚控制485电平转换芯片的收发
// port:子串口号
//
//注意:只有WK2168/WK2204支持该功能
/**************************WK_RS485*******************************************************/
void WK_RS485(u8 port)
{   
   WkWriteSReg(port,WK2XXX_RS485,0x02);//默认高电平
   //WkWriteSReg(port,WK2XXX_RS485,0x03);//默认低电平
  WkWriteSReg(port,WK2XXX_SPAGE,1);//切换到page1
  WkWriteSReg(port,WK2XXX_RTSDLY,0X10);
  WkWriteSReg(port,WK2XXX_SPAGE,0);//切换到page0
}
/**************************WK_RTSCTS*******************************************************/
//函数功能:硬件自动流量控制,需要子设备的支持
// port:子串口号
//
//注意:只有WK2168/WK2204支持该功能
/**************************WK_RTSCTS*******************************************************/
void WK_RTSCTS(u8 port)
{   
   WkWriteSReg(port,WK2XXX_FWCR,0x30);//
  WkWriteSReg(port,WK2XXX_SPAGE,1);//切换到page1
  WkWriteSReg(port,WK2XXX_FWTH,0XF0);//停止接收触点
  WkWriteSReg(port,WK2XXX_FWTL,0X20);//继续接收触点
  WkWriteSReg(port,WK2XXX_SPAGE,0);//切换到page0
}
/**************************WK_IrqApp*******************************************/
//函数功能:中断处理的一般流程,可以根据需要修改
//
//
//
/**************************WK_IrqApp********************************************/
//u8 WK_IrqApp(void)
//{
// u8 gifr,sier,sifr;
// gifr=WkReadGReg(WK2XXX_GIFR);
// if(gifr&WK2XXX_UT1INT)//判断子串口1是否有中断
// {
//  sifr =WkReadSReg(1,WK2XXX_SIFR);
//  if()
// }
// if(gifr&WK2XXX_UT2INT)//判断子串口2是否有中断
// {
//  
// }
// if(gifr&WK2XXX_UT3INT)//判断子串口3是否有中断
// {
//  
// }
// if(gifr&WK2XXX_UT4INT)//判断子串口4是否有中断
// {
//  
// }
//
//
//}

运行数据.jpg (458.74 KB, 下载次数: 33)

程序运行数据

程序运行数据

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:169559 发表于 2022-10-11 12:41 | 只看该作者
楼主 有WK2114的吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表