使用
CH347StreamSPI4函数与SPI从机通信时 偶尔会出现函数不返回阻塞导致进程卡死的现象。 此时只有拔掉CH347的USB口才能解决卡死问题(函数可直接返回错误)
程序已经在CH347OpenDevice后设置了超时
CH347SetTimeout(mDevIndex,500,500);
以下是源码:
#include "ch347.h"
#include "CH347DLL.H"
#include <QDebug>
#include "QsLog.h"
#include "mytime.h"
//pins 0-7 isRisingEdge 是否为上升沿触发
bool Ch347::gpioSetIRQCallback(uint8_t pins,bool isRisingEdge,mPCH347_INT_ROUTINE call)
{
uint8_t Int0TripMode=0;
if(isRisingEdge)
{
Int0TripMode=1;
}
// 设定GPIO中断服务程序
bool isSetIrq=CH347SetIntRoutine(mDevIndex, // 指定设备序号
pins, // 中断0 GPIO引脚号,大于7:不启用此中断源; 为0-7对应gpio0-7
Int0TripMode, // 中断0类型: 00:下降沿触发; 01:上升沿触发; 02:双边沿触发; 03:保留;
9, // 中断1 GPIO引脚号,大于7则不启用此中断源,为0-7对应gpio0-7
0, // 中断1类型: 00:下降沿触发; 01:上升沿触发; 02:双边沿触发; 03:保留;
call);// 指定中断服务程序,为NULL则取消中断服务,否则在中断时调用该程序
return isSetIrq;
}
Ch347::Ch347(int mode)
{
mMode=mode;
QLOG_DEBUG()<<"mMode="<<mMode;
int count=enumDevice();
QLOG_DEBUG()<<"设备数量:"<<count;
if(count<=0)
{
QLOG_ERROR()<<"枚举失败";
}
for (auto it = qAsConst(mDevInfoMap).begin(); it != qAsConst(mDevInfoMap).end(); ++it)
{
QString str(it.value().FuncDescStr);
int key=it.key();
QLOG_DEBUG()<<"枚举设备 index:"<<key<<"信息:"<<str;
}
QLOG_DEBUG()<<"CH347 构造完成";
}
Ch347::~Ch347()
{
closeDev();
}
//枚举设备
int Ch347::enumDevice()
{
ULONG i,DevCnt = 0;
mDevIsOpened = (CH347OpenDevice(mDevIndex) != INVALID_HANDLE_VALUE);
QLOG_DEBUG()<<"devOpen:"<<mDevIsOpened;
if(mDevIsOpened==false)
{
QLOG_ERROR()<<"打开CH347设备出错";
}
CH347SetTimeout(mDevIndex,500,500);
mDeviceInforS DevInfor;
for(i=0;i<16;i++)
{
if(CH347Uart_Open(i) != INVALID_HANDLE_VALUE)
{
CH347Uart_GetDeviceInfor(i,&DevInfor);
mDevInfoMap[DevCnt]=DevInfor;
DevCnt++;
}
CH347Uart_Close(i);
}
return DevCnt;
}
void Ch347::closeDev(void)
{
if(mDevIsOpened)
{
QLOG_DEBUG()<<"关闭CH347设备";
CH347CloseDevice(mDevIndex);
mDevIsOpened=false;
}
}
bool Ch347::SPITest()
{
mSpiCfgS readCfg = {0};
bool rec=CH347SPI_GetCfg(0,&readCfg);
return rec;
}
bool Ch347::SPIOpen()
{
bool RetVal = FALSE;
mSpiCfgS SpiCfg = {0};
UCHAR SpiDatabits = 0; // 设置的数据位 默认0
SpiCfg.iMode = (UCHAR)1;
SpiCfg.iClock = (UCHAR)5;
SpiCfg.iByteOrder = (UCHAR)1;
SpiCfg.iSpiWriteReadInterval =0;
SpiCfg.iSpiOutDefaultData = 0xFF;
SpiCfg.iChipSelect = 0;
SpiCfg.iChipSelect |= 0x80;
SpiCfg.CS1Polarity = (UCHAR)0;
SpiCfg.CS2Polarity = (UCHAR)0;
SpiCfg.iIsAutoDeativeCS = 0;
SpiCfg.iActiveDelay = 0;
SpiCfg.iDelayDeactive =0;
// 设置SPI 数据位
//SpiDatabits = (UCHAR)0;//SendDlgItemMessage(SpiI2cGpioDebugHwnd,IDC_SpiCfg_Databits,CB_GETCURSEL,0,0);
RetVal = CH347SPI_SetDataBits(mDevIndex, SpiDatabits);
RetVal = CH347SPI_Init(mDevIndex,&SpiCfg);
QLOG_DEBUG()<<"CH347SPI_Init "<<RetVal;
return RetVal;
}
bool Ch347::gpioGet(uint8_t pins)
{
bool RetVal;
uint8_t iDir = 0,iData = 0;
RetVal = CH347GPIO_Get(mDevIndex,&iDir,&iData);
if(RetVal)
{
mPinsDir=iDir;
mPinsVol=iData;
//显示方向
uint8_t Dir = (iDir&(1<<pins))?BST_CHECKED:BST_UNCHECKED;
//电平值
uint8_t Sel = (iData&(1<<pins))?BST_CHECKED:BST_UNCHECKED;
bool vol=(bool)Sel;
return vol;
}
return false;
}
bool Ch347::gpioSet(uint8_t pins,bool isHigh,bool isEnable)
{
if(pins>7)
{
return false;
}
uint8_t enable=(uint8_t)isEnable;
uint8_t dir=1;
uint8_t data=(uint8_t)isHigh;
mPinsEnable|=(enable<<pins);
mPinsDir|=(dir<<pins);
mPinsVol|=(data<<pins);
bool rec=CH347GPIO_Set(mDevIndex,// 指定设备序号
mPinsEnable,// 数据有效标志:对应位0-7,对应GPIO0-7.
mPinsDir,// 设置I/O方向,某位清0则对应引脚为输入,某位置1则对应引脚为输出.GPIO0-7对应位0-7.
mPinsVol); // 输出数据,如果I/O方向为输出,那么某位清0时对应引脚输出低电平,某位置1时对应引脚输出高电平
return rec;
}
bool Ch347::SPIWrite(Bytes& bytes)
{
uint8_t buf[1024*3]={0};
int len=bytes.length();
memcpy(buf,bytes.toBuffer(),len);
QLOG_DEBUG()<<"SPI 写入:"<<bytes.toString();
UCHAR ChipSelect=0x80;
//事实上单独的SPI写或读函数是可以直接被 CH347SPI_WriteRead 函数替代使用的。
//之所以提供单独的 CH347SPI_Read 和 CH347SPI_Write 函数
//是考虑到实际应用有需要单向操作的场景,此类函数使用会更直观些
bool rec=CH347SPI_Write(mDevIndex,ChipSelect,len,512,buf);
if(rec==false)
{
QLOG_ERROR()<<"SPI写失败";
}
return rec;
}
bool Ch347::SPIWriteRead(Bytes& bytes)
{
Mytime::delayMs(10);
uint8_t buf[1024*3]={0};
int len=bytes.length();
memcpy(buf,bytes.toBuffer(),len);
QLOG_DEBUG()<<"SPI 写入:"<<bytes.toString();
UCHAR ChipSelect=0x80;
//CH347StreamSPI4其API为适应此前调用方式,功能与CH347SPI_WriteRead一致
bool rec=CH347StreamSPI4(mDevIndex,ChipSelect,len,buf);
memcpy(bytes.toBuffer(),buf,len);
QLOG_DEBUG()<<"SPI 读出:"<<bytes.toString();
if(rec==false)
{
QLOG_ERROR()<<"SPI写失败";
}
return rec;
}
bool Ch347::IICOpen()
{
mDevIsOpened = (CH347OpenDevice(mDevIndex) != INVALID_HANDLE_VALUE);
QLOG_DEBUG()<<"devOpen:"<<mDevIsOpened;
if(mDevIsOpened==false)
{
return false;
}
bool retVal = CH347I2C_Set(mDevIndex, mIICSpeedMode);
QLOG_DEBUG()<<"CH347I2C Set clock:"<<retVal;
retVal = CH347I2C_SetStretch(mDevIndex, false);
QLOG_DEBUG()<<"CH347 I2C set stetching:"<<retVal;
uint32_t I2CDelayMs = 100;
if (I2CDelayMs > 0)
{
retVal = CH347I2C_SetDelaymS(mDevIndex, I2CDelayMs);
QLOG_DEBUG()<<"CH347InitI2C"<<retVal;
}
return retVal;
}
bool Ch347::IICReadWrite(uint8_t* outBuffer,int& outLen,uint8_t* inBuffer,int& inLen)
{
bool RetVal = CH347StreamI2C(mDevIndex,outLen,outBuffer,inLen,inBuffer);
QLOG_DEBUG()<<"read write iic:"<<RetVal;
if(RetVal)
{
QLOG_DEBUG()<<"inlen="<<inLen;
}
return RetVal;
}
热门产品 :
CH390:以太网控制器芯片