本帖最后由 ljxh401 于 2025-11-19 17:08 编辑
#申请原创#
/******************************************************************************
******************************************************************************
文 件 名 : MoniUartX.c
版 本 号 : 初稿
作 者 : ljxh401
生成日期 : 2025年11月18日
最近修改 :
功能描述 : 模拟串口的接收和发送,波特率4800,将时间中断频率设置为波特率的3倍,为了更准确的截取同步信号
尽量精简串口中断的函数,每一路串口都带缓存环
函数列表 :
修改历史 :
1.日 期 : 2025年11月18日
作 者 : ljxh401
修改内容 : 创建文件
******************************************************************************/
头文件
#ifndef __MONI_UARTX_H__
#define __MONI_UARTX_H__
typedef struct{
INT32U *pinRec;
INT32U *pinSnd;
INT8U zeroCnt;
INT8U recbit;
INT8U reccach;
INT8U rb,re;
INT8U rec[16];
INT8U sndbit;
INT8U sndCach;
INT8U sb,se;
INT8U snd[32]; //发送显示数据
}S_MnCom;
void MoniUartInit(void);
void MoniUartSendData(INT8U id,INT8U *buf,INT8U len);
INT8U MoniUartGetData(INT8U id,INT8U *err);
#endif
/*----------------------------------------------*
* 包含头文件 *
*----------------------------------------------*/
#include "includes.h"
/*----------------------------------------------*
* 宏定义 *
*----------------------------------------------*/
#define ComNum 10
#define Boud 9600
#define Mbit(_ADDR,_Bit) (0x42000000+((unsigned long)&(_ADDR)-0x40000000)*32 + _Bit*4)
/*----------------------------------------------*
* 外部变量说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 外部函数原型说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 内部函数原型说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 全局变量 *
*----------------------------------------------*/
/*----------------------------------------------*
* 模块级变量 *
*----------------------------------------------*/
S_MnCom cd[ComNum]; //记录10个串口的接收数据
/*----------------------------------------------*
* 常量定义 *
*----------------------------------------------*/
const INT32U PinTab[]={
Mbit(GPIOB->ODR,1),Mbit(GPIOB->IDR,10),
Mbit(GPIOB->ODR,11),Mbit(GPIOB->IDR,12),
Mbit(GPIOB->ODR,13),Mbit(GPIOB->IDR,14),
Mbit(GPIOB->ODR,15),Mbit(GPIOA->IDR,8),
Mbit(GPIOA->ODR,11),Mbit(GPIOA->IDR,12),
Mbit(GPIOA->ODR,13),Mbit(GPIOA->IDR,14),
Mbit(GPIOA->ODR,15),Mbit(GPIOB->IDR,3),
Mbit(GPIOB->ODR,4),Mbit(GPIOB->IDR,5),
Mbit(GPIOB->ODR,6),Mbit(GPIOB->IDR,7),
Mbit(GPIOB->ODR,8),Mbit(GPIOB->IDR,9),
};
/*****************************************************************************
函 数 名 : MoniUartInit
功能描述 : 模拟串口的初始化
输入参数 : void
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2025年11月18日
作 者 : ljxh401
修改内容 : 新生成函数
*****************************************************************************/
void MoniUartInit(void)
{
INT8U i;
NormalPA131415PB3PB4();
//设置输出
SetPinState(GPIOA, GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_15, GPIO_Mode_Out_PP);
SetPinState(GPIOB, GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_15|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_8, GPIO_Mode_Out_PP);
//设置输入
SetPinState(GPIOB, GPIO_Pin_10|GPIO_Pin_12|GPIO_Pin_14|GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_9, GPIO_Mode_IPU);
SetPinState(GPIOA, GPIO_Pin_8|GPIO_Pin_12|GPIO_Pin_14, GPIO_Mode_IPU);
for(i=0;i<ComNum;i++)
{
cd.pinSnd=(INT32U*)PinTab[i*2+0];
cd.pinRec=(INT32U*)PinTab[i*2+1];
cd.sndbit=10;
cd.recbit=28;
*cd.pinSnd=1;
}
Tim1_PWM_Init(Boud*3,2,0,1);
}
/*****************************************************************************
函 数 名 : MoniUartSendData
功能描述 : 将数据发送到缓存里面
输入参数 : INT8U id
INT8U *buf
INT8U len
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2025年11月18日
作 者 : ljxh401
修改内容 : 新生成函数
*****************************************************************************/
void MoniUartSendData(INT8U id,INT8U *buf,INT8U len)
{
INT8U cnt;
cnt=cd[id].se;
do{
cd[id].snd[cnt]=*buf++;
if(++cnt>=sizeof(cd[0].snd)) cnt=0;
}while(--len>0);
cd[id].se=cnt;
}
/*****************************************************************************
函 数 名 : MoniUartGetData
功能描述 : 将数据发送到缓存里面
输入参数 : INT8U id
INT8U *buf
INT8U len
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2025年11月18日
作 者 : ljxh401
修改内容 : 新生成函数
*****************************************************************************/
INT8U MoniUartGetData(INT8U id,INT8U *err)
{
INT8U d;
if(cd[id].rb!=cd[id].re)
{
*err=0;
d=cd[id].rec[cd[id].rb];
if(++cd[id].rb>=sizeof(cd[0].rec)) cd[id].rb=0;
}
else *err=1;
return d;
}
/*****************************************************************************
函 数 名 : CheckRec
功能描述 : 串口接收,检测串口IO的输入数据
输入参数 : void
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2025年11月18日
作 者 : ljxh401
修改内容 : 新生成函数
*****************************************************************************/
void CheckRec(void)
{
INT8U i;
for(i=0;i<ComNum;i++)
{
if(cd.recbit==28)
{
if(*cd.pinRec==0)
{
if(++cd.zeroCnt>=2) //连线两个0,确定起始帧,然后从第二个0 作为采集帧
{
cd.zeroCnt=0;
cd.reccach=0;
cd.recbit=0;
}
else ++cd.zeroCnt;
}
else cd.zeroCnt=0;
}
else{
if((cd.recbit%3)==2) //在中间采样,这样防止错误率
{
if(*cd.pinRec) cd.reccach|=BitTab[cd.recbit/3];
}
if(++cd.recbit==28) //最后一帧,不做验证后面的28-30 的高电平
{
cd.rec[cd.re]=cd.reccach;
if(++cd.re>=sizeof(cd[0].rec)) cd.re=0;
}
}
}
}
/*****************************************************************************
函 数 名 : SendBitData
功能描述 : 发送串口数据 的模拟IO
输入参数 : INT8U i
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2025年11月18日
作 者 : ljxh401
修改内容 : 新生成函数
*****************************************************************************/
void SendBitData(INT8U i)
{
for(;i<ComNum;i+=3)
{
if(cd.sndbit<10)
{
if(cd.sndbit==0) *cd.pinSnd=0; //启动
else if(cd.sndbit<9) //数据
{
*cd.pinSnd=(cd.sndCach&1);
cd.sndCach>>=1;
}
else *cd.pinSnd=1; //结束
++cd.sndbit;
}
else if(cd.sb!=cd.se)
{
cd.sndCach=cd.snd[cd.sb];
if(++cd.sb>=sizeof(cd[0].snd)) cd.sb=0;
cd.sndbit=0;
}
}
}
/*****************************************************************************
函 数 名 : TIM1_UP_IRQHandler
功能描述 : 定时器1中断
输入参数 : void
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2025年11月18日
作 者 : ljxh401
修改内容 : 新生成函数
*****************************************************************************/
void TIM1_UP_IRQHandler (void)
{
static INT8U cnt=0;
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
CheckRec();
if(++cnt>=3) cnt=0; //均匀每次时间中断的工作量
SendBitData(cnt);
}
|
|