初始化时先调用CH438_PinInit()配置一下并口的IO口,然后调用一下CH438_UARTxInit(UARTx)配置各个串口,接下来就可以用CH438_UARTxRcv读取接收缓存里的数据,以及用CH438_UARTxSendByte和CH438_UARTxSend发送数据了。
CH438的驱动如下
/*********************************************************************************************************
** 功能: CH438引脚初始化
** 输入: 无
** 返回: 无
** 说明: CH438引脚初始化
*********************************************************************************************************/
void CH438_PinInit()
{
CH438_CSHigh();
CH438_ALELow();
CH438_WRHigh();
CH438_RDHigh();
}
/*********************************************************************************************************
** 功能: CH438写寄存器
** 输入: Addr:寄存器地址
** 输入: RegValue:寄存器值
** 返回: 无
** 说明: CH438写寄存器
*********************************************************************************************************/
void CH438_WriteReg(uint8_t Addr, uint8_t RegValue)
{
CH438_SetDPort(Addr);
CH438_CSLow();
CH438_ALEHigh();
CH438_ALELow();
CH438_SetDPort(RegValue);
CH438_WRLow();
CH438_WRHigh();
CH438_CSHigh();
}
/*********************************************************************************************************
** 功能: CH438读寄存器
** 输入: Addr:寄存器地址
** 返回: 寄存器值
** 说明: CH438读寄存器
*********************************************************************************************************/
uint8_t CH438_ReadReg(uint8_t Addr)
{
uint8_t Data;
CH438_SetDPort(Addr);
CH438_CSLow();
CH438_ALEHigh();
CH438_ALELow();
CH438_SetDPortIn();
CH438_RDLow();
Data = CH438_ReadDPort();
CH438_RDHigh();
CH438_CSHigh();
return (Data);
}
/*********************************************************************************************************
** 功能: 检测访问CH438芯片是否正常
** 输入: 无
** 返回: 0 异常; 1 正常
** 说明: 通过往一个寄存器写入值,然后读出判断是否一致,来检测访问是否正常
*********************************************************************************************************/
uint8_t CH438_CheckRW()
{
static uint8_t CheckData=0;
uint8_t Temp;
CH438_WriteReg(REG_SCR_ADDR, CheckData);
Temp = CH438_ReadReg(REG_SCR_ADDR);
if (CheckData != Temp)
{
CheckData ++;
CH438RWErrorFlag = 1;
return 0;
}
CheckData ++;
CH438RWErrorFlag = 0;
return 1;
}
/*********************************************************************************************************
** 功能: 初始化CH438串口UARTx
** 输入: UARTx: UARTx, 0~7
** 返回: 0 成功;1 失败,访问出错
** 说明: 初始化CH438串口UARTx
*********************************************************************************************************/
uint8_t CH438_UARTxInit(uint8_t UARTx)
{
uint16_t DL = CH438_CLK/12/16/UARTsBaud[UARTx];
uint8_t UARTxBase = UARTsBase[UARTx];
uint8_t LCR;
if (!CH438_CheckRW())
{
return (0);
}
//先复位UARTx
CH438_WriteReg(UARTxBase+REG_IER_ADDR, 1<<7);
//设置UARTx的波特率
LCR = CH438_ReadReg(UARTxBase+REG_LCR_ADDR);
LCR |= (1<<7);
CH438_WriteReg(UARTxBase+REG_LCR_ADDR, LCR); //DLAB置1
CH438_WriteReg(UARTxBase+REG_DLL_ADDR, DL);
CH438_WriteReg(UARTxBase+REG_DLM_ADDR, DL >> 8);
LCR &= ~(1<<7);
CH438_WriteReg(UARTxBase+REG_LCR_ADDR, LCR); //DLA清0
//设置数据格式: 无校验; 1个停止位; 8个数据位
CH438_WriteReg(UARTxBase+REG_LCR_ADDR,
(0 << 4) //校验模式 0:奇校验; 1:偶检验; 2:1检验; 3:0检验
| (0 << 3) //校验使能 0:禁能; 1:使能
| (0 << 2) //停止位 0:1个停止位; 1:2个停止位
| (3 << 0)); //字长. 0:5 bits; 1:six bits; 2:7 bits; 3:8 bits
//使能FIFO模式,清空FIFO
CH438_WriteReg(UARTxBase+REG_FCR_ADDR, 0x07);
return (1);
}
/*********************************************************************************************************
** 功能: CH438 UARTx发送一个字节
** 输入: UARTx: UARTx, 0~7
** 输入: Data: 要发送的字节
** 返回: 0 成功;1 失败,访问出错
** 说明: 同步模式,发送完毕,函数才返回
*********************************************************************************************************/
uint8_t CH438_UARTxSendByte(uint8_t UARTx, uint8_t Data)
{
uint8_t UARTxBase = UARTsBase[UARTx];
if (!CH438_CheckRW())
{
return (0);
}
while((CH438_ReadReg(UARTxBase+REG_LSR_ADDR) & (1<<5)) == 0); //等待发送保持寄存器THR空
CH438_WriteReg(UARTxBase+REG_THR_ADDR, Data);
while((CH438_ReadReg(UARTxBase+REG_LSR_ADDR) & (1<<6)) == 0); //等待发送完毕
return (1);
}
/*********************************************************************************************************
** 功能: CH438 UARTx发送
** 输入: UARTx: UARTx, 0~7
** 输入: pData: 发送数据指针
** 输入: Num: 发送字节数
** 返回: 0 成功;1 失败,访问出错
** 说明: 同步模式,发送完毕,函数才返回
*********************************************************************************************************/
uint8_t CH438_UARTxSend(uint8_t UARTx, uint8_t *pData, uint16_t Num)
{
uint8_t UARTxBase = UARTsBase[UARTx];
if (!CH438_CheckRW())
{
return (0);
}
while (Num--)
{
while((CH438_ReadReg(UARTxBase+REG_LSR_ADDR) & (1<<5)) == 0); //等待发送保持寄存器THR空
CH438_WriteReg(UARTxBase+REG_THR_ADDR, *(pData++));
}
while((CH438_ReadReg(UARTxBase+REG_LSR_ADDR) & (1<<6)) == 0); //等待发送完毕
return (1);
}
/*********************************************************************************************************
** 功能: CH438 UARTx发送字符串
** 输入: UARTx: UARTx, 0~7
** 输入: str: 要发送的字符串
** 返回: 0 成功;1 失败,访问出错
** 说明: 同步模式,发送完毕,函数才返回
*********************************************************************************************************/
uint8_t CH438_UARTxSendString(uint8_t UARTx, char *str)
{
uint8_t UARTxBase = UARTsBase[UARTx];
if (!CH438_CheckRW())
{
return (0);
}
while (*str != '\0')
{
while((CH438_ReadReg(UARTxBase+REG_LSR_ADDR) & (1<<5)) == 0); //等待发送保持寄存器THR空
CH438_WriteReg(UARTxBase+REG_THR_ADDR, *(str++));
}
while((CH438_ReadReg(UARTxBase+REG_LSR_ADDR) & (1<<6)) == 0); //等待发送完毕
return (1);
}
/*********************************************************************************************************
** 功能: CH438 UARTx读取数据
** 输入: UARTx: UARTx, 0~7
** 输出: pData: 存放读取数据的指针
** 输出: pRcvNum: 读取到的字节数
** 返回: 0 成功;1 失败,访问出错
** 说明: 同步模式,发送完毕,函数才返回
*********************************************************************************************************/
uint8_t CH438_UARTxRcv(uint8_t UARTx, uint8_t *pData, uint8_t *pRcvNum)
{
uint8_t RcvNum = 0;
uint8_t LSR;
uint8_t UARTxBase = UARTsBase[UARTx];
if (!CH438_CheckRW())
{
return (0);
}
while (1)
{
LSR = CH438_ReadReg(UARTxBase+REG_LSR_ADDR);
if (LSR & (BIT_LSR_BREAKINT | BIT_LSR_FRAMEERR | BIT_LSR_PARERR | BIT_LSR_OVERR)) //接收错误
{
CH438_ReadReg(UARTxBase+REG_RBR_ADDR);
}
else if (LSR & BIT_LSR_DATARDY) //接收缓冲有数据
{
*pData++ = CH438_ReadReg(UARTxBase+REG_RBR_ADDR);
RcvNum ++;
}
else
{
break;
}
if (RcvNum == 128)
{
break;
}
}
*pRcvNum = RcvNum;
return (1);
}
|