|
发表于 2021-2-2 14:34:19
|
显示全部楼层
全部代码:
//main.c
//115200bps@22.1184MHz
#include "fifo.h"
FIFO xdata sRX_Buffer = {0,0,0,{0}}; // 接收队列
FIFO xdata sTX_Buffer = {0,0,0,{0}}; // 发送队列
uint8_t u8Busy_Flag = 0; // 忙标志位
uint8_t u8Temp;
uint8_t u8Count = 0;
void Uart_Send_Buffer(FIFO xdata *sTX_Buffer);
void Uart_Initial(void) //115200bps@22.1184MHz
{
P_SW1 = 0x40; //P36,P37
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xD0; //设定定时初值
TH1 = 0xFF; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES = 1; //使能串口中断
}
void InitGpio(void) //IO初始化
{
// P1 = 0xfe;
P1M0 = 0x00; //P1.0配置为推挽输出
P1M1 = 0x00;
P3M0 = 0x80; //P37配置为推挽输出
P3M1 = 0x00;
P5M0 = 0x00; //
P5M1 = 0x00;
}
/** 需要自行定义部分结束<<< */
void main(void)
{
InitGpio(); // 初始化IO
Uart_Initial(); // 初始化串口
// FIFO_Initial(&sRX_Buffer); // 初如化接收队列
// FIFO_Initial(&sTX_Buffer); // 初如化发送队列
EA = 1;
while(1)
{
u8Count ++;
Uart_Send_Buffer(&sTX_Buffer); // 串口发送发送队列
if(u8Count > 10)
{ // 16.6MHz时钟,大概10uS
u8Count = 0;
if(FIFO_Get_Count(&sRX_Buffer) != 0)
{ // 接收队列不为空
FIFO_Out(&sRX_Buffer, &u8Temp);
FIFO_In_TXBuff(&sTX_Buffer, u8Temp); // 把接收队列的值写入发送队列中
}
}
}
}
/**
* @brief 把队列数据从串口发送出去
*
* @param sTX_Buffer 要发送的队列缓存
*
* @par 函数说明:
* 把队列数据从串口发送出去
*/
void Uart_Send_Buffer(FIFO xdata *sTX_Buffer)
{
uint8_t u8Temp_Send;
if((u8Busy_Flag == 0) && (FIFO_Get_Count(sTX_Buffer) != 0))
{ // 忙标志位为不忙和发送队列不为空
FIFO_Out(sTX_Buffer, &u8Temp_Send);
SBUF = u8Temp_Send;
u8Busy_Flag = 1; // 设置忙标志位为忙
}
}
/**
* @brief 串口1中断处理
*
*
* @par 函数说明:
* 串口1中断处理,中断函数不需要声明。在其他应用中实现,要注释掉本函数。
*/
void Uart1_ISR(void) interrupt 4
{ // 串口1中断向量为15
// uint8_t u8Temp1;
if (RI)
{ // 接收中断
RI = 0; // 清接收中断,需手动清除
/** 接收中断表示数据接收到,取串口缓存寄存器的值 */
/** 存入FIFO中 */
FIFO_In_RXBuff(&sRX_Buffer, SBUF);
}
if(TI)
{ // 发送中断
TI = 0; // 清发送中断,需手动清除
/** 发送中断表示数据发送完成,清忙标志 */
u8Busy_Flag = 0;
}
}
//fifo.c:
#include "fifo.h"
/**
* @brief 存储一个数据到FIFO中
*
* @param sFIFO 要操作的FIFO
* @param u8Data 要存储的数据
* @return eFIFO_State :
* 1. 成功返回 FIFO_SUCESS FIFO操作成功
* 2. FIFO已满,无法写入返回 FIFO_FULL FIFO已满
*
* @par 函数说明:
* 存储一个数据到FIFO中。
*/
void FIFO_In_RXBuff(FIFO xdata *sFIFO, uint8_t u8Data)
{
if(sFIFO->Count < FIFO_SIZE) // FIFO不满
{
*(sFIFO->Buffer + sFIFO->Rear) = u8Data; // 数据存入缓存尾部
sFIFO->Rear = (sFIFO->Rear + 1) % FIFO_SIZE; // 数据尾与缓存长度取模,使数据尾永远在缓存长度范围内
(sFIFO->Count) ++; // 存储数据字节数加1
}
}
void FIFO_In_TXBuff(FIFO xdata *sFIFO, uint8_t u8Data)
{
if(sFIFO->Count < FIFO_SIZE) // FIFO不满
{
*(sFIFO->Buffer + sFIFO->Rear) = u8Data; // 数据存入缓存尾部
sFIFO->Rear = (sFIFO->Rear + 1) % FIFO_SIZE; // 数据尾与缓存长度取模,使数据尾永远在缓存长度范围内
(sFIFO->Count) ++; // 存储数据字节数加1
}
}
/**
* @brief 从FIFO中读出数据,并存入指定指针中
*
* @param sFIFO 要操作的FIFO
* @param u8pData 存储读出数据的指针
* @return eFIFO_State :
* 1. 成功返回 FIFO_SUCESS FIFO操作成功
* 2. FIFO已空,无法读出返回 FIFO_EMPTY FIFO已空
*
* @par 函数说明:
* 从FIFO中读出数据,并存入指定指针中。
*/
void FIFO_Out(FIFO xdata *sFIFO, uint8_t data *u8pData) //reentrant
{
// eFIFO_State eState = FIFO_SUCESS; // 初始状态值为FIFO_SUCESS
if(sFIFO->Count != 0)
{
/** 循环读取,写满返回位置0读 */
*u8pData = *(sFIFO->Buffer + sFIFO->Front); // 从缓存中读取数据
sFIFO->Front = (sFIFO->Front + 1) % FIFO_SIZE; // 数据头与缓存长度取模,使数据头永远在缓存长度范围内
// (sFIFO->Count) --; // 存储数据字节数减1
(sFIFO->Count) --;
}
// return eState;
}
/**
* @brief 获取FIFO中存储数据字节数
*
* @param sFIFO 要操作的FIFO
* @return uint16_t FIFO中存储数据字节数
*
* @par 函数说明:
* 存储数据字节数
*/
uint8_t FIFO_Get_Count(FIFO xdata *sFIFO)
{
return (sFIFO->Count);
}
//fifo.h:
#ifndef _FIFO_H_
#define _FIFO_H_
#include "STC8H.h"
#define FIFO_SIZE 32 /** 定义FIFO缓存长度 */
/**
* @brief FIFO状态定义枚举
*
* @par 函数说明:
* FIFO状态定义枚举
*/
typedef enum {
FIFO_SUCESS, // FIFO操作成功
FIFO_FULL, // FIFO已满
FIFO_EMPTY, // FIFO已空
FIFO_LOCK, // FIFO已上锁
} eFIFO_State;
/**
* @brief FIFO结构定义
*
* @par 函数说明:
* FIFO结构定义。从数据头读出,从数据尾写入。
*/
typedef struct
{
uint8_t Count; // 存储数据字节数
uint8_t Front; // 数据头位置,指向数据读出的位置
uint8_t Rear; // 数据尾位置,指向数据写入的位置
uint8_t Buffer[FIFO_SIZE]; // 数据存储缓存
} FIFO;
/**
* @brief 存储一个数据到FIFO中
*
* @param sFIFO 要操作的FIFO
* @param u8Data 要存储的数据
* @return eFIFO_State :
* 1. 成功返回 FIFO_SUCESS FIFO操作成功
* 2. FIFO已满,无法写入返回 FIFO_FULL FIFO已满
*
* @par 函数说明:
* 存储一个数据到FIFO中。
*/
//eFIFO_State FIFO_In(FIFO xdata *sFIFO, uint8_t u8Data) reentrant;
void FIFO_In_RXBuff(FIFO xdata *sFIFO, uint8_t u8Data);
void FIFO_In_TXBuff(FIFO xdata *sFIFO, uint8_t u8Data);
/**
* @brief 从FIFO中读出数据,并存入指定指针中
*
* @param sFIFO 要操作的FIFO
* @param u8pData 存储读出数据的指针
* @return eFIFO_State :
* 1. 成功返回 FIFO_SUCESS FIFO操作成功
* 2. FIFO已空,无法读出返回 FIFO_EMPTY FIFO已空
*
* @par 函数说明:
* 从FIFO中读出数据,并存入指定指针中。
*/
void FIFO_Out(FIFO xdata *sFIFO, uint8_t data *u8pData);
/**
* @brief 获取FIFO中存储数据字节数
*
* @param sFIFO 要操作的FIFO
* @return uint16_t FIFO中存储数据字节数
*
* @par 函数说明:
* 存储数据字节数
*/
uint8_t FIFO_Get_Count(FIFO xdata *sFIFO);
#endif /** _FIFO_H_ */
|
|