/**************************************************************************
**功能描述: ECAN自测试程序,CAN模块工作在自测试模式。MBX0发送到MBX16***
**MBX1发送到MBX17。该程序不停地高速背靠背传输数据,检查接数据的正确性**
**************************************************************************/
#include "DSP28_Device.h"
void mailbox_check(int32 T1, int32 T2, int32 T3)
void mailbox_read(int16 i)
/////////////芦返///////////////////////
Uint32 ErrorCount = 0
Uint32 MessageReceivedCount = 0
Uint32 TestMbox1 = 0
Uint32 TestMbox2 = 0
Uint32 TestMbox3 = 0
void CAN_INIT()
{
struct ECAN_REGS ECanaShadow
EALLOW
GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 = 1// 设置GPIOF6为CANTX
GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 = 1// 设置GPIOF7为CANRX
EDIS
/*eCAN 控制寄存器需要32位访问。如果想向一个单独位进行写 *** 作,编译器可能会使其进入16位访问。这儿引用了一种解决方法,就是用影子寄存器迫使进行32位访问。 把整个寄存器读入一个影子寄存器。 这个访问将是32位的。用32位写 *** 作改变需要改的位,然后把该值拷贝回eCAN寄存器*/
EALLOW
ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all// 把CANTIOC读入影子寄存器
ECanaShadow.CANTIOC.bit.TXFUNC = 1 // 外部引脚I/O使能标志位。
// TXFUNC=1 CANTX引脚被用于CAN发送功能。
// TXFUNC=0 CANTX引脚被作为通用I/O引脚被使用
ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all// 把配置好的寄存器值回写
ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all // 把CANRIOC读影子寄存器
ECanaShadow.CANRIOC.bit.RXFUNC = 1 // 外部引脚I/O使能标志位。
// RXFUNC=1 CANRX引脚被用于CAN接收功能。
// RXFUNC=0 CANRX引脚被作为通用I/O引脚被使用。
ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all // 把配置好的寄存器值回写
EDIS
// 在配置邮箱ID值之前,CANME对应的位必须复位,
// 如果CANME寄存器中对应的位被置位,则ID写入 *** 作无效。
ECanaRegs.CANME.all = 0// 复位所有的邮箱
ECanaMboxes.MBOX0.MID.all = 0x9555AAA0 // 配置发送邮箱0的ID:扩展标识符29位
ECanaMboxes.MBOX1.MID.all = 0x9555AAA1 // 配置发送邮箱1的ID:扩展标识符29位
ECanaMboxes.MBOX16.MID.all = 0x9555AAA0//伍哗配 确定接收邮箱16的ID
ECanaMboxes.MBOX17.MID.all = 0x9555AAA1// 确定接收邮箱17的ID
// 把邮箱0~15 配置为发送邮箱 , 把邮箱16~31 配置为接收邮箱
ECanaRegs.CANMD.all = 0xFFFF0000
ECanaRegs.CANME.all = 0xFFFFFFFF// CAN模块使能对应的邮箱,
ECanaMboxes.MBOX0.MCF.bit.DLC = 8
ECanaMboxes.MBOX1.MCF.bit.DLC = 8 // 把发送,接收数据的长度定义为8位
ECanaMboxes.MBOX0.MCF.bit.RTR = 0 // 无远程帧请求
// 因为RTR位在复位后状态不定,因此在程序进行初始化的时候必须对该位赋值。
ECanaMboxes.MBOX1.MCF.bit.RTR = 0
// 把待发送的数据写入发送邮箱
ECanaMboxes.MBOX0.MDRL.all = 0x00112233
ECanaMboxes.MBOX0.MDRH.all = 0x44556677
ECanaMboxes.MBOX1.MDRL.all = 0x8899AABB
ECanaMboxes.MBOX1.MDRH.all = 0xCCDDEEFF
EALLOW
// 邮箱中断屏蔽寄存器。上电后所有的中断屏蔽位都清零且停止中断使能。
// 这些位允许独立屏蔽任何邮箱中断。
ECanaRegs.CANMIM.all = 0xFFFFFFFF
// CANMIM .BIT.X=1 邮箱中断被使能(X=1~31)
// CANMIM .BIT.X=0 邮箱中断被禁止(X=1~31)
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all// 把CANMC读入影子寄存器
ECanaShadow.CANMC.bit.CCR = 1 // 改变配置请求位
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all// 把配置好的寄存器值回写
EDIS
/*CPU要求对配置寄存器CANBTC和SCC的接收屏蔽寄存器(CANGAM,LAM[0]和LAM[3])进行写 *** 作。对该位置位后,CPU必须等待,直到CANES寄存器的CCE标志位在送入CANBTC寄存器之前为1 */
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all
} while(ECanaShadow.CANES.bit.CCE != 1 ) // 当CCE=1时可以对CANBTC进行 *** 作。
// 配置波特率
EALLOW
ECanaShadow.CANBTC.all = ECanaRegs.CANBTC.all// 把CANBTC读入影子寄存器
ECanaShadow.CANBTC.bit.BRP = 149 // (BRP+1)=150, 最小时间单位TQ=1us
ECanaShadow.CANBTC.bit.TSEG2 = 2 // 位定时bit-time=(TSEG1+1)+(TSEG1+1)+1
ECanaShadow.CANBTC.bit.TSEG1 = 3 // bit-time=8us, 所以波特率为125Kpbs
ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all // 把配置好的寄存器值回写
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all // 把CANMC读入影子寄存器
ECanaShadow.CANMC.bit.CCR = 0 // 设置CCR=0, CPU请求正常模式
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all // 把配置好的寄存器值回写
EDIS
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all
} while(ECanaShadow.CANES.bit.CCE != 0 ) // 等待 CCE 位被清零
// 配置eCAN为自测试模式,使能eCAN的增强特性
EALLOW
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all
ECanaShadow.CANMC.bit.STM = 1 // 配置CAN 为自测试模式
// CANMC.bit.STM=0,正常模式,CANMC.bit.STM=1,自测试模式
ECanaShadow.CANMC.bit.SCM = 1 // 选择HECC工作模式
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all
EDIS
}
void main(void)
{
Uint16 j
InitSysCtrl()// 系统初始化程序,该子程序在DSP28_sysctrl.c中
DINT // 关闭总中断
IER = 0x0000 // 关闭外设中断
IFR = 0x0000 // 请中断标志
CAN_INIT()
// 开始循环发送数据
while(1)
{
ECanaRegs.CANTRS.all = 0x00000003
while(ECanaRegs.CANTA.all != 0x00000003 ) {}
ECanaRegs.CANTA.all = 0x0000FFFF
MessageReceivedCount++
for(j = 0j<32)
{
mailbox_read(j) // 把邮箱j(j=0~31)的数据读出来
j++
// mailbox_check(TestMbox1,TestMbox2,TestMbox3)// 测试程序是否正确
}
}
}
// 该函数读出邮箱序号(MBXnbr)指示的邮箱内容.
void mailbox_read(int16 MBXnbr)
{
volatile struct MBOX *Mailbox
Mailbox = &ECanaMboxes.MBOX0 + MBXnbr
TestMbox1 = Mailbox->MDRL.all// 读出当前邮箱数据低4字节
TestMbox2 = Mailbox->MDRH.all // 读出当前邮箱数据高4字节
TestMbox3 = Mailbox->MID.all// 读出当前邮箱ID
}
// 接收邮箱MBX的 MID作为MDRL 数据传输data
void mailbox_check(int32 T1,int32 T2,int32 T3)
{
if((T1 != T3) || ( T2 != 0x89ABCDEF))
ErrorCount++
}
程序地址总线(PAB)数据读地址总线(DRAB)
数据写地址总线(DWAB)
程序读数据总线(PRDB)
数据读数据总线(肢肆DRDB)
数据写数据总线(DWDB)
地址总线:PAB、DRAB、DWAB 数据总线:PRDB、DRDB、DWDB
地址总线 数据总线
读程序空间 PAB PRDB
读数据空间 DRABDRDB
写程序空间 PAB DWDB
写数据空间 DWABDWDB
特殊总线 *** 作
一般情况,PAB和PRDB只用于早饥亮从程序空间读指令,而DWDB只用于向数据空陆宽间写数据。而有些指令并不如此:PREAD、PWRITE、MAC、DMAC、QMACL、IMACL、MAC、XMACD
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)