历史上的今天
今天是:2025年08月12日(星期二)
2021年08月12日 | MC9S12XDP512串口使用笔记(中断方式)
2021-08-12 来源:eefocus
1.相关寄存器:
1.SCIBDH,SCIBDL:波特率寄存器(SCIBDH只有低5位有效)
波特率 = 总线频率 / (16 * SBR[12:0])
2. SCICR2: SCI控制寄存器2

TIE: 发送中断使能位。使能发送数据寄存器空标志(TDRE)来产生中断申请
TCIE: 发送完成中断使能位。使能发送完成标志(TC)来产生中断申请
RIE: 接收器满中断使能位
TE: 发送器使能位
RE: 接收器使能位
3.SCISR1: SCI状态寄存器1

TDRE: 发送数据寄存器空标志
TC: 发送完成标志
RDRF: 接收数据寄存器满标志
4.SCIDRL,(SCIDRH): SCI数据寄存器
2.寄存器使用注意事项:
1. TDRE(TC)复位值为1,因此将SCICR2的TIE(TCIE)置为1即可产生中断
2. TDRE,TC的清除方法:读SCISR1,然后写SCIDRL,注意,发送完最后一个字节之后,会产生中断,但因为这是最后一个字节,故不会写SCIDRL,中断标志仍然存在
3. RDRF的清除方法:读SCISR1,然后读SCIDRL。
3.示例函数;
说明:
1. 发送和接收都采用中断方式,以帧为基本处理单元,当接收到一帧完整数据时,置位接收标志,主程序不断查询接收标志,若接收标志置位,则调用接收处理函数解析接收到的帧。
2. 通信协议基本形式:帧头(1字节) +通信头(1字节) +通信数据长度(1字节) +通信数据+校验字(1字节)
通信头: 表示通信的内容
通信数据长度 = 通信数据长度 + 校验字长度
// ============================================================================
// SCI初始化程序
// 注:总线时钟为40MHZ
// baudrate = 153600,即9600bytes/s 使能接收中断(实际:156250bps)
// ============================================================================
void SCI_Init(void)
{
// SCI1
SCI1BDH = 0X00; // baud rate = bus clock / (16*SBR[12:0]) 波特率153600,SBR[12:0]= 16 = 0X0F;
SCI1BDL = 0X0F;
SCI1CR2 = 0x2C; // 接收使能,接收器满中断使能,发送使能
}
// ============================================================================
// 发送数据请求函数
// 如果没有数据正在发送,则立即发送,如果有数据正在发送,则置位发送请求标志位
// 主流程不断查询发送请求标志位,若有该标志位,且没有数据正在发送则发送
// ============================================================================
void Send(byte commd)
{
SCI_Commd=commd;
if(Status.Bits.Uart_R_Over==0) // 发送完成
{
Send_1();
}
else
{
Status.Bits.Uart_T_Commd=1; // 置位发送请求标志
}
}
// ============================================================================
// 发送函数
// Pre_Send():发送预处理函数,根据通信头(commd)内容处理发送缓冲区
// ============================================================================void Send_1(void)
{
Pre_Send();
Status.Bits.Uart_R_Over = 1; // 置位正在发送标志
SCI1CR2 |= 0x40; // 使能中断
}// ============================================================================
// 串口中断程序
// 中断接收和中断发送
// ============================================================================
interrupt void SCI1_INT(void)
{
static byte R_num = 0, R_curr = 0; // 接收数据总数和当前指针
static byte T_num = 0, T_curr = 0; // 发送数据总数和当前指针
if(SCI1SR1_RDRF == 1) // 接收中断
{
Uart_R_Str[R_curr] = SCI1DRL;
R_curr++;
// 判断是否为帧头
if(R_curr == 1)
{
// 若不为帧头,复位指针
if(Uart_R_Str[0] != Frame_Header)
{
R_curr = 0;
R_num = 0;
}
}
if(R_curr == 3) // 第二字节,通信帧长度
R_num = Uart_R_Str[2]+1; // Uart_R_Str[1] 为通信帧长度
// 每接收一个数据,num减1,当num为0时,一帧数据接收完毕
if(R_num != 0)
{
R_num--;
if(R_num == 0)
{
R_curr = 0; // 当前存储位置指向Uart_R_Str[0]
Status.Bits.Uart_Status = 1; // 置Uart接收完一帧数据标志位
}
}
}
// 发送中断
else if(SCI1SR1_TC == 1) // 发送完成标志
{
// 最后一个字节发送完成
if(T_curr == Uart_T_Str[2]+3)
{
//SCI1CR2 &= 0XF7; // 关闭发送功能
SCI1CR2 &= 0xBF;
T_curr = 0; // 复位数据指针
Status.Bits.Uart_R_Over = 0; // 发送完成
}
else
SCI1DRL = Uart_T_Str[T_curr++];
}
}
// ============================================================================
// 主程序
// ============================================================================
/******************************全局变量**************************/
volatile byte Uart_R_Str[Uart_R_Length]; // 串口接收数据缓冲区
volatile byte Uart_T_Str[Uart_T_Length]; // 串口发送数据缓冲区
/****************************************************************/
void main(void)
{
// 初始化代码
...
for(;;)
{
if(Status.Bits.Uart_Status)
{
Uart_Deal(); // 接收帧处理函数,功能:校验,解析帧。
}
if(Status.Bits.Uart_T_Commd && (!Status.Bits.Uart_R_Over))
{
Status.Bits.Uart_T_Commd = 0; // 清除发送请求命令位
Send_1(); // 发送
}
// 其余代码
...
}
}
史海拾趣
|
大家看一下,怎么样让这个板子上的SOUNDER响啊,用kei软件,C语言编写的程序应该是什么样的,哪位大侠帮我这个刚接触单片机的菜鸟编个程序啊,我怎么弄不响啊?谢谢大家了! QQ:553695150 [ 本帖最后由 tiankai001 于 2010-4-27 10:18 编辑 ]… 查看全部问答> |
|
要求如下: 一、基本功能要求:设计并制作LED电子显示屏和控制器。 1.自制一台简易16行*32列点阵显示的LED电子显示屏; 2.自制显示屏控制器,扩展键盘和相应的接口实现多功能显示控制,显示屏显示数字和字母,亮度可用按键连续调整。 3.显示屏 ...… 查看全部问答> |
|
;-------------------------------------------------------------------------- ;[H1+H2]+[ADR]+[CMD]+[CRC] ;[L1+L2]+[ID]+[TEM_1]+[TEM_2]+[TEM_3]+[TEM_4]+[TEM_5]+[DOOR] ;-------------------------------------------------------------- ...… 查看全部问答> |
|
用总线连接方式控制HD44780液晶模块,D15-D8连接到液晶模块的DB7-DB0,A1和A0接到液晶的R/W和RS,RD和WE接到液晶的片选信号E。 哪位能给一个C语言读写IO空间的代码例子?多谢… 查看全部问答> |
|
ARM启动后,设置了PPL时钟工作频率,然后进入main函数执行,在main函数创建启动任务及其他任务,在启动任务里面创建系统滴答时钟定时器。 因为有个模块需要延时100MS复位时间,才能开始工作,初始化时间也要30MS左右。那么我能把这个 ...… 查看全部问答> |
|
$(\'swf_RHB\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', encodeURI(\'http://player.youku.com/player.php/sid/XMzY5MjkwNDIw/v.sw ...… 查看全部问答> |
|
我们寻觅那些卓然不群的开拓者、同样期待那些精益求精的坚守者,而你将成就的是一个远大的梦想、一段激情的旅程。如果不甘寂寞的你渴望今天就开始改变自己、改变世界,请申请加入我们!我们在一览LED英才网上发布招聘信息,期待您的加入。深圳市源 ...… 查看全部问答> |




