2023-03-06 09:51:44 +08:00

195 lines
4.3 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* UART1.c
*
* Created on: 2022年03月12日
* Author: User
*/
/* Includes ------------------------------------------------------------------*/
#include <Main.h>
//#include <Timer0.h>
/* Private define-------------------------------------------------------------*/
#define UART1_Send_LENGTH 10
#define UART1_Rec_LENGTH 10
/* Private variables----------------------------------------------------------*/
static uint8_t xdata ucSend_Buffer[UART1_Send_LENGTH] = {0x00};
static uint8_t xdata ucRec_Buffer[UART1_Rec_LENGTH] = {0x00};
/* Private function prototypes------------------------------------------------*/
static void Init(void); //串口初始化
static void SendData(uint8_t); //串口发送字符
static void SendArray(uint8_t *, uint16_t); //串口发送数组
static void SendString(uint8_t *); //串口发送字符串
static void Protocol_Analy(void); //串口协议
/* Public variables-----------------------------------------------------------*/
UART_t idata UART1 =
{
FALSE,
FALSE,
0,
ucSend_Buffer,
ucRec_Buffer,
Init,
SendData,
SendArray,
SendString,
Protocol_Analy};
/*
* @name Init
* @brief 串口1初始化
* @param None
* @retval None
*/
static void Init() // 9600bps@16MHz
{
// P2M0 = P2M0 & 0xF0 | 0x20; // P20设置为上拉输入
// P0M2 = P0M2 & 0x0F | 0x80; // P05设置为推挽输出
TXD_MAP = 0x05; // TXD映射P05
RXD_MAP = 0x20; // RXD映射P20
BRTSEL = 0X00; // UART1的波特率:00 T4
T4CON = 0x06; // T4工作模式UART1波特率发生器
//波特率计算
//波特率 = 1/16 * (T4时钟源频率 / 定时器4预分频比) / (65536 - 0xFF98)
// = 1/16 * ((16000000 / 1) / 104)
// = 9615.38(误差0.16%)
//波特率9600
//反推初值 = (65536 - ((T4时钟源频率 / 定时器4预分频比) * (1 / 16)) / 波特率)
// = (65536 - (16000000 * (1 / 16) / 9600))
// = (65536 - 104.167)
// = FF98
TH4 = 0xFF;
TL4 = 0x98; //波特率9600
SCON2 = 0x02; // 8位UART波特率可变
SCON = 0x10; //允许串行接收
IE |= 0X10; //使能串口中断
EA = 1; //使能总中断
}
/*
* @name SendData
* @brief 发送字符
* @param dat:待发送字符
* @retval None
*/
static void SendData(uint8_t dat)
{
while (UART1.ucTX_Busy_Flag)
; //等待前面的数据发送完
UART1.ucTX_Busy_Flag = TRUE; //置位忙碌标志
SBUF = dat; //写数据至UART寄存器
}
/*
* @name SendArray
* @brief 串口发送数组
* @param p_Arr:数组首地址LEN:发送长度
* @retval None
*/
static void SendArray(uint8_t *p_Arr, uint16_t LEN)
{
uint16_t i = 0;
for (i = 0; i < LEN; i++)
{
UART1.UART_SendData(*(p_Arr + i));
}
while (UART1.ucTX_Busy_Flag)
; //等待数据发送完
}
/*
* @name SendString
* @brief 发送字符串
* @param p_Str:待发送字符串
* @retval None
// */
static void SendString(uint8_t *p_Str)
{
while (*p_Str)
{
UART1.UART_SendData(*(p_Str++)); //发送当前字符
}
while (UART1.ucTX_Busy_Flag)
; //等待数据发送完
}
// putchar字符发送函数重定向
// extern char putchar(char c)
// {
// UART1.UART_SendData((uint8_t)c);
// return c;
// }
/*
* @name UART1_isr
* @brief 串口1中断服务函数
* @param None
* @retval None
*/
void UART1_isr() interrupt UART1_VECTOR
{
if (RI)
{
RI = (bit)0; //清除接收中断标志
if (UART1.ucRec_Cnt < UART1_Rec_LENGTH)
{
ucRec_Buffer[UART1.ucRec_Cnt++] = SBUF;
}
UART1.ucRec_Flag = TRUE;
}
if (TI)
{
TI = (bit)0; //清除发送中断标志
UART1.ucTX_Busy_Flag = FALSE; //清忙碌标志
}
}
/*
* @name Protocol_Analy
* @brief 串口协议
* @param None
* @retval None
*/
static void Protocol_Analy(void)
{
if (UART1.ucRec_Flag == TRUE)
{
//过滤无用的数据
if (ucRec_Buffer[0] != 0)
{
Timer0.msDelay_Timer = 0;
while (UART1.ucRec_Cnt < Protocol_Len)
{
if (Timer0.msDelay_Timer >= TIMER0_100mS) // 100ms没有接收完 跳出循环
break;
}
// 协议解析
Protocol.Analysis(&UART1); //串口协议处理
}
//清除缓存
Public.Memory_Clr(ucRec_Buffer, (uint16_t)UART1.ucRec_Cnt);
//重新接收
UART1.ucRec_Cnt = 0; //接收计数清零
UART1.ucRec_Flag = FALSE; //接收标志位取消
}
}
/********************************************************
End Of File
********************************************************/