// FILE: Lab9.c
// TITLE:DSP28 CAN Передача
//CPU Timer0 ISR каждые 50 мс
//Watchdog активен, работает в ISR и в главном цикле
//CAN-сообщение: 1 Байт (состояние GPIO B15-B8) каждую 1 секунду
// Скорость 100KBPS
// Идентификатор: 0x1000 0000
// Mailbox #5
#include "DSP281x_Device.h" // Включение заголовочного файла
void Gpio_select(void);
void SpeedUpRevA(void);
void InitSystem(void);
void InitCan();
interrupt void cpu_timer0_isr(void);
// Программа обработки прерывания Timer 0
void main(void)
{
struct ECAN_REGS ECanaShadow;
InitSystem(); // Инициализация регистров ЦСП
Gpio_select(); // Инициализация линий ввода/вывода
InitPieCtrl();// Подключение PIE-модуля (DSP281x_PieCtrl.c)
InitPieVectTable(); // Подключение PIE-вектора (DSP281x_PieVect.c)
// отобразим PIE – вход для таймера прерываний Timer 0
EALLOW; // Необходимо для записи EALLOW в защищенные регистры
PieVectTable.TINT0 = &cpu_timer0_isr;
EDIS; // Необходимо для отмены записи EALLOW в защищенные регистры
InitCpuTimers();
// Настроить CPU-Timer 0 на прерывание каждые 50 мс:
// 150MHz частота CPU, период прерывания 50000 мкс
ConfigCpuTimer(&CpuTimer0, 150, 50000);
// Допуск TINT0 в PIE: Группа 1 прерывание 7
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
// Допуск CPU к INT1 связанному с CPU-Timer 0:
IER = 1;
// Разрешение глобальным прерываниям и более приоритетным событиям отладки в реальном времени:
EINT; // Разрешение глобального прерывания INTM
ERTM; // Разрешение глобального прерывания в реальном времени DBGM
InitCan();
/* Запись в поле MSGID */
ECanaMboxes.MBOX5.MSGID.all = 0x????????;
ECanaMboxes.MBOX5.MSGID.bit.IDE =?; // Установка идентификатора сообщения
/* Установка Mailbox 5 передающим */
ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
ECanaShadow.CANMD.bit.MD5 =?;
ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;
/* Активация Mailbox 5 */
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME5 =?;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
/* Установка длины сообщения равной 1 */
ECanaMboxes.MBOX5.MSGCTRL.bit.DLC =?;
CpuTimer0Regs.TCR.bit.TSS = 0;
while(1)
{
while(CpuTimer0.InterruptCount < 20)
{ // ожидание Timer 0
EALLOW;
SysCtrlRegs.WDKEY = 0xAA; // и передача watchdog #2
EDIS;
}
CpuTimer0.InterruptCount = 0; // обнулить таймер прерываний
ECanaMboxes.MBOX5.MDL.byte.BYTE0 = (GpioDataRegs.GPBDAT.all>>8);
ECanaShadow.CANTRS.all =?;
ECanaShadow.CANTRS.bit.TRS5 =?; // Посыл запроса передачи Mailbox 5
ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
while(ECanaRegs.CANTA.bit.TA5 == 0) {} // Когда бит TA5 установлен..
ECanaShadow.CANTA.all =?;
ECanaShadow.CANTA.bit.TA5 =?; // Установка бита TA5 в исходное состояние
ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;
}
}
void Gpio_select(void)
{
EALLOW;
GpioMuxRegs.GPAMUX.all = 0x?; // Настройка линий ввода/вывода на работу в качестве портов
GpioMuxRegs.GPBMUX.all = 0x?;
GpioMuxRegs.GPDMUX.all = 0x?;
GpioMuxRegs.GPFMUX.all = 0x?;
GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 =?; // Настройка периферийных функций CANTXA и
GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 =?; // CANRXA для работы с CAN-модулем
GpioMuxRegs.GPEMUX.all = 0x?;
GpioMuxRegs.GPGMUX.all = 0x?;
GpioMuxRegs.GPADIR.all = 0x?; // Настройка портов А, D, E, F, G на ввод
GpioMuxRegs.GPBDIR.all = 0x????; // Настройка линий 15-8 на ввод, а линий 7-0 на вывод
GpioMuxRegs.GPDDIR.all = 0x?;
GpioMuxRegs.GPEDIR.all = 0x?;
GpioMuxRegs.GPFDIR.all = 0x?;
GpioMuxRegs.GPGDIR.all = 0x?;
GpioMuxRegs.GPAQUAL.all = 0x?; // Запрещение входного ограничителя
GpioMuxRegs.GPBQUAL.all = 0x?;
GpioMuxRegs.GPDQUAL.all = 0x?;
GpioMuxRegs.GPEQUAL.all = 0x?;
EDIS;
}
void InitSystem(void)
{
EALLOW;
SysCtrlRegs.WDCR= 0x00AF; // Работа сторожевого таймера
// 0x00E8 запрещение работы сторожевого таймера, предделитель = 1
// 0x00AF Разрешение работы сторожевого таймера, предделитель = 64
SysCtrlRegs.SCSR = 0; // Выработка сброса WDT
SysCtrlRegs.PLLCR.bit.DIV = 10; // Настройка блока умножения частоты
SysCtrlRegs.HISPCP.all = 0x1; // Задание значения предделителя высокоскоростного таймера
SysCtrlRegs.LOSPCP.all = 0x2; // Задание значения предделителя низкоскоростного таймера
// Запрещение работы периферийных устройств кроме eCAN
SysCtrlRegs.PCLKCR.bit.EVAENCLK=0;
SysCtrlRegs.PCLKCR.bit.EVBENCLK=0;
SysCtrlRegs.PCLKCR.bit.SCIAENCLK=0;
SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0;
SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0;
SysCtrlRegs.PCLKCR.bit.SPIENCLK=0;
SysCtrlRegs.PCLKCR.bit.ECANENCLK=1;
SysCtrlRegs.PCLKCR.bit.ADCENCLK=0;
EDIS;
}
interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++; // Сообщение watchdog-таймеру о каждом прерывании Timer 0
EALLOW;
SysCtrlRegs.WDKEY = 0x55; // Сообщение таймеру watchdog #1
EDIS;
// Это прерывание произошло от прерываний группы 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
void InitCan(void)
{
asm(" EALLOW");
/* Настроить линии TX и RX на передачу используя регистры eCAN*/
ECanaRegs.CANTIOC.bit.TXFUNC =?;
ECanaRegs.CANRIOC.bit.RXFUNC =?;
/* Настроить eCAN на режим HECC - (доступ к чтению mailboxes 16 - 31) */
// В режиме HECC разрешена особенность временного ограничения
ECanaRegs.CANMC.bit.SCB =?;
/* Настроить параметры тактовой синхронизации */
ECanaRegs.CANMC.bit.CCR =?; // Установка CCR для получения доступа к регистрам времени
while(ECanaRegs.CANES.bit.CCE!= 1) {} // Когда ССЕ (флаг для передачи запроса инициализации CAN)установлен..
ECanaRegs.CANBTC.bit.BRPREG =??; // Установка параметров BRP,TSEG1 и TSEG2
ECanaRegs.CANBTC.bit.TSEG2REG =?; // таким образом, чтобы скорость передачи
ECanaRegs.CANBTC.bit.TSEG1REG =??; // была 100кбит/с
ECanaRegs.CANMC.bit.CCR =?; // Сброс CCR регистра CANMC для запрета доступа к регистру CANBTC
while(ECanaRegs.CANES.bit.CCE ==!0) {} // Когда CCE сброшен..
}
/* Отключить все Mailboxes */
//=================================================
// Конец программы.
//=================================================
Листинг приема сообщения
// FILE: Lab10.c
// TITLE: DSP28 CAN Прием, Mailbox 1
//Идентификатор 0x10 000 000; Скорость 100 KBPS
//Байт данных 1 из CAN – кадр будет скопирован из 8 LED's (GPIOB7 - B0)
// Watchdog активен, работает в ISR и в главном цикле
#include "DSP281x_Device.h" // Включение заголовочного файла
void Gpio_select(void);
void InitSystem(void);
void InitCan(void);
void main(void)
{
struct ECAN_REGS ECanaShadow;
InitSystem(); // Инициализация регистров ЦСП
Gpio_select(); // Инициализация линий ввода/вывода
InitCan();
/* Запись в поле MSGID - MBX номер записан как его MSGID */
ECanaMboxes.MBOX1.MSGID.all = 0x????????; // Установка идентификатора сообщения
ECanaMboxes.MBOX1.MSGID.bit.IDE =?;
/* Установка Mailbox 1 принимающим */
ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
ECanaShadow.CANMD.bit.MD1 =?;
ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;
/* Активация Mailbox 1 */
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME1 =?;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
while(1)
{
do
{
ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;
EALLOW;
SysCtrlRegs.WDKEY = 0x55; // Сообщение таймеру watchdog #1
SysCtrlRegs.WDKEY = 0xAA; // Сообщение таймеру watchdog #2
EDIS;
}
while(ECanaShadow.CANRMP.bit.RMP1!= 1); // Когда RMP1 установлен..
GpioDataRegs.GPBDAT.all = ECanaMboxes.MBOX1.MDL.byte.BYTE0;
ECanaShadow.CANRMP.bit.RMP1 =?;
ECanaRegs.CANRMP.all = ECanaShadow.CANRMP.all;
// Clear RMP1 bit and start again
}
}
void Gpio_select(void)
{
EALLOW;
GpioMuxRegs.GPAMUX.all = 0x?; // Настройка линий ввода/вывода на работу в качестве портов
GpioMuxRegs.GPBMUX.all = 0x?;
GpioMuxRegs.GPDMUX.all = 0x?;
GpioMuxRegs.GPFMUX.all = 0x?;
GpioMuxRegs.GPEMUX.all = 0x?;
GpioMuxRegs.GPGMUX.all = 0x?;
GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 =?; // Настройка периферийных функций CANTхA и CANRхA
GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 =?;
GpioMuxRegs.GPADIR.all = 0x?; // Настройка портов А, D, E, F, G на ввод
GpioMuxRegs.GPBDIR.all = 0x????; // Настройка линий 15-8 на ввод, а линий 7-0 на вывод
GpioMuxRegs.GPDDIR.all = 0x?;
GpioMuxRegs.GPEDIR.all = 0x?;
GpioMuxRegs.GPFDIR.all = 0x?;
GpioMuxRegs.GPGDIR.all = 0x?;
GpioMuxRegs.GPAQUAL.all = 0x?; // Запрещение входного ограничителя
GpioMuxRegs.GPBQUAL.all = 0x?;
GpioMuxRegs.GPDQUAL.all = 0x?;
GpioMuxRegs.GPEQUAL.all = 0x?;
EDIS;
}
void InitSystem(void)
{
EALLOW;
SysCtrlRegs.WDCR= 0x00AF; // Работа сторожевого таймера
// 0x00E8 запрещение работы сторожевого таймера, предделитель = 1
// 0x00AF Разрешение работы сторожевого таймера, предделитель = 64
SysCtrlRegs.SCSR = 0; // Выработка сброса WDT
SysCtrlRegs.PLLCR.bit.DIV = 10; // Настройка блока умножения частоты
SysCtrlRegs.HISPCP.all = 0x1; // Задание значения предделителя высокоскоростного таймера
SysCtrlRegs.LOSPCP.all = 0x2; // Задание значения предделителя низкоскоростного таймера
// Запрещение работы периферийных устройств кроме еСAN
SysCtrlRegs.PCLKCR.bit.EVAENCLK=0;
SysCtrlRegs.PCLKCR.bit.EVBENCLK=0;
SysCtrlRegs.PCLKCR.bit.SCIAENCLK=0;
SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0;
SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0;
SysCtrlRegs.PCLKCR.bit.SPIENCLK=0;
SysCtrlRegs.PCLKCR.bit.ECANENCLK=1;
SysCtrlRegs.PCLKCR.bit.ADCENCLK=0;
EDIS;
}
void InitCan(void)
{
asm(" EALLOW");
/* Настроить линии TX и RX на передачу используя регистры eCAN*/
ECanaRegs.CANTIOC.bit.TXFUNC =?;
ECanaRegs.CANRIOC.bit.RXFUNC =?;
/* Настроить eCAN на режим HECC - (доступ к чтению mailboxes 16 - 31) */
// В режиме HECC разрешена особенность временного ограничения
ECanaRegs.CANMC.bit.SCB =?;
/* Настроить параметры тактовой синхронизации */
ECanaRegs.CANMC.bit.CCR =?; // Установка CCR для получения доступа к регистрам времени
while(ECanaRegs.CANES.bit.CCE!= 1) {} // Когда CCE (флаг для передачи запроса инициализации CAN) установлен..
ECanaRegs.CANBTC.bit.BRPREG =??;
ECanaRegs.CANBTC.bit.TSEG2REG =?;
ECanaRegs.CANBTC.bit.TSEG1REG =??;
ECanaRegs.CANMC.bit.CCR =?; // Сброс бита CCR регистра CANMС для запрета доступа к регистру CANBTC
while(ECanaRegs.CANES.bit.CCE ==!0) {} // Когда CCE сброшен..
/* Отключить все Mailboxes */
ECanaRegs.CANME.all =?; // Отключить все Mailboxеs кроме того который отправляет сообщение
asm(" EDIS");
}
//===========================================================
// Конец программы.
//===========================================================
Содержание отчета:
Отчет должен содерж ать цель работы, краткие теоретические сведения по теме работы, рисунки, тексты исследуемых программ передачи и приема данных через CAN-интерфейс, результаты их выполнения, выводы.
Контрольные вопросы:
1. Особенности CAN-интерфейса DSP TMS320F2812.
2. Модуль и сеть CAN.
3. Протоколы CAN.
4. Контроллеры еCAN.
5. Карта памяти еCAN.
6. Регистры управления и состояния eCAN.
7. Использование Mailbox для приема и передачи сообщений.