历史上的今天
今天是:2025年03月25日(星期二)
2021年03月25日 | 利用飞思卡尔S12X系列单片机双核功能实现串口空闲中断接收
2021-03-25 来源:eefocus
1. 关于协处理器XGATE
Freescale公司推出的S12XE系列双核单片机,其内部集成了一个可编程RISC内核的XGATE协处理器(双核),专门用来处理I/O和中断,其性能就相当于一个DMA控制器。由于采用了RISC架构,且处理速率比CPU快一倍,从而提高了系统的实时处理能力,极大的减轻了CPU的工作负荷,让CPU有能多的“精力”用于处理逻辑及计算上的问题,提高了单片机的工作效率。

2. 协处理器XGATE的工作模式
协处理器XGATE工作独立,和主CPU之间通过片内的双口RAM实现数据交互。同时,两个内核之间可以相互发送中断请求。当主CPU与XGATE之间存在竞争问题时,单片机采用了8个内部硬件信号量予以解决。
对于S12XE系列双核单片机来说,默认状态下,协处理器XGATE功能是不开启的。如果要开启XGATE双核功能,主要通过以下两个步骤:
新建工程时,添加设置XGATE工作模式;
利用代码配置、开启XAGTE功能。
3. 软件实现
关于串口的空闲中断就不在多做说明,这里我们以MC9S12XEP100单片机为例,利用协处理器,实现串口0的空闲中断收发功能,类似于STM32的串口DMA接收功能。
3.1 协处理器XGATE开启及配置
3.1.1 协处理器XGATE初始化配置
首先在main.c中实现协处理器XGATE的初始化,里面包括初始化协处理器的中断向量表以及注册串口中断并指定由协处理器来实现串口0的中断功能,最后开启协处理器中断。
#define SCI0_VEC 0xD6 /* 定义SCI0中断向量地址 */
static void SetupXGATE(void)
{
/* initialize the XGATE vector block and set the XGVBR register to its start address */
XGVBR= (unsigned int)(void*__far)(XGATE_VectorTable - XGATE_VECTOR_OFFSET);
ROUTE_INTERRUPT(SCI0_VEC, 0x81); /* RQST=1 and PRIO=1 */
XGMCTL= 0xFBC1; /* enable XGATE mode and interrupts XGE | XGFRZ | XGIE */
}
3.1.2 协处理器XGATE与CPU间共享内存定义
我们需要定义一片区域,来实现协处理器XGATE与CPU间的数据共享(类似进程间共享内存),这里需要注意定义的格式。
#pragma DATA_SEG SHARED_DATA
volatile unsigned char sic0_rx[256] = {0};
volatile int sic0_rx_len;
3.1.3 协处理器XGATE串口中断函数编写
在xaget.cxgate文件中注册串口0的中断函数并通过代码实现。
const XGATE_TableEntry XGATE_VectorTable[] = {
{ErrorHandler, 0x09}, // Channel 09 - Reserved
...
{(XGATE_Function)Sci0_Thread, 0x6B}, // Channel 6B - SCI0
...
{ErrorHandler, 0x79}, // Channel 79 - IRQ
}
当XGATE核检测到空闲中断后,向CPU核发送一个中断信号,表示数据接收完成。
interrupt void Sci0_Thread(void)
{
unsigned char tmp;
if(SCI0SR1_RDRF==1) /* 中断接收数据 */
{
sic0_rx[sic0_rx_len] = SCI0DRL;
sic0_rx_len++;
}
if(SCI0SR1_IDLE==1) /* 检测到空闲中断 */
{
tmp = SCI0SR1;
tmp = SCI0DRL;
SCI0SR1_IDLE = 0;
asm SIF; /* 向cpu发送中断信号 */
}
}
以上就是协处理器串口中断代码的实现,接下来我们继续完善CPU这边数据的处理工作。
3.2 主CPU功能配置
3.2.1 串口初始化配置
这里我们首先对SCI0进行初始化配置,包括波特率、数据位、校验位、停止位等,最后使能串口发送、空闲中断接收功能。
void sci0_init(dword baud)
{
dword baudRateReg;
baudRateReg = 24000000/16/baud; /* 配置波特率,外部晶振24M*/
SCI0BDH = 0x1f & (baudRateReg >> 8);
SCI0BDL = 0xff & baudRateReg; /* 波特率设置 */
SCI0CR1 = 0X04; /* 无奇偶校验,8位数据位,1位停止位 */
SCI0CR2 = 0X3C; /* 发送空闲中断接收使能*/
}
3.2.2 串口接收中断实现
在main.c中编写实现串口0的中断处理函数,这里我们只需要等待XGATE的中断信号,接收到中断信号后,说明空闲中断完成,执行用户操作后(我们这里利用一个flag来表示接收到空闲中断),清除协处理器中断标志位。
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt 20 void SCI_Handler(void)
{
XGIF1 = 0x0800; /* 清除XAGTE串口0中断标志*/
sic0_send_flag = 1;
}
最后我们在主函数中判断空闲中断标志位,将接收到的数据再通过串口0发送出去。
if(sic0_send_flag==1)
{
sci0_send_data(sic0_rx,sic0_rx_len);
sic0_send_flag = 0;
memset(sic0_rx,0,sizeof(sic0_rx));
sic0_rx_len = 0;
}
4. 结果演示
打开串口调试助手,定时发送一帧数据,可以看到串口正常接收数据并反馈了回来。整个过程中,串口接收数据都由协处理器来完成,主cpu不参与接收过程,只需等待协处理器完成后,发送一个中断信号即可。
上一篇:单片机机器码以及偏移地址的计算
史海拾趣
|
我的电路能够得到一系列的方波信号,但是占空比不一样。因为占空比不一样,如果我直接加不可调的低通滤波器转换成正弦波的话,得到的正弦波有些就不能做到关于时间轴对称。那么如果我要实现所有的正弦波都关于时间轴对称(即对任意占空比的方波都能 ...… 查看全部问答> |
|
为什么同一程序在PB下生成的DLL文件和EVC下的DLL不一样? 在PB下将一个类似驱动程序的源代码编译生成一个DLL文件,通过注册表导入系统中可以工作起来,然后现在想通过EVC来修改这个程序,在EVC下将之前的源代码也可以编译生成DLL文件,这是DLL文件比之前的文件大了几K,此时将这个DLL导入系统中,同样的注 ...… 查看全部问答> |
|
请问:我刚工作不久,在学校的时候用的是Protel99绘制原理图和PCB,但在公司后发现我们公司都是用的PADS来画PCB,我的工作地点是深圳,不知道是PADS更国际化还是怎么回事,是Prote不通用吗?… 查看全部问答> |
|
不需要代码,只要论文,基本的可以自己搞,就是不知道具体的要做个什么东西,希望好心人指点下,提供这方面的资料借鉴下~! 邮箱:wleuler@163.com… 查看全部问答> |
|
关于CEDDK的READ_PORT_UCHAR(<端口号地址>),其中的端口号地址是在哪里定义的呢? 小弟最近在写一个GPIO驱动,在GPI_Read()流接口函数中想用READ_PORT_UCHAR()从指定的GPIO的端口接受数据。我用的是PXA270,其中的GPIO的端口号地址是在哪里定义的呢?我看了PXA270的datasheet好像没有发现。… 查看全部问答> |
|
我是大四的一名学生,我想毕业可从事嵌入式系统这方面的工作,现在我想学习驱动编程,我只在书上看了一些WIN CE的基本驱动的结构, 我想深入了解, 1)应该从那一方面入手呢,或者说先从那一个模块开始深入了解呢? 2)我需要什么专业知识 ...… 查看全部问答> |
|
建立ModelSim SE 的Xilinx仿真库方法,从网上搜到的有很多,实践过其中几种,其中一种较简单的方法如下:1)当然是要安装ModelSim 和ISE 。2)将ModelSim根目录下的modelsim.ini文件的只读属性去掉。3)在ModelSim命令窗口输入:compxlib -s mti_se -a ...… 查看全部问答> |




