📄 serial.c
字号:
//======================================
//串口模块源程序
//FileName =serial.c
//Date Time=20071214...20071215
//======================================
#include "serial.h"
#include "string.h"
/*
使用中断方式进行通讯!
*/
volatile struct _st_serial_buff st_serial_buff; //串口操作缓冲结构
//XCK/T0/PB0 不使用
//RXD/PD0 接收数据引脚
//TXD/PD1 发送数据引脚
//--------------------------------------
// HD_SERIAL_S01
//功能:
// 初始化串口(查询方式),9600,8,1,n
//输入:
// 无
//输出:
// 无
//--------------------------------------
void rs232_init_sets(void)
{
UBRRH =(uchar)(CONST_INT_UBRR_SETS >>8) &0x7f;
UBRRL =(uchar)(CONST_INT_UBRR_SETS &0xff);
UCSRA =(uchar)(CONST_BYTE_UCSRA);
UCSRB =(uchar)(CONST_BYTE_UCSRB);
UCSRC =(uchar)(CONST_BYTE_UCSRC);
//接收参数初始化
st_serial_buff.p_recv_start =0; //起始存储指针
st_serial_buff.p_recv_end =0; //结束存储指针
st_serial_buff.rlen_needed =0; //需要的接收长度(<=接收缓冲的长度)
st_serial_buff.rlen_acted =0; //实际的接收长度
}
//----------------------------------------------
//接收指定长度的数据串
//输入:
// r_str 存储接收数据的指针
// r_len 需要接收的长度
//输出:
// 实际接收的字节数
//----------------------------------------------
uchar rs232_recv_str(uchar *r_str, uchar r_len)
{
uchar i;
st_serial_buff.rlen_acted =0;
st_serial_buff.rlen_needed =r_len;
//必要时这里可以添加接收超时判断,退出
while(st_serial_buff.rlen_acted <r_len);
for(i=0; i<st_serial_buff.rlen_acted; i++)
{
*(r_str +i) =st_serial_buff.recv[st_serial_buff.p_recv_start];
if(++st_serial_buff.p_recv_start >=CONST_RECV_BUFF_LEN_MAX)
{
st_serial_buff.p_recv_start =0;
}
}
st_serial_buff.rlen_needed =0;
st_serial_buff.rlen_acted =0;
return(i);
}
//----------------------------------------------
//指定长度的数据串发送
//输入:
// s_str 发送数据指针
// s_len 发送长度
//输出:
// 无
//----------------------------------------------
void rs232_send_str(uchar *s_str, uchar s_len)
{
memcpy((uchar *)&st_serial_buff.send[0], s_str, s_len);
st_serial_buff.tx_pos_start =1;
st_serial_buff.slen_needed =s_len;
UDR =st_serial_buff.send[0]; //启动中断方式的发送
UCSRB |=BIT(UDRIE); //因为UDRIE中断回自我关断,以减少CPU负荷
while((UCSRB &BIT(UDRIE)) !=0); //等待发送完毕
}
//======================================
//以下是中断模式的函数,需要外部打开‘I’
//======================================
//接收中断接口函数
//输入:
// st_serial_buff.rlen_needed 需要接收的长度
//输出:
// st_serial_buff.recv[]
// st_serial_buff.rlen_acted
//注意:
// 一般设置st_serial_buff.rlen_needed =0 不接收, !=0(<=缓冲长度)接收定长字节,
void _irq_serial_rx_server(void)
{
uchar sreg_bak;
sreg_bak =SREG;
if(!(UCSRA & BIT(FE)) && !(UCSRA & BIT(DOR)) )
{
if(st_serial_buff.rlen_acted <st_serial_buff.rlen_needed)
{
//中断标志读取后自动清除
st_serial_buff.recv[st_serial_buff.p_recv_end] =UDR;
st_serial_buff.rlen_acted ++;
if(++st_serial_buff.p_recv_end >=CONST_RECV_BUFF_LEN_MAX)
{
st_serial_buff.p_recv_end =0;
}
SREG =sreg_bak;
return;
}
}
//仅仅是清除RX中断标志
if(UDR ==0){};
SREG =sreg_bak;
}
//发送缓存空中断接口函数
//输入:
// st_serial_buff.slen_needed
// st_serial_buff.tx_pos_start
// st_serial_buff.send[]
void _irq_serial_udre_server(void)
{
uchar sreg_bak;
sreg_bak =SREG;
if( (st_serial_buff.slen_needed !=0) && (st_serial_buff.tx_pos_start <st_serial_buff.slen_needed) )
{
UDR =st_serial_buff.send[st_serial_buff.tx_pos_start++];
}
else
{ //关闭中断
UCSRB &= ~BIT(UDRIE);
}
SREG =sreg_bak;
}
//发送完毕中断接口函数
//执行结束自动清除中断标志
//输出:
// st_serial_buff.slen_needed
void _irq_serial_tx_server(void)
{
uchar sreg_bak;
sreg_bak =SREG;
st_serial_buff.slen_needed =0;
SREG =sreg_bak;
}
//End Of File
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -